diff options
author | Jasper St. Pierre <jstpierre@mecheye.net> | 2012-01-12 13:36:48 -0500 |
---|---|---|
committer | Jasper St. Pierre <jstpierre@mecheye.net> | 2012-01-12 14:08:12 -0500 |
commit | c63b9f34380352c301fa5e211d03f20a0a4afd97 (patch) | |
tree | 524dd96750f8ffec02a3832d2b6e7ec77c859d23 /gi/object.c | |
parent | 0688f72307596cd86e1f47a21a4ce73a865987f1 (diff) | |
download | gjs-c63b9f34380352c301fa5e211d03f20a0a4afd97.tar.gz |
object: Don't crash when given a GObject singleton
Some GObject libraries, like IBus, implement singletons by adding a custom
construct vfunc, from which they return an existing GObject. This means that
g_object_newv may not always return a new object. In these cases, returning the
existing wrapper JS object should be enough to help clients out.
Diffstat (limited to 'gi/object.c')
-rw-r--r-- | gi/object.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/gi/object.c b/gi/object.c index 79a921db..d7caefbf 100644 --- a/gi/object.c +++ b/gi/object.c @@ -703,6 +703,21 @@ GJS_NATIVE_CONSTRUCTOR_DECLARE(object_instance) } priv->gobj = g_object_newv(gtype, n_params, params); + + if (peek_js_obj(context, priv->gobj) != NULL) { + /* g_object_newv returned an object that's already tracked by a JS + * object. Let's assume this is a singleton like IBus.IBus and return + * the existing JS wrapper object. + * + * 'object' has a value that was originally created by + * JS_NewObjectForConstructor in GJS_NATIVE_CONSTRUCTOR_PRELUDE, but + * we're not actually using it, so just let it get collected. Avoiding + * this would require a non-trivial amount of work. + * */ + object = peek_js_obj(context, priv->gobj); + goto out; + } + free_g_params(params, n_params); g_type_query(gtype, &query); @@ -732,6 +747,7 @@ GJS_NATIVE_CONSTRUCTOR_DECLARE(object_instance) TRACE(GJS_OBJECT_PROXY_NEW(priv, priv->gobj, g_base_info_get_namespace ( (GIBaseInfo*) priv->info), g_base_info_get_name ( (GIBaseInfo*) priv->info) )); + out: GJS_NATIVE_CONSTRUCTOR_FINISH(object_instance); return JS_TRUE; |