diff options
author | Andreas Kling <kling@serenityos.org> | 2021-06-24 19:17:45 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-06-24 19:28:00 +0200 |
commit | c2ad5997830b9b633efd3f6d5ef335ed6622b418 (patch) | |
tree | d945291f68ee5d92b68af96aa95cbcb96e36867c /Userland/Libraries/LibJS | |
parent | 7c88caf99f5935b2c1595917edccf2bfc1c30005 (diff) | |
download | serenity-c2ad5997830b9b633efd3f6d5ef335ed6622b418.zip |
LibJS: Rename CallFrame => ExecutionContext
This struct represents what the ECMAScript specification calls an
"execution context" so let's use the same terminology. :^)
Diffstat (limited to 'Userland/Libraries/LibJS')
-rw-r--r-- | Userland/Libraries/LibJS/AST.cpp | 12 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Bytecode/Interpreter.cpp | 20 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Bytecode/Op.cpp | 4 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Console.cpp | 8 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Interpreter.cpp | 30 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/Exception.cpp | 12 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/FunctionPrototype.cpp | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/GeneratorObject.cpp | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/Object.cpp | 24 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/ScriptFunction.cpp | 18 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/VM.cpp | 97 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/VM.h | 46 |
13 files changed, 139 insertions, 138 deletions
diff --git a/Userland/Libraries/LibJS/AST.cpp b/Userland/Libraries/LibJS/AST.cpp index f85376baa3..cebea7d1d1 100644 --- a/Userland/Libraries/LibJS/AST.cpp +++ b/Userland/Libraries/LibJS/AST.cpp @@ -43,7 +43,7 @@ public: : m_interpreter(interpreter) , m_chain_node { nullptr, node } { - m_interpreter.vm().call_frame().current_node = &node; + m_interpreter.vm().running_execution_context().current_node = &node; m_interpreter.push_ast_node(m_chain_node); } @@ -225,7 +225,7 @@ Value CallExpression::execute(Interpreter& interpreter, GlobalObject& global_obj return perform_eval(script_value, global_object, vm.in_strict_mode() ? CallerMode::Strict : CallerMode::NonStrict, EvalMode::Direct); } - vm.call_frame().current_node = interpreter.current_node(); + vm.running_execution_context().current_node = interpreter.current_node(); Object* new_object = nullptr; Value result; if (is<NewExpression>(*this)) { @@ -308,8 +308,8 @@ Value WithStatement::execute(Interpreter& interpreter, GlobalObject& global_obje VERIFY(object); - auto* object_environment_record = new_object_environment(*object, true, interpreter.vm().call_frame().lexical_environment); - TemporaryChange<EnvironmentRecord*> scope_change(interpreter.vm().call_frame().lexical_environment, object_environment_record); + auto* object_environment_record = new_object_environment(*object, true, interpreter.vm().running_execution_context().lexical_environment); + TemporaryChange<EnvironmentRecord*> scope_change(interpreter.vm().running_execution_context().lexical_environment, object_environment_record); return interpreter.execute_statement(global_object, m_body).value_or(js_undefined()); } @@ -2049,8 +2049,8 @@ Value TryStatement::execute(Interpreter& interpreter, GlobalObject& global_objec HashMap<FlyString, Variable> parameters; parameters.set(m_handler->parameter(), Variable { exception->value(), DeclarationKind::Var }); - auto* catch_scope = interpreter.heap().allocate<DeclarativeEnvironmentRecord>(global_object, move(parameters), interpreter.vm().call_frame().lexical_environment); - TemporaryChange<EnvironmentRecord*> scope_change(interpreter.vm().call_frame().lexical_environment, catch_scope); + auto* catch_scope = interpreter.heap().allocate<DeclarativeEnvironmentRecord>(global_object, move(parameters), interpreter.vm().running_execution_context().lexical_environment); + TemporaryChange<EnvironmentRecord*> scope_change(interpreter.vm().running_execution_context().lexical_environment, catch_scope); result = interpreter.execute_statement(global_object, m_handler->body()); } } diff --git a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp index 988a9c16b7..77072459ba 100644 --- a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp @@ -44,17 +44,17 @@ Value Interpreter::run(Executable const& executable, BasicBlock const* entry_poi vm().set_last_value(Badge<Interpreter> {}, {}); - CallFrame global_call_frame; - if (vm().call_stack().is_empty()) { - global_call_frame.this_value = &global_object(); + ExecutionContext execution_context; + if (vm().execution_context_stack().is_empty()) { + execution_context.this_value = &global_object(); static FlyString global_execution_context_name = "(*BC* global execution context)"; - global_call_frame.function_name = global_execution_context_name; - global_call_frame.lexical_environment = &global_object().environment_record(); - global_call_frame.variable_environment = &global_object().environment_record(); + execution_context.function_name = global_execution_context_name; + execution_context.lexical_environment = &global_object().environment_record(); + execution_context.variable_environment = &global_object().environment_record(); VERIFY(!vm().exception()); // FIXME: How do we know if we're in strict mode? Maybe the Bytecode::Block should know this? - // global_call_frame.is_strict_mode = ???; - vm().push_call_frame(global_call_frame, global_object()); + // execution_context.is_strict_mode = ???; + vm().push_execution_context(execution_context, global_object()); VERIFY(!vm().exception()); } @@ -140,8 +140,8 @@ Value Interpreter::run(Executable const& executable, BasicBlock const* entry_poi if (!m_register_windows.is_empty()) m_register_windows.last()[0] = return_value; - if (vm().call_stack().size() == 1) - vm().pop_call_frame(); + if (vm().execution_context_stack().size() == 1) + vm().pop_execution_context(); vm().finish_execution_generation(); diff --git a/Userland/Libraries/LibJS/Bytecode/Op.cpp b/Userland/Libraries/LibJS/Bytecode/Op.cpp index aedbe50289..6ee8a70c21 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Op.cpp @@ -387,8 +387,8 @@ void PushDeclarativeEnvironmentRecord::execute_impl(Bytecode::Interpreter& inter for (auto& it : m_variables) resolved_variables.set(interpreter.current_executable().get_string(it.key), it.value); auto* environment_record = interpreter.vm().heap().allocate<DeclarativeEnvironmentRecord>(interpreter.global_object(), move(resolved_variables), interpreter.vm().lexical_environment()); - interpreter.vm().call_frame().lexical_environment = environment_record; - interpreter.vm().call_frame().variable_environment = environment_record; + interpreter.vm().running_execution_context().lexical_environment = environment_record; + interpreter.vm().running_execution_context().variable_environment = environment_record; } void Yield::execute_impl(Bytecode::Interpreter& interpreter) const diff --git a/Userland/Libraries/LibJS/Console.cpp b/Userland/Libraries/LibJS/Console.cpp index 8d703e433d..ae5d2bfb7d 100644 --- a/Userland/Libraries/LibJS/Console.cpp +++ b/Userland/Libraries/LibJS/Console.cpp @@ -135,10 +135,10 @@ VM& ConsoleClient::vm() Vector<String> ConsoleClient::get_trace() const { Vector<String> trace; - auto& call_stack = m_console.global_object().vm().call_stack(); - // -2 to skip the console.trace() call frame - for (ssize_t i = call_stack.size() - 2; i >= 0; --i) - trace.append(call_stack[i]->function_name); + auto& execution_context_stack = m_console.global_object().vm().execution_context_stack(); + // NOTE: -2 to skip the console.trace() execution context + for (ssize_t i = execution_context_stack.size() - 2; i >= 0; --i) + trace.append(execution_context_stack[i]->function_name); return trace; } diff --git a/Userland/Libraries/LibJS/Interpreter.cpp b/Userland/Libraries/LibJS/Interpreter.cpp index b70671b788..fda2d1af0d 100644 --- a/Userland/Libraries/LibJS/Interpreter.cpp +++ b/Userland/Libraries/LibJS/Interpreter.cpp @@ -46,21 +46,21 @@ void Interpreter::run(GlobalObject& global_object, const Program& program) vm.set_last_value(Badge<Interpreter> {}, {}); - CallFrame global_call_frame; - global_call_frame.current_node = &program; - global_call_frame.this_value = &global_object; + ExecutionContext execution_context; + execution_context.current_node = &program; + execution_context.this_value = &global_object; static FlyString global_execution_context_name = "(global execution context)"; - global_call_frame.function_name = global_execution_context_name; - global_call_frame.lexical_environment = &global_object.environment_record(); - global_call_frame.variable_environment = &global_object.environment_record(); + execution_context.function_name = global_execution_context_name; + execution_context.lexical_environment = &global_object.environment_record(); + execution_context.variable_environment = &global_object.environment_record(); VERIFY(!vm.exception()); - global_call_frame.is_strict_mode = program.is_strict_mode(); - vm.push_call_frame(global_call_frame, global_object); + execution_context.is_strict_mode = program.is_strict_mode(); + vm.push_execution_context(execution_context, global_object); VERIFY(!vm.exception()); auto value = program.execute(*this, global_object); vm.set_last_value(Badge<Interpreter> {}, value.value_or(js_undefined())); - vm.pop_call_frame(); + vm.pop_execution_context(); // At this point we may have already run any queued promise jobs via on_call_stack_emptied, // in which case this is a no-op. @@ -134,8 +134,8 @@ void Interpreter::enter_scope(const ScopeNode& scope_node, ScopeType scope_type, if (!scope_variables_with_declaration_kind.is_empty()) { auto* environment_record = heap().allocate<DeclarativeEnvironmentRecord>(global_object, move(scope_variables_with_declaration_kind), lexical_environment()); - vm().call_frame().lexical_environment = environment_record; - vm().call_frame().variable_environment = environment_record; + vm().running_execution_context().lexical_environment = environment_record; + vm().running_execution_context().variable_environment = environment_record; pushed_environment_record = true; } @@ -147,8 +147,8 @@ void Interpreter::exit_scope(const ScopeNode& scope_node) while (!m_scope_stack.is_empty()) { auto popped_scope = m_scope_stack.take_last(); if (popped_scope.pushed_environment) { - vm().call_frame().lexical_environment = vm().call_frame().lexical_environment->outer_environment(); - vm().call_frame().variable_environment = vm().call_frame().variable_environment->outer_environment(); + vm().running_execution_context().lexical_environment = vm().running_execution_context().lexical_environment->outer_environment(); + vm().running_execution_context().variable_environment = vm().running_execution_context().variable_environment->outer_environment(); } if (popped_scope.scope_node.ptr() == &scope_node) break; @@ -200,8 +200,8 @@ Value Interpreter::execute_statement(GlobalObject& global_object, const Statemen FunctionEnvironmentRecord* Interpreter::current_function_environment_record() { - VERIFY(is<FunctionEnvironmentRecord>(vm().call_frame().lexical_environment)); - return static_cast<FunctionEnvironmentRecord*>(vm().call_frame().lexical_environment); + VERIFY(is<FunctionEnvironmentRecord>(vm().running_execution_context().lexical_environment)); + return static_cast<FunctionEnvironmentRecord*>(vm().running_execution_context().lexical_environment); } } diff --git a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp index 082a35e2ea..55cd4070dd 100644 --- a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp +++ b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp @@ -221,7 +221,7 @@ Value perform_eval(Value x, GlobalObject& caller_realm, CallerMode strict_caller if (direct == EvalMode::Direct) return interpreter.execute_statement(caller_realm, program).value_or(js_undefined()); - TemporaryChange scope_change(vm.call_frame().lexical_environment, static_cast<EnvironmentRecord*>(&caller_realm.environment_record())); + TemporaryChange scope_change(vm.running_execution_context().lexical_environment, static_cast<EnvironmentRecord*>(&caller_realm.environment_record())); return interpreter.execute_statement(caller_realm, program).value_or(js_undefined()); } diff --git a/Userland/Libraries/LibJS/Runtime/Exception.cpp b/Userland/Libraries/LibJS/Runtime/Exception.cpp index a3fd15a1f2..39792bf8ff 100644 --- a/Userland/Libraries/LibJS/Runtime/Exception.cpp +++ b/Userland/Libraries/LibJS/Runtime/Exception.cpp @@ -17,19 +17,19 @@ Exception::Exception(Value value) : m_value(value) { auto& vm = this->vm(); - m_traceback.ensure_capacity(vm.call_stack().size()); - for (ssize_t i = vm.call_stack().size() - 1; i >= 0; i--) { - auto* call_frame = vm.call_stack()[i]; - auto function_name = call_frame->function_name; + m_traceback.ensure_capacity(vm.execution_context_stack().size()); + for (ssize_t i = vm.execution_context_stack().size() - 1; i >= 0; i--) { + auto* context = vm.execution_context_stack()[i]; + auto function_name = context->function_name; if (function_name.is_empty()) function_name = "<anonymous>"; m_traceback.empend( move(function_name), - // We might not have an AST node associated with the call frame, e.g. in promise + // We might not have an AST node associated with the execution context, e.g. in promise // reaction jobs (which aren't called anywhere from the source code). // They're not going to generate any _unhandled_ exceptions though, so a meaningless // source range is fine. - call_frame->current_node ? call_frame->current_node->source_range() : SourceRange {}); + context->current_node ? context->current_node->source_range() : SourceRange {}); } } diff --git a/Userland/Libraries/LibJS/Runtime/FunctionPrototype.cpp b/Userland/Libraries/LibJS/Runtime/FunctionPrototype.cpp index dde96e0433..9a979a98d4 100644 --- a/Userland/Libraries/LibJS/Runtime/FunctionPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/FunctionPrototype.cpp @@ -79,7 +79,7 @@ JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::bind) Vector<Value> arguments; if (vm.argument_count() > 1) { - arguments = vm.call_frame().arguments; + arguments = vm.running_execution_context().arguments; arguments.remove(0); } diff --git a/Userland/Libraries/LibJS/Runtime/GeneratorObject.cpp b/Userland/Libraries/LibJS/Runtime/GeneratorObject.cpp index 3da30afd6b..091ca2920e 100644 --- a/Userland/Libraries/LibJS/Runtime/GeneratorObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/GeneratorObject.cpp @@ -107,7 +107,7 @@ Value GeneratorObject::next_impl(VM& vm, GlobalObject& global_object, Optional<V } // Temporarily switch to the captured environment record - TemporaryChange change { vm.call_frame().lexical_environment, m_environment_record }; + TemporaryChange change { vm.running_execution_context().lexical_environment, m_environment_record }; m_previous_value = bytecode_interpreter->run(*m_generating_function->bytecode_executable(), next_block); diff --git a/Userland/Libraries/LibJS/Runtime/Object.cpp b/Userland/Libraries/LibJS/Runtime/Object.cpp index e21f067991..c386e93771 100644 --- a/Userland/Libraries/LibJS/Runtime/Object.cpp +++ b/Userland/Libraries/LibJS/Runtime/Object.cpp @@ -1151,32 +1151,32 @@ Value Object::invoke_internal(const StringOrSymbol& property_name, Optional<Mark Value Object::call_native_property_getter(NativeProperty& property, Value this_value) const { auto& vm = this->vm(); - CallFrame call_frame; + ExecutionContext execution_context; if (auto* interpreter = vm.interpreter_if_exists()) - call_frame.current_node = interpreter->current_node(); - call_frame.is_strict_mode = vm.in_strict_mode(); - call_frame.this_value = this_value; - vm.push_call_frame(call_frame, global_object()); + execution_context.current_node = interpreter->current_node(); + execution_context.is_strict_mode = vm.in_strict_mode(); + execution_context.this_value = this_value; + vm.push_execution_context(execution_context, global_object()); if (vm.exception()) return {}; auto result = property.get(vm, global_object()); - vm.pop_call_frame(); + vm.pop_execution_context(); return result; } void Object::call_native_property_setter(NativeProperty& property, Value this_value, Value setter_value) const { auto& vm = this->vm(); - CallFrame call_frame; + ExecutionContext execution_context; if (auto* interpreter = vm.interpreter_if_exists()) - call_frame.current_node = interpreter->current_node(); - call_frame.is_strict_mode = vm.in_strict_mode(); - call_frame.this_value = this_value; - vm.push_call_frame(call_frame, global_object()); + execution_context.current_node = interpreter->current_node(); + execution_context.is_strict_mode = vm.in_strict_mode(); + execution_context.this_value = this_value; + vm.push_execution_context(execution_context, global_object()); if (vm.exception()) return; property.set(vm, global_object(), setter_value); - vm.pop_call_frame(); + vm.pop_execution_context(); } } diff --git a/Userland/Libraries/LibJS/Runtime/ScriptFunction.cpp b/Userland/Libraries/LibJS/Runtime/ScriptFunction.cpp index 86fe879641..bf315675a3 100644 --- a/Userland/Libraries/LibJS/Runtime/ScriptFunction.cpp +++ b/Userland/Libraries/LibJS/Runtime/ScriptFunction.cpp @@ -140,7 +140,7 @@ Value ScriptFunction::execute_function_body() auto* bytecode_interpreter = Bytecode::Interpreter::current(); auto prepare_arguments = [&] { - auto& call_frame_args = vm.call_frame().arguments; + auto& execution_context_arguments = vm.running_execution_context().arguments; for (size_t i = 0; i < m_parameters.size(); ++i) { auto& parameter = m_parameters[i]; parameter.binding.visit( @@ -148,11 +148,11 @@ Value ScriptFunction::execute_function_body() Value argument_value; if (parameter.is_rest) { auto* array = Array::create(global_object()); - for (size_t rest_index = i; rest_index < call_frame_args.size(); ++rest_index) - array->indexed_properties().append(call_frame_args[rest_index]); + for (size_t rest_index = i; rest_index < execution_context_arguments.size(); ++rest_index) + array->indexed_properties().append(execution_context_arguments[rest_index]); argument_value = move(array); - } else if (i < call_frame_args.size() && !call_frame_args[i].is_undefined()) { - argument_value = call_frame_args[i]; + } else if (i < execution_context_arguments.size() && !execution_context_arguments[i].is_undefined()) { + argument_value = execution_context_arguments[i]; } else if (parameter.default_value) { // FIXME: Support default arguments in the bytecode world! if (!bytecode_interpreter) @@ -163,9 +163,9 @@ Value ScriptFunction::execute_function_body() argument_value = js_undefined(); } - if (i >= call_frame_args.size()) - call_frame_args.resize(i + 1); - call_frame_args[i] = argument_value; + if (i >= execution_context_arguments.size()) + execution_context_arguments.resize(i + 1); + execution_context_arguments[i] = argument_value; vm.assign(param, argument_value, global_object(), true, vm.lexical_environment()); }); @@ -191,7 +191,7 @@ Value ScriptFunction::execute_function_body() if (m_kind != FunctionKind::Generator) return result; - return GeneratorObject::create(global_object(), result, this, vm.call_frame().lexical_environment, bytecode_interpreter->snapshot_frame()); + return GeneratorObject::create(global_object(), result, this, vm.running_execution_context().lexical_environment, bytecode_interpreter->snapshot_frame()); } else { VERIFY(m_kind != FunctionKind::Generator); OwnPtr<Interpreter> local_interpreter; diff --git a/Userland/Libraries/LibJS/Runtime/VM.cpp b/Userland/Libraries/LibJS/Runtime/VM.cpp index e805bcba59..2662943380 100644 --- a/Userland/Libraries/LibJS/Runtime/VM.cpp +++ b/Userland/Libraries/LibJS/Runtime/VM.cpp @@ -97,15 +97,15 @@ void VM::gather_roots(HashTable<Cell*>& roots) if (m_last_value.is_cell()) roots.set(&m_last_value.as_cell()); - for (auto& call_frame : m_call_stack) { - if (call_frame->this_value.is_cell()) - roots.set(&call_frame->this_value.as_cell()); - roots.set(call_frame->arguments_object); - for (auto& argument : call_frame->arguments) { + for (auto& execution_context : m_execution_context_stack) { + if (execution_context->this_value.is_cell()) + roots.set(&execution_context->this_value.as_cell()); + roots.set(execution_context->arguments_object); + for (auto& argument : execution_context->arguments) { if (argument.is_cell()) roots.set(&argument.as_cell()); } - roots.set(call_frame->lexical_environment); + roots.set(execution_context->lexical_environment); } #define __JS_ENUMERATE(SymbolName, snake_name) \ @@ -134,7 +134,7 @@ Symbol* VM::get_global_symbol(const String& description) void VM::set_variable(const FlyString& name, Value value, GlobalObject& global_object, bool first_assignment, EnvironmentRecord* specific_scope) { Optional<Variable> possible_match; - if (!specific_scope && m_call_stack.size()) { + if (!specific_scope && m_execution_context_stack.size()) { for (auto* environment_record = lexical_environment(); environment_record; environment_record = environment_record->outer_environment()) { possible_match = environment_record->get_from_environment_record(name); if (possible_match.has_value()) { @@ -166,7 +166,7 @@ bool VM::delete_variable(FlyString const& name) { EnvironmentRecord* specific_scope = nullptr; Optional<Variable> possible_match; - if (!m_call_stack.is_empty()) { + if (!m_execution_context_stack.is_empty()) { for (auto* environment_record = lexical_environment(); environment_record; environment_record = environment_record->outer_environment()) { possible_match = environment_record->get_from_environment_record(name); if (possible_match.has_value()) { @@ -356,8 +356,9 @@ void VM::assign(const NonnullRefPtr<BindingPattern>& target, Value value, Global Value VM::get_variable(const FlyString& name, GlobalObject& global_object) { - if (!m_call_stack.is_empty()) { - if (name == names.arguments.as_string() && !call_frame().callee.is_empty()) { + if (!m_execution_context_stack.is_empty()) { + auto& context = running_execution_context(); + if (name == names.arguments.as_string() && context.callee) { // HACK: Special handling for the name "arguments": // If the name "arguments" is defined in the current scope, for example via // a function parameter, or by a local var declaration, we use that. @@ -366,14 +367,14 @@ Value VM::get_variable(const FlyString& name, GlobalObject& global_object) auto possible_match = lexical_environment()->get_from_environment_record(name); if (possible_match.has_value()) return possible_match.value().value; - if (!call_frame().arguments_object) { - call_frame().arguments_object = Array::create(global_object); - call_frame().arguments_object->put(names.callee, call_frame().callee); - for (auto argument : call_frame().arguments) { - call_frame().arguments_object->indexed_properties().append(argument); + if (!context.arguments_object) { + context.arguments_object = Array::create(global_object); + context.arguments_object->put(names.callee, context.callee); + for (auto argument : context.arguments) { + context.arguments_object->indexed_properties().append(argument); } } - return call_frame().arguments_object; + return context.arguments_object; } for (auto* environment_record = lexical_environment(); environment_record; environment_record = environment_record->outer_environment()) { @@ -403,26 +404,26 @@ Reference VM::get_reference(const FlyString& name) Value VM::construct(Function& function, Function& new_target, Optional<MarkedValueList> arguments) { auto& global_object = function.global_object(); - CallFrame call_frame; - call_frame.callee = &function; + ExecutionContext execution_context; + execution_context.callee = &function; if (auto* interpreter = interpreter_if_exists()) - call_frame.current_node = interpreter->current_node(); - call_frame.is_strict_mode = function.is_strict_mode(); + execution_context.current_node = interpreter->current_node(); + execution_context.is_strict_mode = function.is_strict_mode(); - push_call_frame(call_frame, global_object); + push_execution_context(execution_context, global_object); if (exception()) return {}; - ArmedScopeGuard call_frame_popper = [&] { - pop_call_frame(); + ArmedScopeGuard pop_guard = [&] { + pop_execution_context(); }; - call_frame.function_name = function.name(); - call_frame.arguments = function.bound_arguments(); + execution_context.function_name = function.name(); + execution_context.arguments = function.bound_arguments(); if (arguments.has_value()) - call_frame.arguments.extend(arguments.value().values()); + execution_context.arguments.extend(arguments.value().values()); auto* environment = function.create_environment_record(); - call_frame.lexical_environment = environment; - call_frame.variable_environment = environment; + execution_context.lexical_environment = environment; + execution_context.variable_environment = environment; if (environment) environment->set_new_target(&new_target); @@ -445,13 +446,13 @@ Value VM::construct(Function& function, Function& new_target, Optional<MarkedVal // If we are a Derived constructor, |this| has not been constructed before super is called. Value this_value = function.constructor_kind() == Function::ConstructorKind::Base ? new_object : Value {}; - call_frame.this_value = this_value; + execution_context.this_value = this_value; auto result = function.construct(new_target); if (environment) this_value = environment->get_this_binding(global_object); - pop_call_frame(); - call_frame_popper.disarm(); + pop_execution_context(); + pop_guard.disarm(); // If we are constructing an instance of a derived class, // set the prototype on objects created by constructors that return an object (i.e. NativeFunction subclasses). @@ -509,41 +510,41 @@ Value VM::call_internal(Function& function, Value this_value, Optional<MarkedVal VERIFY(!exception()); VERIFY(!this_value.is_empty()); - CallFrame call_frame; - call_frame.callee = &function; + ExecutionContext execution_context; + execution_context.callee = &function; if (auto* interpreter = interpreter_if_exists()) - call_frame.current_node = interpreter->current_node(); - call_frame.is_strict_mode = function.is_strict_mode(); - call_frame.function_name = function.name(); - call_frame.this_value = function.bound_this().value_or(this_value); - call_frame.arguments = function.bound_arguments(); + execution_context.current_node = interpreter->current_node(); + execution_context.is_strict_mode = function.is_strict_mode(); + execution_context.function_name = function.name(); + execution_context.this_value = function.bound_this().value_or(this_value); + execution_context.arguments = function.bound_arguments(); if (arguments.has_value()) - call_frame.arguments.extend(arguments.value().values()); + execution_context.arguments.extend(arguments.value().values()); auto* environment = function.create_environment_record(); - call_frame.lexical_environment = environment; - call_frame.variable_environment = environment; + execution_context.lexical_environment = environment; + execution_context.variable_environment = environment; if (environment) { VERIFY(environment->this_binding_status() == FunctionEnvironmentRecord::ThisBindingStatus::Uninitialized); - environment->bind_this_value(function.global_object(), call_frame.this_value); + environment->bind_this_value(function.global_object(), execution_context.this_value); } if (exception()) return {}; - push_call_frame(call_frame, function.global_object()); + push_execution_context(execution_context, function.global_object()); if (exception()) return {}; auto result = function.call(); - pop_call_frame(); + pop_execution_context(); return result; } bool VM::in_strict_mode() const { - if (call_stack().is_empty()) + if (execution_context_stack().is_empty()) return false; - return call_frame().is_strict_mode; + return running_execution_context().is_strict_mode; } void VM::run_queued_promise_jobs() @@ -602,8 +603,8 @@ void VM::promise_rejection_tracker(const Promise& promise, Promise::RejectionOpe void VM::dump_backtrace() const { - for (ssize_t i = m_call_stack.size() - 1; i >= 0; --i) - dbgln("-> {}", m_call_stack[i]->function_name); + for (ssize_t i = m_execution_context_stack.size() - 1; i >= 0; --i) + dbgln("-> {}", m_execution_context_stack[i]->function_name); } void VM::dump_environment_record_chain() const diff --git a/Userland/Libraries/LibJS/Runtime/VM.h b/Userland/Libraries/LibJS/Runtime/VM.h index 44c8938251..4b568f7e65 100644 --- a/Userland/Libraries/LibJS/Runtime/VM.h +++ b/Userland/Libraries/LibJS/Runtime/VM.h @@ -42,7 +42,7 @@ struct ScopeFrame { bool pushed_environment { false }; }; -struct CallFrame { +struct ExecutionContext { const ASTNode* current_node { nullptr }; FlyString function_name; Value callee; @@ -100,7 +100,7 @@ public: return *m_single_ascii_character_strings[character]; } - void push_call_frame(CallFrame& call_frame, GlobalObject& global_object) + void push_execution_context(ExecutionContext& context, GlobalObject& global_object) { VERIFY(!exception()); // Ensure we got some stack space left, so the next function call doesn't kill us. @@ -108,58 +108,58 @@ public: if (m_stack_info.size_free() < 32 * KiB) throw_exception<Error>(global_object, "Call stack size limit exceeded"); else - m_call_stack.append(&call_frame); + m_execution_context_stack.append(&context); } - void pop_call_frame() + void pop_execution_context() { - m_call_stack.take_last(); - if (m_call_stack.is_empty() && on_call_stack_emptied) + m_execution_context_stack.take_last(); + if (m_execution_context_stack.is_empty() && on_call_stack_emptied) on_call_stack_emptied(); } - CallFrame& call_frame() { return *m_call_stack.last(); } - const CallFrame& call_frame() const { return *m_call_stack.last(); } - const Vector<CallFrame*>& call_stack() const { return m_call_stack; } - Vector<CallFrame*>& call_stack() { return m_call_stack; } + ExecutionContext& running_execution_context() { return *m_execution_context_stack.last(); } + ExecutionContext const& running_execution_context() const { return *m_execution_context_stack.last(); } + Vector<ExecutionContext*> const& execution_context_stack() const { return m_execution_context_stack; } + Vector<ExecutionContext*>& execution_context_stack() { return m_execution_context_stack; } - EnvironmentRecord const* lexical_environment() const { return call_frame().lexical_environment; } - EnvironmentRecord* lexical_environment() { return call_frame().lexical_environment; } + EnvironmentRecord const* lexical_environment() const { return running_execution_context().lexical_environment; } + EnvironmentRecord* lexical_environment() { return running_execution_context().lexical_environment; } - EnvironmentRecord const* variable_environment() const { return call_frame().variable_environment; } - EnvironmentRecord* variable_environment() { return call_frame().variable_environment; } + EnvironmentRecord const* variable_environment() const { return running_execution_context().variable_environment; } + EnvironmentRecord* variable_environment() { return running_execution_context().variable_environment; } bool in_strict_mode() const; template<typename Callback> void for_each_argument(Callback callback) { - if (m_call_stack.is_empty()) + if (m_execution_context_stack.is_empty()) return; - for (auto& value : call_frame().arguments) + for (auto& value : running_execution_context().arguments) callback(value); } size_t argument_count() const { - if (m_call_stack.is_empty()) + if (m_execution_context_stack.is_empty()) return 0; - return call_frame().arguments.size(); + return running_execution_context().arguments.size(); } Value argument(size_t index) const { - if (m_call_stack.is_empty()) + if (m_execution_context_stack.is_empty()) return {}; - auto& arguments = call_frame().arguments; + auto& arguments = running_execution_context().arguments; return index < arguments.size() ? arguments[index] : js_undefined(); } Value this_value(Object& global_object) const { - if (m_call_stack.is_empty()) + if (m_execution_context_stack.is_empty()) return &global_object; - return call_frame().this_value; + return running_execution_context().this_value; } Value last_value() const { return m_last_value; } @@ -264,7 +264,7 @@ private: Heap m_heap; Vector<Interpreter*> m_interpreters; - Vector<CallFrame*> m_call_stack; + Vector<ExecutionContext*> m_execution_context_stack; Value m_last_value; ScopeType m_unwind_until { ScopeType::None }; |