[gjs/gnome-3-36] gi/wrapperutils: Move gjs_get_string_id() into resolve() implementations



commit a7af1d7e3a38bcfe80b5de6b3b03266b7f372e52
Author: Jonas Dreßler <verdre v0yd nl>
Date:   Thu Oct 22 18:49:36 2020 +0200

    gi/wrapperutils: Move gjs_get_string_id() into resolve() implementations
    
    Calling gjs_get_string_id() allocates a string, which can be quite
    expensive and should be avoided in hot-paths. There are some resolve()
    implementations which don't need the prop_name string and can return
    without it, most notably the implementation of ObjectPrototype, which
    has an unresolvable cache. If we hit that cache, there's no need to
    create the string.
    
    So move the call to gjs_get_string_id() into the implementations of
    resolve() and make sure ObjectPrototype::resolve() avoids calling it in
    case we hit the unresolvable cache.

 gi/boxed.cpp       | 13 ++++++++++---
 gi/boxed.h         |  2 +-
 gi/fundamental.cpp | 15 +++++++++++----
 gi/fundamental.h   |  2 +-
 gi/interface.cpp   | 13 ++++++++++---
 gi/interface.h     |  2 +-
 gi/object.cpp      | 13 ++++++++++---
 gi/object.h        |  2 +-
 gi/union.cpp       | 13 ++++++++++---
 gi/union.h         |  2 +-
 gi/wrapperutils.h  | 13 +------------
 11 files changed, 57 insertions(+), 33 deletions(-)
