Bug 1413049 - Part 1: Add methods to EndianUtils for pointer-sized integers. r=Waldo.

--HG--
extra : rebase_source : 115e40ecaee589b07e4ff9534694e56af7690e9b
This commit is contained in:
Jason Orendorff 2018-03-01 11:05:13 -06:00
Родитель 7c98976964
Коммит 2418dfb4b3
2 изменённых файлов: 95 добавлений и 1 удалений

Просмотреть файл

@ -9,7 +9,9 @@
/*
* The classes LittleEndian and BigEndian expose static methods for
* reading and writing 16-, 32-, and 64-bit signed and unsigned integers
* in their respective endianness. The naming scheme is:
* in their respective endianness. The addresses read from or written
* to may be misaligned (although misaligned accesses may incur
* architecture-specific performance costs). The naming scheme is:
*
* {Little,Big}Endian::{read,write}{Uint,Int}<bitsize>
*
@ -361,6 +363,12 @@ protected:
return read<uint64_t>(aPtr);
}
/** Read a uintptr_t in ThisEndian endianness from |aPtr| and return it. */
static MOZ_MUST_USE uintptr_t readUintptr(const void* aPtr)
{
return read<uintptr_t>(aPtr);
}
/** Read an int16_t in ThisEndian endianness from |aPtr| and return it. */
static MOZ_MUST_USE int16_t readInt16(const void* aPtr)
{
@ -379,6 +387,12 @@ protected:
return read<int64_t>(aPtr);
}
/** Read an intptr_t in ThisEndian endianness from |aPtr| and return it. */
static MOZ_MUST_USE intptr_t readIntptr(const void* aPtr)
{
return read<intptr_t>(aPtr);
}
/** Write |aValue| to |aPtr| using ThisEndian endianness. */
static void writeUint16(void* aPtr, uint16_t aValue)
{
@ -397,6 +411,12 @@ protected:
write(aPtr, aValue);
}
/** Write |aValue| to |aPtr| using ThisEndian endianness. */
static void writeUintptr(void* aPtr, uintptr_t aValue)
{
write(aPtr, aValue);
}
/** Write |aValue| to |aPtr| using ThisEndian endianness. */
static void writeInt16(void* aPtr, int16_t aValue)
{
@ -415,6 +435,12 @@ protected:
write(aPtr, aValue);
}
/** Write |aValue| to |aPtr| using ThisEndian endianness. */
static void writeIntptr(void* aPtr, intptr_t aValue)
{
write(aPtr, aValue);
}
/*
* Converts a value of type T to little-endian format.
*
@ -630,15 +656,19 @@ public:
using super::readUint16;
using super::readUint32;
using super::readUint64;
using super::readUintptr;
using super::readInt16;
using super::readInt32;
using super::readInt64;
using super::readIntptr;
using super::writeUint16;
using super::writeUint32;
using super::writeUint64;
using super::writeUintptr;
using super::writeInt16;
using super::writeInt32;
using super::writeInt64;
using super::writeIntptr;
};
} /* namespace detail */

Просмотреть файл

