mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-24 21:45:20 +00:00
LibJS+LibWeb: Join arguments into vector of registers+constants+locals
This is better because: - Better data locality - Allocate vector for registers+constants+locals+arguments in one go instead of allocating two vectors separately
This commit is contained in:
parent
cd9e491742
commit
c6cd03d7ca
Notes:
github-actions[bot]
2025-04-24 08:32:31 +00:00
Author: https://github.com/kalenikaliaksandr Commit: https://github.com/LadybirdBrowser/ladybird/commit/c6cd03d7ca8 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4434 Reviewed-by: https://github.com/alimpfard
21 changed files with 76 additions and 60 deletions
|
@ -242,7 +242,7 @@ ThrowCompletionOr<Value> Interpreter::run(Script& script_record, GC::Ptr<Environ
|
|||
}
|
||||
|
||||
// 2. Let scriptContext be a new ECMAScript code execution context.
|
||||
auto script_context = ExecutionContext::create(registers_and_constants_and_locals_count);
|
||||
auto script_context = ExecutionContext::create(registers_and_constants_and_locals_count, 0);
|
||||
|
||||
// 3. Set the Function of scriptContext to null.
|
||||
// NOTE: This was done during execution context construction.
|
||||
|
@ -373,7 +373,7 @@ FLATTEN_ON_CLANG void Interpreter::run_bytecode(size_t entry_point)
|
|||
}
|
||||
|
||||
auto& running_execution_context = this->running_execution_context();
|
||||
auto* arguments = running_execution_context.arguments.data();
|
||||
auto* arguments = running_execution_context.arguments().data();
|
||||
auto& accumulator = this->accumulator();
|
||||
auto& executable = current_executable();
|
||||
auto const* bytecode = executable.bytecode.data();
|
||||
|
@ -741,11 +741,11 @@ Interpreter::ResultAndReturnRegister Interpreter::run_executable(Executable& exe
|
|||
|
||||
auto& running_execution_context = vm().running_execution_context();
|
||||
u32 registers_and_constants_and_locals_count = executable.number_of_registers + executable.constants.size() + executable.local_variable_names.size();
|
||||
VERIFY(registers_and_constants_and_locals_count <= running_execution_context.registers_and_constants_and_locals.size());
|
||||
VERIFY(registers_and_constants_and_locals_count <= running_execution_context.registers_and_constants_and_locals_and_arguments.size());
|
||||
|
||||
TemporaryChange restore_running_execution_context { m_running_execution_context, &running_execution_context };
|
||||
TemporaryChange restore_arguments { m_arguments, running_execution_context.arguments.span() };
|
||||
TemporaryChange restore_registers_and_constants_and_locals { m_registers_and_constants_and_locals, running_execution_context.registers_and_constants_and_locals.span() };
|
||||
TemporaryChange restore_arguments { m_arguments, running_execution_context.arguments() };
|
||||
TemporaryChange restore_registers_and_constants_and_locals { m_registers_and_constants_and_locals, running_execution_context.registers_and_constants_and_locals_and_arguments.span() };
|
||||
|
||||
reg(Register::accumulator()) = initial_accumulator_value;
|
||||
reg(Register::return_value()) = js_special_empty_value();
|
||||
|
@ -760,7 +760,7 @@ Interpreter::ResultAndReturnRegister Interpreter::run_executable(Executable& exe
|
|||
running_execution_context.executable = &executable;
|
||||
|
||||
for (size_t i = 0; i < executable.constants.size(); ++i) {
|
||||
running_execution_context.registers_and_constants_and_locals[executable.number_of_registers + i] = executable.constants[i];
|
||||
running_execution_context.registers_and_constants_and_locals_and_arguments[executable.number_of_registers + i] = executable.constants[i];
|
||||
}
|
||||
|
||||
run_bytecode(entry_point.value_or(0));
|
||||
|
@ -768,13 +768,13 @@ Interpreter::ResultAndReturnRegister Interpreter::run_executable(Executable& exe
|
|||
dbgln_if(JS_BYTECODE_DEBUG, "Bytecode::Interpreter did run unit {:p}", &executable);
|
||||
|
||||
if constexpr (JS_BYTECODE_DEBUG) {
|
||||
auto const& registers_and_constants_and_locals = running_execution_context.registers_and_constants_and_locals;
|
||||
auto const& registers_and_constants_and_locals_and_arguments = running_execution_context.registers_and_constants_and_locals_and_arguments;
|
||||
for (size_t i = 0; i < executable.number_of_registers; ++i) {
|
||||
String value_string;
|
||||
if (registers_and_constants_and_locals[i].is_special_empty_value())
|
||||
if (registers_and_constants_and_locals_and_arguments[i].is_special_empty_value())
|
||||
value_string = "(empty)"_string;
|
||||
else
|
||||
value_string = registers_and_constants_and_locals[i].to_string_without_side_effects();
|
||||
value_string = registers_and_constants_and_locals_and_arguments[i].to_string_without_side_effects();
|
||||
dbgln("[{:3}] {}", i, value_string);
|
||||
}
|
||||
}
|
||||
|
@ -788,8 +788,8 @@ Interpreter::ResultAndReturnRegister Interpreter::run_executable(Executable& exe
|
|||
vm().finish_execution_generation();
|
||||
|
||||
if (!exception.is_special_empty_value())
|
||||
return { throw_completion(exception), running_execution_context.registers_and_constants_and_locals[0] };
|
||||
return { return_value, running_execution_context.registers_and_constants_and_locals[0] };
|
||||
return { throw_completion(exception), running_execution_context.registers_and_constants_and_locals_and_arguments[0] };
|
||||
return { return_value, running_execution_context.registers_and_constants_and_locals_and_arguments[0] };
|
||||
}
|
||||
|
||||
void Interpreter::enter_unwind_context()
|
||||
|
@ -2331,7 +2331,7 @@ ThrowCompletionOr<void> CreateVariable::execute_impl(Bytecode::Interpreter& inte
|
|||
|
||||
void CreateRestParams::execute_impl(Bytecode::Interpreter& interpreter) const
|
||||
{
|
||||
auto const& arguments = interpreter.running_execution_context().arguments;
|
||||
auto const arguments = interpreter.running_execution_context().arguments();
|
||||
auto arguments_count = interpreter.running_execution_context().passed_argument_count;
|
||||
auto array = MUST(Array::create(interpreter.realm(), 0));
|
||||
for (size_t rest_index = m_rest_index; rest_index < arguments_count; ++rest_index)
|
||||
|
@ -2342,7 +2342,7 @@ void CreateRestParams::execute_impl(Bytecode::Interpreter& interpreter) const
|
|||
void CreateArguments::execute_impl(Bytecode::Interpreter& interpreter) const
|
||||
{
|
||||
auto const& function = interpreter.running_execution_context().function;
|
||||
auto const& arguments = interpreter.running_execution_context().arguments;
|
||||
auto const arguments = interpreter.running_execution_context().arguments();
|
||||
auto const& environment = interpreter.running_execution_context().lexical_environment;
|
||||
|
||||
auto passed_arguments = ReadonlySpan<Value> { arguments.data(), interpreter.running_execution_context().passed_argument_count };
|
||||
|
|
|
@ -662,7 +662,7 @@ ThrowCompletionOr<Value> perform_eval(VM& vm, Value x, CallerMode strict_caller,
|
|||
executable->dump();
|
||||
|
||||
// 20. Let evalContext be a new ECMAScript code execution context.
|
||||
auto eval_context = ExecutionContext::create(executable->number_of_registers + executable->constants.size() + executable->local_variable_names.size());
|
||||
auto eval_context = ExecutionContext::create(executable->number_of_registers + executable->constants.size() + executable->local_variable_names.size(), 0);
|
||||
|
||||
// 21. Set evalContext's Function to null.
|
||||
// NOTE: This was done in the construction of eval_context.
|
||||
|
|
|
@ -46,7 +46,7 @@ ThrowCompletionOr<GC::Ref<Object>> AsyncFunctionConstructor::construct(FunctionO
|
|||
|
||||
// 2. If bodyArg is not present, set bodyArg to the empty String.
|
||||
// NOTE: This does that, as well as the string extraction done inside of CreateDynamicFunction
|
||||
auto extracted = TRY(extract_parameter_arguments_and_body(vm, vm.running_execution_context().arguments));
|
||||
auto extracted = TRY(extract_parameter_arguments_and_body(vm, vm.running_execution_context().arguments()));
|
||||
|
||||
// 3. Return ? CreateDynamicFunction(C, NewTarget, async, parameterArgs, bodyArg).
|
||||
return TRY(FunctionConstructor::create_dynamic_function(vm, *constructor, &new_target, FunctionKind::Async, extracted.parameters, extracted.body));
|
||||
|
|
|
@ -47,7 +47,7 @@ ThrowCompletionOr<GC::Ref<Object>> AsyncGeneratorFunctionConstructor::construct(
|
|||
|
||||
// 2. If bodyArg is not present, set bodyArg to the empty String.
|
||||
// NOTE: This does that, as well as the string extraction done inside of CreateDynamicFunction
|
||||
auto extracted = TRY(extract_parameter_arguments_and_body(vm, vm.running_execution_context().arguments));
|
||||
auto extracted = TRY(extract_parameter_arguments_and_body(vm, vm.running_execution_context().arguments()));
|
||||
|
||||
// 3. Return ? CreateDynamicFunction(C, NewTarget, async-generator, parameterArgs, bodyArg).
|
||||
return TRY(FunctionConstructor::create_dynamic_function(vm, *constructor, &new_target, FunctionKind::AsyncGenerator, extracted.parameters, extracted.body));
|
||||
|
|
|
@ -500,15 +500,17 @@ ThrowCompletionOr<Value> ECMAScriptFunctionObject::internal_call(Value this_argu
|
|||
m_bytecode_executable = ecmascript_code().bytecode_executable();
|
||||
}
|
||||
|
||||
auto callee_context = ExecutionContext::create(m_bytecode_executable->number_of_registers + m_bytecode_executable->constants.size() + m_bytecode_executable->local_variable_names.size());
|
||||
u32 arguments_count = max(arguments_list.size(), formal_parameters().size());
|
||||
auto callee_context = ExecutionContext::create(m_bytecode_executable->number_of_registers + m_bytecode_executable->constants.size() + m_bytecode_executable->local_variable_names.size(), arguments_count);
|
||||
|
||||
// Non-standard
|
||||
callee_context->arguments.ensure_capacity(max(arguments_list.size(), formal_parameters().size()));
|
||||
callee_context->arguments.append(arguments_list.data(), arguments_list.size());
|
||||
auto arguments = callee_context->arguments();
|
||||
if (!arguments_list.is_empty())
|
||||
arguments.overwrite(0, arguments_list.data(), arguments_list.size() * sizeof(Value));
|
||||
callee_context->passed_argument_count = arguments_list.size();
|
||||
if (arguments_list.size() < formal_parameters().size()) {
|
||||
for (size_t i = arguments_list.size(); i < formal_parameters().size(); ++i)
|
||||
callee_context->arguments.append(js_undefined());
|
||||
arguments[i] = js_undefined();
|
||||
}
|
||||
|
||||
// 2. Let calleeContext be PrepareForOrdinaryCall(F, undefined).
|
||||
|
@ -568,15 +570,17 @@ ThrowCompletionOr<GC::Ref<Object>> ECMAScriptFunctionObject::internal_construct(
|
|||
m_bytecode_executable = ecmascript_code().bytecode_executable();
|
||||
}
|
||||
|
||||
auto callee_context = ExecutionContext::create(m_bytecode_executable->number_of_registers + m_bytecode_executable->constants.size() + m_bytecode_executable->local_variable_names.size());
|
||||
u32 arguments_count = max(arguments_list.size(), formal_parameters().size());
|
||||
auto callee_context = ExecutionContext::create(m_bytecode_executable->number_of_registers + m_bytecode_executable->constants.size() + m_bytecode_executable->local_variable_names.size(), arguments_count);
|
||||
|
||||
// Non-standard
|
||||
callee_context->arguments.ensure_capacity(max(arguments_list.size(), formal_parameters().size()));
|
||||
callee_context->arguments.append(arguments_list.data(), arguments_list.size());
|
||||
auto arguments = callee_context->arguments();
|
||||
if (!arguments_list.is_empty())
|
||||
arguments.overwrite(0, arguments_list.data(), arguments_list.size() * sizeof(Value));
|
||||
callee_context->passed_argument_count = arguments_list.size();
|
||||
if (arguments_list.size() < formal_parameters().size()) {
|
||||
for (size_t i = arguments_list.size(); i < formal_parameters().size(); ++i)
|
||||
callee_context->arguments.append(js_undefined());
|
||||
arguments[i] = js_undefined();
|
||||
}
|
||||
|
||||
// 1. Let callerContext be the running execution context.
|
||||
|
|
|
@ -33,10 +33,11 @@ private:
|
|||
|
||||
static NeverDestroyed<ExecutionContextAllocator> s_execution_context_allocator;
|
||||
|
||||
NonnullOwnPtr<ExecutionContext> ExecutionContext::create(u32 count)
|
||||
NonnullOwnPtr<ExecutionContext> ExecutionContext::create(u32 registers_and_constants_and_locals_count, u32 arguments_count)
|
||||
{
|
||||
auto execution_context = s_execution_context_allocator->allocate();
|
||||
execution_context->registers_and_constants_and_locals.resize_with_default_value(count, js_special_empty_value());
|
||||
execution_context->registers_and_constants_and_locals_and_arguments.resize_with_default_value(registers_and_constants_and_locals_count + arguments_count, js_special_empty_value());
|
||||
execution_context->arguments_offset = registers_and_constants_and_locals_count;
|
||||
return execution_context;
|
||||
}
|
||||
|
||||
|
@ -55,7 +56,7 @@ ExecutionContext::~ExecutionContext()
|
|||
|
||||
NonnullOwnPtr<ExecutionContext> ExecutionContext::copy() const
|
||||
{
|
||||
auto copy = create(registers_and_constants_and_locals.size());
|
||||
auto copy = create(registers_and_constants_and_locals_and_arguments.size(), arguments().size());
|
||||
copy->function = function;
|
||||
copy->realm = realm;
|
||||
copy->script_or_module = script_or_module;
|
||||
|
@ -67,9 +68,9 @@ NonnullOwnPtr<ExecutionContext> ExecutionContext::copy() const
|
|||
copy->this_value = this_value;
|
||||
copy->is_strict_mode = is_strict_mode;
|
||||
copy->executable = executable;
|
||||
copy->arguments = arguments;
|
||||
copy->arguments_offset = arguments_offset;
|
||||
copy->passed_argument_count = passed_argument_count;
|
||||
copy->registers_and_constants_and_locals = registers_and_constants_and_locals;
|
||||
copy->registers_and_constants_and_locals_and_arguments = registers_and_constants_and_locals_and_arguments;
|
||||
copy->unwind_contexts = unwind_contexts;
|
||||
copy->saved_lexical_environments = saved_lexical_environments;
|
||||
copy->previously_scheduled_jumps = previously_scheduled_jumps;
|
||||
|
@ -88,8 +89,7 @@ void ExecutionContext::visit_edges(Cell::Visitor& visitor)
|
|||
visitor.visit(*this_value);
|
||||
visitor.visit(executable);
|
||||
visitor.visit(function_name);
|
||||
visitor.visit(arguments);
|
||||
visitor.visit(registers_and_constants_and_locals);
|
||||
visitor.visit(registers_and_constants_and_locals_and_arguments);
|
||||
for (auto& context : unwind_contexts) {
|
||||
visitor.visit(context.lexical_environment);
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ struct CachedSourceRange : public RefCounted<CachedSourceRange> {
|
|||
|
||||
// 9.4 Execution Contexts, https://tc39.es/ecma262/#sec-execution-contexts
|
||||
struct ExecutionContext {
|
||||
static NonnullOwnPtr<ExecutionContext> create(u32);
|
||||
static NonnullOwnPtr<ExecutionContext> create(u32 registers_and_constants_and_locals_count, u32 arguments_count);
|
||||
[[nodiscard]] NonnullOwnPtr<ExecutionContext> copy() const;
|
||||
|
||||
~ExecutionContext();
|
||||
|
@ -72,24 +72,34 @@ public:
|
|||
|
||||
Value argument(size_t index) const
|
||||
{
|
||||
if (index >= arguments.size()) [[unlikely]]
|
||||
auto arguments_size = registers_and_constants_and_locals_and_arguments.size() - arguments_offset;
|
||||
if (index >= arguments_size) [[unlikely]]
|
||||
return js_undefined();
|
||||
return arguments[index];
|
||||
return registers_and_constants_and_locals_and_arguments[arguments_offset + index];
|
||||
}
|
||||
|
||||
Value& local(size_t index)
|
||||
{
|
||||
return registers_and_constants_and_locals[index];
|
||||
return registers_and_constants_and_locals_and_arguments[index];
|
||||
}
|
||||
|
||||
u32 arguments_offset { 0 };
|
||||
u32 passed_argument_count { 0 };
|
||||
bool is_strict_mode { false };
|
||||
|
||||
Vector<Value> arguments;
|
||||
Span<Value> arguments()
|
||||
{
|
||||
return registers_and_constants_and_locals_and_arguments.span().slice(arguments_offset);
|
||||
}
|
||||
|
||||
ReadonlySpan<Value> arguments() const
|
||||
{
|
||||
return registers_and_constants_and_locals_and_arguments.span().slice(arguments_offset);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class Bytecode::Interpreter;
|
||||
Vector<Value> registers_and_constants_and_locals;
|
||||
Vector<Value> registers_and_constants_and_locals_and_arguments;
|
||||
|
||||
public:
|
||||
Vector<Bytecode::UnwindInfo> unwind_contexts;
|
||||
|
|
|
@ -269,7 +269,7 @@ ThrowCompletionOr<GC::Ref<Object>> FunctionConstructor::construct(FunctionObject
|
|||
|
||||
// 2. If bodyArg is not present, set bodyArg to the empty String.
|
||||
// NOTE: This does that, as well as the string extraction done inside of CreateDynamicFunction
|
||||
auto extracted = TRY(extract_parameter_arguments_and_body(vm, vm.running_execution_context().arguments));
|
||||
auto extracted = TRY(extract_parameter_arguments_and_body(vm, vm.running_execution_context().arguments()));
|
||||
|
||||
// 3. Return ? CreateDynamicFunction(C, NewTarget, normal, parameterArgs, bodyArg).
|
||||
return TRY(create_dynamic_function(vm, *constructor, &new_target, FunctionKind::Normal, extracted.parameters, extracted.body));
|
||||
|
|
|
@ -98,7 +98,7 @@ JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::bind)
|
|||
|
||||
Vector<Value> arguments;
|
||||
if (vm.argument_count() > 1) {
|
||||
arguments.append(vm.running_execution_context().arguments.span().slice(1).data(), vm.argument_count() - 1);
|
||||
arguments.append(vm.running_execution_context().arguments().slice(1).data(), vm.argument_count() - 1);
|
||||
}
|
||||
|
||||
// 3. Let F be ? BoundFunctionCreate(Target, thisArg, args).
|
||||
|
@ -129,7 +129,7 @@ JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::call)
|
|||
// FIXME: 3. Perform PrepareForTailCall().
|
||||
|
||||
auto this_arg = vm.argument(0);
|
||||
auto args = vm.argument_count() > 1 ? vm.running_execution_context().arguments.span().slice(1) : ReadonlySpan<Value> {};
|
||||
auto args = vm.argument_count() > 1 ? vm.running_execution_context().arguments().slice(1) : ReadonlySpan<Value> {};
|
||||
|
||||
// 4. Return ? Call(func, thisArg, args).
|
||||
return TRY(JS::call(vm, function, this_arg, args));
|
||||
|
|
|
@ -45,7 +45,7 @@ ThrowCompletionOr<GC::Ref<Object>> GeneratorFunctionConstructor::construct(Funct
|
|||
|
||||
// 2. If bodyArg is not present, set bodyArg to the empty String.
|
||||
// NOTE: This does that, as well as the string extraction done inside of CreateDynamicFunction
|
||||
auto extracted = TRY(extract_parameter_arguments_and_body(vm, vm.running_execution_context().arguments));
|
||||
auto extracted = TRY(extract_parameter_arguments_and_body(vm, vm.running_execution_context().arguments()));
|
||||
|
||||
// 3. Return ? CreateDynamicFunction(C, NewTarget, generator, parameterArgs, bodyArg).
|
||||
return TRY(FunctionConstructor::create_dynamic_function(vm, *constructor, &new_target, FunctionKind::Generator, extracted.parameters, extracted.body));
|
||||
|
|
|
@ -119,7 +119,7 @@ ThrowCompletionOr<Value> NativeFunction::internal_call(Value this_argument, Read
|
|||
|
||||
// 2. If callerContext is not already suspended, suspend callerContext.
|
||||
// 3. Let calleeContext be a new execution context.
|
||||
auto callee_context = ExecutionContext::create(0);
|
||||
auto callee_context = ExecutionContext::create(0, arguments_list.size());
|
||||
|
||||
// 4. Set the Function of calleeContext to F.
|
||||
callee_context->function = this;
|
||||
|
@ -144,7 +144,8 @@ ThrowCompletionOr<Value> NativeFunction::internal_call(Value this_argument, Read
|
|||
|
||||
// 8. Perform any necessary implementation-defined initialization of calleeContext.
|
||||
callee_context->this_value = this_argument;
|
||||
callee_context->arguments.append(arguments_list.data(), arguments_list.size());
|
||||
if (!arguments_list.is_empty())
|
||||
callee_context->arguments().overwrite(0, arguments_list.data(), arguments_list.size() * sizeof(Value));
|
||||
|
||||
callee_context->lexical_environment = caller_context.lexical_environment;
|
||||
callee_context->variable_environment = caller_context.variable_environment;
|
||||
|
@ -180,7 +181,7 @@ ThrowCompletionOr<GC::Ref<Object>> NativeFunction::internal_construct(ReadonlySp
|
|||
|
||||
// 2. If callerContext is not already suspended, suspend callerContext.
|
||||
// 3. Let calleeContext be a new execution context.
|
||||
auto callee_context = ExecutionContext::create(0);
|
||||
auto callee_context = ExecutionContext::create(0, arguments_list.size());
|
||||
|
||||
// 4. Set the Function of calleeContext to F.
|
||||
callee_context->function = this;
|
||||
|
@ -204,7 +205,8 @@ ThrowCompletionOr<GC::Ref<Object>> NativeFunction::internal_construct(ReadonlySp
|
|||
// Note: This is already the default value.
|
||||
|
||||
// 8. Perform any necessary implementation-defined initialization of calleeContext.
|
||||
callee_context->arguments.append(arguments_list.data(), arguments_list.size());
|
||||
if (!arguments_list.is_empty())
|
||||
callee_context->arguments().overwrite(0, arguments_list.data(), arguments_list.size() * sizeof(Value));
|
||||
|
||||
callee_context->lexical_environment = caller_context.lexical_environment;
|
||||
callee_context->variable_environment = caller_context.variable_environment;
|
||||
|
|
|
@ -465,7 +465,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::try_)
|
|||
auto callback = vm.argument(0);
|
||||
Span<Value> args;
|
||||
if (vm.argument_count() > 1) {
|
||||
args = vm.running_execution_context().arguments.span().slice(1, vm.argument_count() - 1);
|
||||
args = vm.running_execution_context().arguments().slice(1, vm.argument_count() - 1);
|
||||
}
|
||||
|
||||
// 1. Let C be the this value.
|
||||
|
|
|
@ -36,7 +36,7 @@ ThrowCompletionOr<NonnullOwnPtr<ExecutionContext>> Realm::initialize_host_define
|
|||
// FIXME: 6. Set realm.[[TemplateMap]] to a new empty List.
|
||||
|
||||
// 7. Let newContext be a new execution context.
|
||||
auto new_context = ExecutionContext::create(0);
|
||||
auto new_context = ExecutionContext::create(0, 0);
|
||||
|
||||
// 8. Set the Function of newContext to null.
|
||||
new_context->function = nullptr;
|
||||
|
|
|
@ -300,7 +300,7 @@ NonnullOwnPtr<ExecutionContext> get_shadow_realm_context(Realm& shadow_realm, bo
|
|||
variable_environment = lexical_environment;
|
||||
|
||||
// 4. Let context be a new ECMAScript code execution context.
|
||||
auto context = ExecutionContext::create(registers_and_constants_and_locals_count);
|
||||
auto context = ExecutionContext::create(registers_and_constants_and_locals_count, 0);
|
||||
|
||||
// 5. Set context's Function to null.
|
||||
context->function = nullptr;
|
||||
|
|
|
@ -160,7 +160,7 @@ public:
|
|||
|
||||
size_t argument_count() const
|
||||
{
|
||||
return running_execution_context().arguments.size();
|
||||
return running_execution_context().arguments().size();
|
||||
}
|
||||
|
||||
Value argument(size_t index) const
|
||||
|
|
|
@ -62,7 +62,7 @@ ThrowCompletionOr<Value> WrappedFunction::internal_call(Value this_argument, Rea
|
|||
// NOTE: No-op, kept by the VM in its execution context stack.
|
||||
|
||||
// 2. Let calleeContext be PrepareForWrappedFunctionCall(F).
|
||||
auto callee_context = ExecutionContext::create(0);
|
||||
auto callee_context = ExecutionContext::create(0, 0);
|
||||
prepare_for_wrapped_function_call(*this, *callee_context);
|
||||
|
||||
// 3. Assert: calleeContext is now the running execution context.
|
||||
|
|
|
@ -107,7 +107,7 @@ SourceTextModule::SourceTextModule(Realm& realm, StringView filename, Script::Ho
|
|||
RefPtr<ExportStatement const> default_export)
|
||||
: CyclicModule(realm, filename, has_top_level_await, move(requested_modules), host_defined)
|
||||
, m_ecmascript_code(move(body))
|
||||
, m_execution_context(ExecutionContext::create(0))
|
||||
, m_execution_context(ExecutionContext::create(0, 0))
|
||||
, m_import_entries(move(import_entries))
|
||||
, m_local_export_entries(move(local_export_entries))
|
||||
, m_indirect_export_entries(move(indirect_export_entries))
|
||||
|
@ -701,7 +701,7 @@ ThrowCompletionOr<void> SourceTextModule::execute_module(VM& vm, GC::Ptr<Promise
|
|||
}
|
||||
|
||||
// 1. Let moduleContext be a new ECMAScript code execution context.
|
||||
auto module_context = ExecutionContext::create(registers_and_constants_and_locals_count);
|
||||
auto module_context = ExecutionContext::create(registers_and_constants_and_locals_count, 0);
|
||||
|
||||
// Note: This is not in the spec but we require it.
|
||||
module_context->is_strict_mode = true;
|
||||
|
|
|
@ -81,7 +81,7 @@ ThrowCompletionOr<Promise*> SyntheticModule::evaluate(VM& vm)
|
|||
// NOTE: Done by the push on step 8.
|
||||
|
||||
// 2. Let moduleContext be a new ECMAScript code execution context.
|
||||
auto module_context = ExecutionContext::create(0);
|
||||
auto module_context = ExecutionContext::create(0, 0);
|
||||
|
||||
// 3. Set the Function of moduleContext to null.
|
||||
// Note: This is the default value.
|
||||
|
|
|
@ -281,7 +281,7 @@ ErrorOr<void> initialize_main_thread_vm(HTML::EventLoop::Type type)
|
|||
// FIXME: We need to setup a dummy execution context in case a JS::NativeFunction is called when processing the job.
|
||||
// This is because JS::NativeFunction::call excepts something to be on the execution context stack to be able to get the caller context to initialize the environment.
|
||||
// Do note that the JS spec gives _no_ guarantee that the execution context stack has something on it if HostEnqueuePromiseJob was called with a null realm: https://tc39.es/ecma262/#job-preparedtoevaluatecode
|
||||
dummy_execution_context = JS::ExecutionContext::create(0);
|
||||
dummy_execution_context = JS::ExecutionContext::create(0, 0);
|
||||
dummy_execution_context->script_or_module = script_or_module;
|
||||
vm.push_execution_context(*dummy_execution_context);
|
||||
}
|
||||
|
@ -324,7 +324,7 @@ ErrorOr<void> initialize_main_thread_vm(HTML::EventLoop::Type type)
|
|||
// 4. If active script is not null, set script execution context to a new JavaScript execution context, with its Function field set to null,
|
||||
// its Realm field set to active script's realm, and its ScriptOrModule set to active script's record.
|
||||
if (script) {
|
||||
script_execution_context = JS::ExecutionContext::create(0);
|
||||
script_execution_context = JS::ExecutionContext::create(0, 0);
|
||||
script_execution_context->function = nullptr;
|
||||
script_execution_context->realm = &script->realm();
|
||||
if (is<HTML::ClassicScript>(script)) {
|
||||
|
@ -585,7 +585,7 @@ ErrorOr<void> initialize_main_thread_vm(HTML::EventLoop::Type type)
|
|||
// 5. Perform FinishLoadingImportedModule(referrer, moduleRequest, payload, completion).
|
||||
// NON-STANDARD: To ensure that LibJS can find the module on the stack, we push a new execution context.
|
||||
|
||||
auto module_execution_context = JS::ExecutionContext::create(0);
|
||||
auto module_execution_context = JS::ExecutionContext::create(0, 0);
|
||||
module_execution_context->realm = realm;
|
||||
if (module)
|
||||
module_execution_context->script_or_module = GC::Ref { *module };
|
||||
|
|
|
@ -137,7 +137,7 @@ Optional<JS::PropertyDescriptor> cross_origin_get_own_property_helper(Variant<HT
|
|||
if (value->is_function()) {
|
||||
value = JS::NativeFunction::create(
|
||||
realm, [function = GC::make_root(*value)](auto& vm) {
|
||||
return JS::call(vm, function.value(), JS::js_undefined(), vm.running_execution_context().arguments.span());
|
||||
return JS::call(vm, function.value(), JS::js_undefined(), vm.running_execution_context().arguments());
|
||||
},
|
||||
0);
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ Optional<JS::PropertyDescriptor> cross_origin_get_own_property_helper(Variant<HT
|
|||
if (*entry.needs_get) {
|
||||
cross_origin_get = JS::NativeFunction::create(
|
||||
realm, [object_ptr, getter = GC::make_root(*original_descriptor->get)](auto& vm) {
|
||||
return JS::call(vm, getter.cell(), object_ptr, vm.running_execution_context().arguments.span());
|
||||
return JS::call(vm, getter.cell(), object_ptr, vm.running_execution_context().arguments());
|
||||
},
|
||||
0);
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ Optional<JS::PropertyDescriptor> cross_origin_get_own_property_helper(Variant<HT
|
|||
if (*entry.needs_set) {
|
||||
cross_origin_set = JS::NativeFunction::create(
|
||||
realm, [object_ptr, setter = GC::make_root(*original_descriptor->set)](auto& vm) {
|
||||
return JS::call(vm, setter.cell(), object_ptr, vm.running_execution_context().arguments.span());
|
||||
return JS::call(vm, setter.cell(), object_ptr, vm.running_execution_context().arguments());
|
||||
},
|
||||
0);
|
||||
}
|
||||
|
|
|
@ -102,7 +102,7 @@ JS::Promise* JavaScriptModuleScript::run(PreventErrorReporting)
|
|||
VERIFY(record);
|
||||
|
||||
// NON-STANDARD: To ensure that LibJS can find the module on the stack, we push a new execution context.
|
||||
auto module_execution_context = JS::ExecutionContext::create(0);
|
||||
auto module_execution_context = JS::ExecutionContext::create(0, 0);
|
||||
module_execution_context->realm = &realm;
|
||||
module_execution_context->script_or_module = GC::Ref<JS::Module> { *record };
|
||||
vm().push_execution_context(*module_execution_context);
|
||||
|
|
Loading…
Add table
Reference in a new issue