BindingsGenerator: Handle global interfaces without named properties

DedicatedWorkerGlobalScope is an object with a Global extended
attribute, but does not define any named property getters. This needs to
be handled by setting the prototype chain to:

    DedicatedWorkerGlobalScope
    ^ DedicatedWorkerGlobalScopePrototype
    ^ WorkerGlobalScopePrototype

(This is different from something like Window, where there is an
intermediate WindowProperties object for named properties.)

Previously, we treated the GlobalMixin object as if it was a simple
prototype object, accidentally setting DedicatedWorkerGlobalScope's
prototype to WorkerGlobalScopePrototype. This caused the expression

    self instanceof DedicatedWorkerGlobalScope

to return false inside workers.

This makes us pass many more of the "/xhr/idlharness.any.worker" WPT
tests than before, rather than failing early.
This commit is contained in:
sin-ack 2024-10-12 13:52:10 +00:00 committed by Andreas Kling
parent 6923008a55
commit d5948709cd
Notes: github-actions[bot] 2024-10-12 17:22:59 +00:00
4 changed files with 26 additions and 1 deletions

View file

@ -3189,7 +3189,7 @@ void @class_name@::initialize(JS::Realm& realm)
set_prototype(realm.intrinsics().object_prototype());
)~~~");
} else if (is_global_interface && interface.supports_named_properties()) {
} else if (is_global_interface) {
generator.append(R"~~~(
set_prototype(&ensure_web_prototype<@prototype_name@>(realm, "@name@"_fly_string));
)~~~");
@ -4766,6 +4766,10 @@ void @prototype_class@::initialize(JS::Realm& realm)
generator.append(R"~~~(
define_direct_property(vm().well_known_symbol_to_string_tag(), JS::PrimitiveString::create(vm(), "@namespaced_name@"_string), JS::Attribute::Configurable);
set_prototype(&ensure_web_prototype<@prototype_class@>(realm, "@named_properties_class@"_fly_string));
)~~~");
} else {
generator.append(R"~~~(
set_prototype(&ensure_web_prototype<@prototype_base_class@>(realm, "@parent_name@"_fly_string));
)~~~");
}
generator.append(R"~~~(

View file

@ -0,0 +1,5 @@
onmessage = function (event) {
if (event.data === "run") {
postMessage({ result: self instanceof DedicatedWorkerGlobalScope });
}
};

View file

@ -0,0 +1,15 @@
<script src="../include.js"></script>
<script>
asyncTest(done => {
const worker = new Worker("DedicatedWorkerGlobalScope-instanceof-worker.js");
worker.onmessage = function (event) {
if (event.data.result === true) {
println("PASS");
} else {
println("FAIL");
}
done();
};
worker.postMessage("run");
});
</script>