diff options
author | Linus Groh <mail@linusgroh.de> | 2021-09-11 21:42:01 +0100 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2021-09-12 11:10:20 +0100 |
commit | 06e89311fa0d09ac0b0a6bf4ea9b75773ac5d2df (patch) | |
tree | 60bb92eb4900fc2a752713fbb8a5c99fa0dfa268 /Userland/Libraries/LibJS | |
parent | 332946ab4f77a16de6be7f9148817938c00e7ddd (diff) | |
download | serenity-06e89311fa0d09ac0b0a6bf4ea9b75773ac5d2df.zip |
LibJS: Set the callee context's realm in prepare_for_ordinary_call()
This includes making FunctionObject::realm() actually return a Realm,
instead of a GlobalObject.
Diffstat (limited to 'Userland/Libraries/LibJS')
8 files changed, 31 insertions, 11 deletions
diff --git a/Userland/Libraries/LibJS/Interpreter.cpp b/Userland/Libraries/LibJS/Interpreter.cpp index 8747138d96..06cdadabc3 100644 --- a/Userland/Libraries/LibJS/Interpreter.cpp +++ b/Userland/Libraries/LibJS/Interpreter.cpp @@ -53,7 +53,7 @@ void Interpreter::run(GlobalObject& global_object, const Program& program) execution_context.function_name = global_execution_context_name; execution_context.lexical_environment = &realm().global_environment(); execution_context.variable_environment = &realm().global_environment(); - VERIFY(!vm.exception()); + execution_context.realm = &realm(); execution_context.is_strict_mode = program.is_strict_mode(); vm.push_execution_context(execution_context, global_object); VERIFY(!vm.exception()); diff --git a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp index dcf28a1cbb..640325a1d2 100644 --- a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp +++ b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp @@ -118,7 +118,7 @@ GlobalObject* get_function_realm(GlobalObject& global_object, FunctionObject con // 2. If obj has a [[Realm]] internal slot, then if (function.realm()) { // a. Return obj.[[Realm]]. - return function.realm(); + return &function.global_object(); } // 3. If obj is a bound function exotic object, then diff --git a/Userland/Libraries/LibJS/Runtime/FunctionObject.h b/Userland/Libraries/LibJS/Runtime/FunctionObject.h index 3cfa762166..dce1c3ea99 100644 --- a/Userland/Libraries/LibJS/Runtime/FunctionObject.h +++ b/Userland/Libraries/LibJS/Runtime/FunctionObject.h @@ -11,6 +11,7 @@ namespace JS { +// 10.2 ECMAScript Function Objects, https://tc39.es/ecma262/#sec-ecmascript-function-objects class FunctionObject : public Object { JS_OBJECT(Function, Object); @@ -48,7 +49,7 @@ public: virtual Environment* environment() { return nullptr; } // [[Realm]] - virtual GlobalObject* realm() const { return nullptr; } + virtual Realm* realm() const { return nullptr; } enum class ThisMode : u8 { Lexical, diff --git a/Userland/Libraries/LibJS/Runtime/NativeFunction.cpp b/Userland/Libraries/LibJS/Runtime/NativeFunction.cpp index 83cd77f247..e784d3aa97 100644 --- a/Userland/Libraries/LibJS/Runtime/NativeFunction.cpp +++ b/Userland/Libraries/LibJS/Runtime/NativeFunction.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include <LibJS/Interpreter.h> #include <LibJS/Runtime/GlobalObject.h> #include <LibJS/Runtime/NativeFunction.h> #include <LibJS/Runtime/Value.h> @@ -15,8 +16,13 @@ NativeFunction* NativeFunction::create(GlobalObject& global_object, const FlyStr return global_object.heap().allocate<NativeFunction>(global_object, name, move(function), *global_object.function_prototype()); } +// FIXME: m_realm is supposed to be the realm argument of CreateBuiltinFunction, or the current +// Realm Record. The former is not something that's commonly used or we support, the +// latter is impossible as no ExecutionContext exists when most NativeFunctions are created... + NativeFunction::NativeFunction(Object& prototype) : FunctionObject(prototype) + , m_realm(&vm().interpreter().realm()) { } @@ -24,12 +30,14 @@ NativeFunction::NativeFunction(FlyString name, Function<Value(VM&, GlobalObject& : FunctionObject(prototype) , m_name(move(name)) , m_native_function(move(native_function)) + , m_realm(&vm().interpreter().realm()) { } NativeFunction::NativeFunction(FlyString name, Object& prototype) : FunctionObject(prototype) , m_name(move(name)) + , m_realm(&vm().interpreter().realm()) { } diff --git a/Userland/Libraries/LibJS/Runtime/NativeFunction.h b/Userland/Libraries/LibJS/Runtime/NativeFunction.h index 0f88bcf24d..e84b4ef1fc 100644 --- a/Userland/Libraries/LibJS/Runtime/NativeFunction.h +++ b/Userland/Libraries/LibJS/Runtime/NativeFunction.h @@ -29,7 +29,7 @@ public: virtual bool is_strict_mode() const override; - GlobalObject* realm() const override { return &global_object(); } + virtual Realm* realm() const override { return m_realm; } protected: NativeFunction(FlyString name, Object& prototype); @@ -41,6 +41,7 @@ private: FlyString m_name; Function<Value(VM&, GlobalObject&)> m_native_function; + Realm* m_realm { nullptr }; }; template<> diff --git a/Userland/Libraries/LibJS/Runtime/OrdinaryFunctionObject.cpp b/Userland/Libraries/LibJS/Runtime/OrdinaryFunctionObject.cpp index 3e784aa6e4..ad6ca49c72 100644 --- a/Userland/Libraries/LibJS/Runtime/OrdinaryFunctionObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/OrdinaryFunctionObject.cpp @@ -43,7 +43,7 @@ OrdinaryFunctionObject::OrdinaryFunctionObject(GlobalObject& global_object, cons , m_body(body) , m_parameters(move(parameters)) , m_environment(parent_scope) - , m_realm(&global_object) + , m_realm(vm().current_realm()) , m_function_length(function_length) , m_kind(kind) , m_is_strict(is_strict) diff --git a/Userland/Libraries/LibJS/Runtime/OrdinaryFunctionObject.h b/Userland/Libraries/LibJS/Runtime/OrdinaryFunctionObject.h index b310d5697a..4b0a782844 100644 --- a/Userland/Libraries/LibJS/Runtime/OrdinaryFunctionObject.h +++ b/Userland/Libraries/LibJS/Runtime/OrdinaryFunctionObject.h @@ -36,8 +36,7 @@ public: auto& bytecode_executable() const { return m_bytecode_executable; } virtual Environment* environment() override { return m_environment; } - - GlobalObject* realm() const override { return m_realm; } + virtual Realm* realm() const override { return m_realm; } protected: virtual bool is_strict_mode() const final { return m_is_strict; } @@ -54,7 +53,7 @@ private: const Vector<FunctionNode::Parameter> m_parameters; Optional<Bytecode::Executable> m_bytecode_executable; Environment* m_environment { nullptr }; - GlobalObject* m_realm { nullptr }; + Realm* m_realm { nullptr }; i32 m_function_length { 0 }; FunctionKind m_kind { FunctionKind::Regular }; bool m_is_strict { false }; diff --git a/Userland/Libraries/LibJS/Runtime/VM.cpp b/Userland/Libraries/LibJS/Runtime/VM.cpp index f1eafba843..9bbbce248b 100644 --- a/Userland/Libraries/LibJS/Runtime/VM.cpp +++ b/Userland/Libraries/LibJS/Runtime/VM.cpp @@ -479,6 +479,8 @@ Value VM::construct(FunctionObject& function, FunctionObject& new_target, Option return {}; } + // FIXME: prepare_for_ordinary_call() is not supposed to receive a BoundFunction, ProxyObject, etc. - ever. + // This needs to be moved to NativeFunction/OrdinaryFunctionObject's construct() (10.2.2 [[Construct]]) ExecutionContext callee_context(heap()); prepare_for_ordinary_call(function, callee_context, &new_target); if (exception()) @@ -597,9 +599,17 @@ void VM::prepare_for_ordinary_call(FunctionObject& function, ExecutionContext& c callee_context.function_name = function.name(); // 4. Let calleeRealm be F.[[Realm]]. + auto* callee_realm = function.realm(); + // FIXME: See FIXME in VM::call_internal() / VM::construct(). + if (!callee_realm) + callee_realm = current_realm(); + VERIFY(callee_realm); + // 5. Set the Realm of calleeContext to calleeRealm. + callee_context.realm = callee_realm; + // 6. Set the ScriptOrModule of calleeContext to F.[[ScriptOrModule]]. - // FIXME: Our execution context struct currently does not track these items. + // FIXME: Our execution context struct currently does not track this item. // 7. Let localEnv be NewFunctionEnvironment(F, newTarget). // FIXME: This should call NewFunctionEnvironment instead of the ad-hoc FunctionObject::create_environment() @@ -643,8 +653,7 @@ void VM::ordinary_call_bind_this(FunctionObject& function, ExecutionContext& cal if (function.is_strict_mode()) { this_value = this_argument; } else if (this_argument.is_nullish()) { - // FIXME: Make function.realm() an actual Realm, then this will become less horrendous. - auto& global_environment = interpreter().realm().global_environment(); + auto& global_environment = callee_realm->global_environment(); this_value = &global_environment.global_this_value(); } else { this_value = this_argument.to_object(function.global_object()); @@ -668,6 +677,8 @@ Value VM::call_internal(FunctionObject& function, Value this_value, Optional<Mar return call_internal(bound_function.target_function(), bound_function.bound_this(), move(with_bound_arguments)); } + // FIXME: prepare_for_ordinary_call() is not supposed to receive a BoundFunction, ProxyObject, etc. - ever. + // This needs to be moved to NativeFunction/OrdinaryFunctionObject's construct() (10.2.2 [[Construct]]) ExecutionContext callee_context(heap()); prepare_for_ordinary_call(function, callee_context, nullptr); if (exception()) |