Skip to content

Commit

Permalink
Bug 1413049 - Part 1: Add methods to EndianUtils for pointer-sized in…
Browse files Browse the repository at this point in the history
…tegers. r=Waldo.

--HG--
extra : rebase_source : 115e40ecaee589b07e4ff9534694e56af7690e9b
  • Loading branch information
Jason Orendorff committed Mar 1, 2018
1 parent 7c98976 commit 2418dfb
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 1 deletion.
32 changes: 31 additions & 1 deletion mfbt/EndianUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -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>
*
Expand Down Expand Up @@ -361,6 +363,12 @@ class Endian : private EndianUtils
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)
{
Expand All @@ -379,6 +387,12 @@ class Endian : private EndianUtils
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)
{
Expand All @@ -397,6 +411,12 @@ class Endian : private EndianUtils
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)
{
Expand All @@ -415,6 +435,12 @@ class Endian : private EndianUtils
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.
*
Expand Down Expand Up @@ -630,15 +656,19 @@ class EndianReadWrite : public Endian<ThisEndian>
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 */
Expand Down
64 changes: 64 additions & 0 deletions mfbt/tests/TestEndian.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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(
Expand All @@ -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);
Expand All @@ -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));
Expand Down

0 comments on commit 2418dfb

Please sign in to comment.