---
diff --git a/gi/boxed.cpp b/gi/boxed.cpp
index 5630e626..8da25689 100644
--- a/gi/boxed.cpp
+++ b/gi/boxed.cpp
@@ -67,11 +67,18 @@ static bool struct_is_simple(GIStructInfo *info);
 
 // See GIWrapperBase::resolve().
 bool BoxedPrototype::resolve_impl(JSContext* cx, JS::HandleObject obj,
-                                  JS::HandleId, const char* prop_name,
-                                  bool* resolved) {
+                                  JS::HandleId id, bool* resolved) {
+    JS::UniqueChars prop_name;
+    if (!gjs_get_string_id(cx, id, &prop_name))
+        return false;
+    if (!prop_name) {
+        *resolved = false;
+        return true;  // not resolved, but no error
+    }
+
     // Look for methods and other class properties
     GjsAutoFunctionInfo method_info =
-        g_struct_info_find_method(info(), prop_name);
+        g_struct_info_find_method(info(), prop_name.get());
     if (!method_info) {
         *resolved = false;
         return true;
diff --git a/gi/boxed.h b/gi/boxed.h
index 9e1312ec..7eae8b98 100644
--- a/gi/boxed.h
+++ b/gi/boxed.h
@@ -147,7 +147,7 @@ class BoxedPrototype : public GIWrapperPrototype<BoxedBase, BoxedPrototype,
  private:
     GJS_JSAPI_RETURN_CONVENTION
     bool resolve_impl(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
-                      const char* prop_name, bool* resolved);
+                      bool* resolved);
     void trace_impl(JSTracer* trc);
 
     // Helper methods
diff --git a/gi/fundamental.cpp b/gi/fundamental.cpp
index 66c27e60..bed96045 100644
--- a/gi/fundamental.cpp
+++ b/gi/fundamental.cpp
@@ -153,11 +153,18 @@ bool FundamentalPrototype::resolve_interface(JSContext* cx,
 
 // See GIWrapperBase::resolve().
 bool FundamentalPrototype::resolve_impl(JSContext* cx, JS::HandleObject obj,
-                                        JS::HandleId, const char* prop_name,
-                                        bool* resolved) {
+                                        JS::HandleId id, bool* resolved) {
+    JS::UniqueChars prop_name;
+    if (!gjs_get_string_id(cx, id, &prop_name))
+        return false;
+    if (!prop_name) {
+        *resolved = false;
+        return true;  // not resolved, but no error
+    }
+
     /* We are the prototype, so look for methods and other class properties */
     GjsAutoFunctionInfo method_info =
-        g_object_info_find_method(info(), prop_name);
+        g_object_info_find_method(info(), prop_name.get());
 
     if (method_info) {
 #if GJS_VERBOSE_ENABLE_GI_USAGE
@@ -187,7 +194,7 @@ bool FundamentalPrototype::resolve_impl(JSContext* cx, JS::HandleObject obj,
         *resolved = false;
     }
 
-    return resolve_interface(cx, obj, resolved, prop_name);
+    return resolve_interface(cx, obj, resolved, prop_name.get());
 }
 
 /*
diff --git a/gi/fundamental.h b/gi/fundamental.h
index 00c38225..f6fb6e2e 100644
--- a/gi/fundamental.h
+++ b/gi/fundamental.h
@@ -138,7 +138,7 @@ class FundamentalPrototype
 
     GJS_JSAPI_RETURN_CONVENTION
     bool resolve_impl(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
-                      const char* prop_name, bool* resolved);
+                      bool* resolved);
     void trace_impl(JSTracer* trc);
 
     // Public API
diff --git a/gi/interface.cpp b/gi/interface.cpp
index 7ad150ec..efd252cc 100644
--- a/gi/interface.cpp
+++ b/gi/interface.cpp
@@ -51,8 +51,7 @@ InterfacePrototype::~InterfacePrototype(void) {
 
 // See GIWrapperBase::resolve().
 bool InterfacePrototype::resolve_impl(JSContext* context, JS::HandleObject obj,
-                                      JS::HandleId, const char* name,
-                                      bool* resolved) {
+                                      JS::HandleId id, bool* resolved) {
     /* 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. */
@@ -61,8 +60,16 @@ bool InterfacePrototype::resolve_impl(JSContext* context, JS::HandleObject obj,
         return true;
     }
 
+    JS::UniqueChars prop_name;
+    if (!gjs_get_string_id(context, id, &prop_name))
+        return false;
+    if (!prop_name) {
+        *resolved = false;
+        return true;  // not resolved, but no error
+    }
+
     GjsAutoFunctionInfo method_info =
-        g_interface_info_find_method(m_info, name);
+        g_interface_info_find_method(m_info, prop_name.get());
 
     if (method_info) {
         if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) {
diff --git a/gi/interface.h b/gi/interface.h
index a5993666..7251926e 100644
--- a/gi/interface.h
+++ b/gi/interface.h
@@ -109,7 +109,7 @@ class InterfacePrototype
 
     GJS_JSAPI_RETURN_CONVENTION
     bool resolve_impl(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
-                      const char* name, bool* resolved);
+                      bool* resolved);
 
     // JS methods
 
diff --git a/gi/object.cpp b/gi/object.cpp
index b5a638b8..9f36a42a 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -765,14 +765,21 @@ bool ObjectBase::id_is_never_lazy(jsid name, const GjsAtoms& atoms) {
 }
 
 bool ObjectPrototype::resolve_impl(JSContext* context, JS::HandleObject obj,
-                                   JS::HandleId id, const char* name,
-                                   bool* resolved) {
+                                   JS::HandleId id, bool* resolved) {
     if (m_unresolvable_cache.has(id)) {
         *resolved = false;
         return true;
     }
 
-    if (!uncached_resolve(context, obj, id, name, resolved))
+    JS::UniqueChars prop_name;
+    if (!gjs_get_string_id(context, id, &prop_name))
+        return false;
+    if (!prop_name) {
+        *resolved = false;
+        return true;  // not resolved, but no error
+    }
+
+    if (!uncached_resolve(context, obj, id, prop_name.get(), resolved))
         return false;
 
     if (!*resolved && !m_unresolvable_cache.putNew(id)) {
diff --git a/gi/object.h b/gi/object.h
index 1f381b4c..b118d93b 100644
--- a/gi/object.h
+++ b/gi/object.h
@@ -305,7 +305,7 @@ class ObjectPrototype
  private:
     GJS_JSAPI_RETURN_CONVENTION
     bool resolve_impl(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
-                      const char* prop_name, bool* resolved);
+                      bool* resolved);
 
     GJS_JSAPI_RETURN_CONVENTION
     bool new_enumerate_impl(JSContext* cx, JS::HandleObject obj,
diff --git a/gi/union.cpp b/gi/union.cpp
index a58e90e9..15184e50 100644
--- a/gi/union.cpp
+++ b/gi/union.cpp
@@ -62,11 +62,18 @@ UnionInstance::~UnionInstance(void) {
 
 // See GIWrapperBase::resolve().
 bool UnionPrototype::resolve_impl(JSContext* context, JS::HandleObject obj,
-                                  JS::HandleId, const char* prop_name,
-                                  bool* resolved) {
+                                  JS::HandleId id, bool* resolved) {
+    JS::UniqueChars prop_name;
+    if (!gjs_get_string_id(context, id, &prop_name))
+        return false;
+    if (!prop_name) {
+        *resolved = false;
+        return true;  // not resolved, but no error
+    }
+
     // Look for methods and other class properties
     GjsAutoFunctionInfo method_info =
-        g_union_info_find_method(info(), prop_name);
+        g_union_info_find_method(info(), prop_name.get());
 
     if (method_info) {
 #if GJS_VERBOSE_ENABLE_GI_USAGE
diff --git a/gi/union.h b/gi/union.h
index 3d2249f2..7a5bf6be 100644
--- a/gi/union.h
+++ b/gi/union.h
@@ -73,7 +73,7 @@ class UnionPrototype : public GIWrapperPrototype<UnionBase, UnionPrototype,
 
     GJS_JSAPI_RETURN_CONVENTION
     bool resolve_impl(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
-                      const char* prop_name, bool* resolved);
+                      bool* resolved);
 
     // Overrides GIWrapperPrototype::constructor_nargs().
     GJS_USE unsigned constructor_nargs(void) const { return 0; }
diff --git a/gi/wrapperutils.h b/gi/wrapperutils.h
index bcb3203a..74f26235 100644
--- a/gi/wrapperutils.h
+++ b/gi/wrapperutils.h
@@ -445,18 +445,7 @@ class GIWrapperBase {
             return true;
         }
 
-        // A GObject-introspection lazy property will always be a string, so
-        // also bail out if trying to resolve an integer or symbol property.
-        JS::UniqueChars prop_name;
-        if (!gjs_get_string_id(cx, id, &prop_name))
-            return false;
-        if (!prop_name) {
-            *resolved = false;
-            return true;  // not resolved, but no error
-        }
-
-        return priv->to_prototype()->resolve_impl(cx, obj, id, prop_name.get(),
-                                                  resolved);
+        return priv->to_prototype()->resolve_impl(cx, obj, id, resolved);
     }
 
     /*


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