summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp
diff options
context:
space:
mode:
authordavidot <davidot@serenityos.org>2022-02-07 14:36:45 +0100
committerLinus Groh <mail@linusgroh.de>2022-02-08 09:12:42 +0000
commit8108fc7f9c05f368eee0f98828b62d5bbabb5720 (patch)
treed3e5cb4180307b3d77ae2f8574cc6e6832e92994 /Userland/Libraries/LibJS/Bytecode/Interpreter.cpp
parentde90d54be08f0f09b86895916d419833e8a01e5b (diff)
downloadserenity-8108fc7f9c05f368eee0f98828b62d5bbabb5720.zip
LibJS: Convert Instruction::execute in bytecode to ThrowCompletionOr
This allows us to use TRY in these functions :^).
Diffstat (limited to 'Userland/Libraries/LibJS/Bytecode/Interpreter.cpp')
-rw-r--r--Userland/Libraries/LibJS/Bytecode/Interpreter.cpp44
1 files changed, 25 insertions, 19 deletions
diff --git a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp
index 3dfb8c509c..5387b05f7f 100644
--- a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp
+++ b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp
@@ -44,6 +44,7 @@ Interpreter::ValueAndFrame Interpreter::run_and_return_frame(Executable const& e
dbgln_if(JS_BYTECODE_DEBUG, "Bytecode::Interpreter will run unit {:p}", &executable);
TemporaryChange restore_executable { m_current_executable, &executable };
+ VERIFY(m_saved_exception.is_null());
ExecutionContext execution_context(vm().heap());
if (vm().execution_context_stack().is_empty() || !vm().running_execution_context().lexical_environment) {
@@ -76,9 +77,17 @@ Interpreter::ValueAndFrame Interpreter::run_and_return_frame(Executable const& e
bool will_return = false;
while (!pc.at_end()) {
auto& instruction = *pc;
- instruction.execute(*this);
+ auto ran_or_error = instruction.execute(*this);
if (vm().exception()) {
- m_saved_exception = {};
+ if (!ran_or_error.is_error()) {
+ // FIXME: Until exception is removed use this to make sure we always get the error if there is one.
+ ran_or_error = throw_completion(vm().exception()->value());
+ }
+ vm().clear_exception();
+ }
+ if (ran_or_error.is_error()) {
+ auto exception_value = *ran_or_error.throw_completion().value();
+ m_saved_exception = make_handle(exception_value);
if (m_unwind_contexts.is_empty())
break;
auto& unwind_context = m_unwind_contexts.last();
@@ -87,8 +96,8 @@ Interpreter::ValueAndFrame Interpreter::run_and_return_frame(Executable const& e
if (unwind_context.handler) {
block = unwind_context.handler;
unwind_context.handler = nullptr;
- accumulator() = vm().exception()->value();
- vm().clear_exception();
+ accumulator() = exception_value;
+ m_saved_exception = {};
will_jump = true;
break;
}
@@ -96,8 +105,6 @@ Interpreter::ValueAndFrame Interpreter::run_and_return_frame(Executable const& e
block = unwind_context.finalizer;
m_unwind_contexts.take_last();
will_jump = true;
- m_saved_exception = Handle<Exception>::create(vm().exception());
- vm().clear_exception();
break;
}
}
@@ -119,7 +126,7 @@ Interpreter::ValueAndFrame Interpreter::run_and_return_frame(Executable const& e
if (pc.at_end() && !will_jump)
break;
- if (vm().exception())
+ if (!m_saved_exception.is_null())
break;
}
@@ -142,12 +149,6 @@ Interpreter::ValueAndFrame Interpreter::run_and_return_frame(Executable const& e
m_manually_entered_frames.take_last();
}
- Value exception_value;
- if (vm().exception()) {
- exception_value = vm().exception()->value();
- vm().clear_exception();
- }
-
auto return_value = m_return_value.value_or(js_undefined());
m_return_value = {};
@@ -164,8 +165,11 @@ Interpreter::ValueAndFrame Interpreter::run_and_return_frame(Executable const& e
vm().finish_execution_generation();
- if (!exception_value.is_empty())
- return { throw_completion(exception_value), move(frame) };
+ if (!m_saved_exception.is_null()) {
+ Value thrown_value = m_saved_exception.value();
+ m_saved_exception = {};
+ return { throw_completion(thrown_value), move(frame) };
+ }
return { return_value, move(frame) };
}
@@ -180,14 +184,16 @@ void Interpreter::leave_unwind_context()
m_unwind_contexts.take_last();
}
-void Interpreter::continue_pending_unwind(Label const& resume_label)
+ThrowCompletionOr<void> Interpreter::continue_pending_unwind(Label const& resume_label)
{
if (!m_saved_exception.is_null()) {
- vm().set_exception(*m_saved_exception.cell());
+ auto result = throw_completion(m_saved_exception.value());
m_saved_exception = {};
- } else {
- jump(resume_label);
+ return result;
}
+
+ jump(resume_label);
+ return {};
}
AK::Array<OwnPtr<PassManager>, static_cast<UnderlyingType<Interpreter::OptimizationLevel>>(Interpreter::OptimizationLevel::__Count)> Interpreter::s_optimization_pipelines {};