From 57c5a59cab1742f8dd9c66895b164665fd6d79de Mon Sep 17 00:00:00 2001 From: davidot Date: Mon, 17 Jan 2022 14:48:22 +0100 Subject: LibJS: Add ScriptOrModule to execution context and track it everywhere --- Userland/Libraries/LibJS/Forward.h | 2 ++ Userland/Libraries/LibJS/Interpreter.cpp | 3 ++- .../LibJS/Runtime/ECMAScriptFunctionObject.cpp | 9 ++++++++- .../LibJS/Runtime/ECMAScriptFunctionObject.h | 1 + Userland/Libraries/LibJS/Runtime/ExecutionContext.h | 4 ++++ Userland/Libraries/LibJS/Runtime/NativeFunction.cpp | 4 ++-- Userland/Libraries/LibJS/Runtime/ShadowRealm.cpp | 2 +- .../LibJS/Runtime/ShadowRealmConstructor.cpp | 2 +- Userland/Libraries/LibJS/Runtime/VM.cpp | 19 +++++++++++++++++++ Userland/Libraries/LibJS/Runtime/VM.h | 2 ++ 10 files changed, 42 insertions(+), 6 deletions(-) diff --git a/Userland/Libraries/LibJS/Forward.h b/Userland/Libraries/LibJS/Forward.h index 2e002917a5..a7d61fad31 100644 --- a/Userland/Libraries/LibJS/Forward.h +++ b/Userland/Libraries/LibJS/Forward.h @@ -153,6 +153,7 @@ class Heap; class HeapBlock; class Interpreter; class MarkedValueList; +class Module; class NativeFunction; class ObjectEnvironment; class PrimitiveString; @@ -165,6 +166,7 @@ class PropertyKey; class Realm; class Reference; class ScopeNode; +class Script; class Shape; class Statement; class StringOrSymbol; diff --git a/Userland/Libraries/LibJS/Interpreter.cpp b/Userland/Libraries/LibJS/Interpreter.cpp index af08e232c1..1aee2a2444 100644 --- a/Userland/Libraries/LibJS/Interpreter.cpp +++ b/Userland/Libraries/LibJS/Interpreter.cpp @@ -62,7 +62,8 @@ ThrowCompletionOr Interpreter::run(Script& script_record) // 4. Set the Realm of scriptContext to scriptRecord.[[Realm]]. script_context.realm = &script_record.realm(); - // FIXME: 5. Set the ScriptOrModule of scriptContext to scriptRecord. + // 5. Set the ScriptOrModule of scriptContext to scriptRecord. + script_context.script_or_module = &script_record; // 6. Set the VariableEnvironment of scriptContext to globalEnv. script_context.variable_environment = &global_environment; diff --git a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp index 73ef6e4375..32d0102939 100644 --- a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp @@ -71,13 +71,20 @@ ECMAScriptFunctionObject::ECMAScriptFunctionObject(FlyString name, String source , m_is_arrow_function(is_arrow_function) { // NOTE: This logic is from OrdinaryFunctionCreate, https://tc39.es/ecma262/#sec-ordinaryfunctioncreate + + // 9. If thisMode is lexical-this, set F.[[ThisMode]] to lexical. if (m_is_arrow_function) m_this_mode = ThisMode::Lexical; + // 10. Else if Strict is true, set F.[[ThisMode]] to strict. else if (m_strict) m_this_mode = ThisMode::Strict; else + // 11. Else, set F.[[ThisMode]] to global. m_this_mode = ThisMode::Global; + // 15. Set F.[[ScriptOrModule]] to GetActiveScriptOrModule(). + m_script_or_module = vm().get_active_script_or_module(); + // 15.1.3 Static Semantics: IsSimpleParameterList, https://tc39.es/ecma262/#sec-static-semantics-issimpleparameterlist m_has_simple_parameter_list = all_of(m_formal_parameters, [&](auto& parameter) { if (parameter.is_rest) @@ -595,7 +602,7 @@ ThrowCompletionOr ECMAScriptFunctionObject::prepare_for_ordinary_call(Exec callee_context.realm = callee_realm; // 6. Set the ScriptOrModule of calleeContext to F.[[ScriptOrModule]]. - // FIXME: Our execution context struct currently does not track this item. + callee_context.script_or_module = m_script_or_module; // 7. Let localEnv be NewFunctionEnvironment(F, newTarget). auto* local_environment = new_function_environment(*this, new_target); diff --git a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h index cd2cfb7549..5fed81ebff 100644 --- a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h +++ b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h @@ -109,6 +109,7 @@ private: NonnullRefPtr m_ecmascript_code; // [[ECMAScriptCode]] ConstructorKind m_constructor_kind { ConstructorKind::Base }; // [[ConstructorKind]] Realm* m_realm { nullptr }; // [[Realm]] + ScriptOrModule m_script_or_module; // [[ScriptOrModule]] ThisMode m_this_mode { ThisMode::Global }; // [[ThisMode]] bool m_strict { false }; // [[Strict]] Object* m_home_object { nullptr }; // [[HomeObject]] diff --git a/Userland/Libraries/LibJS/Runtime/ExecutionContext.h b/Userland/Libraries/LibJS/Runtime/ExecutionContext.h index a8a4ecaf41..8f247666ca 100644 --- a/Userland/Libraries/LibJS/Runtime/ExecutionContext.h +++ b/Userland/Libraries/LibJS/Runtime/ExecutionContext.h @@ -15,6 +15,8 @@ namespace JS { +using ScriptOrModule = Variant; + // 9.4 Execution Contexts, https://tc39.es/ecma262/#sec-execution-contexts struct ExecutionContext { explicit ExecutionContext(Heap& heap) @@ -28,6 +30,7 @@ struct ExecutionContext { copy.function = function; copy.realm = realm; + copy.script_or_module = script_or_module; copy.lexical_environment = lexical_environment; copy.variable_environment = variable_environment; copy.private_environment = private_environment; @@ -48,6 +51,7 @@ private: public: FunctionObject* function { nullptr }; // [[Function]] Realm* realm { nullptr }; // [[Realm]] + ScriptOrModule script_or_module; // [[ScriptOrModule]] Environment* lexical_environment { nullptr }; // [[LexicalEnvironment]] Environment* variable_environment { nullptr }; // [[VariableEnvironment]] PrivateEnvironment* private_environment { nullptr }; // [[PrivateEnvironment]] diff --git a/Userland/Libraries/LibJS/Runtime/NativeFunction.cpp b/Userland/Libraries/LibJS/Runtime/NativeFunction.cpp index cd719737ec..910fadadfd 100644 --- a/Userland/Libraries/LibJS/Runtime/NativeFunction.cpp +++ b/Userland/Libraries/LibJS/Runtime/NativeFunction.cpp @@ -85,7 +85,7 @@ ThrowCompletionOr NativeFunction::internal_call(Value this_argument, Mark callee_context.realm = callee_realm; // 7. Set the ScriptOrModule of calleeContext to null. - // FIXME: Our execution context struct currently does not track this item. + // Note: This is already the default value. // 8. Perform any necessary implementation-defined initialization of calleeContext. @@ -150,7 +150,7 @@ ThrowCompletionOr NativeFunction::internal_construct(MarkedValueList ar callee_context.realm = callee_realm; // 7. Set the ScriptOrModule of calleeContext to null. - // FIXME: Our execution context struct currently does not track this item. + // Note: This is already the default value. // 8. Perform any necessary implementation-defined initialization of calleeContext. diff --git a/Userland/Libraries/LibJS/Runtime/ShadowRealm.cpp b/Userland/Libraries/LibJS/Runtime/ShadowRealm.cpp index 211a842e9d..ed9086a572 100644 --- a/Userland/Libraries/LibJS/Runtime/ShadowRealm.cpp +++ b/Userland/Libraries/LibJS/Runtime/ShadowRealm.cpp @@ -93,7 +93,7 @@ ThrowCompletionOr perform_shadow_realm_eval(GlobalObject& global_object, eval_context.realm = &eval_realm; // 15. Set evalContext's ScriptOrModule to null. - // FIXME: Our execution context struct currently does not track this item. + // Note: This is already the default value. // 16. Set evalContext's VariableEnvironment to varEnv. eval_context.variable_environment = variable_environment; diff --git a/Userland/Libraries/LibJS/Runtime/ShadowRealmConstructor.cpp b/Userland/Libraries/LibJS/Runtime/ShadowRealmConstructor.cpp index cd8da12739..ecfbe393f9 100644 --- a/Userland/Libraries/LibJS/Runtime/ShadowRealmConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/ShadowRealmConstructor.cpp @@ -55,7 +55,7 @@ ThrowCompletionOr ShadowRealmConstructor::construct(FunctionObject& new context.realm = realm; // 8. Set the ScriptOrModule of context to null. - // FIXME: Our execution context struct currently does not track this item. + // Note: This is already the default value. // 2. Let O be ? OrdinaryCreateFromConstructor(NewTarget, "%ShadowRealm.prototype%", « [[ShadowRealm]], [[ExecutionContext]] »). // 4. Set O.[[ShadowRealm]] to realmRec. diff --git a/Userland/Libraries/LibJS/Runtime/VM.cpp b/Userland/Libraries/LibJS/Runtime/VM.cpp index 16f0982ad8..92b9417f90 100644 --- a/Userland/Libraries/LibJS/Runtime/VM.cpp +++ b/Userland/Libraries/LibJS/Runtime/VM.cpp @@ -663,4 +663,23 @@ void VM::restore_execution_context_stack() m_execution_context_stack = m_saved_execution_context_stacks.take_last(); } +// 9.4.1 GetActiveScriptOrModule ( ), https://tc39.es/ecma262/#sec-getactivescriptormodule +ScriptOrModule VM::get_active_script_or_module() const +{ + // 1. If the execution context stack is empty, return null. + if (m_execution_context_stack.is_empty()) + return Empty {}; + + // 2. Let ec be the topmost execution context on the execution context stack whose ScriptOrModule component is not null. + for (auto i = m_execution_context_stack.size() - 1; i > 0; i--) { + if (!m_execution_context_stack[i]->script_or_module.has()) + return m_execution_context_stack[i]->script_or_module; + } + + // 3. If no such execution context exists, return null. Otherwise, return ec's ScriptOrModule. + // Note: Since it is not empty we have 0 and since we got here all the + // above contexts don't have a non-null ScriptOrModule + return m_execution_context_stack[0]->script_or_module; +} + } diff --git a/Userland/Libraries/LibJS/Runtime/VM.h b/Userland/Libraries/LibJS/Runtime/VM.h index 6e420415e5..efc02f16d0 100644 --- a/Userland/Libraries/LibJS/Runtime/VM.h +++ b/Userland/Libraries/LibJS/Runtime/VM.h @@ -239,6 +239,8 @@ public: void save_execution_context_stack(); void restore_execution_context_stack(); + ScriptOrModule get_active_script_or_module() const; + private: explicit VM(OwnPtr); -- cgit v1.2.3