LibJS: Store Module::environment() as ModuleEnvironment

Let's use a more specific type here to allow for devirtualization.
This commit is contained in:
Andreas Kling 2025-03-16 17:41:24 -05:00 committed by Andreas Kling
commit 8fcff2fa18
Notes: github-actions[bot] 2025-03-20 17:52:55 +00:00
6 changed files with 16 additions and 13 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021-2024, Andreas Kling <andreas@ladybird.org>
* Copyright (c) 2021-2025, Andreas Kling <andreas@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -26,6 +26,7 @@
#include <LibJS/Runtime/GlobalObject.h>
#include <LibJS/Runtime/Iterator.h>
#include <LibJS/Runtime/MathObject.h>
#include <LibJS/Runtime/ModuleEnvironment.h>
#include <LibJS/Runtime/NativeFunction.h>
#include <LibJS/Runtime/ObjectEnvironment.h>
#include <LibJS/Runtime/Realm.h>
@ -1132,10 +1133,10 @@ inline ThrowCompletionOr<Value> get_global(Interpreter& interpreter, IdentifierT
auto& identifier = interpreter.current_executable().get_identifier(identifier_index);
if (vm.running_execution_context().script_or_module.has<GC::Ref<Module>>()) {
if (auto* module = vm.running_execution_context().script_or_module.get_pointer<GC::Ref<Module>>()) {
// NOTE: GetGlobal is used to access variables stored in the module environment and global environment.
// The module environment is checked first since it precedes the global environment in the environment chain.
auto& module_environment = *vm.running_execution_context().script_or_module.get<GC::Ref<Module>>()->environment();
auto& module_environment = *(*module)->environment();
if (TRY(module_environment.has_binding(identifier))) {
// TODO: Cache offset of binding value
return TRY(module_environment.get_binding_value(vm, identifier, vm.in_strict_mode()));

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2021, Andreas Kling <andreas@ladybird.org>
* Copyright (c) 2020-2025, Andreas Kling <andreas@ladybird.org>
* Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
@ -189,6 +189,7 @@ class Intrinsics;
class IteratorRecord;
class MemberExpression;
class MetaProperty;
class ModuleEnvironment;
class Module;
struct ModuleRequest;
class NativeFunction;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, Andreas Kling <andreas@ladybird.org>
* Copyright (c) 2021-2025, Andreas Kling <andreas@ladybird.org>
* Copyright (c) 2022, David Tuin <davidot@serenityos.org>
* Copyright (c) 2023, networkException <networkexception@serenityos.org>
*
@ -8,6 +8,7 @@
#include <LibJS/CyclicModule.h>
#include <LibJS/Module.h>
#include <LibJS/Runtime/ModuleEnvironment.h>
#include <LibJS/Runtime/ModuleNamespaceObject.h>
#include <LibJS/Runtime/ModuleRequest.h>
#include <LibJS/Runtime/Promise.h>

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, Andreas Kling <andreas@ladybird.org>
* Copyright (c) 2021-2025, Andreas Kling <andreas@ladybird.org>
* Copyright (c) 2022, David Tuin <davidot@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
@ -100,7 +100,7 @@ public:
StringView filename() const { return m_filename; }
Environment* environment() { return m_environment; }
GC::Ptr<ModuleEnvironment> environment() { return m_environment; }
Script::HostDefined* host_defined() const { return m_host_defined; }
@ -122,7 +122,7 @@ protected:
virtual void visit_edges(Cell::Visitor&) override;
void set_environment(Environment* environment)
void set_environment(GC::Ref<ModuleEnvironment> environment)
{
m_environment = environment;
}
@ -136,7 +136,7 @@ private:
// stores modules with a RefPtr we cannot just store the VM as that leads to
// cycles.
GC::Ptr<Realm> m_realm; // [[Realm]]
GC::Ptr<Environment> m_environment; // [[Environment]]
GC::Ptr<ModuleEnvironment> m_environment; // [[Environment]]
GC::Ptr<Object> m_namespace; // [[Namespace]]
Script::HostDefined* m_host_defined { nullptr }; // [[HostDefined]]

View file

@ -34,7 +34,7 @@ ThrowCompletionOr<Value> ModuleEnvironment::get_binding_value(VM& vm, Deprecated
// a. Let M and N2 be the indirection values provided when this binding for N was created.
// b. Let targetEnv be M.[[Environment]].
auto* target_env = indirect_binding->module->environment();
auto target_env = indirect_binding->module->environment();
// c. If targetEnv is empty, throw a ReferenceError exception.
if (!target_env)
@ -97,11 +97,10 @@ Optional<ModuleEnvironment::BindingAndIndex> ModuleEnvironment::find_binding_and
{
auto* indirect_binding = get_indirect_binding(name);
if (indirect_binding != nullptr) {
auto* target_env = indirect_binding->module->environment();
auto target_env = indirect_binding->module->environment();
if (!target_env)
return {};
VERIFY(is<ModuleEnvironment>(target_env));
auto& target_module_environment = static_cast<ModuleEnvironment&>(*target_env);
auto result = target_module_environment.find_binding_and_index(indirect_binding->binding_name);
if (!result.has_value())

View file

@ -6,6 +6,7 @@
#include <AK/QuickSort.h>
#include <LibJS/Runtime/GlobalObject.h>
#include <LibJS/Runtime/ModuleEnvironment.h>
#include <LibJS/Runtime/ModuleNamespaceObject.h>
namespace JS {
@ -173,7 +174,7 @@ ThrowCompletionOr<Value> ModuleNamespaceObject::internal_get(PropertyKey const&
}
// 10. Let targetEnv be targetModule.[[Environment]].
auto* target_environment = target_module->environment();
auto target_environment = target_module->environment();
// 11. If targetEnv is empty, throw a ReferenceError exception.
if (!target_environment)