Use the new DOM tree version mechanism to allow HTMLCollection to
remember its internal list of elements instead of rebuilding it on
every access.
This avoids thousands of full DOM walks while loading our GitHub repo.
~15% speed-up on jQuery subtests in Speedometer 3.0 :^)
This commit introduces a WEB_SET_PROTOTYPE_FOR_INTERFACE macro that
caches the interface name in a local static FlyString. This means that
we only pay for FlyString-from-literal lookup once per browser lifetime
instead of every time the interface is instantiated.
We have two known PlatformObjects that need to implement some of the
behavior of LegacyPlatformObjects to date: Window, and HTMLFormElement.
To make this not require double (or virtual) inheritance of
PlatformObject, move the behavior of LegacyPlatformObject into
PlatformObject. The selection of LegacyPlatformObject behavior is done
with a new bitfield of feature flags instead of a dozen virtual
functions that return bool. This change simplifies every class involved
in the diff with the notable exception of Window, which now needs some
ugly const casts to implement named property access.
Ultimately, this API should probably be replaced with something that
updates a cache on relevant DOM mutations instead of regenerating
the list of property names again and again.
With this change, we now have ~1200 CellAllocators across both LibJS and
LibWeb in a normal WebContent instance.
This gives us a minimum heap size of 4.7 MiB in the scenario where we
only have one cell allocated per type. Of course, in practice there will
be many more of each type, so the effective overhead is quite a bit
smaller than that in practice.
I left a few types unconverted to this mechanism because I got tired of
doing this. :^)
This required dealing with a *lot* of fallout, but it's all basically
just switching from DeprecatedFlyString to either FlyString or
Optional<FlyString> in a hundred places to accommodate the change.
This should allow us to add a Element::attribute which returns an
Optional<String>. Eventually all callers should be ported to switch from
the DeprecatedString version, but in the meantime, this should allow us
to port some more IDL interfaces away from DeprecatedString.
Stop worrying about tiny OOMs. Work towards #20449.
While going through these, I also changed the function signature in many
places where returning ThrowCompletionOr<T> is no longer necessary.
Some of the live HTMLCollection only ever contain children of their root
node. When we know that's the case, we can avoid doing a full subtree
traversal of all descendants and only visit children.
This cuts the ECMA262 spec loading time by over 10 seconds. :^)
Every user of HTMLCollection does not expect the root node to be a
potential match, so let's avoid it by using non-inclusive sub-tree
traversal. This avoids matching the element that getElementsByTagName
was called on for example, which is required by Ruffle:
da689b7687/web/packages/core/src/ruffle-object.ts (L321-L329)
With the GC heap conversion, the functionality of legacy platform
objects was broken. This is because the generated implementation of one
of them was used for all of them, removing functionality such as
deletion.
This re-adds all functionality, where questions such as "does the
object support indexed properties?" is instead answered by virtual
functions instead of by the IDL generator checking the presence of
certain keywords/attributes.
Note that as of this commit, there aren't any such throwers, and the
call site in Heap::allocate will drop exceptions on the floor. This
commit only serves to change the declaration of the overrides, make sure
they return an empty value, and to propagate OOM errors frm their base
initialize invocations.
DeprecatedFlyString relies heavily on DeprecatedString's StringImpl, so
let's rename it to A) match the name of DeprecatedString, B) write a new
FlyString class that is tied to String.
We have a new, improved string type coming up in AK (OOM aware, no null
state), and while it's going to use UTF-8, the name UTF8String is a
mouthful - so let's free up the String name by renaming the existing
class.
Making the old one have an annoying name will hopefully also help with
quick adoption :^)
These classes only needed Window to get at its realm. Pass a realm
directly to construct DOM and WebIDL classes.
This change importantly removes the guarantee that a Document will
always have a non-null Window object. Only Documents created by a
BrowsingContext will have a non-null Window object. Documents created by
for example, DocumentFragment, will not have a Window (soon).
This incremental commit leaves some workarounds in place to keep other
parts of the code building.
Unlike ensure_web_prototype<T>(), the cached version doesn't require the
prototype type to be fully formed, so we can use it without including
the FooPrototype.h header. It's also a bit less verbose. :^)
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.
HTMLCollection is an awkward legacy interface from the DOM spec.
It provides a live view of a DOM subtree, with some kind of filtering
that determines which elements are part of the collection.
We now return HTMLCollection objects from these APIs:
- getElementsByClassName()
- getElementsByName()
- getElementsByTagName()
This initial implementation does not do any kind of caching, since that
is quite a tricky problem, and there will be plenty of time for tricky
problems later on when the engine is more mature.