From 9e826ea2832f0444bcef9075b445d481a58a09c2 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 6 Aug 2009 18:24:55 -0400 Subject: [PATCH] [HB] Fix unaligned access --- src/hb-open-type-private.hh | 20 +++++++++++++++++--- src/hb-private.h | 22 ++++++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh index e5802032e..08dd07577 100644 --- a/src/hb-open-type-private.hh +++ b/src/hb-open-type-private.hh @@ -389,8 +389,8 @@ struct Sanitizer * Int types */ -/* TODO On machines that do not allow unaligned access, fix the accessors. */ -#define DEFINE_INT_TYPE1(NAME, TYPE, BIG_ENDIAN, BYTES) \ +/* TODO On machines that allow unaligned access, use this version. */ +#define _DEFINE_INT_TYPE1_UNALIGNED(NAME, TYPE, BIG_ENDIAN, BYTES) \ struct NAME \ { \ inline NAME& operator = (TYPE i) { (TYPE&) v = BIG_ENDIAN (i); return *this; } \ @@ -400,7 +400,21 @@ struct Sanitizer SANITIZE_DEBUG (); \ return SANITIZE_SELF (); \ } \ - private: char v[BYTES]; \ + private: unsigned char v[BYTES]; \ + }; \ + ASSERT_SIZE (NAME, BYTES) + +#define DEFINE_INT_TYPE1(NAME, TYPE, BIG_ENDIAN, BYTES) \ + struct NAME \ + { \ + inline NAME& operator = (TYPE i) { BIG_ENDIAN##_put_unaligned(v, i); return *this; } \ + inline operator TYPE(void) const { return BIG_ENDIAN##_get_unaligned (v); } \ + inline bool operator== (NAME o) const { return BIG_ENDIAN##_cmp_unaligned (v, o.v); } \ + inline bool sanitize (SANITIZE_ARG_DEF) { \ + SANITIZE_DEBUG (); \ + return SANITIZE_SELF (); \ + } \ + private: unsigned char v[BYTES]; \ }; \ ASSERT_SIZE (NAME, BYTES) #define DEFINE_INT_TYPE0(NAME, type, b) DEFINE_INT_TYPE1 (NAME, type##_t, hb_be_##type, b) diff --git a/src/hb-private.h b/src/hb-private.h index 5cb2f56de..98b322fbb 100644 --- a/src/hb-private.h +++ b/src/hb-private.h @@ -78,6 +78,28 @@ typedef GStaticMutex hb_mutex_t; #endif +#define hb_be_uint8_put_unaligned(v,V) (v[0] = (V), 0) +#define hb_be_uint8_get_unaligned(v) (uint8_t) (v[0]) +#define hb_be_uint8_cmp_unaligned(a,b) (a[0] == b[0]) +#define hb_be_int8_put_unaligned hb_be_uint8_put_unaligned +#define hb_be_int8_get_unaligned (int8_t) hb_be_uint8_get_unaligned +#define hb_be_int8_cmp_unaligned hb_be_uint8_cmp_unaligned + +#define hb_be_uint16_put_unaligned(v,V) (v[0] = (V>>8), v[1] = (V), 0) +#define hb_be_uint16_get_unaligned(v) (uint16_t) ((v[0] << 8) + v[1]) +#define hb_be_uint16_cmp_unaligned(a,b) (a[0] == b[0] && a[1] == b[1]) +#define hb_be_int16_put_unaligned hb_be_uint16_put_unaligned +#define hb_be_int16_get_unaligned (int16_t) hb_be_uint16_get_unaligned +#define hb_be_int16_cmp_unaligned hb_be_uint16_cmp_unaligned + +#define hb_be_uint32_put_unaligned(v,V) (v[0] = (V>>24), v[1] = (V>>16), v[2] = (V>>8), v[3] = (V), 0) +#define hb_be_uint32_get_unaligned(v) (uint32_t) ((v[0] << 24) + (v[1] << 16) + (v[2] << 8) + v[3]) +#define hb_be_uint32_cmp_unaligned(a,b) (a[0] == b[0] && a[1] == b[1] && a[2] == b[2] && a[3] == b[3]) +#define hb_be_int32_put_unaligned hb_be_uint32_put_unaligned +#define hb_be_int32_get_unaligned (int32_t) hb_be_uint32_get_unaligned +#define hb_be_int32_cmp_unaligned hb_be_uint32_cmp_unaligned + + /* Basics */ #undef MIN