[HarfBuzz] harfbuzz: Branch 'master' - 3 commits

Behdad Esfahbod behdad at kemper.freedesktop.org
Thu Aug 14 10:06:17 PDT 2014


 src/hb-face-private.hh   |    2 +-
 src/hb-object-private.hh |   44 +++++++++++++++++++++++++++++---------------
 src/hb-set-private.hh    |    2 +-
 3 files changed, 31 insertions(+), 17 deletions(-)

New commits:
commit a5a27073cfff91c4f80209ca8462543130af61dd
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Aug 14 13:05:36 2014 -0400

    Rewrite this==NULL checks to avoid undefined behavior
    
    Fixes https://code.google.com/p/chromium/issues/detail?id=403594

diff --git a/src/hb-object-private.hh b/src/hb-object-private.hh
index 8e3c006..1befd6b 100644
--- a/src/hb-object-private.hh
+++ b/src/hb-object-private.hh
@@ -129,15 +129,11 @@ struct hb_object_header_t
 
   template <typename Type> friend Type *hb_object_reference (Type *obj);
   inline void reference (void) {
-    if (unlikely (!this || this->is_inert ()))
-      return;
     ref_count.inc ();
   }
 
   template <typename Type> friend bool hb_object_destroy (Type *obj);
   inline bool destroy (void) {
-    if (unlikely (!this || this->is_inert ()))
-      return false;
     if (ref_count.dec () != 1)
       return false;
 
@@ -156,18 +152,12 @@ struct hb_object_header_t
 			     void *              data,
 			     hb_destroy_func_t   destroy_func,
 			     hb_bool_t           replace) {
-    if (unlikely (!this || this->is_inert ()))
-      return false;
-
     return user_data.set (key, data, destroy_func, replace);
   }
 
   template <typename type> friend void *hb_object_get_user_data (type               *obj,
 								 hb_user_data_key_t *key);
   inline void *get_user_data (hb_user_data_key_t *key) {
-    if (unlikely (!this || this->is_inert ()))
-      return NULL;
-
     return user_data.get (key);
   }
 
@@ -212,6 +202,8 @@ static inline bool hb_object_is_inert (const Type *obj)
 template <typename Type>
 static inline Type *hb_object_reference (Type *obj)
 {
+  if (unlikely (!obj || obj->header.is_inert ()))
+    return obj;
   hb_object_trace (obj, HB_FUNC);
   obj->header.reference ();
   return obj;
@@ -219,6 +211,8 @@ static inline Type *hb_object_reference (Type *obj)
 template <typename Type>
 static inline bool hb_object_destroy (Type *obj)
 {
+  if (unlikely (!obj || obj->header.is_inert ()))
+    return false;
   hb_object_trace (obj, HB_FUNC);
   return obj->header.destroy ();
 }
@@ -229,6 +223,8 @@ static inline bool hb_object_set_user_data (Type               *obj,
 					    hb_destroy_func_t   destroy,
 					    hb_bool_t           replace)
 {
+  if (unlikely (!obj || obj->header.is_inert ()))
+    return false;
   return obj->header.set_user_data (key, data, destroy, replace);
 }
 
@@ -236,6 +232,8 @@ template <typename Type>
 static inline void *hb_object_get_user_data (Type               *obj,
 					     hb_user_data_key_t *key)
 {
+  if (unlikely (!obj || obj->header.is_inert ()))
+    return NULL;
   return obj->header.get_user_data (key);
 }
 
commit cc3b2d432b02f9381cdf19e2dd5fbbdd002a750c
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Aug 14 12:59:16 2014 -0400

    Remove this==NULL check from face->reference_table()
    
    Not supposed to happen, and apparently this is undefined in C++.
    https://code.google.com/p/chromium/issues/detail?id=403594

diff --git a/src/hb-face-private.hh b/src/hb-face-private.hh
index 6520d3d..c4266ff 100644
--- a/src/hb-face-private.hh
+++ b/src/hb-face-private.hh
@@ -66,7 +66,7 @@ struct hb_face_t {
   {
     hb_blob_t *blob;
 
-    if (unlikely (!this || !reference_table_func))
+    if (unlikely (!reference_table_func))
       return hb_blob_get_empty ();
 
     blob = reference_table_func (/*XXX*/const_cast<hb_face_t *> (this), tag, user_data);
commit cd7ea4f791dc41d62ad238673e2ea0107883c9e3
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Aug 14 12:57:02 2014 -0400

    Make hb_object_t members private
    
    In preparation for fixing:
    https://code.google.com/p/chromium/issues/detail?id=403594

diff --git a/src/hb-object-private.hh b/src/hb-object-private.hh
index 8a9ae34..8e3c006 100644
--- a/src/hb-object-private.hh
+++ b/src/hb-object-private.hh
@@ -68,8 +68,6 @@ struct hb_reference_count_t
 #define HB_USER_DATA_ARRAY_INIT {HB_MUTEX_INIT, HB_LOCKABLE_SET_INIT}
 struct hb_user_data_array_t
 {
-  /* TODO Add tracing. */
-
   struct hb_user_data_item_t {
     hb_user_data_key_t *key;
     void *data;
@@ -106,6 +104,9 @@ struct hb_object_header_t
 
 #define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INVALID, HB_USER_DATA_ARRAY_INIT}
 
+  private:
+
+  template <typename Type> friend Type *hb_object_create (void);
   static inline void *create (unsigned int size) {
     hb_object_header_t *obj = (hb_object_header_t *) calloc (1, size);
 
@@ -115,21 +116,25 @@ struct hb_object_header_t
     return obj;
   }
 
+  template <typename Type> friend void hb_object_init (Type *obj);
   inline void init (void) {
     ref_count.init (1);
     user_data.init ();
   }
 
+  template <typename Type> friend bool hb_object_is_inert (const Type *obj);
   inline bool is_inert (void) const {
     return unlikely (ref_count.is_invalid ());
   }
 
+  template <typename Type> friend Type *hb_object_reference (Type *obj);
   inline void reference (void) {
     if (unlikely (!this || this->is_inert ()))
       return;
     ref_count.inc ();
   }
 
+  template <typename Type> friend bool hb_object_destroy (Type *obj);
   inline bool destroy (void) {
     if (unlikely (!this || this->is_inert ()))
       return false;
@@ -142,6 +147,11 @@ struct hb_object_header_t
     return true;
   }
 
+  template <typename Type> friend bool hb_object_set_user_data (Type               *obj,
+								hb_user_data_key_t *key,
+								void *              data,
+								hb_destroy_func_t   destroy,
+								hb_bool_t           replace);
   inline bool set_user_data (hb_user_data_key_t *key,
 			     void *              data,
 			     hb_destroy_func_t   destroy_func,
@@ -152,6 +162,8 @@ struct hb_object_header_t
     return user_data.set (key, data, destroy_func, replace);
   }
 
+  template <typename type> friend void *hb_object_get_user_data (type               *obj,
+								 hb_user_data_key_t *key);
   inline void *get_user_data (hb_user_data_key_t *key) {
     if (unlikely (!this || this->is_inert ()))
       return NULL;
@@ -159,17 +171,15 @@ struct hb_object_header_t
     return user_data.get (key);
   }
 
+  template <typename Type> friend void hb_object_trace (const Type *obj, const char *function);
   inline void trace (const char *function) const {
     if (unlikely (!this)) return;
-    /* TODO We cannot use DEBUG_MSG_FUNC here since that one currently only
-     * prints the class name and throws away the template info. */
     DEBUG_MSG (OBJECT, (void *) this,
 	       "%s refcount=%d",
 	       function,
 	       this ? ref_count.ref_count : 0);
   }
 
-  private:
   ASSERT_POD ();
 };
 
@@ -181,6 +191,7 @@ static inline void hb_object_trace (const Type *obj, const char *function)
 {
   obj->header.trace (function);
 }
+
 template <typename Type>
 static inline Type *hb_object_create (void)
 {
@@ -189,6 +200,11 @@ static inline Type *hb_object_create (void)
   return obj;
 }
 template <typename Type>
+static inline void hb_object_init (Type *obj)
+{
+  obj->header.init ();
+}
+template <typename Type>
 static inline bool hb_object_is_inert (const Type *obj)
 {
   return unlikely (obj->header.is_inert ());
diff --git a/src/hb-set-private.hh b/src/hb-set-private.hh
index 705f554..59e8f45 100644
--- a/src/hb-set-private.hh
+++ b/src/hb-set-private.hh
@@ -150,7 +150,7 @@ struct hb_set_t
   bool in_error;
 
   inline void init (void) {
-    header.init ();
+    hb_object_init (this);
     clear ();
   }
   inline void fini (void) {


More information about the HarfBuzz mailing list