[gjs] Check for a builtin module before beginning to load it
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs] Check for a builtin module before beginning to load it
- Date: Fri, 10 Dec 2010 16:22:57 +0000 (UTC)
commit 1fb10969bed279e7266de50f31d28c49352778d2
Author: Owen W. Taylor <otaylor fishsoup net>
Date: Fri Dec 10 11:21:04 2010 -0500
Check for a builtin module before beginning to load it
When used to check for builtin modules, import_native_file() would create a
module object, set properties on it, store it in the native class, fail
to load a builtin module of that name, and then back everything out.
Add a pre-check to avoid this. (It means that we do extract the module ID
twice when we actually load a built-in module, but built-in modules will
a small fraction of modules.)
V2: Modified by Colin Walters <walters verbum org> for the fact that
gjs_string_get_ascii() now mallocs.
https://bugzilla.gnome.org/show_bug.cgi?id=635371
gjs/importer.c | 3 +-
gjs/native.c | 132 +++++++++++++++++++++++++++++++++++++++----------------
gjs/native.h | 5 ++
3 files changed, 100 insertions(+), 40 deletions(-)
---
diff --git a/gjs/importer.c b/gjs/importer.c
index 4c03582..d875a38 100644
--- a/gjs/importer.c
+++ b/gjs/importer.c
@@ -515,7 +515,8 @@ do_import(JSContext *context,
directories = NULL;
/* First try importing an internal module like byteArray */
- if (import_native_file(context, obj, name, NULL)) {
+ if (gjs_is_registered_native_module(context, obj, name) &&
+ import_native_file(context, obj, name, NULL)) {
gjs_debug(GJS_DEBUG_IMPORTER,
"successfully imported module '%s'", name);
result = JS_TRUE;
diff --git a/gjs/native.c b/gjs/native.c
index 822fd6a..c2d49f9 100644
--- a/gjs/native.c
+++ b/gjs/native.c
@@ -90,6 +90,88 @@ module_get_parent(JSContext *context,
}
}
+static char *
+get_module_name(JSContext *context,
+ JSObject *module_obj,
+ jsval *tmp)
+{
+ if (gjs_object_get_property(context, module_obj, "__moduleName__", tmp) &&
+ JSVAL_IS_STRING(*tmp))
+ return gjs_string_get_ascii(context, *tmp);
+ else
+ return NULL;
+}
+
+static GjsNativeModule *
+lookup_native_module(JSContext *context,
+ JSObject *parent,
+ const char *name,
+ gboolean is_definition)
+{
+ GjsNativeModule *native_module;
+ GString *module_id;
+
+ module_id = g_string_new(name);
+ while (parent != NULL) {
+ const char *name;
+ jsval tmp;
+
+ name = get_module_name(context, parent, &tmp);
+ if (name != NULL) {
+ g_string_prepend(module_id, name);
+ }
+
+ /* Move up to parent */
+ parent = module_get_parent(context, parent);
+ }
+
+ if (is_definition)
+ gjs_debug(GJS_DEBUG_NATIVE,
+ "Defining native module '%s'",
+ module_id->str);
+
+ if (modules != NULL)
+ native_module = g_hash_table_lookup(modules, module_id->str);
+ else
+ native_module = NULL;
+
+ if (native_module == NULL) {
+ if (is_definition) {
+ gjs_throw(context,
+ "No native module '%s' has registered itself",
+ module_id->str);
+ }
+ g_string_free(module_id, TRUE);
+ return NULL;
+ }
+
+ g_string_free(module_id, TRUE);
+
+ return native_module;
+}
+
+/**
+ * gjs_is_registered_native_module:
+ * @context:
+ * @parent: the parent object defining the namespace
+ * @name: name of the module
+ *
+ * Checks if a native module corresponding to @name has already
+ * been registered. This is used to check to see if a name is a
+ * builtin module without starting to try and load it.
+ */
+gboolean
+gjs_is_registered_native_module(JSContext *context,
+ JSObject *parent,
+ const char *name)
+{
+ GjsNativeModule *native_module;
+
+ native_module = lookup_native_module(context, parent, name, FALSE);
+
+ return native_module != NULL;
+}
+
/**
* gjs_import_native_module:
* @context:
@@ -108,9 +190,9 @@ gjs_import_native_module(JSContext *context,
GjsNativeFlags *flags_p)
{
GModule *gmodule = NULL;
- GString *module_id;
- JSObject *parent;
GjsNativeModule *native_module;
+ JSObject *parent;
+ jsval tmp;
if (flags_p)
*flags_p = 0;
@@ -133,49 +215,21 @@ gjs_import_native_module(JSContext *context,
* a native module. We just have to reverse-engineer
* the module id from module_obj.
*/
- module_id = g_string_new(NULL);
- parent = module_obj;
- while (parent != NULL) {
- jsval value;
-
- if (gjs_object_get_property(context, parent, "__moduleName__", &value) &&
- JSVAL_IS_STRING(value)) {
- char *name;
- name = gjs_string_get_ascii(context, value);
-
- if (module_id->len > 0)
- g_string_prepend(module_id, ".");
-
- g_string_prepend(module_id, name);
- g_free(name);
- }
-
- /* Move up to parent */
- parent = module_get_parent(context, parent);
+ {
+ char *module_name = get_module_name(context, module_obj, &tmp);
+ native_module = lookup_native_module (context,
+ module_get_parent(context, module_obj),
+ module_name,
+ TRUE);
+ g_free(module_name);
}
- gjs_debug(GJS_DEBUG_NATIVE,
- "Defining native module '%s'",
- module_id->str);
-
- if (modules != NULL)
- native_module = g_hash_table_lookup(modules, module_id->str);
- else
- native_module = NULL;
-
- if (native_module == NULL) {
- if (filename) {
- gjs_throw(context,
- "No native module '%s' has registered itself",
- module_id->str);
+ if (!native_module) {
+ if (gmodule)
g_module_close(gmodule);
- }
- g_string_free(module_id, TRUE);
return JS_FALSE;
}
- g_string_free(module_id, TRUE);
-
if (flags_p)
*flags_p = native_module->flags;
diff --git a/gjs/native.h b/gjs/native.h
index 4a8224e..f30d763 100644
--- a/gjs/native.h
+++ b/gjs/native.h
@@ -81,6 +81,11 @@ void gjs_register_native_module (const char *module_id,
GjsDefineModuleFunc func,
GjsNativeFlags flags);
+/* called by importer.c to to check for already loaded modules */
+gboolean gjs_is_registered_native_module(JSContext *context,
+ JSObject *parent,
+ const char *name);
+
/* called by importer.c to load a native module once it finds
* it in the search path
*/
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]