summaryrefslogtreecommitdiff
path: root/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh')
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh106
1 files changed, 56 insertions, 50 deletions
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh
index f58050da06a..3c11243f5a1 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh
@@ -110,17 +110,17 @@ static inline Type& StructAfter(TObject &X)
static const unsigned int min_size = (size)
#define DEFINE_SIZE_ARRAY(size, array) \
- DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + VAR * sizeof (array[0])); \
- DEFINE_COMPILES_ASSERTION ((void) array[0].static_size) \
+ DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + VAR * sizeof ((array)[0])); \
+ DEFINE_COMPILES_ASSERTION ((void) (array)[0].static_size) \
enum { min_size = (size) }
#define DEFINE_SIZE_ARRAY_SIZED(size, array) \
- inline unsigned int get_size (void) const { return (size - array.min_size + array.get_size ()); } \
+ inline unsigned int get_size (void) const { return (size - (array).min_size + (array).get_size ()); } \
DEFINE_SIZE_ARRAY(size, array)
#define DEFINE_SIZE_ARRAY2(size, array1, array2) \
DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + sizeof (this->array1[0]) + sizeof (this->array2[0])); \
- DEFINE_COMPILES_ASSERTION ((void) array1[0].static_size; (void) array2[0].static_size) \
+ DEFINE_COMPILES_ASSERTION ((void) (array1)[0].static_size; (void) (array2)[0].static_size) \
static const unsigned int min_size = (size)
@@ -298,7 +298,8 @@ struct hb_sanitize_context_t :
this->start = this->end = nullptr;
}
- inline bool check_range (const void *base, unsigned int len) const
+ inline bool check_range (const void *base,
+ unsigned int len) const
{
const char *p = (const char *) base;
bool ok = this->start <= p &&
@@ -316,20 +317,37 @@ struct hb_sanitize_context_t :
}
template <typename T>
- inline bool check_array (const T *base, unsigned int len, unsigned int record_size = T::static_size) const
+ inline bool check_range (const T *base,
+ unsigned int a,
+ unsigned int b) const
{
- const char *p = (const char *) base;
- bool overflows = hb_unsigned_mul_overflows (len, record_size);
- unsigned int array_size = record_size * len;
- bool ok = !overflows && this->check_range (base, array_size);
+ return !hb_unsigned_mul_overflows (a, b) &&
+ this->check_range (base, a * b);
+ }
- DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0,
- "check_array [%p..%p] (%d*%d=%d bytes) in [%p..%p] -> %s",
- p, p + (record_size * len), record_size, len, (unsigned int) array_size,
- this->start, this->end,
- overflows ? "OVERFLOWS" : ok ? "OK" : "OUT-OF-RANGE");
+ template <typename T>
+ inline bool check_range (const T *base,
+ unsigned int a,
+ unsigned int b,
+ unsigned int c) const
+ {
+ return !hb_unsigned_mul_overflows (a, b) &&
+ this->check_range (base, a * b, c);
+ }
- return likely (ok);
+ template <typename T>
+ inline bool check_array (const T *base,
+ unsigned int len) const
+ {
+ return this->check_range (base, len, T::static_size);
+ }
+
+ template <typename T>
+ inline bool check_array (const T *base,
+ unsigned int a,
+ unsigned int b) const
+ {
+ return this->check_range (base, a, b, T::static_size);
}
template <typename Type>
@@ -734,21 +752,18 @@ struct hb_data_wrapper_t
return *(((Data **) (void *) this) - WheresData);
}
+ inline bool is_inert (void) const { return !get_data (); }
+
template <typename Stored, typename Subclass>
- inline Stored * call_create (void) const
- {
- Data *data = this->get_data ();
- return likely (data) ? Subclass::create (data) : nullptr;
- }
+ inline Stored * call_create (void) const { return Subclass::create (get_data ()); }
};
template <>
struct hb_data_wrapper_t<void, 0>
{
+ inline bool is_inert (void) const { return false; }
+
template <typename Stored, typename Funcs>
- inline Stored * call_create (void) const
- {
- return Funcs::create ();
- }
+ inline Stored * call_create (void) const { return Funcs::create (); }
};
template <typename T1, typename T2> struct hb_non_void_t { typedef T1 value; };
@@ -775,41 +790,37 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData>
{
retry:
Stored *p = instance.get ();
- if (unlikely (p && !this->instance.cmpexch (p, nullptr)))
+ if (unlikely (p && !cmpexch (p, nullptr)))
goto retry;
do_destroy (p);
}
- inline Stored * do_create (void) const
- {
- Stored *p = this->template call_create<Stored, Funcs> ();
- if (unlikely (!p))
- p = const_cast<Stored *> (Funcs::get_null ());
- return p;
- }
static inline void do_destroy (Stored *p)
{
- if (p && p != Funcs::get_null ())
+ if (p && p != const_cast<Stored *> (Funcs::get_null ()))
Funcs::destroy (p);
}
inline const Returned * operator -> (void) const { return get (); }
inline const Returned & operator * (void) const { return *get (); }
+ explicit_operator inline operator bool (void) const
+ { return get_stored () != Funcs::get_null (); }
template <typename C> inline operator const C * (void) const { return get (); }
- inline Data * get_data (void) const
- {
- return *(((Data **) this) - WheresData);
- }
-
inline Stored * get_stored (void) const
{
retry:
Stored *p = this->instance.get ();
if (unlikely (!p))
{
- p = do_create ();
- if (unlikely (!this->instance.cmpexch (nullptr, p)))
+ if (unlikely (this->is_inert ()))
+ return const_cast<Stored *> (Funcs::get_null ());
+
+ p = this->template call_create<Stored, Funcs> ();
+ if (unlikely (!p))
+ p = const_cast<Stored *> (Funcs::get_null ());
+
+ if (unlikely (!cmpexch (nullptr, p)))
{
do_destroy (p);
goto retry;
@@ -822,15 +833,10 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData>
return this->instance.get_relaxed ();
}
- inline void set_stored (Stored *instance_)
+ inline bool cmpexch (Stored *current, Stored *value) const
{
- /* This *must* be called when there are no other threads accessing.
- * However, to make TSan, etc, happy, we using cmpexch. */
- retry:
- Stored *p = this->instance.get ();
- if (unlikely (!this->instance.cmpexch (p, instance_)))
- goto retry;
- do_destroy (p);
+ /* This *must* be called when there are no other threads accessing. */
+ return this->instance.cmpexch (current, value);
}
inline const Returned * get (void) const { return Funcs::convert (get_stored ()); }
@@ -862,7 +868,7 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData>
free (p);
}
- private:
+// private:
/* Must only have one pointer. */
hb_atomic_ptr_t<Stored *> instance;
};