This is just another workaround, but it should be much more reliable
than Interpreter::realm(), especially when allocating NativeFunctions
and ECMAScriptFunctionObjects: we're guaranteed to have a GlobalObject
at that point, and it likely was set as the GlobalObject of a Realm and
can lead us back to it. We're however not guaranteed that the VM can
give us an Interpreter, which is why functions in LibWeb can be a bit
crashy at the moment.
We use a WeakPtr<Realm> to properly handle the unlikely case where the
Realm goes away after associating a GlobalObject to it.
We'll always need _something_ of this sort if we want to support
OrdinaryFunctionCreate and CreateBuiltinFunction without the explicit
realm argument while no JS is running, because they want to use the
current Realm Record (always in the first and as fallback in the second
case).
The way that transition avoidance (foo_without_transition) was
implemented led to shapes being unshareable and caused shape explosion
instead, precisely what we were trying to avoid.
This patch removes all the attempts to avoid transitioning shapes, and
instead *adds* transitions when changing an object's prototype.
This makes transitions flow naturally, and as a result we end up with
way fewer shape objects in real-world situations.
When we run out of big problems, we can get back to avoiding transitions
as an optimization, but for now, let's avoid ballooning our processes
with a unique shape for every object.
This is where the spec wants to have it. Requires a couple of hacks as
currently everything that needs a Realm actually has a GlobalObject, so
we need to go via the Interpreter.
We don't need transitions for either of these:
- Adding the 'name' property to a constructor object
- Adding the 'constructor' property to its prototype object
This is a tiny difference and only changes anything for primitives in
strict mode. However this is tested in test262 and can be noticed by
overriding toString of primitive values.
This does now require one to wrap an object in a Value to call invoke
but all code using invoke has been migrated.
Add a JS_ENUMERATE_INTL_OBJECTS macro and use it to generate:
- Forward declarations
- CommonPropertyNames class name members
- Constructor and prototype GlobalObject members, getters, visitors,
and initialize_constructor() calls
Add a JS_ENUMERATE_TEMPORAL_OBJECTS macro and use it to generate:
- Forward declarations
- CommonPropertyNames class name members
- Constructor and prototype GlobalObject members, getters, visitors,
and initialize_constructor() calls
This removes all usages of the non-standard define_property helper
method and replaces all it's usages with the specification required
alternative or with define_direct_property where appropriate.
These represent the outermost scope in the environment record
hierarchy. The spec says they should be a "composite" of two things:
- An ObjectEnvironmentRecord wrapping the global object
- A DeclarativeEnvironmentRecord for other declarations
It's not yet clear to me how this should work, so this patch only
implements the first part, an object record wrapping the global object.
This patch adds FunctionEnvironmentRecord as a subclass of the existing
DeclarativeEnvironmentRecord. Things that are specific to function
environment records move into there, simplifying the base.
Most of the abstract operations related to function environment records
are rewritten to match the spec exactly. I also had to implement
GetThisEnvironment() and GetSuperConstructor() to keep tests working
after the changes, so that's nice as well. :^)
This patch makes the following renames:
- get_from_scope() => get_from_environment_record()
- put_to_scope() => put_into_environment_record()
- delete_from_scope() => delete_from_environment_record()
This patch makes the following name changes:
- ScopeObject => EnvironmentRecord
- LexicalEnvironment => DeclarativeEnvironmentRecord
- WithScope => ObjectEnvironmentRecord
We were doing a *lot* of string-to-int conversion while creating a new
global object. This happened because Object::put() would try to convert
the property name (string) to an integer to see if it refers to an
indexed property.
Sidestep this issue by using PropertyName for the CommonPropertyNames
struct on VM (vm.names.foo), and giving PropertyName a flag that tells
us whether it's a string that *may be* a number.
All CommonPropertyNames are set up so they are known to not be numbers.
SPDX License Identifiers are a more compact / standardized
way of representing file license information.
See: https://spdx.dev/resources/use/#identifiers
This was done with the `ambr` search and replace tool.
ambr --no-parent-ignore --key-from-file --rep-from-file key.txt rep.txt *