summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordavidot <davidot@serenityos.org>2022-01-17 14:48:22 +0100
committerLinus Groh <mail@linusgroh.de>2022-01-22 01:21:18 +0000
commit57c5a59cab1742f8dd9c66895b164665fd6d79de (patch)
tree39c623c3580274a1afcfdab0ef5110e97fa2d24c
parent99edf5b25a6df0f2f9b4d809f5de7a8d73bd6556 (diff)
downloadserenity-57c5a59cab1742f8dd9c66895b164665fd6d79de.zip
LibJS: Add ScriptOrModule to execution context and track it everywhere
-rw-r--r--Userland/Libraries/LibJS/Forward.h2
-rw-r--r--Userland/Libraries/LibJS/Interpreter.cpp3
-rw-r--r--Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp9
-rw-r--r--Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h1
-rw-r--r--Userland/Libraries/LibJS/Runtime/ExecutionContext.h4
-rw-r--r--Userland/Libraries/LibJS/Runtime/NativeFunction.cpp4
-rw-r--r--Userland/Libraries/LibJS/Runtime/ShadowRealm.cpp2
-rw-r--r--Userland/Libraries/LibJS/Runtime/ShadowRealmConstructor.cpp2
-rw-r--r--Userland/Libraries/LibJS/Runtime/VM.cpp19
-rw-r--r--Userland/Libraries/LibJS/Runtime/VM.h2
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<Value> 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<void> 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<Statement> 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<Empty, Script*, Module*>;
+
// 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<Value> 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<Object*> 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<Value> 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<Object*> 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<Empty>())
+ 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<CustomData>);