diff options
author | Evan Welsh <contact@evanwelsh.com> | 2022-02-26 08:21:45 -0800 |
---|---|---|
committer | Evan Welsh <contact@evanwelsh.com> | 2022-02-26 08:41:19 -0800 |
commit | e58d083d35752eef7a9603b4d6435e6c5ac98b67 (patch) | |
tree | e0eb6ac5d95c2d9b28af1200e3ac063fbbd8f53f /gi/object.cpp | |
parent | bec10836b3f571b3e8bcabb34ae577f3f83c4f17 (diff) | |
download | gjs-e58d083d35752eef7a9603b4d6435e6c5ac98b67.tar.gz |
gi: Store interface function overrides on the calling this object
Fixes #467
Diffstat (limited to 'gi/object.cpp')
-rw-r--r-- | gi/object.cpp | 47 |
1 files changed, 42 insertions, 5 deletions
diff --git a/gi/object.cpp b/gi/object.cpp index 4c5a9efd..a53f9e52 100644 --- a/gi/object.cpp +++ b/gi/object.cpp @@ -34,6 +34,8 @@ #include <js/MemoryFunctions.h> // for AddAssociatedMemory, RemoveAssoci... #include <js/Object.h> #include <js/PropertyDescriptor.h> // for JSPROP_PERMANENT, JSPROP_READONLY +#include <js/String.h> +#include <js/Symbol.h> #include <js/TypeDecls.h> #include <js/Utility.h> // for UniqueChars #include <js/Value.h> @@ -662,11 +664,32 @@ static bool interface_getter(JSContext* cx, unsigned argc, JS::Value* vp) { const GjsAtoms& atoms = GjsContextPrivate::atoms(cx); // Check if an override value has been set - bool has_override = false; - if (!JS_HasPropertyById(cx, accessor, atoms.override(), &has_override)) + bool has_override_symbol = false; + if (!JS_HasPropertyById(cx, accessor, atoms.override(), + &has_override_symbol)) return false; - if (has_override) - return JS_GetPropertyById(cx, accessor, atoms.override(), args.rval()); + + if (has_override_symbol) { + JS::RootedValue v_override_symbol(cx); + if (!JS_GetPropertyById(cx, accessor, atoms.override(), + &v_override_symbol)) + return false; + g_assert(v_override_symbol.isSymbol() && + "override symbol must be a symbol"); + JS::RootedSymbol override_symbol(cx, v_override_symbol.toSymbol()); + JS::RootedId override_id(cx, SYMBOL_TO_JSID(override_symbol)); + + JS::RootedObject this_obj(cx); + if (!args.computeThis(cx, &this_obj)) + return false; + + bool has_override = false; + if (!JS_HasPropertyById(cx, this_obj, override_id, &has_override)) + return false; + + if (has_override) + return JS_GetPropertyById(cx, this_obj, override_id, args.rval()); + } JS::RootedValue v_prototype(cx); if (!JS_GetPropertyById(cx, accessor, atoms.prototype(), &v_prototype)) @@ -684,9 +707,23 @@ static bool interface_setter(JSContext* cx, unsigned argc, JS::Value* vp) { JS::RootedValue v_accessor( cx, js::GetFunctionNativeReserved(&args.callee(), ACCESSOR_SLOT)); JS::RootedObject accessor(cx, &v_accessor.toObject()); + JS::RootedString description( + cx, JS_AtomizeAndPinString(cx, "Private interface function setter")); + JS::RootedSymbol symbol(cx, JS::NewSymbol(cx, description)); + JS::RootedValue v_symbol(cx, JS::SymbolValue(symbol)); const GjsAtoms& atoms = GjsContextPrivate::atoms(cx); - return JS_SetPropertyById(cx, accessor, atoms.override(), args[0]); + if (!JS_SetPropertyById(cx, accessor, atoms.override(), v_symbol)) + return false; + + args.rval().setUndefined(); + + JS::RootedObject this_obj(cx); + if (!args.computeThis(cx, &this_obj)) + return false; + JS::RootedId override_id(cx, SYMBOL_TO_JSID(symbol)); + + return JS_SetPropertyById(cx, this_obj, override_id, args[0]); } static bool resolve_on_interface_prototype(JSContext* cx, |