[gjs/wip/carlosg/construct-only-setter-fixes] object: Avoid setting construct properties multiple times




commit 9d9af5f633d08553f3b427acedce9aa05d293474
Author: Carlos Garnacho <carlosg gnome org>
Date:   Mon Jun 21 02:00:49 2021 +0200

    object: Avoid setting construct properties multiple times
    
    Construct-only properties may be defined several times in JS land
    with different casings (snake, kebab, camel), but they all resolve
    to the same GParamSpec.
    
    For these cases, discard the redundant GParamSpec lookups when
    collecting the value array for g_object_new_with_properties().
    
    Fixes: https://gitlab.gnome.org/GNOME/gjs/-/issues/422

 gi/object.cpp | 6 ++++++
 1 file changed, 6 insertions(+)
---
diff --git a/gi/object.cpp b/gi/object.cpp
index 03cfd7bc..3bfa42e8 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -13,6 +13,7 @@
 #include <limits>
 #include <string>
 #include <tuple>        // for tie
+#include <unordered_set>
 #include <utility>      // for move
 #include <vector>
 
@@ -1053,6 +1054,7 @@ bool ObjectPrototype::props_to_g_parameters(JSContext* context,
     JS::RootedId prop_id(context);
     JS::RootedValue value(context);
     JS::Rooted<JS::IdVector> ids(context);
+    std::unordered_set<GParamSpec*> visited_params;
     if (!JS_Enumerate(context, props, &ids)) {
         gjs_throw(context, "Failed to create property iterator for object props hash");
         return false;
@@ -1073,6 +1075,10 @@ bool ObjectPrototype::props_to_g_parameters(JSContext* context,
         if (!param_spec)
             return false;
 
+        if (visited_params.find(param_spec) != visited_params.end())
+            continue;
+        visited_params.insert(param_spec);
+
         if (!JS_GetPropertyById(context, props, prop_id, &value))
             return false;
         if (value.isUndefined()) {


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