Better hide nil objects and make them const
diff --git a/src/hb-blob.cc b/src/hb-blob.cc
index ee997ad..04de762 100644
--- a/src/hb-blob.cc
+++ b/src/hb-blob.cc
@@ -59,19 +59,6 @@
   hb_destroy_func_t destroy;
 };
 
-static hb_blob_t _hb_blob_nil = {
-  HB_OBJECT_HEADER_STATIC,
-
-  TRUE, /* immutable */
-
-  NULL, /* data */
-  0, /* length */
-  HB_MEMORY_MODE_READONLY, /* mode */
-
-  NULL, /* user_data */
-  NULL  /* destroy */
-};
-
 
 static bool _try_writable (hb_blob_t *blob);
 
@@ -97,7 +84,7 @@
   if (!length || !(blob = hb_object_create<hb_blob_t> ())) {
     if (destroy)
       destroy (user_data);
-    return &_hb_blob_nil;
+    return hb_blob_get_empty ();
   }
 
   blob->data = data;
@@ -111,7 +98,7 @@
     blob->mode = HB_MEMORY_MODE_READONLY;
     if (!_try_writable (blob)) {
       hb_blob_destroy (blob);
-      return &_hb_blob_nil;
+      return hb_blob_get_empty ();
     }
   }
 
@@ -126,7 +113,7 @@
   hb_blob_t *blob;
 
   if (!length || offset >= parent->length)
-    return &_hb_blob_nil;
+    return hb_blob_get_empty ();
 
   hb_blob_make_immutable (parent);
 
@@ -142,7 +129,20 @@
 hb_blob_t *
 hb_blob_get_empty (void)
 {
-  return &_hb_blob_nil;
+  static const hb_blob_t _hb_blob_nil = {
+    HB_OBJECT_HEADER_STATIC,
+
+    TRUE, /* immutable */
+
+    NULL, /* data */
+    0, /* length */
+    HB_MEMORY_MODE_READONLY, /* mode */
+
+    NULL, /* user_data */
+    NULL  /* destroy */
+  };
+
+  return const_cast<hb_blob_t *> (&_hb_blob_nil);
 }
 
 hb_blob_t *
diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index c566a4a..144a68c 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -37,21 +37,8 @@
 #define HB_DEBUG_BUFFER (HB_DEBUG+0)
 #endif
 
-
-static hb_buffer_t _hb_buffer_nil = {
-  HB_OBJECT_HEADER_STATIC,
-
-  &_hb_unicode_funcs_default,
-  {
-    HB_DIRECTION_INVALID,
-    HB_SCRIPT_INVALID,
-    NULL,
-  },
-
-  TRUE, /* in_error */
-  TRUE, /* have_output */
-  TRUE  /* have_positions */
-};
+#define _HB_BUFFER_UNICODE_FUNCS_DEFAULT _hb_unicode_funcs_default
+#define _HB_BUFFER_PROPS_DEFAULT { HB_DIRECTION_INVALID, HB_SCRIPT_INVALID, HB_LANGUAGE_INVALID }
 
 /* Here is how the buffer works internally:
  *
@@ -154,9 +141,10 @@
     return;
 
   hb_unicode_funcs_destroy (unicode);
-  unicode = _hb_buffer_nil.unicode;
+  unicode = _HB_BUFFER_UNICODE_FUNCS_DEFAULT;
 
-  props = _hb_buffer_nil.props;
+  hb_segment_properties_t default_props = _HB_BUFFER_PROPS_DEFAULT;
+  props = default_props;
 
   in_error = FALSE;
   have_output = FALSE;
@@ -543,7 +531,7 @@
   hb_buffer_t *buffer;
 
   if (!(buffer = hb_object_create<hb_buffer_t> ()))
-    return &_hb_buffer_nil;
+    return hb_buffer_get_empty ();
 
   buffer->reset ();
 
@@ -553,7 +541,18 @@
 hb_buffer_t *
 hb_buffer_get_empty (void)
 {
-  return &_hb_buffer_nil;
+  static const hb_buffer_t _hb_buffer_nil = {
+    HB_OBJECT_HEADER_STATIC,
+
+    _HB_BUFFER_UNICODE_FUNCS_DEFAULT,
+    _HB_BUFFER_PROPS_DEFAULT,
+
+    TRUE, /* in_error */
+    TRUE, /* have_output */
+    TRUE  /* have_positions */
+  };
+
+  return const_cast<hb_buffer_t *> (&_hb_buffer_nil);
 }
 
 hb_buffer_t *
@@ -601,7 +600,7 @@
     return;
 
   if (!unicode)
-    unicode = _hb_buffer_nil.unicode;
+    unicode = _HB_BUFFER_UNICODE_FUNCS_DEFAULT;
 
   hb_unicode_funcs_reference (unicode);
   hb_unicode_funcs_destroy (buffer->unicode);
diff --git a/src/hb-font.cc b/src/hb-font.cc
index 1862ac3..783a2b0 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -217,7 +217,7 @@
 }
 
 
-static hb_font_funcs_t _hb_font_funcs_nil = {
+static const hb_font_funcs_t _hb_font_funcs_nil = {
   HB_OBJECT_HEADER_STATIC,
 
   TRUE, /* immutable */
@@ -236,7 +236,7 @@
   hb_font_funcs_t *ffuncs;
 
   if (!(ffuncs = hb_object_create<hb_font_funcs_t> ()))
-    return &_hb_font_funcs_nil;
+    return hb_font_funcs_get_empty ();
 
   ffuncs->get = _hb_font_funcs_nil.get;
 
@@ -246,7 +246,7 @@
 hb_font_funcs_t *
 hb_font_funcs_get_empty (void)
 {
-  return &_hb_font_funcs_nil;
+  return const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil);
 }
 
 hb_font_funcs_t *
@@ -578,7 +578,7 @@
  * hb_face_t
  */
 
-static hb_face_t _hb_face_nil = {
+static const hb_face_t _hb_face_nil = {
   HB_OBJECT_HEADER_STATIC,
 
   TRUE, /* immutable */
@@ -604,7 +604,7 @@
   if (!reference_table || !(face = hb_object_create<hb_face_t> ())) {
     if (destroy)
       destroy (user_data);
-    return &_hb_face_nil;
+    return hb_face_get_empty ();
   }
 
   face->reference_table = reference_table;
@@ -671,12 +671,12 @@
   hb_face_t *face;
 
   if (unlikely (!blob || !hb_blob_get_length (blob)))
-    return &_hb_face_nil;
+    return hb_face_get_empty ();
 
   hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (Sanitizer<OpenTypeFontFile>::sanitize (hb_blob_reference (blob)), index);
 
   if (unlikely (!closure))
-    return &_hb_face_nil;
+    return hb_face_get_empty ();
 
   face = hb_face_create_for_tables (_hb_face_for_data_reference_table,
 				    closure,
@@ -690,7 +690,7 @@
 hb_face_t *
 hb_face_get_empty (void)
 {
-  return &_hb_face_nil;
+  return const_cast<hb_face_t *> (&_hb_face_nil);
 }
 
 
@@ -811,40 +811,21 @@
  * hb_font_t
  */
 
-static hb_font_t _hb_font_nil = {
-  HB_OBJECT_HEADER_STATIC,
-
-  TRUE, /* immutable */
-
-  NULL, /* parent */
-  &_hb_face_nil,
-
-  0, /* x_scale */
-  0, /* y_scale */
-
-  0, /* x_ppem */
-  0, /* y_ppem */
-
-  &_hb_font_funcs_nil, /* klass */
-  NULL, /* user_data */
-  NULL  /* destroy */
-};
-
 hb_font_t *
 hb_font_create (hb_face_t *face)
 {
   hb_font_t *font;
 
   if (unlikely (!face))
-    face = &_hb_face_nil;
+    face = hb_face_get_empty ();
   if (unlikely (hb_object_is_inert (face)))
-    return &_hb_font_nil;
+    return hb_font_get_empty ();
   if (!(font = hb_object_create<hb_font_t> ()))
-    return &_hb_font_nil;
+    return hb_font_get_empty ();
 
   hb_face_make_immutable (face);
   font->face = hb_face_reference (face);
-  font->klass = &_hb_font_funcs_nil;
+  font->klass = hb_font_funcs_get_empty ();
 
   return font;
 }
@@ -853,7 +834,7 @@
 hb_font_create_sub_font (hb_font_t *parent)
 {
   if (unlikely (!parent))
-    return &_hb_font_nil;
+    return hb_font_get_empty ();
 
   hb_font_t *font = hb_font_create (parent->face);
 
@@ -868,15 +849,32 @@
   font->x_ppem = parent->x_ppem;
   font->y_ppem = parent->y_ppem;
 
-  font->klass = &_hb_font_funcs_nil;
-
   return font;
 }
 
 hb_font_t *
 hb_font_get_empty (void)
 {
-  return &_hb_font_nil;
+  static const hb_font_t _hb_font_nil = {
+    HB_OBJECT_HEADER_STATIC,
+
+    TRUE, /* immutable */
+
+    NULL, /* parent */
+    const_cast<hb_face_t *> (&_hb_face_nil),
+
+    0, /* x_scale */
+    0, /* y_scale */
+
+    0, /* x_ppem */
+    0, /* y_ppem */
+
+    const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil), /* klass */
+    NULL, /* user_data */
+    NULL  /* destroy */
+  };
+
+  return const_cast<hb_font_t *> (&_hb_font_nil);
 }
 
 hb_font_t *
@@ -960,7 +958,7 @@
     font->destroy (font->user_data);
 
   if (!klass)
-    klass = &_hb_font_funcs_nil;
+    klass = hb_font_funcs_get_empty ();
 
   hb_font_funcs_reference (klass);
   hb_font_funcs_destroy (font->klass);
diff --git a/src/hb-ft.cc b/src/hb-ft.cc
index 90adc0d..aa09bd7 100644
--- a/src/hb-ft.cc
+++ b/src/hb-ft.cc
@@ -271,22 +271,22 @@
 }
 
 
-static hb_font_funcs_t ft_ffuncs = {
-  HB_OBJECT_HEADER_STATIC,
-
-  TRUE, /* immutable */
-
-  {
-#define HB_FONT_FUNC_IMPLEMENT(name) hb_ft_get_##name,
-    HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
-#undef HB_FONT_FUNC_IMPLEMENT
-  }
-};
-
 static hb_font_funcs_t *
 _hb_ft_get_font_funcs (void)
 {
-  return &ft_ffuncs;
+  static const hb_font_funcs_t ft_ffuncs = {
+    HB_OBJECT_HEADER_STATIC,
+
+    TRUE, /* immutable */
+
+    {
+#define HB_FONT_FUNC_IMPLEMENT(name) hb_ft_get_##name,
+      HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_FONT_FUNC_IMPLEMENT
+    }
+  };
+
+  return const_cast<hb_font_funcs_t *> (&ft_ffuncs);
 }
 
 
@@ -398,26 +398,21 @@
 }
 
 
-
-
-static FT_Library ft_library;
-static hb_bool_t ft_library_initialized;
-static struct ft_library_destructor {
-  ~ft_library_destructor (void) {
-    if (ft_library)
-      FT_Done_FreeType (ft_library);
-  }
-} static_ft_library_destructor;
-
 static FT_Library
 _get_ft_library (void)
 {
-  if (unlikely (!ft_library_initialized)) {
-    FT_Init_FreeType (&ft_library);
-    ft_library_initialized = TRUE;
-  }
+  static struct ft_library_singleton
+  {
+    ft_library_singleton (void) {
+      FT_Init_FreeType (&ft_library);
+    }
+    ~ft_library_singleton (void) {
+      FT_Done_FreeType (ft_library);
+    }
+    FT_Library ft_library;
+  } ft_library_singleton;
 
-  return ft_library;
+  return ft_library_singleton.ft_library;
 }
 
 static void
diff --git a/src/hb-glib.cc b/src/hb-glib.cc
index 26d40a3..33369b2 100644
--- a/src/hb-glib.cc
+++ b/src/hb-glib.cc
@@ -337,22 +337,21 @@
 }
 
 