@ -367,6 +367,18 @@ main()
MOZ_RELEASE_ASSERT(
BigEndian::readUint64(&unsigned_bytes[0]) == 0x102030405060708ULL);
if (sizeof(uintptr_t) == 8) {
MOZ_RELEASE_ASSERT(
LittleEndian::readUintptr(&unsigned_bytes[0]) == 0x0807060504030201ULL);
MOZ_RELEASE_ASSERT(
BigEndian::readUintptr(&unsigned_bytes[0]) == 0x0102030405060708ULL);
} else {
MOZ_RELEASE_ASSERT(
LittleEndian::readUintptr(&unsigned_bytes[0]) == 0x04030201U);
MOZ_RELEASE_ASSERT(
BigEndian::readUintptr(&unsigned_bytes[0]) == 0x01020304U);
}
LittleEndian::writeUint16(&buffer[0], 0x201);
MOZ_RELEASE_ASSERT(
memcmp(&unsigned_bytes[0], &buffer[0], sizeof(uint16_t)) == 0);
@ -388,6 +400,26 @@ main()
MOZ_RELEASE_ASSERT(
memcmp(&unsigned_bytes[0], &buffer[0], sizeof(uint64_t)) == 0);
memset(&buffer[0], 0xff, sizeof(buffer));
LittleEndian::writeUintptr(&buffer[0], uintptr_t(0x0807060504030201ULL));
MOZ_RELEASE_ASSERT(
memcmp(&unsigned_bytes[0], &buffer[0], sizeof(uintptr_t)) == 0);
if (sizeof(uintptr_t) == 4) {
MOZ_RELEASE_ASSERT(
LittleEndian::readUint32(&buffer[4]) == 0xffffffffU);
}
memset(&buffer[0], 0xff, sizeof(buffer));
if (sizeof(uintptr_t) == 8) {
BigEndian::writeUintptr(&buffer[0], uintptr_t(0x0102030405060708ULL));
} else {
BigEndian::writeUintptr(&buffer[0], uintptr_t(0x01020304U));
MOZ_RELEASE_ASSERT(
LittleEndian::readUint32(&buffer[4]) == 0xffffffffU);
}
MOZ_RELEASE_ASSERT(
memcmp(&unsigned_bytes[0], &buffer[0], sizeof(uintptr_t)) == 0);
MOZ_RELEASE_ASSERT(
LittleEndian::readInt16(&signed_bytes[0]) == int16_t(0xf2f1));
MOZ_RELEASE_ASSERT(
@ -403,6 +435,18 @@ main()
MOZ_RELEASE_ASSERT(
BigEndian::readInt64(&signed_bytes[0]) == int64_t(0xf1f2f3f4f5f6f7f8LL));
if (sizeof(uintptr_t) == 8) {
MOZ_RELEASE_ASSERT(
LittleEndian::readIntptr(&signed_bytes[0]) == intptr_t(0xf8f7f6f5f4f3f2f1LL));
MOZ_RELEASE_ASSERT(
BigEndian::readIntptr(&signed_bytes[0]) == intptr_t(0xf1f2f3f4f5f6f7f8LL));
} else {
MOZ_RELEASE_ASSERT(
LittleEndian::readIntptr(&signed_bytes[0]) == intptr_t(0xf4f3f2f1));
MOZ_RELEASE_ASSERT(
BigEndian::readIntptr(&signed_bytes[0]) == intptr_t(0xf1f2f3f4));
}
LittleEndian::writeInt16(&buffer[0], int16_t(0xf2f1));
MOZ_RELEASE_ASSERT(
memcmp(&signed_bytes[0], &buffer[0], sizeof(int16_t)) == 0);
@ -424,6 +468,26 @@ main()
MOZ_RELEASE_ASSERT(
memcmp(&signed_bytes[0], &buffer[0], sizeof(int64_t)) == 0);
memset(&buffer[0], 0xff, sizeof(buffer));
LittleEndian::writeIntptr(&buffer[0], intptr_t(0xf8f7f6f5f4f3f2f1LL));
MOZ_RELEASE_ASSERT(
memcmp(&signed_bytes[0], &buffer[0], sizeof(intptr_t)) == 0);
if (sizeof(intptr_t) == 4) {
MOZ_RELEASE_ASSERT(
LittleEndian::readUint32(&buffer[4]) == 0xffffffffU);
}
memset(&buffer[0], 0xff, sizeof(buffer));
if (sizeof(intptr_t) == 8) {
BigEndian::writeIntptr(&buffer[0], intptr_t(0xf1f2f3f4f5f6f7f8LL));
} else {
BigEndian::writeIntptr(&buffer[0], intptr_t(0xf1f2f3f4));
MOZ_RELEASE_ASSERT(
LittleEndian::readUint32(&buffer[4]) == 0xffffffffU);
}
MOZ_RELEASE_ASSERT(
memcmp(&signed_bytes[0], &buffer[0], sizeof(intptr_t)) == 0);
TestSingleSwap(uint16_t(0xf2f1), uint16_t(0xf1f2));
TestSingleSwap(uint32_t(0xf4f3f2f1), uint32_t(0xf1f2f3f4));
TestSingleSwap(uint64_t(0xf8f7f6f5f4f3f2f1), uint64_t(0xf1f2f3f4f5f6f7f8));