summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibJS/Runtime
diff options
context:
space:
mode:
Diffstat (limited to 'Userland/Libraries/LibJS/Runtime')
-rw-r--r--Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp2
-rw-r--r--Userland/Libraries/LibJS/Runtime/Exception.cpp12
-rw-r--r--Userland/Libraries/LibJS/Runtime/FunctionPrototype.cpp2
-rw-r--r--Userland/Libraries/LibJS/Runtime/GeneratorObject.cpp2
-rw-r--r--Userland/Libraries/LibJS/Runtime/Object.cpp24
-rw-r--r--Userland/Libraries/LibJS/Runtime/ScriptFunction.cpp18
-rw-r--r--Userland/Libraries/LibJS/Runtime/VM.cpp97
-rw-r--r--Userland/Libraries/LibJS/Runtime/VM.h46
8 files changed, 102 insertions, 101 deletions
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 };