[gjs: 6/8] object: Move imports._gi.hook_up_vfunc() to be a method
- From: Cosimo Cecchi <cosimoc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs: 6/8] object: Move imports._gi.hook_up_vfunc() to be a method
- Date: Wed, 13 Jun 2018 14:39:53 +0000 (UTC)
commit 8fb7b4e14a2e7f96f5c7e0cd9c44d3da65271b20
Author: Philip Chimento <philip chimento gmail com>
Date: Mon Jun 11 00:57:18 2018 -0700
object: Move imports._gi.hook_up_vfunc() to be a method
Since we're required to pass in a GObject prototype to
imports._gi.hook_up_vfunc(), it makes sense to make it a method of the
prototype. It's still only accessible by importing _gi, as we give it a
symbol name which is exposed as imports._gi.hook_up_vfunc_symbol.
gi/object.cpp | 99 ++++++++++++++++++++++++++++++--------------
modules/_legacy.js | 3 +-
modules/overrides/GObject.js | 2 +-
3 files changed, 72 insertions(+), 32 deletions(-)
---
diff --git a/gi/object.cpp b/gi/object.cpp
index 58ca7b37..9e80804b 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -326,6 +326,7 @@ class ObjectInstance {
bool to_string_impl(JSContext *cx, const JS::CallArgs& args);
bool init_impl(JSContext *cx, const JS::CallArgs& args,
JS::MutableHandleObject obj);
+ bool hook_up_vfunc_impl(JSContext *cx, const JS::CallArgs& args);
public:
static bool connect(JSContext *cx, unsigned argc, JS::Value *vp);
@@ -333,12 +334,15 @@ class ObjectInstance {
static bool emit(JSContext *cx, unsigned argc, JS::Value *vp);
static bool to_string(JSContext *cx, unsigned argc, JS::Value *vp);
static bool init(JSContext *cx, unsigned argc, JS::Value *vp);
+ static bool hook_up_vfunc(JSContext *cx, unsigned argc, JS::Value *vp);
/* Methods connected to "public" API */
+ private:
+ static JS::PersistentRootedSymbol hook_up_vfunc_root;
+ public:
bool typecheck_object(JSContext *cx, GType expected_type, bool throw_error);
- bool hook_up_vfunc(JSContext *cx, JS::HandleObject wrapper, const char *name,
- JS::HandleObject function);
+ static JS::Symbol* hook_up_vfunc_symbol(JSContext *cx);
/* Notification callbacks */
@@ -356,6 +360,7 @@ static std::unordered_map<GType, AutoParamArray> class_init_properties;
static bool weak_pointer_callback = false;
ObjectInstance *ObjectInstance::wrapped_gobject_list = nullptr;
+JS::PersistentRootedSymbol ObjectInstance::hook_up_vfunc_root;
extern struct JSClass gjs_object_instance_class;
GJS_DEFINE_PRIV_FROM_JS(ObjectInstance, gjs_object_instance_class)
@@ -2352,6 +2357,19 @@ gjs_object_define_static_methods(JSContext *context,
}
}
+JS::Symbol*
+ObjectInstance::hook_up_vfunc_symbol(JSContext *cx)
+{
+ if (!hook_up_vfunc_root.initialized()) {
+ JS::RootedString descr(cx,
+ JS_NewStringCopyZ(cx, "__GObject__hook_up_vfunc"));
+ if (!descr)
+ g_error("Out of memory defining internal symbol");
+ hook_up_vfunc_root.init(cx, JS::NewSymbol(cx, descr));
+ }
+ return hook_up_vfunc_root;
+}
+
void
gjs_define_object_class(JSContext *context,
JS::HandleObject in_object,
@@ -2435,6 +2453,15 @@ gjs_define_object_class(JSContext *context,
g_error("Can't init class %s", constructor_name);
}
+ /* Hook_up_vfunc can't be included in gjs_object_instance_proto_funcs
+ * because it's a custom symbol. */
+ JS::RootedId hook_up_vfunc(context,
+ SYMBOL_TO_JSID(ObjectInstance::hook_up_vfunc_symbol(context)));
+ if (!JS_DefineFunctionById(context, prototype, hook_up_vfunc,
+ &ObjectInstance::hook_up_vfunc, 3,
+ GJS_MODULE_PROP_FLAGS))
+ return;
+
GJS_INC_COUNTER(object);
priv = g_slice_new0(ObjectInstance);
new (priv) ObjectInstance(prototype, info, gtype);
@@ -2638,39 +2665,33 @@ find_vfunc_info (JSContext *context,
}
}
-static bool
-gjs_hook_up_vfunc(JSContext *cx,
- unsigned argc,
- JS::Value *vp)
+bool
+ObjectInstance::hook_up_vfunc(JSContext *cx,
+ unsigned argc,
+ JS::Value *vp)
{
- JS::CallArgs argv = JS::CallArgsFromVp (argc, vp);
- GjsAutoJSChar name;
- JS::RootedObject object(cx), function(cx);
-
- if (!gjs_parse_call_args(cx, "hook_up_vfunc", argv, "oso",
- "object", &object,
- "name", &name,
- "function", &function))
- return false;
-
- if (!do_base_typecheck(cx, object, true))
- return false;
-
- argv.rval().setUndefined();
-
- auto *priv = ObjectInstance::for_js(cx, object);
+ GJS_GET_PRIV(cx, argc, vp, args, object, ObjectInstance, priv);
if (!priv)
return throw_priv_is_null_error(cx);
- return priv->hook_up_vfunc(cx, object, name, function);
+ return priv->hook_up_vfunc_impl(cx, args);
}
bool
-ObjectInstance::hook_up_vfunc(JSContext *cx,
- JS::HandleObject wrapper,
- const char *name,
- JS::HandleObject function)
+ObjectInstance::hook_up_vfunc_impl(JSContext *cx,
+ const JS::CallArgs& args)
{
+ g_assert(is_prototype());
+
+ GjsAutoJSChar name;
+ JS::RootedObject function(cx);
+ if (!gjs_parse_call_args(cx, "hook_up_vfunc", args, "so",
+ "name", &name,
+ "function", &function))
+ return false;
+
+ args.rval().setUndefined();
+
/* find the first class that actually has repository information */
GIObjectInfo *info = m_info;
GType info_gtype = m_gtype;
@@ -2710,7 +2731,8 @@ ObjectInstance::hook_up_vfunc(JSContext *cx,
}
if (!vfunc) {
- gjs_throw(cx, "Could not find definition of virtual function %s", name);
+ gjs_throw(cx, "Could not find definition of virtual function %s",
+ name.get());
return false;
}
@@ -2726,6 +2748,7 @@ ObjectInstance::hook_up_vfunc(JSContext *cx,
method_ptr = G_STRUCT_MEMBER_P(implementor_vtable, offset);
JS::RootedValue v_function(cx, JS::ObjectValue(*function));
+ JS::RootedObject wrapper(cx, m_wrapper);
trampoline = gjs_callback_trampoline_new(cx, v_function, vfunc,
GI_SCOPE_TYPE_NOTIFIED,
wrapper, true);
@@ -3392,21 +3415,37 @@ gjs_signal_new(JSContext *cx,
return true;
}
+static bool
+hook_up_vfunc_symbol_getter(JSContext *cx,
+ unsigned argc,
+ JS::Value *vp)
+{
+ JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
+ args.rval().setSymbol(ObjectInstance::hook_up_vfunc_symbol(cx));
+ return true;
+}
+
static JSFunctionSpec module_funcs[] = {
JS_FS("override_property", gjs_override_property, 2, GJS_MODULE_PROP_FLAGS),
JS_FS("register_interface", gjs_register_interface, 3, GJS_MODULE_PROP_FLAGS),
JS_FS("register_type", gjs_register_type, 4, GJS_MODULE_PROP_FLAGS),
- JS_FS("hook_up_vfunc", gjs_hook_up_vfunc, 3, GJS_MODULE_PROP_FLAGS),
JS_FS("signal_new", gjs_signal_new, 6, GJS_MODULE_PROP_FLAGS),
JS_FS_END,
};
+static JSPropertySpec module_props[] = {
+ JS_PSG("hook_up_vfunc_symbol", hook_up_vfunc_symbol_getter,
+ GJS_MODULE_PROP_FLAGS),
+ JS_PS_END
+};
+
bool
gjs_define_private_gi_stuff(JSContext *cx,
JS::MutableHandleObject module)
{
module.set(JS_NewPlainObject(cx));
- return JS_DefineFunctions(cx, module, &module_funcs[0]);
+ return JS_DefineFunctions(cx, module, module_funcs) &&
+ JS_DefineProperties(cx, module, module_props);
}
bool
diff --git a/modules/_legacy.js b/modules/_legacy.js
index a89420c4..4dcde002 100644
--- a/modules/_legacy.js
+++ b/modules/_legacy.js
@@ -475,7 +475,8 @@ function defineGObjectLegacyObjects(GObject) {
let wrapped = this.prototype[name];
if (name.slice(0, 6) == 'vfunc_') {
- Gi.hook_up_vfunc(this.prototype, name.slice(6), wrapped);
+ this.prototype[Gi.hook_up_vfunc_symbol](name.slice(6),
+ wrapped);
} else if (name.slice(0, 3) == 'on_') {
let id = GObject.signal_lookup(name.slice(3).replace('_', '-'), this.$gtype);
if (id !== 0) {
diff --git a/modules/overrides/GObject.js b/modules/overrides/GObject.js
index 741a9f39..aa32c627 100644
--- a/modules/overrides/GObject.js
+++ b/modules/overrides/GObject.js
@@ -362,7 +362,7 @@ function _init() {
let func = newClass.prototype[name];
if (name.startsWith('vfunc_')) {
- Gi.hook_up_vfunc(newClass.prototype, name.slice(6), func);
+ newClass.prototype[Gi.hook_up_vfunc_symbol](name.slice(6), func);
} else if (name.startsWith('on_')) {
let id = GObject.signal_lookup(name.slice(3).replace('_', '-'),
newClass.$gtype);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]