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:
parent
99edf5b25a
commit
57c5a59cab
10 changed files with 42 additions and 6 deletions
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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]]
|
||||||
|
|
|
@ -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]]
|
||||||
|
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue