mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 20:08:13 +00:00
LibJS: Fast non-local variable access :^)
This patch introduces the "environment coordinate" concept, which encodes the distance from a variable access to the binding it ends up resolving to. EnvironmentCoordinate has two fields: - hops: The number of hops up the lexical environment chain we have to make before getting to the resolved binding. - index: The index of the resolved binding within its declarative environment record. Whenever a variable lookup resolves somewhere inside a declarative environment, we now cache the coordinates and reuse them in subsequent lookups. This is achieved via a coordinate cache in JS::Identifier. Note that non-strict direct eval() breaks this optimization and so it will not be performed if the resolved environment has been permanently screwed by eval(). This makes variable access *significantly* faster. :^)
This commit is contained in:
parent
421845b0cd
commit
41a072bded
8 changed files with 65 additions and 12 deletions
|
@ -435,7 +435,7 @@ ThrowCompletionOr<void> VM::iterator_binding_initialization(BindingPattern const
|
|||
}
|
||||
|
||||
// 9.1.2.1 GetIdentifierReference ( env, name, strict ), https://tc39.es/ecma262/#sec-getidentifierreference
|
||||
Reference VM::get_identifier_reference(Environment* environment, FlyString name, bool strict)
|
||||
Reference VM::get_identifier_reference(Environment* environment, FlyString name, bool strict, size_t hops)
|
||||
{
|
||||
// 1. If env is the value null, then
|
||||
if (!environment) {
|
||||
|
@ -448,10 +448,14 @@ Reference VM::get_identifier_reference(Environment* environment, FlyString name,
|
|||
if (exception())
|
||||
return {};
|
||||
|
||||
Optional<EnvironmentCoordinate> environment_coordinate;
|
||||
if (index.has_value())
|
||||
environment_coordinate = EnvironmentCoordinate { .hops = hops, .index = index.value() };
|
||||
|
||||
if (exists)
|
||||
return Reference { *environment, move(name), strict, index };
|
||||
return Reference { *environment, move(name), strict, environment_coordinate };
|
||||
else
|
||||
return get_identifier_reference(environment->outer_environment(), move(name), strict);
|
||||
return get_identifier_reference(environment->outer_environment(), move(name), strict, hops + 1);
|
||||
}
|
||||
|
||||
// 9.4.2 ResolveBinding ( name [ , env ] ), https://tc39.es/ecma262/#sec-resolvebinding
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue