[gjs] Make gjs_object_require_property deal with ids instead of names



commit dfa7ce574b8e497c99f74ca54ace0a0f3c835a92
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Mon Apr 8 23:03:17 2013 +0200

    Make gjs_object_require_property deal with ids instead of names
    
    This way we can cache the IDs.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=697592

 gi/arg.c                  |    4 +-
 gi/boxed.c                |   67 ++++++++++++++++++++++++-------------
 gi/gerror.c               |   40 ++++++++++++++++-------
 gi/object.c               |   13 ++++---
 gi/param.c                |    4 ++-
 gi/repo.c                 |   80 +++++++++++++++++++++++++++++---------------
 gi/repo.h                 |    2 +-
 gi/value.c                |    2 +-
 gjs/importer.c            |   15 +++++++--
 gjs/jsapi-dynamic-class.c |    5 ++-
 gjs/jsapi-util-string.c   |   10 ++++++
 gjs/jsapi-util.c          |   56 +++++++++++++++++--------------
 gjs/jsapi-util.h          |   10 +++--
 gjs/runtime.c             |   13 +++----
 gjs/runtime.h             |    8 ++++
 15 files changed, 214 insertions(+), 115 deletions(-)
---
diff --git a/gi/arg.c b/gi/arg.c
index dd6e85e..72034da 100644
--- a/gi/arg.c
+++ b/gi/arg.c
@@ -1111,7 +1111,7 @@ gjs_array_to_explicit_array_internal(JSContext       *context,
 
         if (!gjs_object_require_property(context,
                                          JSVAL_TO_OBJECT(value), NULL,
-                                         "length",
+                                         length_name,
                                          &length_value) ||
             !JS_ValueToECMAUint32(context, length_value, &length)) {
             goto out;
@@ -1592,7 +1592,7 @@ gjs_value_to_g_argument(JSContext      *context,
 
             if (!gjs_object_require_property(context,
                                              JSVAL_TO_OBJECT(value), NULL,
-                                             "length",
+                                             length_name,
                                              &length_value) ||
                 !JS_ValueToECMAUint32(context, length_value, &length)) {
                 wrong = TRUE;
diff --git a/gi/boxed.c b/gi/boxed.c
index 7c5280d..5db3c70 100644
--- a/gi/boxed.c
+++ b/gi/boxed.c
@@ -45,7 +45,9 @@ typedef struct {
     GIBoxedInfo *info;
     GType gtype;
     gint zero_args_constructor; /* -1 if none */
+    jsid zero_args_constructor_name;
     gint default_constructor; /* -1 if none */
+    jsid default_constructor_name;
 
     /* instance info */
     void *gboxed; /* NULL if we are the prototype and not an instance */
@@ -302,7 +304,7 @@ boxed_init_from_props(JSContext   *context,
             goto out;
         }
 
-        if (!gjs_object_require_property(context, props, "property list", name, &value)) {
+        if (!gjs_object_require_property(context, props, "property list", prop_id, &value)) {
             g_free(name);
             goto out;
         }
@@ -327,21 +329,24 @@ boxed_init_from_props(JSContext   *context,
 static JSBool
 boxed_invoke_constructor(JSContext   *context,
                          JSObject    *obj,
-                         const gchar *constructor_name,
+                         jsid         constructor_name,
                          unsigned     argc,
                          jsval       *argv,
                          jsval       *rval)
 {
     jsval js_constructor, js_constructor_func;
+    jsid constructor_const;
 
-    if (!gjs_object_require_property (context, obj, NULL, "constructor", &js_constructor))
+    constructor_const = gjs_runtime_get_const_string(JS_GetRuntime(context),
+                                                     GJS_STRING_CONSTRUCTOR);
+    if (!gjs_object_require_property(context, obj, NULL, constructor_const, &js_constructor))
         return JS_FALSE;
 
-    if (!gjs_object_require_property (context, JSVAL_TO_OBJECT(js_constructor), NULL,
-                                      constructor_name, &js_constructor_func))
+    if (!gjs_object_require_property(context, JSVAL_TO_OBJECT(js_constructor), NULL,
+                                     constructor_name, &js_constructor_func))
         return JS_FALSE;
 
-    return gjs_call_function_value (context, NULL, js_constructor_func, argc, argv, rval);
+    return gjs_call_function_value(context, NULL, js_constructor_func, argc, argv, rval);
 }
 
 static JSBool
@@ -353,9 +358,13 @@ boxed_new(JSContext   *context,
           jsval       *rval)
 {
     if (priv->gtype == G_TYPE_VARIANT) {
+        jsid constructor_name;
+
         /* Short-circuit construction for GVariants by calling into the JS packing
            function */
-        return boxed_invoke_constructor (context, obj, "_new_internal", argc, argv, rval);
+        constructor_name = gjs_runtime_get_const_string(JS_GetRuntime(context),
+                                                        GJS_STRING_NEW_INTERNAL);
+        return boxed_invoke_constructor (context, obj, constructor_name, argc, argv, rval);
     }
 
     /* If the structure is registered as a boxed, we can create a new instance by
@@ -391,21 +400,12 @@ boxed_new(JSContext   *context,
     } else if (priv->can_allocate_directly) {
         boxed_new_direct(priv);
     } else if (priv->default_constructor >= 0) {
-        GIFunctionInfo *constructor;
-        const gchar *constructor_name;
         JSBool retval;
 
         /* for simplicity, we simply delegate all the work to the actual JS constructor
            function (which we retrieve from the JS constructor, that is, Namespace.BoxedType,
            or object.constructor, given that object was created with the right prototype */
-
-        constructor = g_struct_info_get_method(priv->info, priv->default_constructor);
-        constructor_name = g_base_info_get_name((GIBaseInfo*)constructor);
-
-        retval = boxed_invoke_constructor(context, obj, constructor_name, argc, argv, rval);
-
-        g_base_info_unref((GIBaseInfo*)constructor);
-
+        retval = boxed_invoke_constructor(context, obj, priv->default_constructor_name, argc, argv, rval);
         return retval;
     } else {
         gjs_throw(context, "Unable to construct struct type %s since it has no default constructor and 
cannot be allocated directly",
@@ -1119,10 +1119,12 @@ struct_is_simple(GIStructInfo *info)
 }
 
 static void
-boxed_fill_prototype_info(Boxed *priv)
+boxed_fill_prototype_info(JSContext *context,
+                          Boxed     *priv)
 {
     int i, n_methods;
     int first_constructor = -1;
+    jsid first_constructor_name = JSID_VOID;
 
     priv->gtype = g_registered_type_info_get_g_type( (GIRegisteredTypeInfo*) priv->info);
     priv->zero_args_constructor = -1;
@@ -1144,25 +1146,42 @@ boxed_fill_prototype_info(Boxed *priv)
 
             flags = g_function_info_get_flags(func_info);
             if ((flags & GI_FUNCTION_IS_CONSTRUCTOR) != 0) {
-                if (first_constructor < 0)
+                if (first_constructor < 0) {
+                    const char *name;
+
+                    name = g_base_info_get_name((GIBaseInfo*) func_info);
                     first_constructor = i;
+                    first_constructor_name = gjs_intern_string_to_id(context, name);
+                }
 
                 if (priv->zero_args_constructor < 0 &&
-                    g_callable_info_get_n_args((GICallableInfo*) func_info) == 0)
+                    g_callable_info_get_n_args((GICallableInfo*) func_info) == 0) {
+                    const char *name;
+
+                    name = g_base_info_get_name((GIBaseInfo*) func_info);
                     priv->zero_args_constructor = i;
+                    priv->zero_args_constructor_name = gjs_intern_string_to_id(context, name);
+                }
 
                 if (priv->default_constructor < 0 &&
-                    strcmp(g_base_info_get_name ((GIBaseInfo*) func_info), "new") == 0)
+                    strcmp(g_base_info_get_name ((GIBaseInfo*) func_info), "new") == 0) {
                     priv->default_constructor = i;
+                    priv->default_constructor_name = gjs_runtime_get_const_string(JS_GetRuntime(context),
+                                                                                  GJS_STRING_NEW);
+                }
             }
 
             g_base_info_unref((GIBaseInfo*) func_info);
         }
 
-        if (priv->default_constructor < 0)
+        if (priv->default_constructor < 0) {
             priv->default_constructor = priv->zero_args_constructor;
-        if (priv->default_constructor < 0)
+            priv->default_constructor_name = priv->zero_args_constructor_name;
+        }
+        if (priv->default_constructor < 0) {
             priv->default_constructor = first_constructor;
+            priv->default_constructor_name = first_constructor_name;
+        }
     }
 }
 
@@ -1239,7 +1258,7 @@ gjs_define_boxed_class(JSContext    *context,
     GJS_INC_COUNTER(boxed);
     priv = g_slice_new0(Boxed);
     priv->info = info;
-    boxed_fill_prototype_info(priv);
+    boxed_fill_prototype_info(context, priv);
 
     g_base_info_ref( (GIBaseInfo*) priv->info);
     priv->gtype = g_registered_type_info_get_g_type ((GIRegisteredTypeInfo*) priv->info);
diff --git a/gi/gerror.c b/gi/gerror.c
index 2187d3d..74d93ce 100644
--- a/gi/gerror.c
+++ b/gi/gerror.c
@@ -62,6 +62,7 @@ GJS_NATIVE_CONSTRUCTOR_DECLARE(error)
     Error *priv;
     Error *proto_priv;
     JSObject *proto;
+    jsid message_name, code_name;
     jsval v_message, v_code;
     gchar *message;
 
@@ -102,17 +103,21 @@ GJS_NATIVE_CONSTRUCTOR_DECLARE(error)
     g_base_info_ref( (GIBaseInfo*) priv->info);
     priv->domain = proto_priv->domain;
 
-    if (!gjs_object_require_property (context, JSVAL_TO_OBJECT(argv[0]),
-                                      "GError constructor", "message", &v_message))
+    message_name = gjs_runtime_get_const_string(JS_GetRuntime(context),
+                                                GJS_STRING_MESSAGE);
+    code_name = gjs_runtime_get_const_string(JS_GetRuntime(context),
+                                             GJS_STRING_CODE);
+    if (!gjs_object_require_property(context, JSVAL_TO_OBJECT(argv[0]),
+                                     "GError constructor", message_name, &v_message))
         return JS_FALSE;
-    if (!gjs_object_require_property (context, JSVAL_TO_OBJECT(argv[0]),
-                                      "GError constructor", "code", &v_code))
+    if (!gjs_object_require_property(context, JSVAL_TO_OBJECT(argv[0]),
+                                     "GError constructor", code_name, &v_code))
         return JS_FALSE;
     if (!gjs_string_to_utf8 (context, v_message, &message))
         return JS_FALSE;
 
-    priv->gerror = g_error_new_literal (priv->domain, JSVAL_TO_INT(v_code),
-                                        message);
+    priv->gerror = g_error_new_literal(priv->domain, JSVAL_TO_INT(v_code),
+                                       message);
 
     g_free (message);
 
@@ -260,6 +265,7 @@ error_constructor_value_of(JSContext *context, unsigned argc, jsval *vp)
     jsval v_self, v_prototype;
     Error *priv;
     jsval v_out;
+    jsid prototype_name;
 
     v_self = JS_THIS(context, vp);
     if (!JSVAL_IS_OBJECT(v_self)) {
@@ -268,10 +274,12 @@ error_constructor_value_of(JSContext *context, unsigned argc, jsval *vp)
         return JS_FALSE;
     }
 
+    prototype_name = gjs_runtime_get_const_string(JS_GetRuntime(context),
+                                                  GJS_STRING_PROTOTYPE);
     if (!gjs_object_require_property(context,
                                      JSVAL_TO_OBJECT(v_self),
                                      "constructor",
-                                     "prototype",
+                                     prototype_name,
                                      &v_prototype))
         return JS_FALSE;
 
@@ -533,6 +541,7 @@ define_error_properties(JSContext *context,
     GString *stack;
     const char *filename;
     GjsContext *gjs_context;
+    jsid stack_name, filename_name, linenumber_name;
 
     /* find the JS frame that triggered the error */
     frame = NULL;
@@ -554,18 +563,25 @@ define_error_properties(JSContext *context,
     gjs_context = JS_GetContextPrivate(context);
     gjs_context_print_stack_to_buffer(gjs_context, frame, stack);
 
+    stack_name = gjs_runtime_get_const_string(JS_GetRuntime(context),
+                                              GJS_STRING_STACK);
+    filename_name = gjs_runtime_get_const_string(JS_GetRuntime(context),
+                                                 GJS_STRING_FILENAME);
+    linenumber_name = gjs_runtime_get_const_string(JS_GetRuntime(context),
+                                                   GJS_STRING_LINE_NUMBER);
+
     if (gjs_string_from_utf8(context, stack->str, stack->len, &v))
-        JS_DefineProperty(context, obj, "stack", v,
+        JS_DefinePropertyById(context, obj, stack_name, v,
                           NULL, NULL, JSPROP_ENUMERATE);
 
     filename = JS_GetScriptFilename(context, script);
     if (gjs_string_from_filename(context, filename, -1, &v))
-        JS_DefineProperty(context, obj, "fileName", v,
-                          NULL, NULL, JSPROP_ENUMERATE);
+        JS_DefinePropertyById(context, obj, filename_name, v,
+                              NULL, NULL, JSPROP_ENUMERATE);
 
     v = INT_TO_JSVAL(JS_PCToLineNumber(context, script, pc));
-    JS_DefineProperty(context, obj, "lineNumber", v,
-                      NULL, NULL, JSPROP_ENUMERATE);
+    JS_DefinePropertyById(context, obj, linenumber_name, v,
+                          NULL, NULL, JSPROP_ENUMERATE);
 
     g_string_free(stack, TRUE);
 }
diff --git a/gi/object.c b/gi/object.c
index f510a5c..a76579a 100644
--- a/gi/object.c
+++ b/gi/object.c
@@ -726,14 +726,14 @@ object_instance_props_to_g_parameters(JSContext   *context,
         jsval value;
         GParameter gparam = { NULL, { 0, }};
 
-        if (!gjs_get_string_id(context, prop_id, &name))
-            goto free_array_and_fail;
-
-        if (!gjs_object_require_property(context, props, "property list", name, &value)) {
+        if (!gjs_object_require_property(context, props, "property list", prop_id, &value)) {
             g_free(name);
             goto free_array_and_fail;
         }
 
+        if (!gjs_get_string_id(context, prop_id, &name))
+            goto free_array_and_fail;
+
         switch (init_g_param_from_property(context, name,
                                            value,
                                            gtype,
@@ -1278,10 +1278,13 @@ GJS_NATIVE_CONSTRUCTOR_DECLARE(object_instance)
     JSBool ret;
     jsval initer;
     jsval rval;
+    jsid object_init_name;
 
     GJS_NATIVE_CONSTRUCTOR_PRELUDE(object_instance);
 
-    if (!gjs_object_require_property(context, object, "GObject instance", "_init", &initer))
+    object_init_name = gjs_runtime_get_const_string(JS_GetRuntime(context),
+                                                    GJS_STRING_GOBJECT_INIT);
+    if (!gjs_object_require_property(context, object, "GObject instance", object_init_name, &initer))
         return JS_FALSE;
 
     rval = JSVAL_VOID;
diff --git a/gi/param.c b/gi/param.c
index 7e0b8bc..f676092 100644
--- a/gi/param.c
+++ b/gi/param.c
@@ -461,8 +461,10 @@ gjs_lookup_param_prototype(JSContext    *context)
 {
     JSObject *ns;
     JSObject *proto;
+    jsid gobject_name;
 
-    ns = gjs_lookup_namespace_object_by_name(context, "GObject");
+    gobject_name = gjs_intern_string_to_id(context, "GObject");
+    ns = gjs_lookup_namespace_object_by_name(context, gobject_name);
 
     if (ns == NULL)
         return NULL;
diff --git a/gi/repo.c b/gi/repo.c
index 8aefe86..65f4d29 100644
--- a/gi/repo.c
+++ b/gi/repo.c
@@ -45,8 +45,6 @@
 #include <girepository.h>
 #include <string.h>
 
-#define DUMPBIN "_gjs_private"
-
 typedef struct {
     void *dummy;
 
@@ -56,15 +54,17 @@ 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 * lookup_override_function(JSContext *, jsid);
 
 static JSObject*
 resolve_namespace_object(JSContext  *context,
                          JSObject   *repo_obj,
+                         jsid        ns_id,
                          const char *ns_name)
 {
     GIRepository *repo;
     GError *error;
+    jsid versions_name;
     jsval versions_val;
     JSObject *versions;
     jsval version_val;
@@ -75,7 +75,9 @@ resolve_namespace_object(JSContext  *context,
 
     JS_BeginRequest(context);
 
-    if (!gjs_object_require_property(context, repo_obj, "GI repository object", "versions", &versions_val) ||
+    versions_name = gjs_runtime_get_const_string(JS_GetRuntime(context),
+                                                 GJS_STRING_GI_VERSIONS);
+    if (!gjs_object_require_property(context, repo_obj, "GI repository object", versions_name, 
&versions_val) ||
         !JSVAL_IS_OBJECT(versions_val)) {
         gjs_throw(context, "No 'versions' property in GI repository object");
 
@@ -86,7 +88,7 @@ resolve_namespace_object(JSContext  *context,
     versions = JSVAL_TO_OBJECT(versions_val);
 
     version = NULL;
-    if (JS_GetProperty(context, versions, ns_name, &version_val) &&
+    if (JS_GetPropertyById(context, versions, ns_id, &version_val) &&
         JSVAL_IS_STRING(version_val)) {
         gjs_string_to_utf8(context, version_val, &version);
     }
@@ -122,7 +124,7 @@ resolve_namespace_object(JSContext  *context,
                            GJS_MODULE_PROP_FLAGS))
         gjs_fatal("no memory to define ns property");
 
-    override = lookup_override_function(context, ns_name);
+    override = lookup_override_function(context, ns_id);
     if (override && !JS_CallFunctionValue (context,
                                            namespace, /* thisp */
                                            OBJECT_TO_JSVAL(override), /* callee */
@@ -183,7 +185,7 @@ repo_new_resolve(JSContext *context,
         goto out;
 
     JS_BeginRequest(context);
-    if (resolve_namespace_object(context, *obj, name) == NULL) {
+    if (resolve_namespace_object(context, *obj, *id, name) == NULL) {
         ret = JS_FALSE;
     } else {
         *objp = *obj; /* store the object we defined the prop in */
@@ -247,8 +249,9 @@ repo_new(JSContext *context)
     JSObject *repo;
     JSObject *global;
     JSObject *versions;
+    JSObject *private_ns;
     JSBool found;
-    jsid versions_name;
+    jsid versions_name, private_ns_name;
 
     global = gjs_get_import_global(context);
 
@@ -304,14 +307,19 @@ repo_new(JSContext *context)
     versions = JS_NewObject(context, NULL, NULL, global);
     versions_name = gjs_runtime_get_const_string(JS_GetRuntime(context),
                                                  GJS_STRING_GI_VERSIONS);
-
     JS_DefinePropertyById(context, repo,
                           versions_name,
                           OBJECT_TO_JSVAL(versions),
                           NULL, NULL,
                           JSPROP_PERMANENT);
 
-    JS_DefineObject(context, repo, DUMPBIN, NULL, NULL, JSPROP_PERMANENT);
+    private_ns = JS_NewObject(context, NULL, NULL, global);
+    private_ns_name = gjs_runtime_get_const_string(JS_GetRuntime(context),
+                                                   GJS_STRING_PRIVATE_NS_MARKER);
+    JS_DefinePropertyById(context, repo,
+                          private_ns_name,
+                          OBJECT_TO_JSVAL(private_ns),
+                          NULL, NULL, JSPROP_PERMANENT);
 
     /* FIXME - hack to make namespaces load, since
      * gobject-introspection does not yet search a path properly.
@@ -519,7 +527,11 @@ gjs_define_info(JSContext  *context,
 JSObject*
 gjs_lookup_private_namespace(JSContext *context)
 {
-    return gjs_lookup_namespace_object_by_name(context, DUMPBIN);
+    jsid ns_name;
+
+    ns_name = gjs_runtime_get_const_string(JS_GetRuntime(context),
+                                           GJS_STRING_PRIVATE_NS_MARKER);
+    return gjs_lookup_namespace_object_by_name(context, ns_name);
 }
 
 /* Get the namespace object that the GIBaseInfo should be inside */
@@ -528,6 +540,7 @@ gjs_lookup_namespace_object(JSContext  *context,
                             GIBaseInfo *info)
 {
     const char *ns;
+    jsid ns_name;
 
     ns = g_base_info_get_namespace(info);
     if (ns == NULL) {
@@ -538,40 +551,48 @@ gjs_lookup_namespace_object(JSContext  *context,
         return NULL;
     }
 
-    return gjs_lookup_namespace_object_by_name(context, ns);
+    ns_name = gjs_intern_string_to_id(context, ns);
+    return gjs_lookup_namespace_object_by_name(context, ns_name);
 }
 
 static JSObject*
 lookup_override_function(JSContext  *context,
-                         const char *ns)
+                         jsid        ns_name)
 {
     JSObject *global;
     jsval importer;
     jsval overridespkg;
     jsval module;
     jsval function;
+    jsid imports_name, overrides_name, object_init_name;
 
     JS_BeginRequest(context);
     global = gjs_get_import_global(context);
 
     importer = JSVAL_VOID;
-    if (!gjs_object_require_property(context, global, "global object", "imports", &importer) ||
+    imports_name = gjs_runtime_get_const_string(JS_GetRuntime(context),
+                                                GJS_STRING_IMPORTS);
+    if (!gjs_object_require_property(context, global, "global object", imports_name, &importer) ||
         !JSVAL_IS_OBJECT(importer))
         goto fail;
 
     overridespkg = JSVAL_VOID;
+    overrides_name = gjs_runtime_get_const_string(JS_GetRuntime(context),
+                                                  GJS_STRING_GI_OVERRIDES);
     if (!gjs_object_require_property(context, JSVAL_TO_OBJECT(importer), "importer",
-                                        "overrides", &overridespkg) ||
+                                     overrides_name, &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)
+    if (!gjs_object_require_property(context, JSVAL_TO_OBJECT(overridespkg), "GI repository object", 
ns_name, &module)
         || !JSVAL_IS_OBJECT(module))
         goto fail;
 
+    object_init_name = gjs_runtime_get_const_string(JS_GetRuntime(context),
+                                                    GJS_STRING_GOBJECT_INIT);
     if (!gjs_object_require_property(context, JSVAL_TO_OBJECT(module), "override module",
-                                     "_init", &function) ||
+                                     object_init_name, &function) ||
         !JSVAL_IS_OBJECT(function))
         goto fail;
 
@@ -586,24 +607,22 @@ lookup_override_function(JSContext  *context,
 
 JSObject*
 gjs_lookup_namespace_object_by_name(JSContext      *context,
-                                    const char     *ns)
+                                    jsid            ns_name)
 {
     JSObject *global;
     JSObject *repo_obj;
     jsval importer;
     jsval girepository;
     jsval ns_obj;
-
-    /* This is a little bit of a hack, we hardcode an assumption that
-     * the only repo object that exists is called "imports.gi" and is
-     * is stored in the "import global" for the runtime.
-     */
+    jsid imports_name, gi_name;
 
     JS_BeginRequest(context);
     global = gjs_get_import_global(context);
 
     importer = JSVAL_VOID;
-    if (!gjs_object_require_property(context, global, "global object", "imports", &importer) ||
+    imports_name = gjs_runtime_get_const_string(JS_GetRuntime(context),
+                                                GJS_STRING_IMPORTS);
+    if (!gjs_object_require_property(context, global, "global object", imports_name, &importer) ||
         !JSVAL_IS_OBJECT(importer)) {
         gjs_log_exception(context, NULL);
         gjs_throw(context, "No imports property in global object");
@@ -611,8 +630,10 @@ gjs_lookup_namespace_object_by_name(JSContext      *context,
     }
 
     girepository = JSVAL_VOID;
+    gi_name = gjs_runtime_get_const_string(JS_GetRuntime(context),
+                                           GJS_STRING_GI_MODULE);
     if (!gjs_object_require_property(context, JSVAL_TO_OBJECT(importer), "importer",
-                                        "gi", &girepository) ||
+                                     gi_name, &girepository) ||
         !JSVAL_IS_OBJECT(girepository)) {
         gjs_log_exception(context, NULL);
         gjs_throw(context, "No gi property in importer");
@@ -621,12 +642,17 @@ gjs_lookup_namespace_object_by_name(JSContext      *context,
 
     repo_obj = JSVAL_TO_OBJECT(girepository);
 
-    if (!gjs_object_require_property(context, repo_obj, "GI repository object", ns, &ns_obj)) {
+    if (!gjs_object_require_property(context, repo_obj, "GI repository object", ns_name, &ns_obj)) {
         goto fail;
     }
 
     if (!JSVAL_IS_OBJECT(ns_obj)) {
-        gjs_throw(context, "Namespace '%s' is not an object?", ns);
+        char *name;
+
+        gjs_get_string_id(context, ns_name, &name);
+        gjs_throw(context, "Namespace '%s' is not an object?", name);
+
+        g_free(name);
         goto fail;
     }
 
diff --git a/gi/repo.h b/gi/repo.h
index 0161e94..ff3214c 100644
--- a/gi/repo.h
+++ b/gi/repo.h
@@ -40,7 +40,7 @@ JSObject*   gjs_lookup_private_namespace        (JSContext      *context);
 JSObject*   gjs_lookup_namespace_object         (JSContext      *context,
                                                  GIBaseInfo     *info);
 JSObject*   gjs_lookup_namespace_object_by_name (JSContext      *context,
-                                                 const char     *name);
+                                                 jsid            name);
 JSObject*   gjs_lookup_function_object          (JSContext      *context,
                                                  GIFunctionInfo *info);
 JSBool      gjs_define_info                     (JSContext      *context,
diff --git a/gi/value.c b/gi/value.c
index ece1db3..c69debe 100644
--- a/gi/value.c
+++ b/gi/value.c
@@ -367,7 +367,7 @@ gjs_value_to_g_value_internal(JSContext    *context,
 
             if (!gjs_object_require_property(context,
                                              JSVAL_TO_OBJECT(value), NULL,
-                                             "length",
+                                             length_name,
                                              &length_value) ||
                 !JS_ValueToECMAUint32(context, length_value, &length)) {
                 gjs_throw(context,
diff --git a/gjs/importer.c b/gjs/importer.c
index 0b03d02..b51756f 100644
--- a/gjs/importer.c
+++ b/gjs/importer.c
@@ -506,8 +506,11 @@ do_import(JSContext  *context,
     guint32 i;
     JSBool result;
     GPtrArray *directories;
+    jsid search_path_name;
 
-    if (!gjs_object_require_property(context, obj, "importer", "searchPath", &search_path_val)) {
+    search_path_name = gjs_runtime_get_const_string(JS_GetRuntime(context),
+                                                    GJS_STRING_SEARCH_PATH);
+    if (!gjs_object_require_property(context, obj, "importer", search_path_name, &search_path_val)) {
         return JS_FALSE;
     }
 
@@ -741,6 +744,7 @@ importer_new_enumerate(JSContext  *context,
         jsval search_path_val;
         guint32 search_path_len;
         guint32 i;
+        jsid search_path_name;
 
         if (state_p)
             *state_p = JSVAL_NULL;
@@ -754,7 +758,9 @@ importer_new_enumerate(JSContext  *context,
             /* we are enumerating the prototype properties */
             return JS_TRUE;
 
-        if (!gjs_object_require_property(context, *object, "importer", "searchPath", &search_path_val))
+        search_path_name = gjs_runtime_get_const_string(JS_GetRuntime(context),
+                                                        GJS_STRING_SEARCH_PATH);
+        if (!gjs_object_require_property(context, *object, "importer", search_path_name, &search_path_val))
             return JS_FALSE;
 
         if (!JSVAL_IS_OBJECT(search_path_val)) {
@@ -1215,14 +1221,17 @@ gjs_define_root_importer(JSContext   *context,
     JSObject *global;
     jsval value;
     JSBool success;
+    jsid imports_name;
 
     success = JS_FALSE;
     global = gjs_get_import_global(context);
     JS_BeginRequest(context);
 
+    imports_name = gjs_runtime_get_const_string(JS_GetRuntime(context),
+                                                GJS_STRING_IMPORTS);
     if (!gjs_object_require_property(context,
                                      global, "global object",
-                                     "imports", &value) ||
+                                     imports_name, &value) ||
         !JSVAL_IS_OBJECT(value)) {
         gjs_debug(GJS_DEBUG_IMPORTER, "Root importer did not exist, couldn't get from load context; must 
create it");
         goto fail;
diff --git a/gjs/jsapi-dynamic-class.c b/gjs/jsapi-dynamic-class.c
index 35bf713..b7fe2ca 100644
--- a/gjs/jsapi-dynamic-class.c
+++ b/gjs/jsapi-dynamic-class.c
@@ -210,11 +210,14 @@ gjs_construct_object_dynamic(JSContext      *context,
     JSObject *constructor;
     JSObject *result = NULL;
     jsval value;
+    jsid constructor_name;
 
     JS_BeginRequest(context);
 
+    constructor_name = gjs_runtime_get_const_string(JS_GetRuntime(context),
+                                                    GJS_STRING_CONSTRUCTOR);
     if (!gjs_object_require_property(context, proto, "prototype",
-                                     "constructor", &value))
+                                     constructor_name, &value))
         goto out;
 
     constructor = JSVAL_TO_OBJECT(value);
diff --git a/gjs/jsapi-util-string.c b/gjs/jsapi-util-string.c
index 31d5cbf..87c0664 100644
--- a/gjs/jsapi-util-string.c
+++ b/gjs/jsapi-util-string.c
@@ -242,3 +242,13 @@ gjs_unichar_from_string (JSContext *context,
     }
     return FALSE;
 }
+
+jsid
+gjs_intern_string_to_id (JSContext  *context,
+                         const char *string)
+{
+    JSString *str;
+
+    str = JS_InternString(context, string);
+    return INTERNED_STRING_TO_JSID(context, str);
+}
diff --git a/gjs/jsapi-util.c b/gjs/jsapi-util.c
index da08aa2..8891bb3 100644
--- a/gjs/jsapi-util.c
+++ b/gjs/jsapi-util.c
@@ -105,48 +105,52 @@ gjs_init_context_standard (JSContext       *context)
 
 /* Returns whether the object had the property; if the object did
  * not have the property, always sets an exception. Treats
- * "the property's value is JSVAL_VOID" the same as "no such property,"
- * while JS_GetProperty() treats only "no such property" as an error.
+ * "the property's value is JSVAL_VOID" the same as "no such property,".
  * Guarantees that *value_p is set to something, if only JSVAL_VOID,
  * even if an exception is set and false is returned.
+ *
+ * Requires request.
  */
 gboolean
 gjs_object_require_property(JSContext       *context,
                             JSObject        *obj,
                             const char      *obj_description,
-                            const char      *property_name,
+                            jsid             property_name,
                             jsval           *value_p)
 {
     jsval value;
-
-    JS_BeginRequest(context);
+    char *name;
 
     value = JSVAL_VOID;
-    JS_GetProperty(context, obj, property_name, &value);
-
     if (value_p)
         *value_p = value;
 
-    if (!JSVAL_IS_VOID(value)) {
-        JS_ClearPendingException(context); /* in case JS_GetProperty() was on crack */
-        JS_EndRequest(context);
-        return TRUE;
-    } else {
-        /* remember gjs_throw() is a no-op if JS_GetProperty()
-         * already set an exception
-         */
-        if (obj_description)
-            gjs_throw(context,
-                      "No property '%s' in %s (or its value was undefined)",
-                      property_name, obj_description);
-        else
-            gjs_throw(context,
-                      "No property '%s' in object %p (or its value was undefined)",
-                      property_name, obj);
+    if (G_UNLIKELY (!JS_GetPropertyById(context, obj, property_name, &value)))
+        return JS_FALSE;
 
-        JS_EndRequest(context);
-        return FALSE;
+    if (G_LIKELY (!JSVAL_IS_VOID(value))) {
+        if (value_p)
+            *value_p = value;
+        return JS_TRUE;
     }
+
+    /* remember gjs_throw() is a no-op if JS_GetProperty()
+     * already set an exception
+     */
+
+    gjs_get_string_id(context, property_name, &name);
+
+    if (obj_description)
+        gjs_throw(context,
+                  "No property '%s' in %s (or its value was undefined)",
+                  name, obj_description);
+    else
+        gjs_throw(context,
+                  "No property '%s' in object %p (or its value was undefined)",
+                  name, obj);
+
+    g_free(name);
+    return JS_FALSE;
 }
 
 void
diff --git a/gjs/jsapi-util.h b/gjs/jsapi-util.h
index c154a74..fff9db8 100644
--- a/gjs/jsapi-util.h
+++ b/gjs/jsapi-util.h
@@ -151,7 +151,8 @@ jsval gjs_##cname##_create_proto(JSContext *context, JSObject *module, const cha
 { \
     jsval rval; \
     JSObject *global = gjs_get_import_global(context); \
-    if (!JS_GetProperty(context, global, gjs_##cname##_class.name, &rval)) \
+    jsid class_name = gjs_intern_string_to_id(context, gjs_##cname##_class.name); \
+    if (!JS_GetPropertyById(context, global, class_name, &rval))                       \
         return JSVAL_NULL; \
     if (JSVAL_IS_VOID(rval)) { \
         JSObject *prototype = JS_InitClass(context, global, \
@@ -168,7 +169,7 @@ jsval gjs_##cname##_create_proto(JSContext *context, JSObject *module, const cha
         } \
         if (!gjs_object_require_property( \
                 context, global, NULL, \
-                gjs_##cname##_class.name, &rval)) { \
+                class_name, &rval)) { \
             return JSVAL_NULL; \
         } \
         if (!JS_DefineProperty(context, module, proto_name, \
@@ -184,7 +185,7 @@ JSObject*   gjs_get_import_global            (JSContext       *context);
 gboolean    gjs_object_require_property      (JSContext       *context,
                                               JSObject        *obj,
                                               const char      *obj_description,
-                                              const char      *property_name,
+                                              jsid             property_name,
                                               jsval           *value_p);
 
 JSObject   *gjs_new_object_for_constructor   (JSContext       *context,
@@ -299,7 +300,8 @@ JSBool      gjs_string_get_uint16_data       (JSContext       *context,
 JSBool      gjs_get_string_id                (JSContext       *context,
                                               jsid             id,
                                               char           **name_p);
-
+jsid        gjs_intern_string_to_id          (JSContext       *context,
+                                              const char      *string);
 
 gboolean    gjs_unichar_from_string          (JSContext       *context,
                                               jsval            string,
diff --git a/gjs/runtime.c b/gjs/runtime.c
index ed69b49..e24ee4e 100644
--- a/gjs/runtime.c
+++ b/gjs/runtime.c
@@ -44,9 +44,10 @@ typedef struct {
 static const char *const_strings[] = {
     "constructor", "prototype", "length",
     "imports", "__parentModule__", "__init__", "searchPath",
-    "__gjsKeepAlive",
+    "__gjsKeepAlive", "__gjsPrivateNS",
     "gi", "versions", "overrides",
-    "_init"
+    "_init", "_new_internal", "new",
+    "message", "code", "stack", "fileName", "lineNumber"
 };
 
 G_STATIC_ASSERT(G_N_ELEMENTS(const_strings) == GJS_STRING_LAST);
@@ -91,12 +92,8 @@ gjs_runtime_init_for_context(JSRuntime *runtime,
     data = g_new(GjsRuntimeData, 1);
 
     data->context = context;
-    for (i = 0; i < GJS_STRING_LAST; i++) {
-        JSString *str;
-
-        str = JS_InternString(context, const_strings[i]);
-        data->const_strings[i] = INTERNED_STRING_TO_JSID(context, str);
-    }
+    for (i = 0; i < GJS_STRING_LAST; i++)
+        data->const_strings[i] = gjs_intern_string_to_id(context, const_strings[i]);
 
     JS_SetRuntimePrivate(runtime, data);
 }
diff --git a/gjs/runtime.h b/gjs/runtime.h
index 59ae413..7a6a36e 100644
--- a/gjs/runtime.h
+++ b/gjs/runtime.h
@@ -33,10 +33,18 @@ typedef enum {
   GJS_STRING_MODULE_INIT,
   GJS_STRING_SEARCH_PATH,
   GJS_STRING_KEEP_ALIVE_MARKER,
+  GJS_STRING_PRIVATE_NS_MARKER,
   GJS_STRING_GI_MODULE,
   GJS_STRING_GI_VERSIONS,
   GJS_STRING_GI_OVERRIDES,
   GJS_STRING_GOBJECT_INIT,
+  GJS_STRING_NEW_INTERNAL,
+  GJS_STRING_NEW,
+  GJS_STRING_MESSAGE,
+  GJS_STRING_CODE,
+  GJS_STRING_STACK,
+  GJS_STRING_FILENAME,
+  GJS_STRING_LINE_NUMBER,
   GJS_STRING_LAST
 } GjsConstString;
 


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