[gjs/wip/ptomato/mozjs38: 25/26] WIP - importer: Switch back to lazy enumeration



commit d1232b4b2f53d0e02e36de270b3990d27227b715
Author: Philip Chimento <philip chimento gmail com>
Date:   Wed Jan 11 23:38:42 2017 -0800

    WIP - importer: Switch back to lazy enumeration
    
    Lazy enumeration is still available through the jsfriend API in
    js::Class, which is really JSClass but with some extra fields that are
    masked in the public version.
    
    In addition, JSNewEnumerateOp has changed somewhat, compared with
    SpiderMonkey 31. Instead of the enumerate callback being called
    incrementally for each property, now it is just called once the first
    time an object's properties are enumerated, and you have to fill in the
    passed-in JS::AutoIdVector with any names of lazy properties.
    
    FIXME: This changes the behaviour, since the AutoIdVector already
    contains any enumerable property names that the JS engine already knows
    about, before the enumerate callback is called! So we now get searchPath,
    byteArray, etc. when we enumerate the importer.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=777962

 gjs/importer.cpp |   70 +++++++++++++++++++++++++++++++----------------------
 1 files changed, 41 insertions(+), 29 deletions(-)
---
diff --git a/gjs/importer.cpp b/gjs/importer.cpp
index 4fbbfa3..acefae3 100644
--- a/gjs/importer.cpp
+++ b/gjs/importer.cpp
@@ -53,9 +53,11 @@ typedef struct {
     unsigned int index;
 } ImporterIterator;
 
-extern struct JSClass gjs_importer_class;
+extern js::Class gjs_importer_extended_class;
+// FIXME make JSClass const in macro
+static JSClass *gjs_importer_class = (JSClass *)(&gjs_importer_extended_class);
 