-extern HB_INTERNAL hb_unicode_funcs_t _hb_unicode_funcs_glib;
-hb_unicode_funcs_t _hb_glib_unicode_funcs = {
-  HB_OBJECT_HEADER_STATIC,
-
-  NULL, /* parent */
-  TRUE, /* immutable */
-  {
-#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_glib_unicode_##name,
-    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
-#undef HB_UNICODE_FUNC_IMPLEMENT
-  }
-};
-
 hb_unicode_funcs_t *
 hb_glib_get_unicode_funcs (void)
 {
-  return &_hb_glib_unicode_funcs;
+  static const hb_unicode_funcs_t _hb_glib_unicode_funcs = {
+    HB_OBJECT_HEADER_STATIC,
+
+    NULL, /* parent */
+    TRUE, /* immutable */
+    {
+#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_glib_unicode_##name,
+      HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_UNICODE_FUNC_IMPLEMENT
+    }
+  };
+
+  return const_cast<hb_unicode_funcs_t *> (&_hb_glib_unicode_funcs);
 }
 
diff --git a/src/hb-icu.cc b/src/hb-icu.cc
index 5cd0143..78cbc1a 100644
--- a/src/hb-icu.cc
+++ b/src/hb-icu.cc
@@ -269,23 +269,22 @@
   return ret;
 }
 
-extern HB_INTERNAL hb_unicode_funcs_t _hb_unicode_funcs_icu;
-hb_unicode_funcs_t _hb_icu_unicode_funcs = {
-  HB_OBJECT_HEADER_STATIC,
-
-  NULL, /* parent */
-  TRUE, /* immutable */
-  {
-#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_icu_unicode_##name,
-    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
-#undef HB_UNICODE_FUNC_IMPLEMENT
-  }
-};
-
 hb_unicode_funcs_t *
 hb_icu_get_unicode_funcs (void)
 {
-  return &_hb_icu_unicode_funcs;
+  static const hb_unicode_funcs_t _hb_icu_unicode_funcs = {
+    HB_OBJECT_HEADER_STATIC,
+
+    NULL, /* parent */
+    TRUE, /* immutable */
+    {
+#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_icu_unicode_##name,
+      HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_UNICODE_FUNC_IMPLEMENT
+    }
+  };
+
+  return const_cast<hb_unicode_funcs_t *> (&_hb_icu_unicode_funcs);
 }
 
 
diff --git a/src/hb-set.cc b/src/hb-set.cc
index 5045386..a044199 100644
--- a/src/hb-set.cc
+++ b/src/hb-set.cc
@@ -30,12 +30,6 @@
 
 /* Public API */
 
-static hb_set_t _hb_set_nil = {
-  HB_OBJECT_HEADER_STATIC,
-
-  {0} /* elts */
-};
-
 
 hb_set_t *
 hb_set_create ()
@@ -43,7 +37,7 @@
   hb_set_t *set;
 
   if (!(set = hb_object_create<hb_set_t> ()))
-    return &_hb_set_nil;
+    return hb_set_get_empty ();
 
   set->clear ();
 
@@ -53,7 +47,13 @@
 hb_set_t *
 hb_set_get_empty (void)
 {
-  return &_hb_set_nil;
+  static const hb_set_t _hb_set_nil = {
+    HB_OBJECT_HEADER_STATIC,
+
+    {0} /* elts */
+  };
+
+  return const_cast<hb_set_t *> (&_hb_set_nil);
 }
 
 hb_set_t *
diff --git a/src/hb-unicode-private.hh b/src/hb-unicode-private.hh
index ddba1ac..9a900f5 100644
--- a/src/hb-unicode-private.hh
+++ b/src/hb-unicode-private.hh
@@ -91,15 +91,14 @@
 
 
 #ifdef HAVE_GLIB
-extern HB_INTERNAL hb_unicode_funcs_t _hb_glib_unicode_funcs;
-#define _hb_unicode_funcs_default _hb_glib_unicode_funcs
+extern "C" hb_unicode_funcs_t * hb_glib_get_unicode_funcs (void);
+#define _hb_unicode_funcs_default hb_glib_get_unicode_funcs ()
 #elif defined(HAVE_ICU)
-extern HB_INTERNAL hb_unicode_funcs_t _hb_icu_unicode_funcs;
-#define _hb_unicode_funcs_default _hb_icu_unicode_funcs
+extern "C" hb_unicode_funcs_t * hb_icu_get_unicode_funcs (void);
+#define _hb_unicode_funcs_default hb_icu_get_unicode_funcs ()
 #else
 #define HB_UNICODE_FUNCS_NIL 1
-extern HB_INTERNAL hb_unicode_funcs_t _hb_unicode_funcs_nil;
-#define _hb_unicode_funcs_default _hb_unicode_funcs_nil
+#define _hb_unicode_funcs_default hb_unicode_funcs_get_empty ()
 #endif
 
 
diff --git a/src/hb-unicode.cc b/src/hb-unicode.cc
index f2fbebb..b7a5f8d 100644
--- a/src/hb-unicode.cc
+++ b/src/hb-unicode.cc
@@ -99,23 +99,11 @@
 }
 
 
-hb_unicode_funcs_t _hb_unicode_funcs_nil = {
-  HB_OBJECT_HEADER_STATIC,
-
-  NULL, /* parent */
-  TRUE, /* immutable */
-  {
-#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_nil,
-    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
-#undef HB_UNICODE_FUNC_IMPLEMENT
-  }
-};
-
 
 hb_unicode_funcs_t *
 hb_unicode_funcs_get_default (void)
 {
-  return &_hb_unicode_funcs_default;
+  return _hb_unicode_funcs_default;
 }
 
 hb_unicode_funcs_t *
@@ -124,10 +112,10 @@
   hb_unicode_funcs_t *ufuncs;
 
   if (!(ufuncs = hb_object_create<hb_unicode_funcs_t> ()))
-    return &_hb_unicode_funcs_nil;
+    return hb_unicode_funcs_get_empty ();
 
   if (!parent)
-    parent = &_hb_unicode_funcs_nil;
+    parent = hb_unicode_funcs_get_empty ();
 
   hb_unicode_funcs_make_immutable (parent);
   ufuncs->parent = hb_unicode_funcs_reference (parent);
@@ -145,7 +133,19 @@
 hb_unicode_funcs_t *
 hb_unicode_funcs_get_empty (void)
 {
-  return &_hb_unicode_funcs_nil;
+  static const hb_unicode_funcs_t _hb_unicode_funcs_nil = {
+    HB_OBJECT_HEADER_STATIC,
+
+    NULL, /* parent */
+    TRUE, /* immutable */
+    {
+#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_nil,
+      HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_UNICODE_FUNC_IMPLEMENT
+    }
+  };
+
+  return const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil);
 }
 
 hb_unicode_funcs_t *
@@ -205,7 +205,7 @@
 hb_unicode_funcs_t *
 hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs)
 {
-  return ufuncs->parent ? ufuncs->parent : &_hb_unicode_funcs_nil;
+  return ufuncs->parent ? ufuncs->parent : hb_unicode_funcs_get_empty ();
 }