[gjs/wip/ptomato/mozjs38: 20/23] WIP - object.cpp weak pointer callback



commit c927c3ef5450c4787cc64bf8242de8539e623665
Author: Philip Chimento <philip chimento gmail com>
Date:   Wed Jan 11 23:37:28 2017 -0800

    WIP - object.cpp weak pointer callback
    
    Weak pointers need callbacks now!
    
    Also can get rid of gjs_runtime_is_sweeping()?

 gi/object.cpp |   49 ++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 38 insertions(+), 11 deletions(-)
---
diff --git a/gi/object.cpp b/gi/object.cpp
index 7a7be6c..f651f9d 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -23,6 +23,7 @@
 
 #include <config.h>
 
+#include <deque>
 #include <memory>
 #include <stack>
 #include <string.h>
@@ -93,6 +94,11 @@ enum {
 static std::stack<JS::PersistentRootedObject> object_init_list;
 static GHashTable *class_init_properties;
 
+static bool weak_pointer_callback = false;
+/* Use std::deque here instead of std::vector so that elements don't have to
+ * get moved around when the storage size changes */
+static std::deque<GObject *> weak_pointer_list;
+
 extern struct JSClass gjs_object_instance_class;
 static GThread *gjs_eval_thread;
 static volatile gint pending_idle_toggles;
@@ -1205,16 +1211,7 @@ wrapped_gobj_toggle_notify(gpointer      data,
                 g_error("toggling up object %s that's already queued to toggle up\n",
                         G_OBJECT_TYPE_NAME(gobj));
             }
-            if (is_sweeping) {
-                if (JS_IsAboutToBeFinalized(ensure_heap_wrapper(gobj))) {
-                    /* Ouch, the JS object is dead already. Disassociate the GObject
-                     * and hope the GObject dies too.
-                     */
-                    disassociate_js_gobject(gobj);
-                }
-            } else {
-                handle_toggle_up(gobj);
-            }
+            handle_toggle_up(gobj);
         } else {
             queue_toggle_idle(gobj, TOGGLE_UP);
         }
@@ -1297,6 +1294,34 @@ init_object_private (JSContext       *context,
 }
 
 static void
+update_heap_wrapper_weak_pointers(JSRuntime *rt,
+                                  gpointer   data)
+{
+    for (auto iter = weak_pointer_list.begin(); iter != weak_pointer_list.end();
+         iter++) {
+        GObject *gobj = *iter;
+        auto heap_wrapper = ensure_heap_wrapper(gobj);
+        JS_UpdateWeakPointerAfterGC(heap_wrapper);
+
+        if (heap_wrapper == NULL) {
+            /* Ouch, the JS object is dead already. Disassociate the GObject
+             * and hope the GObject dies too.
+             */
+            disassociate_js_gobject(gobj);
+            iter = weak_pointer_list.erase(iter);
+        }
+    }
+}
+
+static void
+ensure_weak_pointer_callback(JSContext *cx)
+{
+    if (!weak_pointer_callback)
+        JS_AddWeakPointerCallback(JS_GetRuntime(cx),
+                                  update_heap_wrapper_weak_pointers, NULL);
+}
+
+static void
 associate_js_gobject (JSContext       *context,
                       JS::HandleObject object,
                       GObject         *gobj)
@@ -1306,6 +1331,8 @@ associate_js_gobject (JSContext       *context,
     priv = priv_from_js(context, object);
     priv->gobj = gobj;
 
+    ensure_weak_pointer_callback(context);
+
     g_assert(peek_js_obj(gobj) == NULL);
     set_js_obj(gobj, object);
 
@@ -2146,7 +2173,7 @@ static void
 set_js_obj(GObject  *gobj,
            JSObject *obj)
 {
-    ensure_heap_wrapper(gobj)->set(obj);
+    *ensure_heap_wrapper(gobj) = obj;
 }
 
 static void


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