[gjs/wip/ptomato/mozjs31prep: 7/7] object: Use JS::Heap for GObject-JSObject weak ref
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/wip/ptomato/mozjs31prep: 7/7] object: Use JS::Heap for GObject-JSObject weak ref
- Date: Sat, 5 Nov 2016 19:11:05 +0000 (UTC)
commit 6741009fe52da0a44acf00a802262171f81b1005
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 | 42 +++++++++++++++++++++++++++++++++++-------
1 files changed, 35 insertions(+), 7 deletions(-)
---
diff --git a/gi/object.cpp b/gi/object.cpp
index bdb7b14..6000473 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);
@@ -1211,8 +1212,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);
@@ -1971,26 +1972,53 @@ 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 (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());
+ auto heap_object = ensure_heap_wrapper(gobj);
- if (G_UNLIKELY (object == (JSObject*)(-1))) {
+ if (G_UNLIKELY ((gpointer) heap_object == (gpointer) 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)));
+ g_object_set_qdata(gobj, gjs_object_priv_quark(), NULL);
return NULL; /* return null to associate again with a new wrapper */
}
- return object;
+ return heap_object->get();
}
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)
+{
+ /* COMPAT: Use JS::Heap::setToCrashOnTouch() in mozjs31 */
+ g_object_set_qdata(gobj, gjs_object_priv_quark(), (gpointer) 1);
}
JSObject*
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]