diff options
author | davidot <davidot@serenityos.org> | 2022-02-07 14:36:45 +0100 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-02-08 09:12:42 +0000 |
commit | 8108fc7f9c05f368eee0f98828b62d5bbabb5720 (patch) | |
tree | d3e5cb4180307b3d77ae2f8574cc6e6832e92994 /Userland/Libraries/LibJS/Bytecode/Interpreter.cpp | |
parent | de90d54be08f0f09b86895916d419833e8a01e5b (diff) | |
download | serenity-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.cpp | 44 |
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 {}; |