[gjs] Gjs: work around GType bug with dynamic types



commit d2f67b73a81ee02b37ed007686df143ef5a06d01
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Tue Oct 30 16:57:58 2012 +0100

    Gjs: work around GType bug with dynamic types
    
    g_type_query() only works with static types, so it fails when inheriting
    from another JS class. Work around that by using the first static parent
    for GJS custom type (as we never override the instance or class type)
    
    https://bugzilla.gnome.org/show_bug.cgi?id=687184

 gi/object.c                 |   27 ++++++++++++++++++++++++---
 test/js/testGObjectClass.js |   18 ++++++++++++++++++
 2 files changed, 42 insertions(+), 3 deletions(-)
---
diff --git a/gi/object.c b/gi/object.c
index c2cd0c5..fb77924 100644
--- a/gi/object.c
+++ b/gi/object.c
@@ -120,6 +120,21 @@ gjs_is_custom_property_quark (void)
     return val;
 }
 
+/* Plain g_type_query fails and leaves @query uninitialized for
+   dynamic types.
+   See https://bugzilla.gnome.org/show_bug.cgi?id=687184 and
+   https://bugzilla.gnome.org/show_bug.cgi?id=687211
+*/
+static void
+g_type_query_dynamic_safe (GType       type,
+                           GTypeQuery *query)
+{
+    while (g_type_get_qdata(type, gjs_is_custom_type_quark()))
+        type = g_type_parent(type);
+
+    g_type_query(type, query);
+}
+
 static void
 throw_priv_is_null_error(JSContext *context)
 {
@@ -966,8 +981,9 @@ object_instance_init (JSContext *context,
         goto out;
     }
 
-    g_type_query(gtype, &query);
-    JS_updateMallocCounter(context, query.instance_size);
+    g_type_query_dynamic_safe(gtype, &query);
+    if (G_LIKELY (query.type))
+        JS_updateMallocCounter(context, query.instance_size);
 
     if (G_IS_INITIALLY_UNOWNED(gobj) &&
         !g_object_is_floating(gobj)) {
@@ -2305,7 +2321,12 @@ gjs_register_type(JSContext *cx,
 
     parent_type = parent_priv->gtype;
 
-    g_type_query(parent_type, &query);
+    g_type_query_dynamic_safe(parent_type, &query);
+    if (G_UNLIKELY (query.type == 0)) {
+        gjs_throw (cx, "Cannot inherit from a non-gjs dynamic type [bug 687184]");
+        return JS_FALSE;
+    }
+
     type_info.class_size = query.class_size;
     type_info.instance_size = query.instance_size;
 
diff --git a/test/js/testGObjectClass.js b/test/js/testGObjectClass.js
index 99a408c..6ac38ed 100644
--- a/test/js/testGObjectClass.js
+++ b/test/js/testGObjectClass.js
@@ -148,6 +148,15 @@ const MyInitable = new Lang.Class({
     }
 });
 
+const Derived = new Lang.Class({
+    Name: 'Derived',
+    Extends: MyObject,
+
+    _init: function() {
+        this.parent({ readwrite: 'yes' });
+    }
+});
+
 function testGObjectClass() {
     let myInstance = new MyObject();
 
@@ -260,4 +269,13 @@ function testInterface() {
     // assertTrue(instance instanceof Gio.Initable)
 }
 
+function testDerived() {
+    let derived = new Derived();
+
+    assertTrue(derived instanceof Derived);
+    assertTrue(derived instanceof MyObject);
+
+    assertEquals('yes', derived.readwrite);
+}
+
 gjstestRun();



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