mirror of
https://github.com/fergalmoran/ladybird.git
synced 2026-01-06 08:36:15 +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 {};
|
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 {
|
struct CalleeAndThis {
|
||||||
Value callee;
|
Value callee;
|
||||||
Value this_value;
|
Value this_value;
|
||||||
@@ -558,13 +536,11 @@ inline ThrowCompletionOr<CalleeAndThis> get_callee_and_this_from_environment(Byt
|
|||||||
Value this_value = js_undefined();
|
Value this_value = js_undefined();
|
||||||
|
|
||||||
if (cache.has_value()) {
|
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)
|
for (size_t i = 0; i < cache->hops; ++i)
|
||||||
environment = environment->outer_environment();
|
environment = environment->outer_environment();
|
||||||
VERIFY(environment);
|
|
||||||
VERIFY(environment->is_declarative_environment());
|
|
||||||
if (!environment->is_permanently_screwed_by_eval()) {
|
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();
|
this_value = js_undefined();
|
||||||
if (auto base_object = environment->with_base_object())
|
if (auto base_object = environment->with_base_object())
|
||||||
this_value = 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
|
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 {};
|
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
|
// 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.
|
// 1. Assert: envRec has a binding for N.
|
||||||
auto binding_and_index = find_binding_and_index(name);
|
auto binding_and_index = find_binding_and_index(name);
|
||||||
VERIFY(binding_and_index.has_value());
|
VERIFY(binding_and_index.has_value());
|
||||||
|
|
||||||
// 2-3. (extracted into a non-standard function below)
|
// 2-3. (extracted into a non-standard function below)
|
||||||
return get_binding_value_direct(vm, binding_and_index->binding(), strict);
|
return get_binding_value_direct(vm, binding_and_index->binding());
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9.1.1.1.7 DeleteBinding ( N ), https://tc39.es/ecma262/#sec-declarative-environment-records-deletebinding-n
|
// 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<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();
|
void shrink_to_fit();
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ public:
|
|||||||
[[nodiscard]] u64 environment_serial_number() const { return m_environment_serial_number; }
|
[[nodiscard]] u64 environment_serial_number() const { return m_environment_serial_number; }
|
||||||
|
|
||||||
private:
|
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);
|
ThrowCompletionOr<void> set_mutable_binding_direct(VM&, Binding&, Value, bool strict);
|
||||||
|
|
||||||
friend Completion dispose_resources(VM&, GCPtr<DeclarativeEnvironment>, Completion);
|
friend Completion dispose_resources(VM&, GCPtr<DeclarativeEnvironment>, Completion);
|
||||||
@@ -131,6 +131,21 @@ private:
|
|||||||
u64 m_environment_serial_number { 0 };
|
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<>
|
template<>
|
||||||
inline bool Environment::fast_is<DeclarativeEnvironment>() const { return is_declarative_environment(); }
|
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))) {
|
if (MUST(m_declarative_record->has_binding(name, &index))) {
|
||||||
// a. Return ? DclRec.GetBindingValue(N, S).
|
// a. Return ? DclRec.GetBindingValue(N, S).
|
||||||
if (index.has_value())
|
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);
|
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).
|
// c. Return ? base.GetBindingValue(V.[[ReferencedName]], V.[[Strict]]) (see 9.1).
|
||||||
if (m_environment_coordinate.has_value())
|
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);
|
return m_base_environment->get_binding_value(vm, m_name.as_string(), m_strict);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user