mirror of
https://github.com/RGBCube/serenity
synced 2026-01-12 22:41:00 +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
|
|
@ -1005,7 +1005,20 @@ Reference Expression::to_reference(Interpreter&, GlobalObject&) const
|
|||
|
||||
Reference Identifier::to_reference(Interpreter& interpreter, GlobalObject&) const
|
||||
{
|
||||
return interpreter.vm().resolve_binding(string());
|
||||
if (m_cached_environment_coordinate.has_value()) {
|
||||
auto* environment = interpreter.vm().running_execution_context().lexical_environment;
|
||||
for (size_t i = 0; i < m_cached_environment_coordinate->hops; ++i)
|
||||
environment = environment->outer_environment();
|
||||
VERIFY(environment);
|
||||
VERIFY(environment->is_declarative_environment());
|
||||
if (!environment->is_permanently_screwed_by_eval())
|
||||
return Reference { *environment, string(), interpreter.vm().in_strict_mode(), m_cached_environment_coordinate };
|
||||
m_cached_environment_coordinate = {};
|
||||
}
|
||||
auto reference = interpreter.vm().resolve_binding(string());
|
||||
if (reference.environment_coordinate().has_value())
|
||||
const_cast<Identifier&>(*this).m_cached_environment_coordinate = reference.environment_coordinate();
|
||||
return reference;
|
||||
}
|
||||
|
||||
Reference MemberExpression::to_reference(Interpreter& interpreter, GlobalObject& global_object) const
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue