[gjs/wip/ptomato/mozjs38: 8/14] js: Adapt to new signature of resolve operation



commit a3a794f8534e2d9f37504244c2da55556c47e093
Author: Philip Chimento <philip chimento gmail com>
Date:   Wed Jan 11 23:27:46 2017 -0800

    js: Adapt to new signature of resolve operation
    
    JSNewResolveOp and JSResolveOp are merged in SpiderMonkey 38. There is
    only one signature, so no need to distinguish the two with the
    JSCLASS_NEW_RESOLVE flag.
    
    Converting from the old JSNewResolveOp callback to the new JSResolveOp
    callback is a matter of making sure that *resolved is set whenever the
    callback returns true. (The equivalent of *resolved = true before this
    change was objp.set(obj) on the passed-in MutableHandleObject.)

 gi/boxed.cpp       |   35 +++++++-------
 gi/fundamental.cpp |  126 +++++++++++++++++++++++++--------------------------
 gi/interface.cpp   |   38 ++++++++--------
 gi/ns.cpp          |   52 +++++++++------------
 gi/object.cpp      |   99 +++++++++++++++++++----------------------
 gi/param.cpp       |   26 +++++------
 gi/repo.cpp        |   43 ++++++++---------
 gi/union.cpp       |  106 ++++++++++++++++++++++----------------------
 gjs/importer.cpp   |   45 +++++++++---------
 9 files changed, 275 insertions(+), 295 deletions(-)
---
diff --git a/gi/boxed.cpp b/gi/boxed.cpp
index 359abc9..a27b128 100644
--- a/gi/boxed.cpp
+++ b/gi/boxed.cpp
@@ -115,24 +115,25 @@ gjs_define_static_methods(JSContext       *context,
  * if id was resolved.
  */
 static bool
-boxed_new_resolve(JSContext *context,
-                  JS::HandleObject obj,
-                  JS::HandleId id,
-                  JS::MutableHandleObject objp)
+boxed_resolve(JSContext       *context,
+              JS::HandleObject obj,
+              JS::HandleId     id,
+              bool            *resolved)
 {
     Boxed *priv;
-    char *name;
-    bool ret = false;
+    g_autofree char *name = NULL;
 
-    if (!gjs_get_string_id(context, id, &name))
-        return true; /* not resolved, but no error */
+    if (!gjs_get_string_id(context, id, &name)) {
+        *resolved = false;
+        return true;
+    }
 
     priv = priv_from_js(context, obj);
     gjs_debug_jsprop(GJS_DEBUG_GBOXED, "Resolve prop '%s' hook obj %p priv %p",
                      name, obj.get(), priv);
 
     if (priv == NULL)
-        goto out; /* wrong class */
+        return false; /* wrong class */
 
     if (priv->gboxed == NULL) {
         /* We are the prototype, so look for methods and other class properties */
@@ -160,10 +161,12 @@ boxed_new_resolve(JSContext *context,
                 if (gjs_define_function(context, obj, priv->gtype,
                                         (GICallableInfo *)method_info) == NULL) {
                     g_base_info_unref( (GIBaseInfo*) method_info);
-                    goto out;
+                    return false;
                 }
 
-                objp.set(obj); /* we defined the prop in object_proto */
+                *resolved = true;
+            } else {
+                *resolved = false;
             }
 
             g_base_info_unref( (GIBaseInfo*) method_info);
@@ -176,12 +179,9 @@ boxed_new_resolve(JSContext *context,
          * see any changes made from C. So we use the get/set prop
          * hooks, not this resolve hook.
          */
+        *resolved = false;
     }
-    ret = true;
-
- out:
-    g_free(name);
-    return ret;
+    return true;
 }
 
 /* Check to see if JS::Value passed in is another Boxed object of the same,
@@ -917,7 +917,6 @@ boxed_trace(JSTracer *tracer,
 struct JSClass gjs_boxed_class = {
     "GObject_Boxed",
     JSCLASS_HAS_PRIVATE |
-    JSCLASS_NEW_RESOLVE |
     JSCLASS_HAS_RESERVED_SLOTS(1) |
     JSCLASS_IMPLEMENTS_BARRIERS,
     NULL,  /* addProperty */
@@ -925,7 +924,7 @@ struct JSClass gjs_boxed_class = {
     NULL,  /* getProperty */
     NULL,  /* setProperty */
     NULL,  /* enumerate */
-    (JSResolveOp) boxed_new_resolve, /* needs cast since it's the new resolve signature */
+    boxed_resolve,
     NULL,  /* convert */
     boxed_finalize,
     NULL,  /* call */
diff --git a/gi/fundamental.cpp b/gi/fundamental.cpp
index db77d3b..944e49c 100644
--- a/gi/fundamental.cpp
+++ b/gi/fundamental.cpp
@@ -224,11 +224,11 @@ find_fundamental_constructor(JSContext    *context,
 /**/
 
 static bool
-fundamental_instance_new_resolve_interface(JSContext    *context,
-                                           JS::HandleObject obj,
-                                           JS::MutableHandleObject objp,
-                                           Fundamental  *proto_priv,
-                                           char         *name)
+fundamental_instance_resolve_interface(JSContext       *context,
+                                       JS::HandleObject obj,
+                                       bool            *resolved,
+                                       Fundamental     *proto_priv,
+                                       char            *name)
 {
     GIFunctionInfo *method_info;
     bool ret;
@@ -263,7 +263,7 @@ fundamental_instance_new_resolve_interface(JSContext    *context,
                 if (gjs_define_function(context, obj,
                                         proto_priv->gtype,
                                         (GICallableInfo *) method_info)) {
-                    objp.set(obj);
+                    *resolved = true;
                 } else {
                     ret = false;
                 }
@@ -278,22 +278,22 @@ fundamental_instance_new_resolve_interface(JSContext    *context,
 }
 
 /*
- * The *objp out parameter, on success, should be null to indicate that id
- * was not resolved; and non-null, referring to obj or one of its prototypes,
- * if id was resolved.
+ * The *resolved out parameter, on success, should be false to indicate that id
+ * was not resolved; and true if id was resolved.
  */
 static bool
-fundamental_instance_new_resolve(JSContext  *context,
-                                 JS::HandleObject obj,
-                                 JS::HandleId id,
-                                 JS::MutableHandleObject objp)
+fundamental_instance_resolve(JSContext       *context,
+                             JS::HandleObject obj,
+                             JS::HandleId     id,
+                             bool            *resolved)
 {
     FundamentalInstance *priv;
-    char *name;
-    bool ret = false;
+    g_autofree char *name = NULL;
 
-    if (!gjs_get_string_id(context, id, &name))
+    if (!gjs_get_string_id(context, id, &name)) {
+        *resolved = false;
         return true; /* not resolved, but no error */
+    }
 
     priv = priv_from_js(context, obj);
     gjs_debug_jsprop(GJS_DEBUG_GFUNDAMENTAL,
@@ -301,71 +301,70 @@ fundamental_instance_new_resolve(JSContext  *context,
                      name, obj.get(), priv);
 
     if (priv == NULL)
-        goto out; /* wrong class */
+        return false; /* wrong class */
 
-    if (priv->prototype == NULL) {
-        /* We are the prototype, so look for methods and other class properties */
-        Fundamental *proto_priv = (Fundamental *) priv;
-        GIFunctionInfo *method_info;
+    if (priv->prototype != NULL) {
+        /* We are an instance, not a prototype, so look for
+         * per-instance props that we want to define on the
+         * JSObject. Generally we do not want to cache these in JS, we
+         * want to always pull them from the C object, or JS would not
+         * see any changes made from C. So we use the get/set prop
+         * hooks, not this resolve hook.
+         */
+        *resolved = false;
+        return true;
+    }
 
-        method_info = g_object_info_find_method((GIStructInfo*) proto_priv->info,
-                                                name);
+    /* We are the prototype, so look for methods and other class properties */
+    Fundamental *proto_priv = (Fundamental *) priv;
+    GIFunctionInfo *method_info;
 
-        if (method_info != NULL) {
-            const char *method_name;
+    method_info = g_object_info_find_method((GIStructInfo*) proto_priv->info,
+                                            name);
+
+    if (method_info != NULL) {
+        const char *method_name;
 
 #if GJS_VERBOSE_ENABLE_GI_USAGE
-            _gjs_log_info_usage((GIBaseInfo *) method_info);
+        _gjs_log_info_usage((GIBaseInfo *) method_info);
 #endif
-            if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) {
-                method_name = g_base_info_get_name((GIBaseInfo *) method_info);
-
-                /* we do not define deprecated methods in the prototype */
-                if (g_base_info_is_deprecated((GIBaseInfo *) method_info)) {
-                    gjs_debug(GJS_DEBUG_GFUNDAMENTAL,
-                              "Ignoring definition of deprecated method %s in prototype %s.%s",
-                              method_name,
-                              g_base_info_get_namespace((GIBaseInfo *) proto_priv->info),
-                              g_base_info_get_name((GIBaseInfo *) proto_priv->info));
-                    g_base_info_unref((GIBaseInfo *) method_info);
-                    ret = true;
-                    goto out;
-                }
+        if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) {
+            method_name = g_base_info_get_name((GIBaseInfo *) method_info);
 
+            /* we do not define deprecated methods in the prototype */
+            if (g_base_info_is_deprecated((GIBaseInfo *) method_info)) {
                 gjs_debug(GJS_DEBUG_GFUNDAMENTAL,
-                          "Defining method %s in prototype for %s.%s",
+                          "Ignoring definition of deprecated method %s in prototype %s.%s",
                           method_name,
                           g_base_info_get_namespace((GIBaseInfo *) proto_priv->info),
                           g_base_info_get_name((GIBaseInfo *) proto_priv->info));
+                g_base_info_unref((GIBaseInfo *) method_info);
+                *resolved = false;
+                return true;
+            }
 
-                if (gjs_define_function(context, obj, proto_priv->gtype,
-                                        method_info) == NULL) {
-                    g_base_info_unref((GIBaseInfo *) method_info);
-                    goto out;
-                }
+            gjs_debug(GJS_DEBUG_GFUNDAMENTAL,
+                      "Defining method %s in prototype for %s.%s",
+                      method_name,
+                      g_base_info_get_namespace((GIBaseInfo *) proto_priv->info),
+                      g_base_info_get_name((GIBaseInfo *) proto_priv->info));
 
-                objp.set(obj);
+            if (gjs_define_function(context, obj, proto_priv->gtype,
+                                    method_info) == NULL) {
+                g_base_info_unref((GIBaseInfo *) method_info);
+                return false;
             }
 
-            g_base_info_unref((GIBaseInfo *) method_info);
+            *resolved = true;
         }
 
-        ret = fundamental_instance_new_resolve_interface(context, obj, objp,
-                                                         proto_priv, name);
+        g_base_info_unref((GIBaseInfo *) method_info);
     } else {
-        /* We are an instance, not a prototype, so look for
-         * per-instance props that we want to define on the
-         * JSObject. Generally we do not want to cache these in JS, we
-         * want to always pull them from the C object, or JS would not
-         * see any changes made from C. So we use the get/set prop
-         * hooks, not this resolve hook.
-         */
+        *resolved = false;
     }
 
-    ret = true;
- out:
-    g_free(name);
-    return ret;
+    return fundamental_instance_resolve_interface(context, obj, resolved,
+                                                  proto_priv, name);
 }
 
 static bool
@@ -539,14 +538,13 @@ fundamental_trace(JSTracer *tracer,
 struct JSClass gjs_fundamental_instance_class = {
     "GFundamental_Object",
     JSCLASS_HAS_PRIVATE |
-    JSCLASS_IMPLEMENTS_BARRIERS |
-    JSCLASS_NEW_RESOLVE,
+    JSCLASS_IMPLEMENTS_BARRIERS,
     NULL,  /* addProperty */
     NULL,  /* deleteProperty */
     NULL,  /* getProperty */
     NULL,  /* setProperty */
     NULL,  /* enumerate */
-    (JSResolveOp) fundamental_instance_new_resolve, /* needs cast since it's the new resolve signature */
+    fundamental_instance_resolve,
     NULL,  /* convert */
     fundamental_finalize,
     NULL,  /* call */
diff --git a/gi/interface.cpp b/gi/interface.cpp
index e72b474..19ddaaf 100644
--- a/gi/interface.cpp
+++ b/gi/interface.cpp
@@ -105,30 +105,31 @@ gjs_define_static_methods(JSContext       *context,
 }
 
 static bool
-interface_new_resolve(JSContext *context,
-                      JS::HandleObject obj,
-                      JS::HandleId id,
-                      JS::MutableHandleObject objp)
+interface_resolve(JSContext       *context,
+                  JS::HandleObject obj,
+                  JS::HandleId     id,
+                  bool            *resolved)
 {
     Interface *priv;
-    char *name;
-    bool ret = false;
+    g_autofree char *name = NULL;
     GIFunctionInfo *method_info;
 
-    if (!gjs_get_string_id(context, id, &name))
+    if (!gjs_get_string_id(context, id, &name)) {
+        *resolved = false;
         return true;
+    }
 
     priv = priv_from_js(context, obj);
 
     if (priv == NULL)
-        goto out;
+        return false;
 
     /* If we have no GIRepository information then this interface was defined
      * from within GJS. In that case, it has no properties that need to be
      * resolved from within C code, as interfaces cannot inherit. */
     if (priv->info == NULL) {
-        ret = true;
-        goto out;
+        *resolved = false;
+        return true;
     }
 
     method_info = g_interface_info_find_method((GIInterfaceInfo*) priv->info, name);
@@ -139,26 +140,25 @@ interface_new_resolve(JSContext *context,
                                     priv->gtype,
                                     (GICallableInfo*)method_info) == NULL) {
                 g_base_info_unref((GIBaseInfo*)method_info);
-                goto out;
+                return false;
             }
 
-            objp.set(obj);
+            *resolved = true;
+        } else {
+            *resolved = false;
         }
 
         g_base_info_unref((GIBaseInfo*)method_info);
+    } else {
+        *resolved = false;
     }
 
-    ret = true;
-
- out:
-    g_free (name);
-    return ret;
+    return true;
 }
 
 struct JSClass gjs_interface_class = {
     "GObject_Interface",
     JSCLASS_HAS_PRIVATE |
-    JSCLASS_NEW_RESOLVE |
     JSCLASS_BACKGROUND_FINALIZE |
     JSCLASS_IMPLEMENTS_BARRIERS,
     NULL,  /* addProperty */
@@ -166,7 +166,7 @@ struct JSClass gjs_interface_class = {
     NULL,  /* getProperty */
     NULL,  /* setProperty */
     NULL,  /* enumerate */
-    (JSResolveOp) interface_new_resolve,
+    interface_resolve,
     NULL,  /* convert */
     interface_finalize
 };
diff --git a/gi/ns.cpp b/gi/ns.cpp
index f22f631..d89ab50 100644
--- a/gi/ns.cpp
+++ b/gi/ns.cpp
@@ -48,26 +48,27 @@ GJS_DEFINE_PRIV_FROM_JS(Ns, gjs_ns_class)
  * if id was resolved.
  */
 static bool
-ns_new_resolve(JSContext *context,
-               JS::HandleObject obj,
-               JS::HandleId id,
-               JS::MutableHandleObject objp)
+ns_resolve(JSContext       *context,
+           JS::HandleObject obj,
+           JS::HandleId     id,
+           bool            *resolved)
 {
     Ns *priv;
-    char *name;
+    g_autofree char *name = NULL;
     GIRepository *repo;
     GIBaseInfo *info;
-    bool ret = false;
     bool defined;
 
-    if (!gjs_get_string_id(context, id, &name))
+    if (!gjs_get_string_id(context, id, &name)) {
+        *resolved = false;
         return true; /* not resolved, but no error */
+    }
 
     /* let Object.prototype resolve these */
     if (strcmp(name, "valueOf") == 0 ||
         strcmp(name, "toString") == 0) {
-        ret = true;
-        goto out;
+        *resolved = false;
+        return true;
     }
 
     priv = priv_from_js(context, obj);
@@ -76,20 +77,16 @@ ns_new_resolve(JSContext *context,
                      name, obj.get(), priv);
 
     if (priv == NULL) {
-        ret = true; /* we are the prototype, or have the wrong class */
-        goto out;
+        *resolved = false;  /* we are the prototype, or have the wrong class */
+        return true;
     }
 
-    JS_BeginRequest(context);
-
     repo = g_irepository_get_default();
 
     info = g_irepository_find_by_name(repo, priv->gi_namespace, name);
     if (info == NULL) {
-        /* No property defined, but no error either, so return true */
-        JS_EndRequest(context);
-        ret = true;
-        goto out;
+        *resolved = false; /* No property defined, but no error either */
+        return true;
     }
 
     gjs_debug(GJS_DEBUG_GNAMESPACE,
@@ -98,23 +95,21 @@ ns_new_resolve(JSContext *context,
               g_base_info_get_name(info),
               g_base_info_get_namespace(info));
 
-    if (gjs_define_info(context, obj, info, &defined)) {
-        g_base_info_unref(info);
-        if (defined)
-            objp.set(obj); /* we defined the property in this object */
-        ret = true;
-    } else {
+    JSAutoRequest ar(context);
+
+    if (!gjs_define_info(context, obj, info, &defined)) {
         gjs_debug(GJS_DEBUG_GNAMESPACE,
                   "Failed to define info '%s'",
                   g_base_info_get_name(info));
 
         g_base_info_unref(info);
+        return false;
     }
-    JS_EndRequest(context);
 
- out:
-    g_free(name);
-    return ret;
+    /* we defined the property in this object */
+    g_base_info_unref(info);
+    *resolved = true;
+    return true;
 }
 
 static bool
@@ -158,14 +153,13 @@ ns_finalize(JSFreeOp *fop,
 struct JSClass gjs_ns_class = {
     "GIRepositoryNamespace",
     JSCLASS_HAS_PRIVATE |
-    JSCLASS_NEW_RESOLVE |
     JSCLASS_IMPLEMENTS_BARRIERS,
     NULL,  /* addProperty */
     NULL,  /* deleteProperty */
     NULL,  /* getProperty */
     NULL,  /* setProperty */
     NULL,  /* enumerate */
-    (JSResolveOp) ns_new_resolve, /* needs cast since it's the new resolve signature */
+    ns_resolve,
     NULL,  /* convert */
     ns_finalize
 };
diff --git a/gi/object.cpp b/gi/object.cpp
index 700513a..7a7be6c 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -601,20 +601,20 @@ find_vfunc_on_parents(GIObjectInfo *info,
 }
 
 static bool
-object_instance_new_resolve_no_info(JSContext       *context,
-                                    JS::HandleObject obj,
-                                    JS::MutableHandleObject objp,
-                                    ObjectInstance  *priv,
-                                    char            *name)
+object_instance_resolve_no_info(JSContext       *context,
+                                JS::HandleObject obj,
+                                bool            *resolved,
+                                ObjectInstance  *priv,
+                                char            *name)
 {
     GIFunctionInfo *method_info;
     bool ret;
-    GType *interfaces;
     guint n_interfaces;
     guint i;
 
     ret = true;
-    interfaces = g_type_interfaces(priv->gtype, &n_interfaces);
+    *resolved = false;  /* technically we shouldn't touch this if returning false? */
+    g_autofree GType *interfaces = g_type_interfaces(priv->gtype, &n_interfaces);
     for (i = 0; i < n_interfaces; i++) {
         GIBaseInfo *base_info;
         GIInterfaceInfo *iface_info;
@@ -639,7 +639,8 @@ object_instance_new_resolve_no_info(JSContext       *context,
             if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) {
                 if (gjs_define_function(context, obj, priv->gtype,
                                         (GICallableInfo *)method_info)) {
-                    objp.set(obj);
+                    *resolved = true;
+                    ret = true;
                 } else {
                     ret = false;
                 }
@@ -649,7 +650,6 @@ object_instance_new_resolve_no_info(JSContext       *context,
         }
     }
 
-    g_free(interfaces);
     return ret;
 }
 
@@ -659,18 +659,19 @@ object_instance_new_resolve_no_info(JSContext       *context,
  * if id was resolved.
  */
 static bool
-object_instance_new_resolve(JSContext *context,
-                            JS::HandleObject obj,
-                            JS::HandleId id,
-                            JS::MutableHandleObject objp)
+object_instance_resolve(JSContext       *context,
+                        JS::HandleObject obj,
+                        JS::HandleId     id,
+                        bool            *resolved)
 {
     GIFunctionInfo *method_info;
     ObjectInstance *priv;
-    char *name;
-    bool ret = false;
+    g_autofree char *name = NULL;
 
-    if (!gjs_get_string_id(context, id, &name))
+    if (!gjs_get_string_id(context, id, &name)) {
+        *resolved = false;
         return true; /* not resolved, but no error */
+    }
 
     priv = priv_from_js(context, obj);
 
@@ -693,21 +694,20 @@ object_instance_new_resolve(JSContext *context,
          * will run afterwards will fail because of the "priv == NULL"
          * check there.
          */
-        ret = true;
-        goto out;
+        *resolved = false;
+        return true;
     }
 
     if (priv->gobj != NULL) {
-        ret = true;
-        goto out;
+        *resolved = false;
+        return true;
     }
 
     /* If we have no GIRepository information (we're a JS GObject subclass),
      * we need to look at exposing interfaces. Look up our interfaces through
      * GType data, and then hope that *those* are introspectable. */
     if (priv->info == NULL) {
-        ret = object_instance_new_resolve_no_info(context, obj, objp, priv, name);
-        goto out;
+        return object_instance_resolve_no_info(context, obj, resolved, priv, name);
     }
 
     if (g_str_has_prefix (name, "vfunc_")) {
@@ -735,15 +735,14 @@ object_instance_new_resolve(JSContext *context,
              * prototypal inheritance take over. */
             if (defined_by_parent && is_vfunc_unchanged(vfunc, priv->gtype)) {
                 g_base_info_unref((GIBaseInfo *)vfunc);
-                ret = true;
-                goto out;
+                *resolved = false;
+                return true;
             }
 
             gjs_define_function(context, obj, priv->gtype, vfunc);
-            objp.set(obj);
+            *resolved = true;
             g_base_info_unref((GIBaseInfo *)vfunc);
-            ret = true;
-            goto out;
+            return true;
         }
 
         /* If the vfunc wasn't found, fall through, back to normal
@@ -770,38 +769,33 @@ object_instance_new_resolve(JSContext *context,
      * this could be done better.  See
      * https://bugzilla.gnome.org/show_bug.cgi?id=632922
      */
-    if (method_info == NULL) {
-        ret = object_instance_new_resolve_no_info(context, obj, objp,
-                                                  priv, name);
-        goto out;
-    } else {
+    if (method_info == NULL)
+        return object_instance_resolve_no_info(context, obj, resolved, priv, name);
+
 #if GJS_VERBOSE_ENABLE_GI_USAGE
-        _gjs_log_info_usage((GIBaseInfo*) method_info);
+    _gjs_log_info_usage((GIBaseInfo*) method_info);
 #endif
 
-        if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) {
-            gjs_debug(GJS_DEBUG_GOBJECT,
-                      "Defining method %s in prototype for %s (%s.%s)",
-                      g_base_info_get_name( (GIBaseInfo*) method_info),
-                      g_type_name(priv->gtype),
-                      g_base_info_get_namespace( (GIBaseInfo*) priv->info),
-                      g_base_info_get_name( (GIBaseInfo*) priv->info));
-
-            if (gjs_define_function(context, obj, priv->gtype, method_info) == NULL) {
-                g_base_info_unref( (GIBaseInfo*) method_info);
-                goto out;
-            }
+    if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) {
+        gjs_debug(GJS_DEBUG_GOBJECT,
+                  "Defining method %s in prototype for %s (%s.%s)",
+                  g_base_info_get_name( (GIBaseInfo*) method_info),
+                  g_type_name(priv->gtype),
+                  g_base_info_get_namespace( (GIBaseInfo*) priv->info),
+                  g_base_info_get_name( (GIBaseInfo*) priv->info));
 
-            objp.set(obj); /* we defined the prop in obj */
+        if (gjs_define_function(context, obj, priv->gtype, method_info) == NULL) {
+            g_base_info_unref( (GIBaseInfo*) method_info);
+            return false;
         }
 
-        g_base_info_unref( (GIBaseInfo*) method_info);
+        *resolved = true; /* we defined the prop in obj */
+    } else {
+        *resolved = false;
     }
 
-    ret = true;
- out:
-    g_free(name);
-    return ret;
+    g_base_info_unref( (GIBaseInfo*) method_info);
+    return true;
 }
 
 static void
@@ -1904,14 +1898,13 @@ to_string_func(JSContext *context,
 struct JSClass gjs_object_instance_class = {
     "GObject_Object",
     JSCLASS_HAS_PRIVATE |
-    JSCLASS_NEW_RESOLVE |
     JSCLASS_IMPLEMENTS_BARRIERS,
     NULL,  /* addProperty */
     NULL,  /* deleteProperty */
     object_instance_get_prop,
     object_instance_set_prop,
     NULL,  /* enumerate */
-    (JSResolveOp) object_instance_new_resolve, /* needs cast since it's the new resolve signature */
+    object_instance_resolve,
     NULL,  /* convert */
     object_instance_finalize,
     NULL,
diff --git a/gi/param.cpp b/gi/param.cpp
index 28a7f80..9d16d98 100644
--- a/gi/param.cpp
+++ b/gi/param.cpp
@@ -45,20 +45,19 @@ extern struct JSClass gjs_param_class;
 GJS_DEFINE_PRIV_FROM_JS(Param, gjs_param_class)
 
 /*
- * The *objp out parameter, on success, should be null to indicate that id
- * was not resolved; and non-null, referring to obj or one of its prototypes,
- * if id was resolved.
+ * The *resolved out parameter, on success, should be false to indicate that id
+ * was not resolved; and true if id was resolved.
  */
 static bool
-param_new_resolve(JSContext *context,
-                  JS::HandleObject obj,
-                  JS::HandleId id,
-                  JS::MutableHandleObject objp)
+param_resolve(JSContext       *context,
+              JS::HandleObject obj,
+              JS::HandleId     id,
+              bool            *resolved)
 {
     GIObjectInfo *info = NULL;
     GIFunctionInfo *method_info;
     Param *priv;
-    char *name;
+    g_autofree char *name = NULL;
     bool ret = false;
 
     if (!gjs_get_string_id(context, id, &name))
@@ -68,14 +67,15 @@ param_new_resolve(JSContext *context,
 
     if (priv != NULL) {
         /* instance, not prototype */
-        ret = true;
-        goto out;
+        *resolved = false;
+        return true;
     }
 
     info = (GIObjectInfo*)g_irepository_find_by_gtype(g_irepository_get_default(), G_TYPE_PARAM);
     method_info = g_object_info_find_method(info, name);
 
     if (method_info == NULL) {
+        *resolved = false;
         ret = true;
         goto out;
     }
@@ -93,14 +93,13 @@ param_new_resolve(JSContext *context,
             goto out;
         }
 
-        objp.set(obj); /* we defined the prop in obj */
+        *resolved = true; /* we defined the prop in obj */
     }
 
     g_base_info_unref( (GIBaseInfo*) method_info);
 
     ret = true;
  out:
-    g_free(name);
     if (info != NULL)
         g_base_info_unref( (GIBaseInfo*)info);
 
@@ -145,7 +144,6 @@ param_finalize(JSFreeOp *fop,
 struct JSClass gjs_param_class = {
     "GObject_ParamSpec",
     JSCLASS_HAS_PRIVATE |
-    JSCLASS_NEW_RESOLVE |
     JSCLASS_BACKGROUND_FINALIZE |
     JSCLASS_IMPLEMENTS_BARRIERS,
     NULL,  /* addProperty */
@@ -153,7 +151,7 @@ struct JSClass gjs_param_class = {
     NULL,  /* getProperty */
     NULL,  /* setProperty */
     NULL,  /* enumerate */
-    (JSResolveOp) param_new_resolve,
+    param_resolve,
     NULL,  /* convert */
     param_finalize
 };
diff --git a/gi/repo.cpp b/gi/repo.cpp
index cb19a00..f048dae 100644
--- a/gi/repo.cpp
+++ b/gi/repo.cpp
@@ -145,44 +145,42 @@ resolve_namespace_object(JSContext       *context,
 }
 
 /*
- * The *objp out parameter, on success, should be null to indicate that id
- * was not resolved; and non-null, referring to obj or one of its prototypes,
- * if id was resolved.
+ * The *resolved out parameter, on success, should be false to indicate that id
+ * was not resolved; and true if id was resolved.
  */
 static bool
-repo_new_resolve(JSContext *context,
-                 JS::HandleObject obj,
-                 JS::HandleId id,
-                 JS::MutableHandleObject objp)
+repo_resolve(JSContext       *context,
+             JS::HandleObject obj,
+             JS::HandleId     id,
+             bool            *resolved)
 {
     Repo *priv;
-    char *name;
-    bool ret = true;
+    g_autofree char *name = NULL;
 
-    if (!gjs_get_string_id(context, id, &name))
+    if (!gjs_get_string_id(context, id, &name)) {
+        *resolved = false;
         return true; /* not resolved, but no error */
+    }
 
     /* let Object.prototype resolve these */
     if (strcmp(name, "valueOf") == 0 ||
-        strcmp(name, "toString") == 0)
-        goto out;
+        strcmp(name, "toString") == 0) {
+        *resolved = false;
+        return true;
+    }
 
     priv = priv_from_js(context, obj);
     gjs_debug_jsprop(GJS_DEBUG_GREPO, "Resolve prop '%s' hook obj %p priv %p",
                      name, obj.get(), priv);
 
     if (priv == NULL) /* we are the prototype, or have the wrong class */
-        goto out;
+        return false;
 
-    if (!resolve_namespace_object(context, obj, id, name)) {
-        ret = false;
-    } else {
-        objp.set(obj); /* store the object we defined the prop in */
-    }
+    if (!resolve_namespace_object(context, obj, id, name))
+        return false;
 
- out:
-    g_free(name);
-    return ret;
+    *resolved = true;
+    return true;
 }
 
 GJS_NATIVE_CONSTRUCTOR_DEFINE_ABSTRACT(repo)
@@ -210,14 +208,13 @@ repo_finalize(JSFreeOp *fop,
 struct JSClass gjs_repo_class = {
     "GIRepository", /* means "new GIRepository()" works */
     JSCLASS_HAS_PRIVATE |
-    JSCLASS_NEW_RESOLVE |
     JSCLASS_IMPLEMENTS_BARRIERS,
     NULL,  /* addProperty */
     NULL,  /* deleteProperty */
     NULL,  /* getProperty */
     NULL,  /* setProperty */
     NULL,  /* enumerate */
-    (JSResolveOp) repo_new_resolve, /* needs cast since it's the new resolve signature */
+    repo_resolve,
     NULL,  /* convert */
     repo_finalize
 };
diff --git a/gi/union.cpp b/gi/union.cpp
index 265d8c4..f5aefae 100644
--- a/gi/union.cpp
+++ b/gi/union.cpp
@@ -50,81 +50,82 @@ extern struct JSClass gjs_union_class;
 GJS_DEFINE_PRIV_FROM_JS(Union, gjs_union_class)
 
 /*
- * The *objp out parameter, on success, should be null to indicate that id
- * was not resolved; and non-null, referring to obj or one of its prototypes,
- * if id was resolved.
+ * The *resolved out parameter, on success, should be false to indicate that id
+ * was not resolved; and true if id was resolved.
  */
 static bool
-union_new_resolve(JSContext *context,
-                  JS::HandleObject obj,
-                  JS::HandleId id,
-                  JS::MutableHandleObject objp)
+union_resolve(JSContext       *context,
+              JS::HandleObject obj,
+              JS::HandleId     id,
+              bool            *resolved)
 {
     Union *priv;
-    char *name;
-    bool ret = true;
+    g_autofree char *name = NULL;
 
-    if (!gjs_get_string_id(context, id, &name))
+    if (!gjs_get_string_id(context, id, &name)) {
+        *resolved = false;
         return true; /* not resolved, but no error */
+    }
 
     priv = priv_from_js(context, obj);
     gjs_debug_jsprop(GJS_DEBUG_GBOXED, "Resolve prop '%s' hook obj %p priv %p",
                      name, obj.get(), priv);
 
-    if (priv == NULL) {
-        ret = false; /* wrong class */
-        goto out;
+    if (priv == NULL)
+        return false; /* wrong class */
+
+    if (priv->gboxed != NULL) {
+        /* We are an instance, not a prototype, so look for
+         * per-instance props that we want to define on the
+         * JSObject. Generally we do not want to cache these in JS, we
+         * want to always pull them from the C object, or JS would not
+         * see any changes made from C. So we use the get/set prop
+         * hooks, not this resolve hook.
+         */
+        *resolved = false;
+        return true;
     }
 
-    if (priv->gboxed == NULL) {
-        /* We are the prototype, so look for methods and other class properties */
-        GIFunctionInfo *method_info;
+    /* We are the prototype, so look for methods and other class properties */
+    GIFunctionInfo *method_info;
 
-        method_info = g_union_info_find_method((GIUnionInfo*) priv->info,
-                                               name);
+    method_info = g_union_info_find_method((GIUnionInfo*) priv->info,
+                                           name);
 
-        if (method_info != NULL) {
-            const char *method_name;
+    if (method_info != NULL) {
+        const char *method_name;
 
 #if GJS_VERBOSE_ENABLE_GI_USAGE
-            _gjs_log_info_usage((GIBaseInfo*) method_info);
+        _gjs_log_info_usage((GIBaseInfo*) method_info);
 #endif
-            if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) {
-                method_name = g_base_info_get_name( (GIBaseInfo*) method_info);
-
-                gjs_debug(GJS_DEBUG_GBOXED,
-                          "Defining method %s in prototype for %s.%s",
-                          method_name,
-                          g_base_info_get_namespace( (GIBaseInfo*) priv->info),
-                          g_base_info_get_name( (GIBaseInfo*) priv->info));
-
-                /* obj is union proto */
-                if (gjs_define_function(context, obj,
-                                        g_registered_type_info_get_g_type(priv->info),
-                                        method_info) == NULL) {
-                    g_base_info_unref( (GIBaseInfo*) method_info);
-                    ret = false;
-                    goto out;
-                }
-
-                objp.set(obj); /* we defined the prop in object_proto */
+        if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) {
+            method_name = g_base_info_get_name( (GIBaseInfo*) method_info);
+
+            gjs_debug(GJS_DEBUG_GBOXED,
+                      "Defining method %s in prototype for %s.%s",
+                      method_name,
+                      g_base_info_get_namespace( (GIBaseInfo*) priv->info),
+                      g_base_info_get_name( (GIBaseInfo*) priv->info));
+
+            /* obj is union proto */
+            if (gjs_define_function(context, obj,
+                                    g_registered_type_info_get_g_type(priv->info),
+                                    method_info) == NULL) {
+                g_base_info_unref( (GIBaseInfo*) method_info);
+                return false;
             }
 
-            g_base_info_unref( (GIBaseInfo*) method_info);
+            *resolved = true; /* we defined the prop in object_proto */
+        } else {
+            *resolved = false;
         }
+
+        g_base_info_unref( (GIBaseInfo*) method_info);
     } else {
-        /* We are an instance, not a prototype, so look for
-         * per-instance props that we want to define on the
-         * JSObject. Generally we do not want to cache these in JS, we
-         * want to always pull them from the C object, or JS would not
-         * see any changes made from C. So we use the get/set prop
-         * hooks, not this resolve hook.
-         */
+        *resolved = false;
     }
 
- out:
-    g_free(name);
-    return ret;
+    return true;
 }
 
 static void*
@@ -288,14 +289,13 @@ to_string_func(JSContext *context,
 struct JSClass gjs_union_class = {
     "GObject_Union",
     JSCLASS_HAS_PRIVATE |
-    JSCLASS_NEW_RESOLVE |
     JSCLASS_IMPLEMENTS_BARRIERS,
     NULL,  /* addProperty */
     NULL,  /* deleteProperty */
     NULL,  /* getProperty */
     NULL,  /* setProperty */
     NULL,  /* enumerate */
-    (JSResolveOp) union_new_resolve, /* needs cast since it's the new resolve signature */
+    union_resolve,
     NULL,  /* convert */
     union_finalize
 };
diff --git a/gjs/importer.cpp b/gjs/importer.cpp
index 94695e2..5c9bc82 100644
--- a/gjs/importer.cpp
+++ b/gjs/importer.cpp
@@ -863,19 +863,20 @@ importer_new_enumerate(JSContext  *context,
  * if id was resolved.
  */
 static bool
-importer_new_resolve(JSContext *context,
-                     JS::HandleObject obj,
-                     JS::HandleId id,
-                     JS::MutableHandleObject objp)
+importer_resolve(JSContext        *context,
+                 JS::HandleObject  obj,
+                 JS::HandleId      id,
+                 bool             *resolved)
 {
     Importer *priv;
-    char *name;
-    bool ret = true;
+    g_autofree char *name = NULL;
     jsid module_init_name;
 
     module_init_name = gjs_context_get_const_string(context, GJS_STRING_MODULE_INIT);
-    if (id == module_init_name)
+    if (id == module_init_name) {
+        *resolved = false;
         return true;
+    }
 
     if (!gjs_get_string_id(context, id, &name))
         return false;
@@ -883,26 +884,27 @@ importer_new_resolve(JSContext *context,
     /* let Object.prototype resolve these */
     if (strcmp(name, "valueOf") == 0 ||
         strcmp(name, "toString") == 0 ||
-        strcmp(name, "__iterator__") == 0)
-        goto out;
+        strcmp(name, "__iterator__") == 0) {
+        *resolved = false;
+        return true;
+    }
     priv = priv_from_js(context, obj);
 
     gjs_debug_jsprop(GJS_DEBUG_IMPORTER,
                      "Resolve prop '%s' hook obj %p priv %p",
                      name, obj.get(), priv);
-    if (priv == NULL) /* we are the prototype, or have the wrong class */
-        goto out;
-    JS_BeginRequest(context);
-    if (do_import(context, obj, priv, name)) {
-        objp.set(obj);
-    } else {
-        ret = false;
+    if (priv == NULL) {
+        /* we are the prototype, or have the wrong class */
+        *resolved = false;
+        return true;
     }
-    JS_EndRequest(context);
 
- out:
-    g_free(name);
-    return ret;
+    JSAutoRequest ar(context);
+    if (!do_import(context, obj, priv, name))
+        return false;
+
+    *resolved = true;
+    return true;
 }
 
 GJS_NATIVE_CONSTRUCTOR_DEFINE_ABSTRACT(importer)
@@ -930,7 +932,6 @@ importer_finalize(JSFreeOp *fop,
 struct JSClass gjs_importer_class = {
     "GjsFileImporter",
     JSCLASS_HAS_PRIVATE |
-    JSCLASS_NEW_RESOLVE |
     JSCLASS_NEW_ENUMERATE |
     JSCLASS_IMPLEMENTS_BARRIERS,
     NULL,  /* addProperty */
@@ -938,7 +939,7 @@ struct JSClass gjs_importer_class = {
     NULL,  /* getProperty */
     NULL,  /* setProperty */
     (JSEnumerateOp) importer_new_enumerate, /* needs cast since it's the new enumerate signature */
-    (JSResolveOp) importer_new_resolve, /* needs cast since it's the new resolve signature */
+    importer_resolve,
     NULL,  /* convert */
     importer_finalize
 };



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