-GJS_DEFINE_PRIV_FROM_JS(Importer, gjs_importer_class)
+GJS_DEFINE_PRIV_FROM_JS(Importer, (*gjs_importer_class))
 
 static bool
 importer_to_string(JSContext *cx,
@@ -96,7 +98,7 @@ define_meta_properties(JSContext       *context,
     /* We define both __moduleName__ and __parentModule__ to null
      * on the root importer
      */
-    parent_is_module = parent && JS_InstanceOf(context, parent, &gjs_importer_class, NULL);
+    parent_is_module = parent && JS_InstanceOf(context, parent, gjs_importer_class, NULL);
 
     gjs_debug(GJS_DEBUG_IMPORTER, "Defining parent %p of %p '%s' is mod %d",
               parent.get(), module_obj.get(),
@@ -674,8 +676,9 @@ do_import(JSContext       *context,
  * then on its prototype.
  */
 static bool
-importer_enumerate(JSContext       *context,
-                   JS::HandleObject object)
+importer_enumerate(JSContext        *context,
+                   JS::HandleObject  object,
+                   JS::AutoIdVector& properties)
 {
     Importer *priv;
     guint32 search_path_len;
@@ -729,16 +732,7 @@ importer_enumerate(JSContext       *context,
 
         init_path = g_build_filename(dirname, MODULE_INIT_FILENAME, NULL);
 
-        JS::AutoIdVector module_props(context);
-        JS::RootedValue v_prop_name(context);
-        load_module_elements(context, object, module_props, init_path);
-        for (const jsid *id = module_props.begin(); id != module_props.end(); id++) {
-            v_prop_name.setString(JSID_TO_STRING(*id));
-            g_autofree char *prop_name = NULL;
-            if (!gjs_string_to_filename(context, v_prop_name, &prop_name) ||
-                !do_import(context, object, priv, prop_name))
-                return false;
-        }
+        load_module_elements(context, object, properties, init_path);
 
         g_free(init_path);
 
@@ -768,14 +762,12 @@ importer_enumerate(JSContext       *context,
                 continue;
 
             if (g_file_info_get_file_type(info) == G_FILE_TYPE_DIRECTORY) {
-                if (!do_import(context, object, priv, filename))
-                    return false;
+                properties.append(gjs_intern_string_to_id(context, filename));
             } else if (g_str_has_suffix(filename, "." G_MODULE_SUFFIX) ||
                        g_str_has_suffix(filename, ".js")) {
                 g_autofree char *filename_noext =
                     g_strndup(filename, strlen(filename) - 3);
-                if (!do_import(context, object, priv, filename_noext))
-                    return false;
+                properties.append(gjs_intern_string_to_id(context, filename_noext));
             }
         }
     }
@@ -835,8 +827,8 @@ importer_resolve(JSContext        *context,
 GJS_NATIVE_CONSTRUCTOR_DEFINE_ABSTRACT(importer)
 
 static void
-importer_finalize(JSFreeOp *fop,
-                  JSObject *obj)
+importer_finalize(js::FreeOp *fop,
+                  JSObject   *obj)
 {
     Importer *priv;
 
@@ -854,7 +846,7 @@ importer_finalize(JSFreeOp *fop,
  * instances of the object, and to the prototype that instances of the
  * class have.
  */
-struct JSClass gjs_importer_class = {
+js::Class gjs_importer_extended_class = {
     "GjsFileImporter",
     JSCLASS_HAS_PRIVATE |
     JSCLASS_IMPLEMENTS_BARRIERS,
@@ -862,10 +854,30 @@ struct JSClass gjs_importer_class = {
     NULL,  /* deleteProperty */
     NULL,  /* getProperty */
     NULL,  /* setProperty */
-    importer_enumerate,
+    NULL,  /* enumerate (see below) */
     importer_resolve,
     NULL,  /* convert */
-    importer_finalize
+    importer_finalize,
+    NULL,  /* call */
+    NULL,  /* hasInstance */
+    NULL,  /* construct */
+    NULL,  /* trace */
+    JS_NULL_CLASS_SPEC,
+    JS_NULL_CLASS_EXT,
+    {
+        NULL,  /* lookupProperty */
+        NULL,  /* defineProperty */
+        NULL,  /* hasProperty */
+        NULL,  /* getProperty */
+        NULL,  /* setProperty */
+        NULL,  /* getOwnPropertyDescriptor */
+        NULL,  /* deleteProperty */
+        NULL,  /* watch */
+        NULL,  /* unwatch */
+        NULL,  /* getElements */
+        importer_enumerate,
+        NULL,  /* thisObject */
+    }
 };
 
 JSPropertySpec gjs_importer_proto_props[] = {
@@ -886,7 +898,7 @@ importer_new(JSContext *context,
 
     JS::RootedObject global(context, gjs_get_import_global(context));
 
-    if (!JS_HasProperty(context, global, gjs_importer_class.name, &found))
+    if (!JS_HasProperty(context, global, gjs_importer_class->name, &found))
         g_error("HasProperty call failed creating importer class");
 
     if (!found) {
@@ -897,7 +909,7 @@ importer_new(JSContext *context,
                                   * Object.prototype
                                   */
                                  JS::NullPtr(),
-                                 &gjs_importer_class,
+                                 gjs_importer_class,
                                  /* constructor for instances (NULL for
                                   * none - just name the prototype like
                                   * Math - rarely correct)
@@ -914,14 +926,14 @@ importer_new(JSContext *context,
                                  /* funcs of constructor, MyConstructor.myfunc() */
                                  NULL);
         if (prototype == NULL)
-            g_error("Can't init class %s", gjs_importer_class.name);
+            g_error("Can't init class %s", gjs_importer_class->name);
 
         gjs_debug(GJS_DEBUG_IMPORTER, "Initialized class %s prototype %p",
-                  gjs_importer_class.name, prototype);
+                  gjs_importer_class->name, prototype);
     }
 
     JS::RootedObject importer(context,
-        JS_NewObject(context, &gjs_importer_class, global));
+        JS_NewObject(context, gjs_importer_class, global));
     if (importer == NULL)
         g_error("No memory to create importer importer");
 


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