Meta: Set constructor prototype in IDLGenerators

Without this, retrieving `__proto__` from any interface will always
yield an instance of `FunctionPrototype`.
This commit is contained in:
Jelle Raaijmakers 2024-11-26 11:56:48 +01:00 committed by Tim Ledbetter
commit 614b93beca
Notes: github-actions[bot] 2024-11-26 12:45:02 +00:00
4 changed files with 34 additions and 4 deletions

View file

@ -4513,6 +4513,8 @@ void generate_constructor_implementation(IDL::Interface const& interface, String
generator.set("prototype_class", interface.prototype_class); generator.set("prototype_class", interface.prototype_class);
generator.set("constructor_class", interface.constructor_class); generator.set("constructor_class", interface.constructor_class);
generator.set("fully_qualified_name", interface.fully_qualified_name); generator.set("fully_qualified_name", interface.fully_qualified_name);
generator.set("parent_name", interface.parent_name);
generator.set("prototype_base_class", interface.prototype_base_class);
generator.append(R"~~~( generator.append(R"~~~(
#include <LibIDL/Types.h> #include <LibIDL/Types.h>
@ -4535,6 +4537,10 @@ void generate_constructor_implementation(IDL::Interface const& interface, String
#include <LibWeb/WebIDL/Tracing.h> #include <LibWeb/WebIDL/Tracing.h>
#include <LibWeb/WebIDL/Types.h> #include <LibWeb/WebIDL/Types.h>
#if __has_include(<LibWeb/Bindings/@prototype_base_class@.h>)
# include <LibWeb/Bindings/@prototype_base_class@.h>
#endif
)~~~"); )~~~");
if (interface.constructors.size() == 1) { if (interface.constructors.size() == 1) {
@ -4586,6 +4592,15 @@ void @constructor_class@::initialize(JS::Realm& realm)
[[maybe_unused]] u8 default_attributes = JS::Attribute::Enumerable; [[maybe_unused]] u8 default_attributes = JS::Attribute::Enumerable;
Base::initialize(realm); Base::initialize(realm);
)~~~");
if (interface.prototype_base_class != "ObjectPrototype") {
generator.append(R"~~~(
set_prototype(&ensure_web_constructor<@prototype_base_class@>(realm, "@parent_name@"_fly_string));
)~~~");
}
generator.append(R"~~~(
define_direct_property(vm.names.prototype, &ensure_web_prototype<@prototype_class@>(realm, "@namespaced_name@"_fly_string), 0); define_direct_property(vm.names.prototype, &ensure_web_prototype<@prototype_class@>(realm, "@namespaced_name@"_fly_string), 0);
define_direct_property(vm.names.length, JS::Value(@constructor.length@), JS::Attribute::Configurable); define_direct_property(vm.names.length, JS::Value(@constructor.length@), JS::Attribute::Configurable);

View file

@ -0,0 +1,5 @@
function SVGElement() { [native code] }
function Element() { [native code] }
function Node() { [native code] }
function EventTarget() { [native code] }
function () { [native code] }

View file

@ -6,10 +6,10 @@ Rerun
Found 13 tests Found 13 tests
11 Pass 12 Pass
2 Fail 1 Fail
Details Details
Result Test Name MessageFail CSSStyleRule is a CSSGroupingRule Result Test Name MessagePass CSSStyleRule is a CSSGroupingRule
Pass Simple CSSOM manipulation of subrules Pass Simple CSSOM manipulation of subrules
Pass Simple CSSOM manipulation of subrules 1 Pass Simple CSSOM manipulation of subrules 1
Pass Simple CSSOM manipulation of subrules 2 Pass Simple CSSOM manipulation of subrules 2
@ -21,4 +21,4 @@ Pass Simple CSSOM manipulation of subrules 7
Fail Simple CSSOM manipulation of subrules 8 Fail Simple CSSOM manipulation of subrules 8
Pass Simple CSSOM manipulation of subrules 9 Pass Simple CSSOM manipulation of subrules 9
Pass Simple CSSOM manipulation of subrules 10 Pass Simple CSSOM manipulation of subrules 10
Pass Mutating the selectorText of outer rule invalidates inner rules Pass Mutating the selectorText of outer rule invalidates inner rules

View file

@ -0,0 +1,10 @@
<script src="../include.js"></script>
<script>
test(() => {
println(SVGElement.toString());
println(SVGElement.__proto__.toString());
println(SVGElement.__proto__.__proto__.toString());
println(SVGElement.__proto__.__proto__.__proto__.toString());
println(SVGElement.__proto__.__proto__.__proto__.__proto__.toString());
});
</script>