1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 08:08:12 +00:00

LibJS: Add ScriptOrModule to execution context and track it everywhere

This commit is contained in:
davidot 2022-01-17 14:48:22 +01:00 committed by Linus Groh
parent 99edf5b25a
commit 57c5a59cab
10 changed files with 42 additions and 6 deletions

View file

@ -153,6 +153,7 @@ class Heap;
class HeapBlock; class HeapBlock;
class Interpreter; class Interpreter;
class MarkedValueList; class MarkedValueList;
class Module;
class NativeFunction; class NativeFunction;
class ObjectEnvironment; class ObjectEnvironment;
class PrimitiveString; class PrimitiveString;
@ -165,6 +166,7 @@ class PropertyKey;
class Realm; class Realm;
class Reference; class Reference;
class ScopeNode; class ScopeNode;
class Script;
class Shape; class Shape;
class Statement; class Statement;
class StringOrSymbol; class StringOrSymbol;

View file

@ -62,7 +62,8 @@ ThrowCompletionOr<Value> Interpreter::run(Script& script_record)
// 4. Set the Realm of scriptContext to scriptRecord.[[Realm]]. // 4. Set the Realm of scriptContext to scriptRecord.[[Realm]].
script_context.realm = &script_record.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. // 6. Set the VariableEnvironment of scriptContext to globalEnv.
script_context.variable_environment = &global_environment; script_context.variable_environment = &global_environment;

View file

@ -71,13 +71,20 @@ ECMAScriptFunctionObject::ECMAScriptFunctionObject(FlyString name, String source
, m_is_arrow_function(is_arrow_function) , m_is_arrow_function(is_arrow_function)
{ {
// NOTE: This logic is from OrdinaryFunctionCreate, https://tc39.es/ecma262/#sec-ordinaryfunctioncreate // 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) if (m_is_arrow_function)
m_this_mode = ThisMode::Lexical; m_this_mode = ThisMode::Lexical;
// 10. Else if Strict is true, set F.[[ThisMode]] to strict.
else if (m_strict) else if (m_strict)
m_this_mode = ThisMode::Strict; m_this_mode = ThisMode::Strict;
else else
// 11. Else, set F.[[ThisMode]] to global.
m_this_mode = ThisMode::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 // 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) { m_has_simple_parameter_list = all_of(m_formal_parameters, [&](auto& parameter) {
if (parameter.is_rest) if (parameter.is_rest)
@ -595,7 +602,7 @@ ThrowCompletionOr<void> ECMAScriptFunctionObject::prepare_for_ordinary_call(Exec
callee_context.realm = callee_realm; callee_context.realm = callee_realm;
// 6. Set the ScriptOrModule of calleeContext to F.[[ScriptOrModule]]. // 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). // 7. Let localEnv be NewFunctionEnvironment(F, newTarget).
auto* local_environment = new_function_environment(*this, new_target); auto* local_environment = new_function_environment(*this, new_target);

View file

@ -109,6 +109,7 @@ private:
NonnullRefPtr<Statement> m_ecmascript_code; // [[ECMAScriptCode]] NonnullRefPtr<Statement> m_ecmascript_code; // [[ECMAScriptCode]]
ConstructorKind m_constructor_kind { ConstructorKind::Base }; // [[ConstructorKind]] ConstructorKind m_constructor_kind { ConstructorKind::Base }; // [[ConstructorKind]]
Realm* m_realm { nullptr }; // [[Realm]] Realm* m_realm { nullptr }; // [[Realm]]
ScriptOrModule m_script_or_module; // [[ScriptOrModule]]
ThisMode m_this_mode { ThisMode::Global }; // [[ThisMode]] ThisMode m_this_mode { ThisMode::Global }; // [[ThisMode]]
bool m_strict { false }; // [[Strict]] bool m_strict { false }; // [[Strict]]
Object* m_home_object { nullptr }; // [[HomeObject]] Object* m_home_object { nullptr }; // [[HomeObject]]

View file

@ -15,6 +15,8 @@
namespace JS { namespace JS {
using ScriptOrModule = Variant<Empty, Script*, Module*>;
// 9.4 Execution Contexts, https://tc39.es/ecma262/#sec-execution-contexts // 9.4 Execution Contexts, https://tc39.es/ecma262/#sec-execution-contexts
struct ExecutionContext { struct ExecutionContext {
explicit ExecutionContext(Heap& heap) explicit ExecutionContext(Heap& heap)
@ -28,6 +30,7 @@ struct ExecutionContext {
copy.function = function; copy.function = function;
copy.realm = realm; copy.realm = realm;
copy.script_or_module = script_or_module;
copy.lexical_environment = lexical_environment; copy.lexical_environment = lexical_environment;
copy.variable_environment = variable_environment; copy.variable_environment = variable_environment;
copy.private_environment = private_environment; copy.private_environment = private_environment;
@ -48,6 +51,7 @@ private:
public: public:
FunctionObject* function { nullptr }; // [[Function]] FunctionObject* function { nullptr }; // [[Function]]
Realm* realm { nullptr }; // [[Realm]] Realm* realm { nullptr }; // [[Realm]]
ScriptOrModule script_or_module; // [[ScriptOrModule]]
Environment* lexical_environment { nullptr }; // [[LexicalEnvironment]] Environment* lexical_environment { nullptr }; // [[LexicalEnvironment]]
Environment* variable_environment { nullptr }; // [[VariableEnvironment]] Environment* variable_environment { nullptr }; // [[VariableEnvironment]]
PrivateEnvironment* private_environment { nullptr }; // [[PrivateEnvironment]] PrivateEnvironment* private_environment { nullptr }; // [[PrivateEnvironment]]

View file

@ -85,7 +85,7 @@ ThrowCompletionOr<Value> NativeFunction::internal_call(Value this_argument, Mark
callee_context.realm = callee_realm; callee_context.realm = callee_realm;
// 7. Set the ScriptOrModule of calleeContext to null. // 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. // 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; callee_context.realm = callee_realm;
// 7. Set the ScriptOrModule of calleeContext to null. // 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. // 8. Perform any necessary implementation-defined initialization of calleeContext.

View file

@ -93,7 +93,7 @@ ThrowCompletionOr<Value> perform_shadow_realm_eval(GlobalObject& global_object,
eval_context.realm = &eval_realm; eval_context.realm = &eval_realm;
// 15. Set evalContext's ScriptOrModule to null. // 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. // 16. Set evalContext's VariableEnvironment to varEnv.
eval_context.variable_environment = variable_environment; eval_context.variable_environment = variable_environment;

View file

@ -55,7 +55,7 @@ ThrowCompletionOr<Object*> ShadowRealmConstructor::construct(FunctionObject& new
context.realm = realm; context.realm = realm;
// 8. Set the ScriptOrModule of context to null. // 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]] »). // 2. Let O be ? OrdinaryCreateFromConstructor(NewTarget, "%ShadowRealm.prototype%", « [[ShadowRealm]], [[ExecutionContext]] »).
// 4. Set O.[[ShadowRealm]] to realmRec. // 4. Set O.[[ShadowRealm]] to realmRec.

View file

@ -663,4 +663,23 @@ void VM::restore_execution_context_stack()
m_execution_context_stack = m_saved_execution_context_stacks.take_last(); 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;
}
} }

View file

@ -239,6 +239,8 @@ public:
void save_execution_context_stack(); void save_execution_context_stack();
void restore_execution_context_stack(); void restore_execution_context_stack();
ScriptOrModule get_active_script_or_module() const;
private: private:
explicit VM(OwnPtr<CustomData>); explicit VM(OwnPtr<CustomData>);