This is a monster patch that turns all EventTargets into GC-allocated
PlatformObjects. Their C++ wrapper classes are removed, and the LibJS
garbage collector is now responsible for their lifetimes.
There's a fair amount of hacks and band-aids in this patch, and we'll
have a lot of cleanup to do after this.
This patch moves the following things to being GC-allocated:
- Bindings::CallbackType
- HTML::EventHandler
- DOM::IDLEventListener
- DOM::DOMEventListener
- DOM::NodeFilter
Note that we only use PlatformObject for things that might be exposed
to web content. Anything that is only used internally inherits directly
from JS::Cell instead, making them a bit more lightweight.
This removes the requirement of having a global object that actually
inherits from JS::GlobalObject, which is now a perfectly valid scenario.
With the upcoming removal of wrapper objects in LibWeb, the HTML::Window
object will inherit from DOM::EventTarget, which means it cannot also
inherit from JS::GlobalObject.
The protocol of the origin is used for checking if the a file://
iframe is allowed to be loaded (a document with a file:// origin
can load other files in iframes).
This used to be the case, but was changed in
6e71e400e6, which broke file:// iframes.
- Prefer VM::current_realm() over GlobalObject::associated_realm()
- Prefer VM::heap() over GlobalObject::heap()
- Prefer Cell::vm() over Cell::global_object()
- Prefer Wrapper::vm() over Wrapper::global_object()
- Inline Realm::global_object() calls used to access intrinsics as they
will later perform a direct lookup without going through the global
object
This is needed so that the allocated NativeFunction receives the correct
realm, usually forwarded from the Object's initialize() function, rather
than using the current realm.
Similar to create() in LibJS, wrap() et al. are on a low enough level to
warrant passing a Realm directly instead of relying on the current realm
from the VM, as a wrapper may need to be allocated while no JS is being
executed.
This is a continuation of the previous five commits.
A first big step into the direction of no longer having to pass a realm
(or currently, a global object) trough layers upon layers of AOs!
Unlike the create() APIs we can safely assume that this is only ever
called when a running execution context and therefore current realm
exists. If not, you can always manually allocate the Error and put it in
a Completion :^)
In the spec, throw exceptions implicitly use the current realm's
intrinsics as well: https://tc39.es/ecma262/#sec-throw-an-exception
This is a continuation of the previous three commits.
Now that create() receives the allocating realm, we can simply forward
that to allocate(), which accounts for the majority of these changes.
Additionally, we can get rid of the realm_from_global_object() in one
place, with one more remaining in VM::throw_completion().
This is a continuation of the previous two commits.
As allocating a JS cell already primarily involves a realm instead of a
global object, and we'll need to pass one to the allocate() function
itself eventually (it's bridged via the global object right now), the
create() functions need to receive a realm as well.
The plan is for this to be the highest-level function that actually
receives a realm and passes it around, AOs on an even higher level will
use the "current realm" concept via VM::current_realm() as that's what
the spec assumes; passing around realms (or global objects, for that
matter) on higher AO levels is pointless and unlike for allocating
individual objects, which may happen outside of regular JS execution, we
don't need control over the specific realm that is being used there.
This patch implements the "create a new browsing context" function from
the HTML spec and replaces our existing logic with it.
The big difference is that browsing contexts now initially navigate to
"about:blank" instead of starting out in a strange "empty" state.
This makes it possible for websites to create a new iframe and start
scripting inside it right away, without having to load an URL into it.
The way we've been creating DOM::Document has been pretty far from what
the spec tells us to do, and this is a first big step towards getting us
closer to spec.
The new Document::create_and_initialize() is called by FrameLoader after
loading a "text/html" resource.
We create the JS Realm and the Window object when creating the Document
(previously, we'd do it on first access to Document::interpreter().)
The realm execution context is owned by the Environment Settings Object.