From f8ebe1dacd71d93dc2b401d0afbac86f5e14311d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Jun 2020 00:20:45 -0700 Subject: [PATCH 01/31] [constexpr] BEInt --- src/hb.hh | 64 ++++++++++++++++++++----------------------------------- 1 file changed, 23 insertions(+), 41 deletions(-) diff --git a/src/hb.hh b/src/hb.hh index ef735583f..0512304b0 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -530,25 +530,19 @@ template struct BEInt { public: - BEInt& operator = (Type V) - { - v = V; - return *this; - } - operator Type () const { return v; } + BEInt () = default; + constexpr BEInt (Type V) : v {V} {} + constexpr operator Type () const { return v; } private: uint8_t v; }; template struct BEInt { public: - BEInt& operator = (Type V) - { - v[0] = (V >> 8) & 0xFF; - v[1] = (V ) & 0xFF; - return *this; - } - operator Type () const + BEInt () = default; + constexpr BEInt (Type V) : v {(V >> 8) & 0xFF, + (V ) & 0xFF} {} + constexpr operator Type () const { #if ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) && \ defined(__BYTE_ORDER) && \ @@ -571,40 +565,28 @@ template struct BEInt { public: - BEInt& operator = (Type V) - { - v[0] = (V >> 16) & 0xFF; - v[1] = (V >> 8) & 0xFF; - v[2] = (V ) & 0xFF; - return *this; - } - operator Type () const - { - return (v[0] << 16) - + (v[1] << 8) - + (v[2] ); - } + BEInt () = default; + constexpr BEInt (Type V) : v {(V >> 16) & 0xFF, + (V >> 8) & 0xFF, + (V ) & 0xFF} {} + constexpr operator Type () const { return (v[0] << 16) + + (v[1] << 8) + + (v[2] ); } private: uint8_t v[3]; }; template struct BEInt { public: - BEInt& operator = (Type V) - { - v[0] = (V >> 24) & 0xFF; - v[1] = (V >> 16) & 0xFF; - v[2] = (V >> 8) & 0xFF; - v[3] = (V ) & 0xFF; - return *this; - } - operator Type () const - { - return (v[0] << 24) - + (v[1] << 16) - + (v[2] << 8) - + (v[3] ); - } + BEInt () = default; + constexpr BEInt (Type V) : v {(V >> 24) & 0xFF, + (V >> 16) & 0xFF, + (V >> 8) & 0xFF, + (V ) & 0xFF} {} + constexpr operator Type () const { return (v[0] << 24) + + (v[1] << 16) + + (v[2] << 8) + + (v[3] ); } private: uint8_t v[4]; }; From a4a99de0eb17b1de1be99534b5184fd1f1c53c37 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Jun 2020 00:22:02 -0700 Subject: [PATCH 02/31] [constexpr] bswap --- src/hb.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hb.hh b/src/hb.hh index 0512304b0..1e8919861 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -515,9 +515,9 @@ _hb_roundf (float x) { return floorf (x + .5f); } #define roundf(x) _hb_roundf(x) /* Endian swap, used in Windows related backends */ -static inline uint16_t hb_uint16_swap (const uint16_t v) +static inline constexpr uint16_t hb_uint16_swap (uint16_t v) { return (v >> 8) | (v << 8); } -static inline uint32_t hb_uint32_swap (const uint32_t v) +static inline constexpr uint32_t hb_uint32_swap (uint32_t v) { return (hb_uint16_swap (v) << 16) | hb_uint16_swap (v >> 16); } /* From 1981d83d7fefbc22d28d69714bfdac7aa5064d15 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Jun 2020 00:28:31 -0700 Subject: [PATCH 03/31] [constexpr] HB_MARK_AS_FLAG_T --- src/hb.hh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hb.hh b/src/hb.hh index 1e8919861..82e19422c 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -484,10 +484,10 @@ static_assert ((sizeof (hb_var_int_t) == 4), ""); #endif #define HB_MARK_AS_FLAG_T(T) \ extern "C++" { \ - static inline T operator | (T l, T r) { return T ((unsigned) l | (unsigned) r); } \ - static inline T operator & (T l, T r) { return T ((unsigned) l & (unsigned) r); } \ - static inline T operator ^ (T l, T r) { return T ((unsigned) l ^ (unsigned) r); } \ - static inline T operator ~ (T r) { return T (~(unsigned int) r); } \ + static inline constexpr T operator | (T l, T r) { return T ((unsigned) l | (unsigned) r); } \ + static inline constexpr T operator & (T l, T r) { return T ((unsigned) l & (unsigned) r); } \ + static inline constexpr T operator ^ (T l, T r) { return T ((unsigned) l ^ (unsigned) r); } \ + static inline constexpr T operator ~ (T r) { return T (~(unsigned int) r); } \ static inline T& operator |= (T &l, T r) { l = l | r; return l; } \ static inline T& operator &= (T& l, T r) { l = l & r; return l; } \ static inline T& operator ^= (T& l, T r) { l = l ^ r; return l; } \ From 59cfffb1af82c706e181db64e81794f43af05cf4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Jun 2020 00:34:07 -0700 Subject: [PATCH 04/31] m Change ASSERT_STATIC_EXPR_ZERO template arg type to bool --- src/hb.hh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hb.hh b/src/hb.hh index 82e19422c..f567f26a1 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -442,9 +442,9 @@ static int HB_UNUSED _hb_errno = 0; #define HB_STMT_END while (0) /* Static-assert as expression. */ -template class hb_assert_constant_t; -template <> class hb_assert_constant_t<1> {}; -#define ASSERT_STATIC_EXPR_ZERO(_cond) (0 * (unsigned int) sizeof (hb_assert_constant_t<_cond>)) +template class hb_assert_constant_t; +template <> class hb_assert_constant_t {}; +#define ASSERT_STATIC_EXPR_ZERO(_cond) (0u * (unsigned int) sizeof (hb_assert_constant_t<_cond>)) /* Lets assert int types. Saves trouble down the road. */ static_assert ((sizeof (int8_t) == 1), ""); From 61f8d0e57dd9eee7e174f091f4e43646251dbb06 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Jun 2020 00:38:56 -0700 Subject: [PATCH 05/31] m Rename ASSERT_STATIC_EXPR_ZERO to static_assert_expr --- src/hb-ot-shape-complex-arabic-win1256.hh | 4 ++-- src/hb-ot-shape-complex-indic.hh | 2 +- src/hb.hh | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/hb-ot-shape-complex-arabic-win1256.hh b/src/hb-ot-shape-complex-arabic-win1256.hh index b15e145f2..41e3dd38a 100644 --- a/src/hb-ot-shape-complex-arabic-win1256.hh +++ b/src/hb-ot-shape-complex-arabic-win1256.hh @@ -142,7 +142,7 @@ OT_UARRAY(Name##Substitute, OT_LIST(ToGlyphs)) \ ) \ OT_COVERAGE1(Name##Coverage, OT_LIST(FromGlyphs)) \ - /* ASSERT_STATIC_EXPR_ZERO (len(FromGlyphs) == len(ToGlyphs)) */ + /* static_assert_expr (len(FromGlyphs) == len(ToGlyphs)) */ #define OT_SUBLOOKUP_LIGATURE_SUBST_FORMAT1(Name, FirstGlyphs, LigatureSetOffsets) \ OT_SUBLOOKUP(Name, 1, \ @@ -151,7 +151,7 @@ OT_UARRAY(Name##LigatureSetOffsetsArray, OT_LIST(LigatureSetOffsets)) \ ) \ OT_COVERAGE1(Name##Coverage, OT_LIST(FirstGlyphs)) \ - /* ASSERT_STATIC_EXPR_ZERO (len(FirstGlyphs) == len(LigatureSetOffsets)) */ + /* static_assert_expr (len(FirstGlyphs) == len(LigatureSetOffsets)) */ #define OT_LIGATURE_SET(Name, LigatureSetOffsets) \ OT_UARRAY(Name, OT_LIST(LigatureSetOffsets)) diff --git a/src/hb-ot-shape-complex-indic.hh b/src/hb-ot-shape-complex-indic.hh index 63dc93ea9..dcb28a4e8 100644 --- a/src/hb-ot-shape-complex-indic.hh +++ b/src/hb-ot-shape-complex-indic.hh @@ -175,7 +175,7 @@ enum indic_matra_category_t { #define INDIC_COMBINE_CATEGORIES(S,M) \ ( \ - ASSERT_STATIC_EXPR_ZERO (S < 255 && M < 255) + \ + static_assert_expr (S < 255 && M < 255) + \ ( S | \ ( \ ( \ diff --git a/src/hb.hh b/src/hb.hh index f567f26a1..e4abc7c9e 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -444,7 +444,7 @@ static int HB_UNUSED _hb_errno = 0; /* Static-assert as expression. */ template class hb_assert_constant_t; template <> class hb_assert_constant_t {}; -#define ASSERT_STATIC_EXPR_ZERO(_cond) (0u * (unsigned int) sizeof (hb_assert_constant_t<_cond>)) +#define static_assert_expr(_cond) (bool (0u * (unsigned int) sizeof (hb_assert_constant_t<_cond>))) /* Lets assert int types. Saves trouble down the road. */ static_assert ((sizeof (int8_t) == 1), ""); @@ -498,10 +498,10 @@ static_assert ((sizeof (hb_var_int_t) == 4), ""); * For example, for testing "x ∈ {x1, x2, x3}" use: * (FLAG_UNSAFE(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3))) */ -#define FLAG(x) (ASSERT_STATIC_EXPR_ZERO ((unsigned)(x) < 32) + (((uint32_t) 1U) << (unsigned)(x))) +#define FLAG(x) (static_assert_expr ((unsigned)(x) < 32) + (((uint32_t) 1U) << (unsigned)(x))) #define FLAG_UNSAFE(x) ((unsigned)(x) < 32 ? (((uint32_t) 1U) << (unsigned)(x)) : 0) -#define FLAG_RANGE(x,y) (ASSERT_STATIC_EXPR_ZERO ((x) < (y)) + FLAG(y+1) - FLAG(x)) -#define FLAG64(x) (ASSERT_STATIC_EXPR_ZERO ((unsigned)(x) < 64) + (((uint64_t) 1ULL) << (unsigned)(x))) +#define FLAG_RANGE(x,y) (static_assert_expr ((x) < (y)) + FLAG(y+1) - FLAG(x)) +#define FLAG64(x) (static_assert_expr ((unsigned)(x) < 64) + (((uint64_t) 1ULL) << (unsigned)(x))) #define FLAG64_UNSAFE(x) ((unsigned)(x) < 64 ? (((uint64_t) 1ULL) << (unsigned)(x)) : 0) From 017f6b0d2441dc7602d9cb4b6783aaf5a0424f96 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Jun 2020 00:44:41 -0700 Subject: [PATCH 06/31] m Move static_assert_expr<> --- src/hb-meta.hh | 4 ++++ src/hb.hh | 5 ----- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 4c0898b1b..9fd73ac7f 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -49,6 +49,10 @@ template using hb_bool_constant = hb_integral_constant; using hb_true_type = hb_bool_constant; using hb_false_type = hb_bool_constant; +/* Static-assert as expression. */ +template struct static_assert_expr; +template <> struct static_assert_expr : hb_false_type {}; +#define static_assert_expr(C) static_assert_expr::value /* Basic type SFINAE. */ diff --git a/src/hb.hh b/src/hb.hh index e4abc7c9e..a8a22ae8b 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -441,11 +441,6 @@ static int HB_UNUSED _hb_errno = 0; #define HB_STMT_START do #define HB_STMT_END while (0) -/* Static-assert as expression. */ -template class hb_assert_constant_t; -template <> class hb_assert_constant_t {}; -#define static_assert_expr(_cond) (bool (0u * (unsigned int) sizeof (hb_assert_constant_t<_cond>))) - /* Lets assert int types. Saves trouble down the road. */ static_assert ((sizeof (int8_t) == 1), ""); static_assert ((sizeof (uint8_t) == 1), ""); From e1706ffecdc0469063b90bbef6178c092dd7f32b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Jun 2020 00:59:06 -0700 Subject: [PATCH 07/31] m [algs] Move flags here --- src/hb-algs.hh | 36 ++++++++++++++++++++++++++++++++++++ src/hb.hh | 36 ------------------------------------ 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 5b9c14e62..71f28434e 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -35,6 +35,42 @@ #include "hb-number.hh" +/* Flags */ + +/* Enable bitwise ops on enums marked as flags_t */ +/* To my surprise, looks like the function resolver is happy to silently cast + * one enum to another... So this doesn't provide the type-checking that I + * originally had in mind... :(. + * + * For MSVC warnings, see: https://github.com/harfbuzz/harfbuzz/pull/163 + */ +#ifdef _MSC_VER +# pragma warning(disable:4200) +# pragma warning(disable:4800) +#endif +#define HB_MARK_AS_FLAG_T(T) \ + extern "C++" { \ + static inline constexpr T operator | (T l, T r) { return T ((unsigned) l | (unsigned) r); } \ + static inline constexpr T operator & (T l, T r) { return T ((unsigned) l & (unsigned) r); } \ + static inline constexpr T operator ^ (T l, T r) { return T ((unsigned) l ^ (unsigned) r); } \ + static inline constexpr T operator ~ (T r) { return T (~(unsigned int) r); } \ + static inline T& operator |= (T &l, T r) { l = l | r; return l; } \ + static inline T& operator &= (T& l, T r) { l = l & r; return l; } \ + static inline T& operator ^= (T& l, T r) { l = l ^ r; return l; } \ + } \ + static_assert (true, "") + +/* Useful for set-operations on small enums. + * For example, for testing "x ∈ {x1, x2, x3}" use: + * (FLAG_UNSAFE(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3))) + */ +#define FLAG(x) (static_assert_expr ((unsigned)(x) < 32) + (((uint32_t) 1U) << (unsigned)(x))) +#define FLAG_UNSAFE(x) ((unsigned)(x) < 32 ? (((uint32_t) 1U) << (unsigned)(x)) : 0) +#define FLAG_RANGE(x,y) (static_assert_expr ((x) < (y)) + FLAG(y+1) - FLAG(x)) +#define FLAG64(x) (static_assert_expr ((unsigned)(x) < 64) + (((uint64_t) 1ULL) << (unsigned)(x))) +#define FLAG64_UNSAFE(x) ((unsigned)(x) < 64 ? (((uint64_t) 1ULL) << (unsigned)(x)) : 0) + + /* Encodes three unsigned integers in one 64-bit number. If the inputs have more than 21 bits, * values will be truncated / overlap, and might not decode exactly. */ #define HB_CODEPOINT_ENCODE3(x,y,z) (((uint64_t) (x) << 42) | ((uint64_t) (y) << 21) | (uint64_t) (z)) diff --git a/src/hb.hh b/src/hb.hh index a8a22ae8b..eab1cdb0c 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -464,42 +464,6 @@ static_assert ((sizeof (hb_var_int_t) == 4), ""); void operator=(const TypeName&) = delete -/* Flags */ - -/* Enable bitwise ops on enums marked as flags_t */ -/* To my surprise, looks like the function resolver is happy to silently cast - * one enum to another... So this doesn't provide the type-checking that I - * originally had in mind... :(. - * - * For MSVC warnings, see: https://github.com/harfbuzz/harfbuzz/pull/163 - */ -#ifdef _MSC_VER -# pragma warning(disable:4200) -# pragma warning(disable:4800) -#endif -#define HB_MARK_AS_FLAG_T(T) \ - extern "C++" { \ - static inline constexpr T operator | (T l, T r) { return T ((unsigned) l | (unsigned) r); } \ - static inline constexpr T operator & (T l, T r) { return T ((unsigned) l & (unsigned) r); } \ - static inline constexpr T operator ^ (T l, T r) { return T ((unsigned) l ^ (unsigned) r); } \ - static inline constexpr T operator ~ (T r) { return T (~(unsigned int) r); } \ - static inline T& operator |= (T &l, T r) { l = l | r; return l; } \ - static inline T& operator &= (T& l, T r) { l = l & r; return l; } \ - static inline T& operator ^= (T& l, T r) { l = l ^ r; return l; } \ - } \ - static_assert (true, "") - -/* Useful for set-operations on small enums. - * For example, for testing "x ∈ {x1, x2, x3}" use: - * (FLAG_UNSAFE(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3))) - */ -#define FLAG(x) (static_assert_expr ((unsigned)(x) < 32) + (((uint32_t) 1U) << (unsigned)(x))) -#define FLAG_UNSAFE(x) ((unsigned)(x) < 32 ? (((uint32_t) 1U) << (unsigned)(x)) : 0) -#define FLAG_RANGE(x,y) (static_assert_expr ((x) < (y)) + FLAG(y+1) - FLAG(x)) -#define FLAG64(x) (static_assert_expr ((unsigned)(x) < 64) + (((uint64_t) 1ULL) << (unsigned)(x))) -#define FLAG64_UNSAFE(x) ((unsigned)(x) < 64 ? (((uint64_t) 1ULL) << (unsigned)(x)) : 0) - - /* Size signifying variable-sized array */ #ifndef HB_VAR_ARRAY #define HB_VAR_ARRAY 1 From c2dbd6cc0f9f30b2faed1fa0f40cfff742baae86 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Jun 2020 01:15:36 -0700 Subject: [PATCH 08/31] Remove static_assert of sizeof basic sized int types --- src/hb.hh | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/hb.hh b/src/hb.hh index eab1cdb0c..3bddeeaeb 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -442,14 +442,6 @@ static int HB_UNUSED _hb_errno = 0; #define HB_STMT_END while (0) /* Lets assert int types. Saves trouble down the road. */ -static_assert ((sizeof (int8_t) == 1), ""); -static_assert ((sizeof (uint8_t) == 1), ""); -static_assert ((sizeof (int16_t) == 2), ""); -static_assert ((sizeof (uint16_t) == 2), ""); -static_assert ((sizeof (int32_t) == 4), ""); -static_assert ((sizeof (uint32_t) == 4), ""); -static_assert ((sizeof (int64_t) == 8), ""); -static_assert ((sizeof (uint64_t) == 8), ""); static_assert ((sizeof (hb_codepoint_t) == 4), ""); static_assert ((sizeof (hb_position_t) == 4), ""); static_assert ((sizeof (hb_mask_t) == 4), ""); From 2caae4a59aadf889b410c4e2f42c0285013c22e6 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Jun 2020 01:18:28 -0700 Subject: [PATCH 09/31] m Move class traits --- src/hb-meta.hh | 11 +++++++++++ src/hb.hh | 8 -------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 9fd73ac7f..e40d9fd17 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -224,6 +224,8 @@ struct hb_reference_wrapper }; +/* Type traits */ + template using hb_is_integral = hb_bool_constant< hb_is_same (hb_decay, char) || @@ -296,6 +298,15 @@ template <> struct hb_int_max : hb_integral_constant::value +/* Class traits. */ + +#define HB_DELETE_COPY_ASSIGN(TypeName) \ + TypeName(const TypeName&) = delete; \ + void operator=(const TypeName&) = delete +#define HB_DELETE_CREATE_COPY_ASSIGN(TypeName) \ + TypeName() = delete; \ + TypeName(const TypeName&) = delete; \ + void operator=(const TypeName&) = delete template struct _hb_is_destructible : hb_false_type {}; diff --git a/src/hb.hh b/src/hb.hh index 3bddeeaeb..f569fbfc7 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -447,14 +447,6 @@ static_assert ((sizeof (hb_position_t) == 4), ""); static_assert ((sizeof (hb_mask_t) == 4), ""); static_assert ((sizeof (hb_var_int_t) == 4), ""); -#define HB_DELETE_COPY_ASSIGN(TypeName) \ - TypeName(const TypeName&) = delete; \ - void operator=(const TypeName&) = delete -#define HB_DELETE_CREATE_COPY_ASSIGN(TypeName) \ - TypeName() = delete; \ - TypeName(const TypeName&) = delete; \ - void operator=(const TypeName&) = delete - /* Size signifying variable-sized array */ #ifndef HB_VAR_ARRAY From e5b7bc424dd08c206f8c5baf5ac1b67d1dfd116e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Jun 2020 01:24:02 -0700 Subject: [PATCH 10/31] m Add default value to BEInt<> Size template parameter --- src/hb-open-type.hh | 14 +++++++------- src/hb-serialize.hh | 2 +- src/hb.hh | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 8c4271b68..478bb60ac 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -53,7 +53,7 @@ namespace OT { */ /* Integer types in big-endian order and no alignment requirement */ -template +template struct IntType { typedef Type type; @@ -107,12 +107,12 @@ struct IntType DEFINE_SIZE_STATIC (Size); }; -typedef IntType HBUINT8; /* 8-bit unsigned integer. */ -typedef IntType HBINT8; /* 8-bit signed integer. */ -typedef IntType HBUINT16; /* 16-bit unsigned integer. */ -typedef IntType HBINT16; /* 16-bit signed integer. */ -typedef IntType HBUINT32; /* 32-bit unsigned integer. */ -typedef IntType HBINT32; /* 32-bit signed integer. */ +typedef IntType HBUINT8; /* 8-bit unsigned integer. */ +typedef IntType HBINT8; /* 8-bit signed integer. */ +typedef IntType HBUINT16; /* 16-bit unsigned integer. */ +typedef IntType HBINT16; /* 16-bit signed integer. */ +typedef IntType HBUINT32; /* 32-bit unsigned integer. */ +typedef IntType HBINT32; /* 32-bit signed integer. */ /* Note: we cannot defined a signed HBINT24 because there's no corresponding C type. * Works for unsigned, but not signed, since we rely on compiler for sign-extension. */ typedef IntType HBUINT24; /* 24-bit unsigned integer. */ diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index 7238fb0d8..fe29bdf96 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -524,7 +524,7 @@ struct hb_serialize_context_t template void assign_offset (const object_t* parent, const object_t::link_t &link, unsigned offset) { - auto &off = * ((BEInt *) (parent->head + link.position)); + auto &off = * ((BEInt *) (parent->head + link.position)); assert (0 == off); check_assign (off, offset); } diff --git a/src/hb.hh b/src/hb.hh index f569fbfc7..fe6ffc873 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -464,10 +464,10 @@ static inline constexpr uint32_t hb_uint32_swap (uint32_t v) { return (hb_uint16_swap (v) << 16) | hb_uint16_swap (v >> 16); } /* - * Big-endian integers. Here because fundamental. + * Big-endian integers. */ -template struct BEInt; +template struct BEInt; template struct BEInt From 47f01c0726388102b82c1e04a5f134abb74b1831 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Jun 2020 01:25:35 -0700 Subject: [PATCH 11/31] m[algs] Move BEInt here --- src/hb-algs.hh | 81 +++++++++++++++++++++++++++++++++++++++++++++++++- src/hb.hh | 76 ---------------------------------------------- 2 files changed, 80 insertions(+), 77 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 71f28434e..52e64aed6 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -35,7 +35,9 @@ #include "hb-number.hh" -/* Flags */ +/* + * Flags + */ /* Enable bitwise ops on enums marked as flags_t */ /* To my surprise, looks like the function resolver is happy to silently cast @@ -71,6 +73,83 @@ #define FLAG64_UNSAFE(x) ((unsigned)(x) < 64 ? (((uint64_t) 1ULL) << (unsigned)(x)) : 0) +/* + * Big-endian integers. + */ + +/* Endian swap, used in Windows related backends */ +static inline constexpr uint16_t hb_uint16_swap (uint16_t v) +{ return (v >> 8) | (v << 8); } +static inline constexpr uint32_t hb_uint32_swap (uint32_t v) +{ return (hb_uint16_swap (v) << 16) | hb_uint16_swap (v >> 16); } + +template struct BEInt; +template +struct BEInt +{ + public: + BEInt () = default; + constexpr BEInt (Type V) : v {V} {} + constexpr operator Type () const { return v; } + private: uint8_t v; +}; +template +struct BEInt +{ + public: + BEInt () = default; + constexpr BEInt (Type V) : v {(V >> 8) & 0xFF, + (V ) & 0xFF} {} + constexpr operator Type () const + { +#if ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) && \ + defined(__BYTE_ORDER) && \ + (__BYTE_ORDER == __LITTLE_ENDIAN || __BYTE_ORDER == __BIG_ENDIAN) + /* Spoon-feed the compiler a big-endian integer with alignment 1. + * https://github.com/harfbuzz/harfbuzz/pull/1398 */ + struct __attribute__((packed)) packed_uint16_t { uint16_t v; }; +#if __BYTE_ORDER == __LITTLE_ENDIAN + return __builtin_bswap16 (((packed_uint16_t *) this)->v); +#else /* __BYTE_ORDER == __BIG_ENDIAN */ + return ((packed_uint16_t *) this)->v; +#endif +#endif + return (v[0] << 8) + + (v[1] ); + } + private: uint8_t v[2]; +}; +template +struct BEInt +{ + public: + BEInt () = default; + constexpr BEInt (Type V) : v {(V >> 16) & 0xFF, + (V >> 8) & 0xFF, + (V ) & 0xFF} {} + constexpr operator Type () const { return (v[0] << 16) + + (v[1] << 8) + + (v[2] ); } + private: uint8_t v[3]; +}; +template +struct BEInt +{ + public: + BEInt () = default; + constexpr BEInt (Type V) : v {(V >> 24) & 0xFF, + (V >> 16) & 0xFF, + (V >> 8) & 0xFF, + (V ) & 0xFF} {} + constexpr operator Type () const { return (v[0] << 24) + + (v[1] << 16) + + (v[2] << 8) + + (v[3] ); } + private: uint8_t v[4]; +}; + + + /* Encodes three unsigned integers in one 64-bit number. If the inputs have more than 21 bits, * values will be truncated / overlap, and might not decode exactly. */ #define HB_CODEPOINT_ENCODE3(x,y,z) (((uint64_t) (x) << 42) | ((uint64_t) (y) << 21) | (uint64_t) (z)) diff --git a/src/hb.hh b/src/hb.hh index fe6ffc873..54d0d9823 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -457,82 +457,6 @@ static inline float _hb_roundf (float x) { return floorf (x + .5f); } #define roundf(x) _hb_roundf(x) -/* Endian swap, used in Windows related backends */ -static inline constexpr uint16_t hb_uint16_swap (uint16_t v) -{ return (v >> 8) | (v << 8); } -static inline constexpr uint32_t hb_uint32_swap (uint32_t v) -{ return (hb_uint16_swap (v) << 16) | hb_uint16_swap (v >> 16); } - -/* - * Big-endian integers. - */ - -template struct BEInt; - -template -struct BEInt -{ - public: - BEInt () = default; - constexpr BEInt (Type V) : v {V} {} - constexpr operator Type () const { return v; } - private: uint8_t v; -}; -template -struct BEInt -{ - public: - BEInt () = default; - constexpr BEInt (Type V) : v {(V >> 8) & 0xFF, - (V ) & 0xFF} {} - constexpr operator Type () const - { -#if ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) && \ - defined(__BYTE_ORDER) && \ - (__BYTE_ORDER == __LITTLE_ENDIAN || __BYTE_ORDER == __BIG_ENDIAN) - /* Spoon-feed the compiler a big-endian integer with alignment 1. - * https://github.com/harfbuzz/harfbuzz/pull/1398 */ - struct __attribute__((packed)) packed_uint16_t { uint16_t v; }; -#if __BYTE_ORDER == __LITTLE_ENDIAN - return __builtin_bswap16 (((packed_uint16_t *) this)->v); -#else /* __BYTE_ORDER == __BIG_ENDIAN */ - return ((packed_uint16_t *) this)->v; -#endif -#endif - return (v[0] << 8) - + (v[1] ); - } - private: uint8_t v[2]; -}; -template -struct BEInt -{ - public: - BEInt () = default; - constexpr BEInt (Type V) : v {(V >> 16) & 0xFF, - (V >> 8) & 0xFF, - (V ) & 0xFF} {} - constexpr operator Type () const { return (v[0] << 16) - + (v[1] << 8) - + (v[2] ); } - private: uint8_t v[3]; -}; -template -struct BEInt -{ - public: - BEInt () = default; - constexpr BEInt (Type V) : v {(V >> 24) & 0xFF, - (V >> 16) & 0xFF, - (V >> 8) & 0xFF, - (V ) & 0xFF} {} - constexpr operator Type () const { return (v[0] << 24) - + (v[1] << 16) - + (v[2] << 8) - + (v[3] ); } - private: uint8_t v[4]; -}; - /* * For lack of a better place, put Zawgyi script hack here. From 711c241f6c7e18c5403602375a733af74df76f83 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Jun 2020 01:40:30 -0700 Subject: [PATCH 12/31] m[mutex] Remove busyloop mutex implemenation Don't know why I ever added this. :) --- configure.ac | 5 ----- meson.build | 3 --- src/hb-mutex.hh | 18 ------------------ 3 files changed, 26 deletions(-) diff --git a/configure.ac b/configure.ac index 2e16b4861..de22f5185 100644 --- a/configure.ac +++ b/configure.ac @@ -449,11 +449,6 @@ if $hb_cv_have_solaris_atomic_ops; then AC_DEFINE(HAVE_SOLARIS_ATOMIC_OPS, 1, [Have Solaris __machine_*_barrier and atomic_* operations]) fi -if test "$os_win32" = no && ! $have_pthread; then - AC_CHECK_HEADERS(sched.h) - AC_SEARCH_LIBS(sched_yield,rt,AC_DEFINE(HAVE_SCHED_YIELD, 1, [Have sched_yield])) -fi - dnl =========================================================================== AC_CONFIG_FILES([ diff --git a/meson.build b/meson.build index 83c179967..71073e26e 100644 --- a/meson.build +++ b/meson.build @@ -285,9 +285,6 @@ if host_machine.system() != 'windows' if thread_dep.found() conf.set('HAVE_PTHREAD', 1) - else - check_headers += ['sched.h'] - check_funcs += ['sched_yield', {'link_with': 'rt'}] endif endif diff --git a/src/hb-mutex.hh b/src/hb-mutex.hh index 56392d049..2fc8d7ee5 100644 --- a/src/hb-mutex.hh +++ b/src/hb-mutex.hh @@ -73,24 +73,6 @@ typedef CRITICAL_SECTION hb_mutex_impl_t; #define hb_mutex_impl_finish(M) DeleteCriticalSection (M) -#elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES) - -#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_YIELD) -# include -# define HB_SCHED_YIELD() sched_yield () -#else -# define HB_SCHED_YIELD() HB_STMT_START {} HB_STMT_END -#endif - -/* This actually is not a totally awful implementation. */ -typedef volatile int hb_mutex_impl_t; -#define HB_MUTEX_IMPL_INIT 0 -#define hb_mutex_impl_init(M) *(M) = 0 -#define hb_mutex_impl_lock(M) HB_STMT_START { while (__sync_lock_test_and_set((M), 1)) HB_SCHED_YIELD (); } HB_STMT_END -#define hb_mutex_impl_unlock(M) __sync_lock_release (M) -#define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END - - #elif defined(HB_NO_MT) typedef int hb_mutex_impl_t; From 7099a6dca18c12a3bb062adba4d429abc46d76a9 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Jun 2020 01:47:37 -0700 Subject: [PATCH 13/31] [atomic] Remove old Intel primitives implementation --- .github/workflows/coverity-scan.yml | 6 +++--- CMakeLists.txt | 14 -------------- configure.ac | 16 ---------------- meson-cc-tests/intel-atomic-primitives-test.c | 6 ------ meson.build | 4 ---- src/hb-atomic.hh | 9 --------- 6 files changed, 3 insertions(+), 52 deletions(-) delete mode 100644 meson-cc-tests/intel-atomic-primitives-test.c diff --git a/.github/workflows/coverity-scan.yml b/.github/workflows/coverity-scan.yml index a2c311f9c..6fcb4e5ef 100644 --- a/.github/workflows/coverity-scan.yml +++ b/.github/workflows/coverity-scan.yml @@ -19,12 +19,12 @@ jobs: tar xzf cov-analysis-linux64.tar.gz --strip 1 -C cov-analysis-linux64 env: TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }} - + # ideally we should've used meson and ninja here but it complains about coverage or something - - run: cov-analysis-linux64/bin/cov-build --dir cov-int clang src/hb-*.cc -DHAVE_FREETYPE -DHAVE_GRAPHITE2 -DHAVE_GLIB -DHAVE_ICU `pkg-config --cflags freetype2 graphite2 glib-2.0 icu-uc` -DHAVE_INTEL_ATOMIC_PRIMITIVES -DHAVE_ROUNDF -DHAVE_SYS_MMAN_H -DHAVE_UNISTD_H -DHAVE_GETPAGESIZE -DHB_EXPERIMENTAL_API -c + - run: cov-analysis-linux64/bin/cov-build --dir cov-int clang src/hb-*.cc -DHAVE_FREETYPE -DHAVE_GRAPHITE2 -DHAVE_GLIB -DHAVE_ICU `pkg-config --cflags freetype2 graphite2 glib-2.0 icu-uc` -DHAVE_ROUNDF -DHAVE_SYS_MMAN_H -DHAVE_UNISTD_H -DHAVE_GETPAGESIZE -DHB_EXPERIMENTAL_API -c - run: tar czvf harfbuzz.tgz cov-int - + - name: submit to coverity run: | curl \ diff --git a/CMakeLists.txt b/CMakeLists.txt index 11118595f..9c290ff12 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -407,20 +407,6 @@ if (HB_HAVE_GOBJECT) endif () ## Atomic ops availability detection -file(WRITE "${PROJECT_BINARY_DIR}/try_compile_intel_atomic_primitives.c" -" void memory_barrier (void) { __sync_synchronize (); } - int atomic_add (int *i) { return __sync_fetch_and_add (i, 1); } - int mutex_trylock (int *m) { return __sync_lock_test_and_set (m, 1); } - void mutex_unlock (int *m) { __sync_lock_release (m); } - int main () { return 0; } -") -try_compile(HB_HAVE_INTEL_ATOMIC_PRIMITIVES - ${PROJECT_BINARY_DIR}/try_compile_intel_atomic_primitives - ${PROJECT_BINARY_DIR}/try_compile_intel_atomic_primitives.c) -if (HB_HAVE_INTEL_ATOMIC_PRIMITIVES) - add_definitions(-DHAVE_INTEL_ATOMIC_PRIMITIVES) -endif () - file(WRITE "${PROJECT_BINARY_DIR}/try_compile_solaris_atomic_ops.c" " #include /* This requires Solaris Studio 12.2 or newer: */ diff --git a/configure.ac b/configure.ac index de22f5185..eeb9a5090 100644 --- a/configure.ac +++ b/configure.ac @@ -417,22 +417,6 @@ AM_CONDITIONAL(HAVE_CORETEXT, $have_coretext) dnl =========================================================================== -AC_CACHE_CHECK([for Intel atomic primitives], hb_cv_have_intel_atomic_primitives, [ - hb_cv_have_intel_atomic_primitives=false - AC_TRY_LINK([ - void memory_barrier (void) { __sync_synchronize (); } - int atomic_add (int *i) { return __sync_fetch_and_add (i, 1); } - int mutex_trylock (int *m) { return __sync_lock_test_and_set (m, 1); } - void mutex_unlock (int *m) { __sync_lock_release (m); } - ], [], hb_cv_have_intel_atomic_primitives=true - ) -]) -if $hb_cv_have_intel_atomic_primitives; then - AC_DEFINE(HAVE_INTEL_ATOMIC_PRIMITIVES, 1, [Have Intel __sync_* atomic primitives]) -fi - -dnl =========================================================================== - AC_CACHE_CHECK([for Solaris atomic operations], hb_cv_have_solaris_atomic_ops, [ hb_cv_have_solaris_atomic_ops=false AC_TRY_LINK([ diff --git a/meson-cc-tests/intel-atomic-primitives-test.c b/meson-cc-tests/intel-atomic-primitives-test.c deleted file mode 100644 index a5c804091..000000000 --- a/meson-cc-tests/intel-atomic-primitives-test.c +++ /dev/null @@ -1,6 +0,0 @@ -void memory_barrier (void) { __sync_synchronize (); } -int atomic_add (int *i) { return __sync_fetch_and_add (i, 1); } -int mutex_trylock (int *m) { return __sync_lock_test_and_set (m, 1); } -void mutex_unlock (int *m) { __sync_lock_release (m); } - -int main(void) { return 0;} diff --git a/meson.build b/meson.build index 71073e26e..343c06bf3 100644 --- a/meson.build +++ b/meson.build @@ -334,10 +334,6 @@ foreach check : check_funcs endif endforeach -if cpp.links(files('meson-cc-tests/intel-atomic-primitives-test.c'), name: 'Intel atomics') - conf.set('HAVE_INTEL_ATOMIC_PRIMITIVES', 1) -endif - if cpp.links(files('meson-cc-tests/solaris-atomic-operations.c'), name: 'Solaris atomic ops') conf.set('HAVE_SOLARIS_ATOMIC_OPS', 1) endif diff --git a/src/hb-atomic.hh b/src/hb-atomic.hh index b3fb296b4..60717c236 100644 --- a/src/hb-atomic.hh +++ b/src/hb-atomic.hh @@ -123,15 +123,6 @@ static_assert ((sizeof (LONG) == sizeof (int)), ""); #define hb_atomic_ptr_impl_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((P), (N), (O)) == (O)) -#elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES) - -#define _hb_memory_barrier() __sync_synchronize () - -#define hb_atomic_int_impl_add(AI, V) __sync_fetch_and_add ((AI), (V)) - -#define hb_atomic_ptr_impl_cmpexch(P,O,N) __sync_bool_compare_and_swap ((P), (O), (N)) - - #elif !defined(HB_NO_MT) && defined(HAVE_SOLARIS_ATOMIC_OPS) #include From c2fc2aa44cc8018ac689dde36efa34a635544197 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Jun 2020 01:49:28 -0700 Subject: [PATCH 14/31] [atomic] Remove Solaris intrinsics --- CMakeLists.txt | 17 ------------- configure.ac | 18 -------------- meson-cc-tests/solaris-atomic-operations.c | 8 ------ meson.build | 4 --- src/hb-atomic.hh | 29 ---------------------- 5 files changed, 76 deletions(-) delete mode 100644 meson-cc-tests/solaris-atomic-operations.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c290ff12..b95523f6e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -406,23 +406,6 @@ if (HB_HAVE_GOBJECT) ) endif () -## Atomic ops availability detection -file(WRITE "${PROJECT_BINARY_DIR}/try_compile_solaris_atomic_ops.c" -" #include - /* This requires Solaris Studio 12.2 or newer: */ - #include - void memory_barrier (void) { __machine_rw_barrier (); } - int atomic_add (volatile unsigned *i) { return atomic_add_int_nv (i, 1); } - void *atomic_ptr_cmpxchg (volatile void **target, void *cmp, void *newval) { return atomic_cas_ptr (target, cmp, newval); } - int main () { return 0; } -") -try_compile(HB_HAVE_SOLARIS_ATOMIC_OPS - ${PROJECT_BINARY_DIR}/try_compile_solaris_atomic_ops - ${PROJECT_BINARY_DIR}/try_compile_solaris_atomic_ops.c) -if (HB_HAVE_SOLARIS_ATOMIC_OPS) - add_definitions(-DHAVE_SOLARIS_ATOMIC_OPS) -endif () - ## Define harfbuzz library add_library(harfbuzz ${project_sources} ${project_extra_sources} ${project_headers}) diff --git a/configure.ac b/configure.ac index eeb9a5090..14199272e 100644 --- a/configure.ac +++ b/configure.ac @@ -417,24 +417,6 @@ AM_CONDITIONAL(HAVE_CORETEXT, $have_coretext) dnl =========================================================================== -AC_CACHE_CHECK([for Solaris atomic operations], hb_cv_have_solaris_atomic_ops, [ - hb_cv_have_solaris_atomic_ops=false - AC_TRY_LINK([ - #include - /* This requires Solaris Studio 12.2 or newer: */ - #include - void memory_barrier (void) { __machine_rw_barrier (); } - int atomic_add (volatile unsigned *i) { return atomic_add_int_nv (i, 1); } - void *atomic_ptr_cmpxchg (volatile void **target, void *cmp, void *newval) { return atomic_cas_ptr (target, cmp, newval); } - ], [], hb_cv_have_solaris_atomic_ops=true - ) -]) -if $hb_cv_have_solaris_atomic_ops; then - AC_DEFINE(HAVE_SOLARIS_ATOMIC_OPS, 1, [Have Solaris __machine_*_barrier and atomic_* operations]) -fi - -dnl =========================================================================== - AC_CONFIG_FILES([ Makefile src/Makefile diff --git a/meson-cc-tests/solaris-atomic-operations.c b/meson-cc-tests/solaris-atomic-operations.c deleted file mode 100644 index fae0acd87..000000000 --- a/meson-cc-tests/solaris-atomic-operations.c +++ /dev/null @@ -1,8 +0,0 @@ -#include -/* This requires Solaris Studio 12.2 or newer: */ -#include -void memory_barrier (void) { __machine_rw_barrier (); } -int atomic_add (volatile unsigned *i) { return atomic_add_int_nv (i, 1); } -void *atomic_ptr_cmpxchg (volatile void **target, void *cmp, void *newval) { return atomic_cas_ptr (target, cmp, newval); } - -int main(void) { return 0; } diff --git a/meson.build b/meson.build index 343c06bf3..2099e136b 100644 --- a/meson.build +++ b/meson.build @@ -334,10 +334,6 @@ foreach check : check_funcs endif endforeach -if cpp.links(files('meson-cc-tests/solaris-atomic-operations.c'), name: 'Solaris atomic ops') - conf.set('HAVE_SOLARIS_ATOMIC_OPS', 1) -endif - subdir('src') subdir('util') diff --git a/src/hb-atomic.hh b/src/hb-atomic.hh index 60717c236..0abe50caa 100644 --- a/src/hb-atomic.hh +++ b/src/hb-atomic.hh @@ -123,35 +123,6 @@ static_assert ((sizeof (LONG) == sizeof (int)), ""); #define hb_atomic_ptr_impl_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((P), (N), (O)) == (O)) -#elif !defined(HB_NO_MT) && defined(HAVE_SOLARIS_ATOMIC_OPS) - -#include -#include - -#define _hb_memory_r_barrier() __machine_r_barrier () -#define _hb_memory_w_barrier() __machine_w_barrier () -#define _hb_memory_barrier() __machine_rw_barrier () - -static inline int _hb_fetch_and_add (int *AI, int V) -{ - _hb_memory_w_barrier (); - int result = atomic_add_int_nv ((uint_t *) AI, V) - V; - _hb_memory_r_barrier (); - return result; -} -static inline bool _hb_compare_and_swap_ptr (void **P, void *O, void *N) -{ - _hb_memory_w_barrier (); - bool result = atomic_cas_ptr (P, O, N) == O; - _hb_memory_r_barrier (); - return result; -} - -#define hb_atomic_int_impl_add(AI, V) _hb_fetch_and_add ((AI), (V)) - -#define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_compare_and_swap_ptr ((P), (O), (N)) - - #elif !defined(HB_NO_MT) && defined(__APPLE__) #include From e208f80449caccea19f68e395ad4c38353849da6 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 20 Feb 2021 15:31:27 -0700 Subject: [PATCH 15/31] Make constexpr BEInt::operator Type() C++11-compatible Multiple return values not permitted until C++14 --- src/hb-algs.hh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 52e64aed6..ccb293d60 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -113,9 +113,10 @@ struct BEInt #else /* __BYTE_ORDER == __BIG_ENDIAN */ return ((packed_uint16_t *) this)->v; #endif -#endif +#else return (v[0] << 8) + (v[1] ); +#endif } private: uint8_t v[2]; }; From a89d9f25b4baa538293c397920e5a4489859878c Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 20 Feb 2021 15:35:28 -0700 Subject: [PATCH 16/31] m Err on -Wnarrowing instead of -Wc++11-narrowing On clang, -Wnarrowing is synonym for -Wc++11-narrowing. On gcc it isn't. So, use the widely-available one --- src/hb.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb.hh b/src/hb.hh index 54d0d9823..fd893d5fc 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -62,7 +62,6 @@ /* Error. Should never happen. */ #ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_ERROR -#pragma GCC diagnostic error "-Wc++11-narrowing" #pragma GCC diagnostic error "-Wcast-align" #pragma GCC diagnostic error "-Wcast-function-type" #pragma GCC diagnostic error "-Wdelete-non-virtual-dtor" @@ -75,6 +74,7 @@ #pragma GCC diagnostic error "-Wmissing-braces" #pragma GCC diagnostic error "-Wmissing-declarations" #pragma GCC diagnostic error "-Wmissing-prototypes" +#pragma GCC diagnostic error "-Wnarrowing" #pragma GCC diagnostic error "-Wnested-externs" #pragma GCC diagnostic error "-Wold-style-definition" #pragma GCC diagnostic error "-Wpointer-arith" From ff7bf88192b0ceed3e9489c82f6b902ced37e1b4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 20 Feb 2021 15:39:29 -0700 Subject: [PATCH 17/31] m[algs] Fix BEInt -Wnarrowing errors --- src/hb-algs.hh | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index ccb293d60..93d4acb3f 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -89,7 +89,7 @@ struct BEInt { public: BEInt () = default; - constexpr BEInt (Type V) : v {V} {} + constexpr BEInt (Type V) : v {uint8_t (V)} {} constexpr operator Type () const { return v; } private: uint8_t v; }; @@ -98,8 +98,8 @@ struct BEInt { public: BEInt () = default; - constexpr BEInt (Type V) : v {(V >> 8) & 0xFF, - (V ) & 0xFF} {} + constexpr BEInt (Type V) : v {uint8_t ((V >> 8) & 0xFF), + uint8_t ((V ) & 0xFF)} {} constexpr operator Type () const { #if ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) && \ @@ -125,9 +125,9 @@ struct BEInt { public: BEInt () = default; - constexpr BEInt (Type V) : v {(V >> 16) & 0xFF, - (V >> 8) & 0xFF, - (V ) & 0xFF} {} + constexpr BEInt (Type V) : v {uint8_t ((V >> 16) & 0xFF), + uint8_t ((V >> 8) & 0xFF), + uint8_t ((V ) & 0xFF)} {} constexpr operator Type () const { return (v[0] << 16) + (v[1] << 8) + (v[2] ); } @@ -138,10 +138,10 @@ struct BEInt { public: BEInt () = default; - constexpr BEInt (Type V) : v {(V >> 24) & 0xFF, - (V >> 16) & 0xFF, - (V >> 8) & 0xFF, - (V ) & 0xFF} {} + constexpr BEInt (Type V) : v {uint8_t ((V >> 24) & 0xFF), + uint8_t ((V >> 16) & 0xFF), + uint8_t ((V >> 8) & 0xFF), + uint8_t ((V ) & 0xFF)} {} constexpr operator Type () const { return (v[0] << 24) + (v[1] << 16) + (v[2] << 8) From 69464e9da04b9e9b7f5ac33688d3832b84a8318d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 20 Feb 2021 15:42:44 -0700 Subject: [PATCH 18/31] [algs] Another try at fixing BEInt constexpr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ../src/hb-algs.hh:120:3: error: body of constexpr function ‘constexpr BEInt::operator Type() const [with Type = short unsigned int]’ not a return-statement --- src/hb-algs.hh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 93d4acb3f..b053923df 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -100,6 +100,8 @@ struct BEInt BEInt () = default; constexpr BEInt (Type V) : v {uint8_t ((V >> 8) & 0xFF), uint8_t ((V ) & 0xFF)} {} + + struct __attribute__((packed)) packed_uint16_t { uint16_t v; }; constexpr operator Type () const { #if ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) && \ @@ -107,7 +109,6 @@ struct BEInt (__BYTE_ORDER == __LITTLE_ENDIAN || __BYTE_ORDER == __BIG_ENDIAN) /* Spoon-feed the compiler a big-endian integer with alignment 1. * https://github.com/harfbuzz/harfbuzz/pull/1398 */ - struct __attribute__((packed)) packed_uint16_t { uint16_t v; }; #if __BYTE_ORDER == __LITTLE_ENDIAN return __builtin_bswap16 (((packed_uint16_t *) this)->v); #else /* __BYTE_ORDER == __BIG_ENDIAN */ From f0947717ff43c37a6273e9de7c83d082ffec22eb Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Jun 2020 01:53:21 -0700 Subject: [PATCH 19/31] m[machinery] Move HB_VAR_ARRAY here --- src/hb-machinery.hh | 5 +++++ src/hb.hh | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index 54bc60d4c..3bd5a979b 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -80,6 +80,11 @@ static inline Type& StructAfter(TObject &X) * Size checking */ +/* Size signifying variable-sized array */ +#ifndef HB_VAR_ARRAY +#define HB_VAR_ARRAY 1 +#endif + /* Check _assertion in a method environment */ #define _DEFINE_INSTANCE_ASSERTION1(_line, _assertion) \ void _instance_assertion_on_line_##_line () const \ diff --git a/src/hb.hh b/src/hb.hh index fd893d5fc..5915e2819 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -448,11 +448,6 @@ static_assert ((sizeof (hb_mask_t) == 4), ""); static_assert ((sizeof (hb_var_int_t) == 4), ""); -/* Size signifying variable-sized array */ -#ifndef HB_VAR_ARRAY -#define HB_VAR_ARRAY 1 -#endif - static inline float _hb_roundf (float x) { return floorf (x + .5f); } #define roundf(x) _hb_roundf(x) From cba9893ac5470e5d70888ec240453b581a657252 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Jun 2020 01:55:57 -0700 Subject: [PATCH 20/31] m[algs] Move roundf() here --- src/hb-algs.hh | 7 +++++++ src/hb.hh | 5 ----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index b053923df..fc6ba15d5 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -150,6 +150,12 @@ struct BEInt private: uint8_t v[4]; }; +/* Floats. */ + +/* We want our rounding towards +infinity. */ +static inline float +_hb_roundf (float x) { return floorf (x + .5f); } +#define roundf(x) _hb_roundf(x) /* Encodes three unsigned integers in one 64-bit number. If the inputs have more than 21 bits, @@ -165,6 +171,7 @@ struct BEInt #define HB_CODEPOINT_DECODE3_11_7_14_2(v) ((hb_codepoint_t) (((v) >> 14) & 0x007Fu) | 0x0300) #define HB_CODEPOINT_DECODE3_11_7_14_3(v) ((hb_codepoint_t) (v) & 0x3FFFu) + struct { /* Note. This is dangerous in that if it's passed an rvalue, it returns rvalue-reference. */ diff --git a/src/hb.hh b/src/hb.hh index 5915e2819..0033215a4 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -448,11 +448,6 @@ static_assert ((sizeof (hb_mask_t) == 4), ""); static_assert ((sizeof (hb_var_int_t) == 4), ""); -static inline float -_hb_roundf (float x) { return floorf (x + .5f); } -#define roundf(x) _hb_roundf(x) - - /* * For lack of a better place, put Zawgyi script hack here. * https://github.com/harfbuzz/harfbuzz/issues/1162 From c55bf55154887ae485501bf8843e26abb5cdedaa Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Jun 2020 02:04:16 -0700 Subject: [PATCH 21/31] Remove HB_CONST_FUNC and HB_PURE_FUNC They are not necessary for inline functions. --- src/hb-algs.hh | 6 +++--- src/hb-face.hh | 2 +- src/hb.hh | 4 ---- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index fc6ba15d5..05c98ef20 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -537,7 +537,7 @@ HB_FUNCOBJ (hb_clamp); /* Return the number of 1 bits in v. */ template -static inline HB_CONST_FUNC unsigned int +static inline unsigned int hb_popcount (T v) { #if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) @@ -578,7 +578,7 @@ hb_popcount (T v) /* Returns the number of bits needed to store number */ template -static inline HB_CONST_FUNC unsigned int +static inline unsigned int hb_bit_storage (T v) { if (unlikely (!v)) return 0; @@ -652,7 +652,7 @@ hb_bit_storage (T v) /* Returns the number of zero bits in the least significant side of v */ template -static inline HB_CONST_FUNC unsigned int +static inline unsigned int hb_ctz (T v) { if (unlikely (!v)) return 8 * sizeof (T); diff --git a/src/hb-face.hh b/src/hb-face.hh index f1b472ccf..765f27285 100644 --- a/src/hb-face.hh +++ b/src/hb-face.hh @@ -81,7 +81,7 @@ struct hb_face_t return blob; } - HB_PURE_FUNC unsigned int get_upem () const + unsigned int get_upem () const { unsigned int ret = upem.get_relaxed (); if (unlikely (!ret)) diff --git a/src/hb.hh b/src/hb.hh index 0033215a4..4a7a834c8 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -245,12 +245,8 @@ extern "C" void hb_free_impl(void *ptr); #endif #if defined(__GNUC__) && (__GNUC__ >= 3) -#define HB_PURE_FUNC __attribute__((pure)) -#define HB_CONST_FUNC __attribute__((const)) #define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (__printf__, format_idx, arg_idx))) #else -#define HB_PURE_FUNC -#define HB_CONST_FUNC #define HB_PRINTF_FUNC(format_idx, arg_idx) #endif #if defined(__GNUC__) && (__GNUC__ >= 4) || (__clang__) From a3c35aee30879cd86351413fc395d3128fe6817a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Jun 2020 02:07:20 -0700 Subject: [PATCH 22/31] m Move HB_SCRIPT_MYANMAR_ZAWGYI --- src/hb-ot-shape-complex.hh | 3 ++- src/hb.hh | 8 -------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/hb-ot-shape-complex.hh b/src/hb-ot-shape-complex.hh index b592cad10..19e24b9f3 100644 --- a/src/hb-ot-shape-complex.hh +++ b/src/hb-ot-shape-complex.hh @@ -265,8 +265,9 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) return &_hb_ot_complex_shaper_myanmar; - /* https://github.com/harfbuzz/harfbuzz/issues/1162 */ +#define HB_SCRIPT_MYANMAR_ZAWGYI ((hb_script_t) HB_TAG ('Q','a','a','g')) case HB_SCRIPT_MYANMAR_ZAWGYI: + /* https://github.com/harfbuzz/harfbuzz/issues/1162 */ return &_hb_ot_complex_shaper_myanmar_zawgyi; diff --git a/src/hb.hh b/src/hb.hh index 4a7a834c8..31a6287a8 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -444,14 +444,6 @@ static_assert ((sizeof (hb_mask_t) == 4), ""); static_assert ((sizeof (hb_var_int_t) == 4), ""); -/* - * For lack of a better place, put Zawgyi script hack here. - * https://github.com/harfbuzz/harfbuzz/issues/1162 - */ - -#define HB_SCRIPT_MYANMAR_ZAWGYI ((hb_script_t) HB_TAG ('Q','a','a','g')) - - /* Headers we include for everyone. Keep topologically sorted by dependency. * They express dependency amongst themselves, but no other file should include * them directly.*/ From b39c1f7829bb6c7a69eb783e579246fdb627cd94 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 20 Feb 2021 15:46:17 -0700 Subject: [PATCH 23/31] a[build] Fix distcheck --- Makefile.am | 2 -- 1 file changed, 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index f476c964f..9f34c5f1a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -40,8 +40,6 @@ EXTRA_DIST = \ perf/texts/en-words.txt \ perf/texts/fa-monologue.txt \ perf/texts/fa-thelittleprince.txt \ - meson-cc-tests/intel-atomic-primitives-test.c \ - meson-cc-tests/solaris-atomic-operations.c \ mingw-configure.sh \ $(NULL) From 4d116ed0f02920f9ba4634d87f6201343930b657 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 22 Feb 2021 17:14:45 -0700 Subject: [PATCH 24/31] [ci] Remove cmake Apparently(?) our cmake build never bothered setting up pthreads. So when I removed the busy-loop mutex impl it now doesn't build. 711c241f6c7e18c5403602375a733af74df76f83 https://github.com/harfbuzz/harfbuzz/pull/2874#issuecomment-782778263 --- .circleci/config.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 26fa93971..d5e7de213 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -54,14 +54,13 @@ jobs: executor: autotools-executor steps: - checkout - - run: sudo apt update && DEBIAN_FRONTEND=noninteractive sudo apt install -y git ninja-build binutils libtool autoconf automake make gcc g++ pkg-config ragel gtk-doc-tools gobject-introspection libfontconfig1-dev libfreetype6-dev libglib2.0-dev libgirepository1.0-dev libcairo2-dev libicu-dev libgraphite2-dev python3 python3-pip cmake + - run: sudo apt update && DEBIAN_FRONTEND=noninteractive sudo apt install -y git ninja-build binutils libtool autoconf automake make gcc g++ pkg-config ragel gtk-doc-tools gobject-introspection libfontconfig1-dev libfreetype6-dev libglib2.0-dev libgirepository1.0-dev libcairo2-dev libicu-dev libgraphite2-dev python3 python3-pip - run: pip3 install fonttools meson --upgrade - run: ./autogen.sh - run: make -j32 - run: make distcheck - run: rm harfbuzz-* && make distdir - run: cd harfbuzz-* && meson build && ninja -Cbuild test - - run: cd harfbuzz-* && cmake -Bcmakebuild -H. && cmake --build cmakebuild - run: make dist - persist_to_workspace: root: . From 2ec802b42a0766c3fc159fd47a2596a5eaf27742 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Jun 2020 03:48:38 -0700 Subject: [PATCH 25/31] [object] Simplify reference_count_t --- src/hb-object.hh | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/hb-object.hh b/src/hb-object.hh index 39845a70e..fd96ea8ad 100644 --- a/src/hb-object.hh +++ b/src/hb-object.hh @@ -140,9 +140,7 @@ struct hb_lockable_set_t * Reference-count. */ -#define HB_REFERENCE_COUNT_INERT_VALUE 0 -#define HB_REFERENCE_COUNT_POISON_VALUE -0x0000DEAD -#define HB_REFERENCE_COUNT_INIT {HB_ATOMIC_INT_INIT (HB_REFERENCE_COUNT_INERT_VALUE)} +#define HB_REFERENCE_COUNT_INIT {HB_ATOMIC_INT_INIT (0)} struct hb_reference_count_t { @@ -152,9 +150,9 @@ struct hb_reference_count_t int get_relaxed () const { return ref_count.get_relaxed (); } int inc () const { return ref_count.inc (); } int dec () const { return ref_count.dec (); } - void fini () { ref_count.set_relaxed (HB_REFERENCE_COUNT_POISON_VALUE); } + void fini () { ref_count.set_relaxed (-0x0000DEAD); } - bool is_inert () const { return ref_count.get_relaxed () == HB_REFERENCE_COUNT_INERT_VALUE; } + bool is_inert () const { return !ref_count.get_relaxed (); } bool is_valid () const { return ref_count.get_relaxed () > 0; } }; From 140797d4a2841d4109ad667a38226bfd59de5829 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Jun 2020 03:51:09 -0700 Subject: [PATCH 26/31] [constexpr] hb_atomic_int_t --- src/hb-atomic.hh | 13 ++++++++----- src/hb-face.cc | 4 ++-- src/hb-object.hh | 11 +++-------- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/hb-atomic.hh b/src/hb-atomic.hh index 0abe50caa..6048efe86 100644 --- a/src/hb-atomic.hh +++ b/src/hb-atomic.hh @@ -221,9 +221,11 @@ inline void *hb_atomic_ptr_impl_get (void ** const P) { void *v = *P; _hb_memory #endif -#define HB_ATOMIC_INT_INIT(V) {V} struct hb_atomic_int_t { + hb_atomic_int_t () = default; + constexpr hb_atomic_int_t (int v) : v (v) {} + void set_relaxed (int v_) { hb_atomic_int_impl_set_relaxed (&v, v_); } void set (int v_) { hb_atomic_int_impl_set (&v, v_); } int get_relaxed () const { return hb_atomic_int_impl_get_relaxed (&v); } @@ -231,16 +233,17 @@ struct hb_atomic_int_t int inc () { return hb_atomic_int_impl_add (&v, 1); } int dec () { return hb_atomic_int_impl_add (&v, -1); } - int v; + int v = 0; }; - -#define HB_ATOMIC_PTR_INIT(V) {V} template struct hb_atomic_ptr_t { typedef hb_remove_pointer

T; + hb_atomic_ptr_t () = default; + constexpr hb_atomic_ptr_t (T* v) : v (v) {} + void init (T* v_ = nullptr) { set_relaxed (v_); } void set_relaxed (T* v_) { hb_atomic_ptr_impl_set_relaxed (&v, v_); } T *get_relaxed () const { return (T *) hb_atomic_ptr_impl_get_relaxed (&v); } @@ -250,7 +253,7 @@ struct hb_atomic_ptr_t T * operator -> () const { return get (); } template operator C * () const { return get (); } - T *v; + T *v = nullptr; }; diff --git a/src/hb-face.cc b/src/hb-face.cc index 900014fae..61bd4af7b 100644 --- a/src/hb-face.cc +++ b/src/hb-face.cc @@ -89,8 +89,8 @@ DEFINE_NULL_INSTANCE (hb_face_t) = nullptr, /* destroy */ 0, /* index */ - HB_ATOMIC_INT_INIT (1000), /* upem */ - HB_ATOMIC_INT_INIT (0), /* num_glyphs */ + 1000, /* upem */ + 0, /* num_glyphs */ /* Zero for the rest is fine. */ }; diff --git a/src/hb-object.hh b/src/hb-object.hh index fd96ea8ad..f3048b1c3 100644 --- a/src/hb-object.hh +++ b/src/hb-object.hh @@ -140,7 +140,7 @@ struct hb_lockable_set_t * Reference-count. */ -#define HB_REFERENCE_COUNT_INIT {HB_ATOMIC_INT_INIT (0)} +#define HB_REFERENCE_COUNT_INIT {0} struct hb_reference_count_t { @@ -195,15 +195,10 @@ struct hb_user_data_array_t struct hb_object_header_t { hb_reference_count_t ref_count; - mutable hb_atomic_int_t writable; + mutable hb_atomic_int_t writable = 0; hb_atomic_ptr_t user_data; }; -#define HB_OBJECT_HEADER_STATIC \ - { \ - HB_REFERENCE_COUNT_INIT, \ - HB_ATOMIC_INT_INIT (false), \ - HB_ATOMIC_PTR_INIT (nullptr) \ - } +#define HB_OBJECT_HEADER_STATIC {} /* From 3528a21e8d135e65d748895b469bf83c0ebec5ae Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Jun 2020 10:40:21 -0700 Subject: [PATCH 27/31] [atomic] Remove Apple implementation Continuation of https://github.com/harfbuzz/harfbuzz/pull/676 --- src/hb-atomic.hh | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/src/hb-atomic.hh b/src/hb-atomic.hh index 6048efe86..31c5b2b95 100644 --- a/src/hb-atomic.hh +++ b/src/hb-atomic.hh @@ -123,30 +123,6 @@ static_assert ((sizeof (LONG) == sizeof (int)), ""); #define hb_atomic_ptr_impl_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((P), (N), (O)) == (O)) -#elif !defined(HB_NO_MT) && defined(__APPLE__) - -#include -#ifdef __MAC_OS_X_MIN_REQUIRED -#include -#elif defined(__IPHONE_OS_MIN_REQUIRED) -#include -#endif - -#define _hb_memory_barrier() OSMemoryBarrier () - -#define hb_atomic_int_impl_add(AI, V) (OSAtomicAdd32Barrier ((V), (AI)) - (V)) - -#if (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4 || __IPHONE_VERSION_MIN_REQUIRED >= 20100) -#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwapPtrBarrier ((O), (N), (P)) -#else -#if __ppc64__ || __x86_64__ || __aarch64__ -#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap64Barrier ((int64_t) (O), (int64_t) (N), (int64_t*) (P)) -#else -#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap32Barrier ((int32_t) (O), (int32_t) (N), (int32_t*) (P)) -#endif -#endif - - #elif !defined(HB_NO_MT) && defined(_AIX) && (defined(__IBMCPP__) || defined(__ibmxl__)) #include From a666fe64a92206cc51d961be0848455d4fbd2bdd Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Jun 2020 10:43:49 -0700 Subject: [PATCH 28/31] [atomic] Comment --- src/hb-atomic.hh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hb-atomic.hh b/src/hb-atomic.hh index 31c5b2b95..94ae86c6f 100644 --- a/src/hb-atomic.hh +++ b/src/hb-atomic.hh @@ -52,7 +52,7 @@ #elif !defined(HB_NO_MT) && defined(__ATOMIC_ACQUIRE) -/* C++11-style GCC primitives. */ +/* C++11-style GCC primitives. We prefer these as they don't require standard library. */ #define _hb_memory_barrier() __sync_synchronize () @@ -102,6 +102,8 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N) #elif !defined(HB_NO_MT) && defined(_WIN32) +/* Windows branch still needed because MSVC doesn't correctly define __cplusplus: + * https://github.com/harfbuzz/harfbuzz/pull/2362 */ #include From 52f91269607a45e4ae94ecca52df2299d6596de4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 22 Feb 2021 17:22:09 -0700 Subject: [PATCH 29/31] [atomic] Remove Windows implementation Since we require C++11 now, there's no point to do a macro version check. Which means we don't hit the MSVC issue defining __cplusplus wrongly. --- src/hb-atomic.hh | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/src/hb-atomic.hh b/src/hb-atomic.hh index 94ae86c6f..47b8d27d7 100644 --- a/src/hb-atomic.hh +++ b/src/hb-atomic.hh @@ -52,7 +52,7 @@ #elif !defined(HB_NO_MT) && defined(__ATOMIC_ACQUIRE) -/* C++11-style GCC primitives. We prefer these as they don't require standard library. */ +/* C++11-style GCC primitives. We prefer these as they don't require linking to libstdc++ / libc++. */ #define _hb_memory_barrier() __sync_synchronize () @@ -73,7 +73,7 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N) } #define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_atomic_ptr_impl_cmplexch ((const void **) (P), (O), (N)) -#elif !defined(HB_NO_MT) && __cplusplus >= 201103L +#elif !defined(HB_NO_MT) /* C++11 atomics. */ @@ -101,30 +101,6 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N) #define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_atomic_ptr_impl_cmplexch ((const void **) (P), (O), (N)) -#elif !defined(HB_NO_MT) && defined(_WIN32) -/* Windows branch still needed because MSVC doesn't correctly define __cplusplus: - * https://github.com/harfbuzz/harfbuzz/pull/2362 */ - -#include - -static inline void _hb_memory_barrier () -{ -#if !defined(MemoryBarrier) && !defined(__MINGW32_VERSION) - /* MinGW has a convoluted history of supporting MemoryBarrier. */ - LONG dummy = 0; - InterlockedExchange (&dummy, 1); -#else - MemoryBarrier (); -#endif -} -#define _hb_memory_barrier() _hb_memory_barrier () - -#define hb_atomic_int_impl_add(AI, V) InterlockedExchangeAdd ((LONG *) (AI), (V)) -static_assert ((sizeof (LONG) == sizeof (int)), ""); - -#define hb_atomic_ptr_impl_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((P), (N), (O)) == (O)) - - #elif !defined(HB_NO_MT) && defined(_AIX) && (defined(__IBMCPP__) || defined(__ibmxl__)) #include From b368a0736be279fe1ae78caa818351d88dc7131a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 22 Feb 2021 17:23:53 -0700 Subject: [PATCH 30/31] [atomic] Remove IBM/AIX implementation The C++11 implementation shall be enough for everyone. --- src/hb-atomic.hh | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/src/hb-atomic.hh b/src/hb-atomic.hh index 47b8d27d7..93265f655 100644 --- a/src/hb-atomic.hh +++ b/src/hb-atomic.hh @@ -73,6 +73,7 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N) } #define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_atomic_ptr_impl_cmplexch ((const void **) (P), (O), (N)) + #elif !defined(HB_NO_MT) /* C++11 atomics. */ @@ -101,33 +102,6 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N) #define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_atomic_ptr_impl_cmplexch ((const void **) (P), (O), (N)) -#elif !defined(HB_NO_MT) && defined(_AIX) && (defined(__IBMCPP__) || defined(__ibmxl__)) - -#include - -#define _hb_memory_barrier() __lwsync () - -static inline int _hb_fetch_and_add (int *AI, int V) -{ - _hb_memory_barrier (); - int result = __fetch_and_add (AI, V); - _hb_memory_barrier (); - return result; -} -static inline bool _hb_compare_and_swaplp (long *P, long O, long N) -{ - _hb_memory_barrier (); - bool result = __compare_and_swaplp (P, &O, N); - _hb_memory_barrier (); - return result; -} - -#define hb_atomic_int_impl_add(AI, V) _hb_fetch_and_add ((AI), (V)) - -#define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_compare_and_swaplp ((long *) (P), (long) (O), (long) (N)) -static_assert ((sizeof (long) == sizeof (void *)), ""); - - #elif defined(HB_NO_MT) #define hb_atomic_int_impl_add(AI, V) ((*(AI) += (V)) - (V)) From 11c28cb5fa101a47b179e702e15ebf39d6483b32 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 22 Feb 2021 17:38:53 -0700 Subject: [PATCH 31/31] [cmake] Define HAVE_PTHREAD if not on win32 Yeah... --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index b95523f6e..ec5fac7f5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -102,6 +102,8 @@ if (${HAVE_STDBOOL_H}) add_definitions(-DHAVE_STDBOOL_H) endif () +# https://github.com/harfbuzz/harfbuzz/pull/2874#issuecomment-782859099 +if (NOT WIN32) add_definitions("-DHAVE_PTHREAD") endif () if (MSVC) add_definitions(-wd4244 -wd4267 -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS)