--- modules/jsonreader/SkJSONReader.cpp.orig +++ modules/jsonreader/SkJSONReader.cpp @@ -37,7 +37,11 @@ void Value::init_tagged(Tag t) { memset(fData8, 0, sizeof(fData8)); +#if defined(SK_CPU_LENDIAN) fData8[0] = SkTo(t); +#else + fData8[kValueSize-1] = SkTo(t); +#endif SkASSERT(this->getTag() == t); } @@ -46,8 +50,13 @@ if (sizeof(Value) == sizeof(uintptr_t)) { *this->cast() = reinterpret_cast(p); // For 64-bit, we rely on the pointer lower bits being zero. +#if defined(SK_CPU_LENDIAN) SkASSERT(!(fData8[0] & kTagMask)); fData8[0] |= SkTo(t); +#else + SkASSERT(!(fData8[kValueSize-1] & kTagMask)); + fData8[kValueSize-1] |= SkTo(t); +#endif } else { // For 32-bit, we store the pointer in the upper word SkASSERT(sizeof(Value) == sizeof(uintptr_t) * 2); @@ -179,19 +188,26 @@ // Note: we picked kShortString == 0 to avoid setting explicitly below. static_assert(SkToU8(Tag::kShortString) == 0, "please don't break this"); +#if defined(SK_CPU_LENDIAN) // Since the first byte is occupied by the tag, we want the string chars [0..5] to land // on bytes [1..6] => the fastest way is to read8 @(src - 1) (always safe, because the // string requires a " prefix at the very least). memcpy(s64, src - 1, 8); -#if defined(SK_CPU_LENDIAN) // The mask for a max-length string (6), with a leading tag and trailing \0 is // 0x00ffffffffffff00. Accounting for the final left-shift, this becomes // 0x0000ffffffffffff. *s64 &= (0x0000ffffffffffffULL >> ((kMaxInlineStringSize - size) * 8)) // trailing \0s << 8; // tag byte #else - static_assert(false, "Big-endian builds are not supported at this time."); + // Same trick as above: read8 @(src - 1), which is always safe, then shift the tag + // byte off the top. (Reading 8 bytes forward from src is *not* safe: FastString + // only guarantees src[0..6].) + memcpy(s64, src - 1, 8); + + // Chars [0..5] now sit in bytes [0..5], byte 6 is the \0 terminator and byte 7 is + // the (zero) tag. + *s64 = (*s64 << 8) & (0xffffffffffff0000ULL << ((kMaxInlineStringSize - size) * 8)); #endif } };