[gjs] Introduce infrastructure for override modules
- From: Giovanni Campagna <gcampagna src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs] Introduce infrastructure for override modules
- Date: Thu, 19 May 2011 17:38:34 +0000 (UTC)
commit dc77c6a069f96b97f2b617d64a18adad47f2e2c1
Author: Giovanni Campagna <gcampagna src gnome org>
Date: Tue Mar 29 16:51:55 2011 +0200
Introduce infrastructure for override modules
Override modules are JS modules that can subsume or replace native
modules from GObject Introspection.
https://bugzilla.gnome.org/show_bug.cgi?id=646633
Makefile-modules.am | 3 ++
Makefile.am | 3 +-
gi/ns.c | 18 +---------
gi/ns.h | 3 +-
gi/repo.c | 77 ++++++++++++++++++++++++++++++++++++++++++++--
modules/overrides/Gio.js | 2 +
6 files changed, 84 insertions(+), 22 deletions(-)
---
diff --git a/Makefile-modules.am b/Makefile-modules.am
index c43b2d8..fb1864d 100644
--- a/Makefile-modules.am
+++ b/Makefile-modules.am
@@ -3,6 +3,9 @@ dist_gjstweener_DATA = \
modules/tweener/tweener.js \
modules/tweener/tweenList.js
+dist_gjsoverride_DATA = \
+ modules/overrides/Gio.js
+
dist_gjsjs_DATA += \
modules/gettext.js \
modules/lang.js \
diff --git a/Makefile.am b/Makefile.am
index f1a7777..b0e433a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -12,7 +12,8 @@ TEST_PROGS =
check_PROGRAMS = $(TEST_PROGS)
gjsjsdir = @gjsjsdir@
-gjstweenerdir = @gjsjsdir@/tweener
+gjsoverridedir = $(gjsjsdir)/overrides
+gjstweenerdir = $(gjsjsdir)/tweener
gjsnativedir = @gjsnativedir@
gjs_public_includedir = $(includedir)/gjs-1.0
diff --git a/gi/ns.c b/gi/ns.c
index b9a1ea7..1033969 100644
--- a/gi/ns.c
+++ b/gi/ns.c
@@ -287,23 +287,9 @@ ns_new(JSContext *context,
}
JSObject*
-gjs_define_ns(JSContext *context,
- JSObject *in_object,
+gjs_create_ns(JSContext *context,
const char *ns_name,
GIRepository *repo)
{
- JSObject *ns;
-
- ns = ns_new(context, ns_name, repo);
-
- if (!JS_DefineProperty(context, in_object,
- ns_name, OBJECT_TO_JSVAL(ns),
- NULL, NULL,
- GJS_MODULE_PROP_FLAGS))
- gjs_fatal("no memory to define ns property");
-
- gjs_debug(GJS_DEBUG_GNAMESPACE,
- "Defined namespace '%s' %p in GIRepository %p", ns_name, ns, in_object);
-
- return ns;
+ return ns_new(context, ns_name, repo);
}
diff --git a/gi/ns.h b/gi/ns.h
index d5bf2ac..f717ea6 100644
--- a/gi/ns.h
+++ b/gi/ns.h
@@ -32,8 +32,7 @@
G_BEGIN_DECLS
-JSObject* gjs_define_ns(JSContext *context,
- JSObject *in_object,
+JSObject* gjs_create_ns(JSContext *context,
const char *ns_name,
GIRepository *repo);
diff --git a/gi/repo.c b/gi/repo.c
index a17ed4c..955f561 100644
--- a/gi/repo.c
+++ b/gi/repo.c
@@ -50,6 +50,8 @@ static struct JSClass gjs_repo_class;
GJS_DEFINE_PRIV_FROM_JS(Repo, gjs_repo_class)
+static JSObject * lookup_override_function(JSContext *, const char *);
+
static JSObject*
resolve_namespace_object(JSContext *context,
JSObject *repo_obj,
@@ -61,7 +63,9 @@ resolve_namespace_object(JSContext *context,
JSObject *versions;
jsval version_val;
char *version;
- JSObject *result;
+ JSObject *namespace;
+ JSObject *override;
+ jsval result;
JS_BeginRequest(context);
@@ -101,9 +105,33 @@ resolve_namespace_object(JSContext *context,
* with the given namespace name, pointing to that namespace
* in the repo.
*/
- result = gjs_define_ns(context, repo_obj, ns_name, repo);
+ namespace = gjs_create_ns(context, ns_name, repo);
+ JS_AddObjectRoot(context, &namespace);
+
+ override = lookup_override_function(context, ns_name);
+ if (override && !JS_CallFunctionValue (context,
+ namespace, /* thisp */
+ OBJECT_TO_JSVAL(override), /* callee */
+ 0, /* argc */
+ NULL, /* argv */
+ &result)) {
+ JS_RemoveObjectRoot(context, &namespace);
+ JS_EndRequest(context);
+ return NULL;
+ }
+
+ if (!JS_DefineProperty(context, repo_obj,
+ ns_name, OBJECT_TO_JSVAL(namespace),
+ NULL, NULL,
+ GJS_MODULE_PROP_FLAGS))
+ gjs_fatal("no memory to define ns property");
+
+ gjs_debug(GJS_DEBUG_GNAMESPACE,
+ "Defined namespace '%s' %p in GIRepository %p", ns_name, namespace, repo_obj);
+
+ JS_RemoveObjectRoot(context, &namespace);
JS_EndRequest(context);
- return result;
+ return namespace;
}
/*
@@ -503,6 +531,49 @@ gjs_lookup_namespace_object(JSContext *context,
return gjs_lookup_namespace_object_by_name(context, ns);
}
+static JSObject*
+lookup_override_function(JSContext *context,
+ const char *ns)
+{
+ JSObject *global;
+ jsval importer;
+ jsval overridespkg;
+ jsval module;
+ jsval function;
+
+ JS_BeginRequest(context);
+ global = gjs_get_import_global(context);
+
+ importer = JSVAL_VOID;
+ if (!gjs_object_require_property(context, global, "global object", "imports", &importer) ||
+ !JSVAL_IS_OBJECT(importer))
+ goto fail;
+
+ overridespkg = JSVAL_VOID;
+ if (!gjs_object_require_property(context, JSVAL_TO_OBJECT(importer), "importer",
+ "overrides", &overridespkg) ||
+ !JSVAL_IS_OBJECT(overridespkg))
+ goto fail;
+
+ module = JSVAL_VOID;
+ if (!gjs_object_require_property(context, JSVAL_TO_OBJECT(overridespkg), "GI repository object", ns, &module)
+ || !JSVAL_IS_OBJECT(module))
+ goto fail;
+
+ if (!gjs_object_require_property(context, JSVAL_TO_OBJECT(module), "override module",
+ "_init", &function) ||
+ !JSVAL_IS_OBJECT(function))
+ goto fail;
+
+ JS_EndRequest(context);
+ return JSVAL_TO_OBJECT(function);
+
+ fail:
+ JS_ClearPendingException(context);
+ JS_EndRequest(context);
+ return NULL;
+}
+
JSObject*
gjs_lookup_namespace_object_by_name(JSContext *context,
const char *ns)
diff --git a/modules/overrides/Gio.js b/modules/overrides/Gio.js
new file mode 100644
index 0000000..bbb3bbe
--- /dev/null
+++ b/modules/overrides/Gio.js
@@ -0,0 +1,2 @@
+function _init() {
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]