mirror of
https://github.com/RGBCube/serenity
synced 2025-05-28 12:55:09 +00:00
LibJS: Convert Instruction::execute in bytecode to ThrowCompletionOr
This allows us to use TRY in these functions :^).
This commit is contained in:
parent
de90d54be0
commit
8108fc7f9c
6 changed files with 238 additions and 294 deletions
|
@ -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 {};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue