[gjs/wip/ptomato/mozjs31prep: 1/2] object: Use JS::Heap for GObject-JSObject weak ref



commit e323d5d304fa37167affc65418f738baad57d506
Author: Philip Chimento <philip endlessm com>
Date:   Wed Nov 2 17:48:22 2016 -0700

    object: Use JS::Heap for GObject-JSObject weak ref
    
    This will be necessary in mozjs31 because the garbage collector could
    move the object around, which should be tracked by JS::Heap.
    
    Unlike other uses of JS::Heap, we do not want to either trace or root the
    object, because it is supposed to be a weak reference.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=742249

 gi/object.cpp |   36 +++++++++++++++++++++++++++++++-----
 1 files changed, 31 insertions(+), 5 deletions(-)
---
diff --git a/gi/object.cpp b/gi/object.cpp
index b4a0d0d..28cb9c0 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -101,6 +101,7 @@ GJS_DEFINE_PRIV_FROM_JS(ObjectInstance, gjs_object_instance_class)
 static JSObject*       peek_js_obj  (GObject   *gobj);
 static void            set_js_obj   (GObject   *gobj,
                                      JSObject  *obj);
+static void            poison_js_obj(GObject   *gobj);
 
 static void            disassociate_js_gobject (GObject *gobj);
 static void            invalidate_all_signals (ObjectInstance *priv);
@@ -1213,8 +1214,8 @@ disassociate_js_gobject (GObject   *gobj)
     invalidate_all_signals(priv);
     release_native_object(priv);
 
-    /* Use -1 to mark that a JS object once existed, but it doesn't any more */
-    set_js_obj(gobj, (JSObject*)(-1));
+    /* Mark that a JS object once existed, but it doesn't any more */
+    poison_js_obj(gobj);
 
 #if DEBUG_DISPOSE
     g_object_weak_unref(gobj, wrapped_gobj_dispose_notify, object);
@@ -1973,15 +1974,34 @@ gjs_define_object_class(JSContext              *context,
                       NULL, NULL, JSPROP_PERMANENT);
 }
 
+static void
+release_heap_wrapper(gpointer data)
+{
+    delete static_cast<JS::Heap<JSObject *> *>(data);
+}
+
+static JS::Heap<JSObject *> *
+ensure_heap_wrapper(GObject *gobj)
+{
+    gpointer data = g_object_get_qdata(gobj, gjs_object_priv_quark());
+    if (G_UNLIKELY(data == NULL)) {
+        auto heap_object = new JS::Heap<JSObject *>();
+        g_object_set_qdata_full(gobj, gjs_object_priv_quark(), heap_object,
+                                release_heap_wrapper);
+        return heap_object;
+    }
+    return static_cast<JS::Heap<JSObject *> *>(data);
+}
+
 static JSObject*
 peek_js_obj(GObject *gobj)
 {
-    JSObject *object = (JSObject*) g_object_get_qdata(gobj, gjs_object_priv_quark());
+    JSObject *object = ensure_heap_wrapper(gobj)->get();
 
     if (G_UNLIKELY (object == (JSObject*)(-1))) {
         g_critical ("Object %p (a %s) resurfaced after the JS wrapper was finalized. "
                     "This is some library doing dubious memory management inside dispose()",
-                    gobj, g_type_name(G_TYPE_FROM_INSTANCE(object)));
+                    gobj, g_type_name(G_TYPE_FROM_INSTANCE(gobj)));
         return NULL; /* return null to associate again with a new wrapper */
     }
 
@@ -1992,7 +2012,13 @@ static void
 set_js_obj(GObject  *gobj,
            JSObject *obj)
 {
-    g_object_set_qdata(gobj, gjs_object_priv_quark(), obj);
+    ensure_heap_wrapper(gobj)->set(obj);
+}
+
+static void
+poison_js_obj(GObject *gobj)
+{
+    ensure_heap_wrapper(gobj)->set((JSObject *) -1);
 }
 
 JSObject*


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]