mirror of
https://github.com/fergalmoran/ladybird.git
synced 2026-01-06 16:45:03 +00:00
LibJS: Inline more of cached environment variable access in interpreter
And stop passing VM strictness to direct access, since it doesn't care about strictness anyway.
This commit is contained in:
@@ -523,28 +523,6 @@ inline ThrowCompletionOr<void> put_by_value(VM& vm, Value base, Optional<Depreca
|
||||
return {};
|
||||
}
|
||||
|
||||
inline ThrowCompletionOr<Value> get_variable(Bytecode::Interpreter& interpreter, DeprecatedFlyString const& name, EnvironmentVariableCache& cache)
|
||||
{
|
||||
auto& vm = interpreter.vm();
|
||||
|
||||
if (cache.has_value()) {
|
||||
auto environment = vm.running_execution_context().lexical_environment;
|
||||
for (size_t i = 0; i < cache->hops; ++i)
|
||||
environment = environment->outer_environment();
|
||||
VERIFY(environment);
|
||||
VERIFY(environment->is_declarative_environment());
|
||||
if (!environment->is_permanently_screwed_by_eval()) {
|
||||
return TRY(verify_cast<DeclarativeEnvironment>(*environment).get_binding_value_direct(vm, cache.value().index, vm.in_strict_mode()));
|
||||
}
|
||||
cache = {};
|
||||
}
|
||||
|
||||
auto reference = TRY(vm.resolve_binding(name));
|
||||
if (reference.environment_coordinate().has_value())
|
||||
cache = reference.environment_coordinate();
|
||||
return TRY(reference.get_value(vm));
|
||||
}
|
||||
|
||||
struct CalleeAndThis {
|
||||
Value callee;
|
||||
Value this_value;
|
||||
@@ -558,13 +536,11 @@ inline ThrowCompletionOr<CalleeAndThis> get_callee_and_this_from_environment(Byt
|
||||
Value this_value = js_undefined();
|
||||
|
||||
if (cache.has_value()) {
|
||||
auto environment = vm.running_execution_context().lexical_environment;
|
||||
auto const* environment = vm.running_execution_context().lexical_environment.ptr();
|
||||
for (size_t i = 0; i < cache->hops; ++i)
|
||||
environment = environment->outer_environment();
|
||||
VERIFY(environment);
|
||||
VERIFY(environment->is_declarative_environment());
|
||||
if (!environment->is_permanently_screwed_by_eval()) {
|
||||
callee = TRY(verify_cast<DeclarativeEnvironment>(*environment).get_binding_value_direct(vm, cache.value().index, vm.in_strict_mode()));
|
||||
callee = TRY(static_cast<DeclarativeEnvironment const&>(*environment).get_binding_value_direct(vm, cache.value().index));
|
||||
this_value = js_undefined();
|
||||
if (auto base_object = environment->with_base_object())
|
||||
this_value = base_object;
|
||||
|
||||
@@ -1232,7 +1232,25 @@ ThrowCompletionOr<void> ConcatString::execute_impl(Bytecode::Interpreter& interp
|
||||
|
||||
ThrowCompletionOr<void> GetVariable::execute_impl(Bytecode::Interpreter& interpreter) const
|
||||
{
|
||||
interpreter.set(dst(), TRY(get_variable(interpreter, interpreter.current_executable().get_identifier(m_identifier), interpreter.current_executable().environment_variable_caches[m_cache_index])));
|
||||
auto& vm = interpreter.vm();
|
||||
auto& executable = interpreter.current_executable();
|
||||
auto& cache = executable.environment_variable_caches[m_cache_index];
|
||||
|
||||
if (cache.has_value()) {
|
||||
auto const* environment = vm.running_execution_context().lexical_environment.ptr();
|
||||
for (size_t i = 0; i < cache->hops; ++i)
|
||||
environment = environment->outer_environment();
|
||||
if (!environment->is_permanently_screwed_by_eval()) {
|
||||
interpreter.set(dst(), TRY(static_cast<DeclarativeEnvironment const&>(*environment).get_binding_value_direct(vm, cache.value().index)));
|
||||
return {};
|
||||
}
|
||||
cache = {};
|
||||
}
|
||||
|
||||
auto reference = TRY(vm.resolve_binding(executable.get_identifier(m_identifier)));
|
||||
if (reference.environment_coordinate().has_value())
|
||||
cache = reference.environment_coordinate();
|
||||
interpreter.set(dst(), TRY(reference.get_value(vm)));
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
@@ -182,29 +182,14 @@ ThrowCompletionOr<void> DeclarativeEnvironment::set_mutable_binding_direct(VM& v
|
||||
}
|
||||
|
||||
// 9.1.1.1.6 GetBindingValue ( N, S ), https://tc39.es/ecma262/#sec-declarative-environment-records-getbindingvalue-n-s
|
||||
ThrowCompletionOr<Value> DeclarativeEnvironment::get_binding_value(VM& vm, DeprecatedFlyString const& name, bool strict)
|
||||
ThrowCompletionOr<Value> DeclarativeEnvironment::get_binding_value(VM& vm, DeprecatedFlyString const& name, [[maybe_unused]] bool strict)
|
||||
{
|
||||
// 1. Assert: envRec has a binding for N.
|
||||
auto binding_and_index = find_binding_and_index(name);
|
||||
VERIFY(binding_and_index.has_value());
|
||||
|
||||
// 2-3. (extracted into a non-standard function below)
|
||||
return get_binding_value_direct(vm, binding_and_index->binding(), strict);
|
||||
}
|
||||
|
||||
ThrowCompletionOr<Value> DeclarativeEnvironment::get_binding_value_direct(VM& vm, size_t index, bool strict)
|
||||
{
|
||||
return get_binding_value_direct(vm, m_bindings[index], strict);
|
||||
}
|
||||
|
||||
ThrowCompletionOr<Value> DeclarativeEnvironment::get_binding_value_direct(VM&, Binding& binding, bool)
|
||||
{
|
||||
// 2. If the binding for N in envRec is an uninitialized binding, throw a ReferenceError exception.
|
||||
if (!binding.initialized)
|
||||
return vm().throw_completion<ReferenceError>(ErrorType::BindingNotInitialized, binding.name);
|
||||
|
||||
// 3. Return the value currently bound to N in envRec.
|
||||
return binding.value;
|
||||
return get_binding_value_direct(vm, binding_and_index->binding());
|
||||
}
|
||||
|
||||
// 9.1.1.1.7 DeleteBinding ( N ), https://tc39.es/ecma262/#sec-declarative-environment-records-deletebinding-n
|
||||
|
||||
@@ -57,7 +57,7 @@ public:
|
||||
}
|
||||
|
||||
ThrowCompletionOr<void> set_mutable_binding_direct(VM&, size_t index, Value, bool strict);
|
||||
ThrowCompletionOr<Value> get_binding_value_direct(VM&, size_t index, bool strict);
|
||||
ThrowCompletionOr<Value> get_binding_value_direct(VM&, size_t index) const;
|
||||
|
||||
void shrink_to_fit();
|
||||
|
||||
@@ -69,7 +69,7 @@ public:
|
||||
[[nodiscard]] u64 environment_serial_number() const { return m_environment_serial_number; }
|
||||
|
||||
private:
|
||||
ThrowCompletionOr<Value> get_binding_value_direct(VM&, Binding&, bool strict);
|
||||
ThrowCompletionOr<Value> get_binding_value_direct(VM&, Binding const&) const;
|
||||
ThrowCompletionOr<void> set_mutable_binding_direct(VM&, Binding&, Value, bool strict);
|
||||
|
||||
friend Completion dispose_resources(VM&, GCPtr<DeclarativeEnvironment>, Completion);
|
||||
@@ -131,6 +131,21 @@ private:
|
||||
u64 m_environment_serial_number { 0 };
|
||||
};
|
||||
|
||||
inline ThrowCompletionOr<Value> DeclarativeEnvironment::get_binding_value_direct(VM& vm, size_t index) const
|
||||
{
|
||||
return get_binding_value_direct(vm, m_bindings[index]);
|
||||
}
|
||||
|
||||
inline ThrowCompletionOr<Value> DeclarativeEnvironment::get_binding_value_direct(VM&, Binding const& binding) const
|
||||
{
|
||||
// 2. If the binding for N in envRec is an uninitialized binding, throw a ReferenceError exception.
|
||||
if (!binding.initialized)
|
||||
return vm().throw_completion<ReferenceError>(ErrorType::BindingNotInitialized, binding.name);
|
||||
|
||||
// 3. Return the value currently bound to N in envRec.
|
||||
return binding.value;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool Environment::fast_is<DeclarativeEnvironment>() const { return is_declarative_environment(); }
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ ThrowCompletionOr<Value> GlobalEnvironment::get_binding_value(VM& vm, Deprecated
|
||||
if (MUST(m_declarative_record->has_binding(name, &index))) {
|
||||
// a. Return ? DclRec.GetBindingValue(N, S).
|
||||
if (index.has_value())
|
||||
return m_declarative_record->get_binding_value_direct(vm, index.value(), strict);
|
||||
return m_declarative_record->get_binding_value_direct(vm, index.value());
|
||||
return m_declarative_record->get_binding_value(vm, name, strict);
|
||||
}
|
||||
|
||||
|
||||
@@ -142,7 +142,7 @@ ThrowCompletionOr<Value> Reference::get_value(VM& vm) const
|
||||
|
||||
// c. Return ? base.GetBindingValue(V.[[ReferencedName]], V.[[Strict]]) (see 9.1).
|
||||
if (m_environment_coordinate.has_value())
|
||||
return static_cast<DeclarativeEnvironment*>(m_base_environment)->get_binding_value_direct(vm, m_environment_coordinate->index, m_strict);
|
||||
return static_cast<DeclarativeEnvironment*>(m_base_environment)->get_binding_value_direct(vm, m_environment_coordinate->index);
|
||||
return m_base_environment->get_binding_value(vm, m_name.as_string(), m_strict);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user