mirror of
https://github.com/RGBCube/serenity
synced 2025-05-28 18:45:10 +00:00
LibJS: Keep current exception in a call frame register
Instead of keeping it in a Bytecode::Interpreter member, move it into a dedicated call frame register.
This commit is contained in:
parent
ebb822def9
commit
3887b840a3
4 changed files with 20 additions and 20 deletions
|
@ -252,7 +252,7 @@ private:
|
||||||
NonnullOwnPtr<IdentifierTable> m_identifier_table;
|
NonnullOwnPtr<IdentifierTable> m_identifier_table;
|
||||||
NonnullOwnPtr<RegexTable> m_regex_table;
|
NonnullOwnPtr<RegexTable> m_regex_table;
|
||||||
|
|
||||||
u32 m_next_register { 2 };
|
u32 m_next_register { 3 };
|
||||||
u32 m_next_block { 1 };
|
u32 m_next_block { 1 };
|
||||||
u32 m_next_property_lookup_cache { 0 };
|
u32 m_next_property_lookup_cache { 0 };
|
||||||
u32 m_next_global_variable_cache { 0 };
|
u32 m_next_global_variable_cache { 0 };
|
||||||
|
|
|
@ -33,8 +33,6 @@ void Interpreter::visit_edges(Cell::Visitor& visitor)
|
||||||
{
|
{
|
||||||
if (m_return_value.has_value())
|
if (m_return_value.has_value())
|
||||||
visitor.visit(*m_return_value);
|
visitor.visit(*m_return_value);
|
||||||
if (m_saved_exception.has_value())
|
|
||||||
visitor.visit(*m_saved_exception);
|
|
||||||
for (auto& frame : m_call_frames) {
|
for (auto& frame : m_call_frames) {
|
||||||
frame.visit([&](auto& value) { value->visit_edges(visitor); });
|
frame.visit([&](auto& value) { value->visit_edges(visitor); });
|
||||||
}
|
}
|
||||||
|
@ -171,7 +169,6 @@ Interpreter::ValueAndFrame Interpreter::run_and_return_frame(Executable& executa
|
||||||
|
|
||||||
TemporaryChange restore_executable { m_current_executable, &executable };
|
TemporaryChange restore_executable { m_current_executable, &executable };
|
||||||
TemporaryChange restore_saved_jump { m_scheduled_jump, static_cast<BasicBlock const*>(nullptr) };
|
TemporaryChange restore_saved_jump { m_scheduled_jump, static_cast<BasicBlock const*>(nullptr) };
|
||||||
TemporaryChange restore_saved_exception { m_saved_exception, {} };
|
|
||||||
|
|
||||||
VERIFY(!vm().execution_context_stack().is_empty());
|
VERIFY(!vm().execution_context_stack().is_empty());
|
||||||
|
|
||||||
|
@ -196,8 +193,7 @@ Interpreter::ValueAndFrame Interpreter::run_and_return_frame(Executable& executa
|
||||||
auto& instruction = *pc;
|
auto& instruction = *pc;
|
||||||
auto ran_or_error = instruction.execute(*this);
|
auto ran_or_error = instruction.execute(*this);
|
||||||
if (ran_or_error.is_error()) {
|
if (ran_or_error.is_error()) {
|
||||||
auto exception_value = *ran_or_error.throw_completion().value();
|
reg(Register::exception()) = *ran_or_error.throw_completion().value();
|
||||||
m_saved_exception = exception_value;
|
|
||||||
if (unwind_contexts().is_empty())
|
if (unwind_contexts().is_empty())
|
||||||
break;
|
break;
|
||||||
auto& unwind_context = unwind_contexts().last();
|
auto& unwind_context = unwind_contexts().last();
|
||||||
|
@ -208,8 +204,8 @@ Interpreter::ValueAndFrame Interpreter::run_and_return_frame(Executable& executa
|
||||||
m_current_block = unwind_context.handler;
|
m_current_block = unwind_context.handler;
|
||||||
unwind_context.handler_called = true;
|
unwind_context.handler_called = true;
|
||||||
|
|
||||||
accumulator() = exception_value;
|
accumulator() = reg(Register::exception());
|
||||||
m_saved_exception = {};
|
reg(Register::exception()) = {};
|
||||||
will_jump = true;
|
will_jump = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -219,7 +215,7 @@ Interpreter::ValueAndFrame Interpreter::run_and_return_frame(Executable& executa
|
||||||
// from the `finally` block. But if the exception is from the `try` block, and has already been
|
// from the `finally` block. But if the exception is from the `try` block, and has already been
|
||||||
// handled by `catch`, we swallow it.
|
// handled by `catch`, we swallow it.
|
||||||
if (!unwind_context.handler_called)
|
if (!unwind_context.handler_called)
|
||||||
m_saved_exception = {};
|
reg(Register::exception()) = {};
|
||||||
will_jump = true;
|
will_jump = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -261,7 +257,7 @@ Interpreter::ValueAndFrame Interpreter::run_and_return_frame(Executable& executa
|
||||||
if (pc.at_end())
|
if (pc.at_end())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (m_saved_exception.has_value())
|
if (!reg(Register::exception()).is_empty())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (will_return)
|
if (will_return)
|
||||||
|
@ -282,6 +278,7 @@ Interpreter::ValueAndFrame Interpreter::run_and_return_frame(Executable& executa
|
||||||
}
|
}
|
||||||
|
|
||||||
auto saved_return_value = reg(Register::saved_return_value());
|
auto saved_return_value = reg(Register::saved_return_value());
|
||||||
|
auto exception = reg(Register::exception());
|
||||||
|
|
||||||
auto frame = pop_call_frame();
|
auto frame = pop_call_frame();
|
||||||
|
|
||||||
|
@ -302,12 +299,10 @@ Interpreter::ValueAndFrame Interpreter::run_and_return_frame(Executable& executa
|
||||||
|
|
||||||
vm().finish_execution_generation();
|
vm().finish_execution_generation();
|
||||||
|
|
||||||
if (m_saved_exception.has_value()) {
|
if (!exception.is_empty()) {
|
||||||
Value thrown_value = m_saved_exception.value();
|
|
||||||
m_saved_exception = {};
|
|
||||||
if (auto* call_frame = frame.get_pointer<NonnullOwnPtr<CallFrame>>())
|
if (auto* call_frame = frame.get_pointer<NonnullOwnPtr<CallFrame>>())
|
||||||
return { throw_completion(thrown_value), move(*call_frame) };
|
return { throw_completion(exception), move(*call_frame) };
|
||||||
return { throw_completion(thrown_value), nullptr };
|
return { throw_completion(exception), nullptr };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto* call_frame = frame.get_pointer<NonnullOwnPtr<CallFrame>>())
|
if (auto* call_frame = frame.get_pointer<NonnullOwnPtr<CallFrame>>())
|
||||||
|
@ -331,9 +326,8 @@ void Interpreter::leave_unwind_context()
|
||||||
|
|
||||||
ThrowCompletionOr<void> Interpreter::continue_pending_unwind(Label const& resume_label)
|
ThrowCompletionOr<void> Interpreter::continue_pending_unwind(Label const& resume_label)
|
||||||
{
|
{
|
||||||
if (m_saved_exception.has_value()) {
|
if (auto exception = reg(Register::exception()); !exception.is_empty())
|
||||||
return throw_completion(m_saved_exception.release_value());
|
return throw_completion(exception);
|
||||||
}
|
|
||||||
|
|
||||||
if (!saved_return_value().is_empty()) {
|
if (!saved_return_value().is_empty()) {
|
||||||
do_return(saved_return_value());
|
do_return(saved_return_value());
|
||||||
|
|
|
@ -77,7 +77,7 @@ public:
|
||||||
void do_return(Value return_value)
|
void do_return(Value return_value)
|
||||||
{
|
{
|
||||||
m_return_value = return_value;
|
m_return_value = return_value;
|
||||||
m_saved_exception = {};
|
reg(Register::exception()) = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void enter_unwind_context(Optional<Label> handler_target, Optional<Label> finalizer_target);
|
void enter_unwind_context(Optional<Label> handler_target, Optional<Label> finalizer_target);
|
||||||
|
@ -118,7 +118,6 @@ private:
|
||||||
BasicBlock const* m_scheduled_jump { nullptr };
|
BasicBlock const* m_scheduled_jump { nullptr };
|
||||||
Optional<Value> m_this_value;
|
Optional<Value> m_this_value;
|
||||||
Optional<Value> m_return_value;
|
Optional<Value> m_return_value;
|
||||||
Optional<Value> m_saved_exception;
|
|
||||||
Executable* m_current_executable { nullptr };
|
Executable* m_current_executable { nullptr };
|
||||||
BasicBlock const* m_current_block { nullptr };
|
BasicBlock const* m_current_block { nullptr };
|
||||||
Optional<InstructionStreamIterator&> m_pc {};
|
Optional<InstructionStreamIterator&> m_pc {};
|
||||||
|
|
|
@ -26,6 +26,13 @@ public:
|
||||||
return Register(saved_return_value_index);
|
return Register(saved_return_value_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static constexpr u32 exception_index = 2;
|
||||||
|
|
||||||
|
static constexpr Register exception()
|
||||||
|
{
|
||||||
|
return Register(exception_index);
|
||||||
|
}
|
||||||
|
|
||||||
constexpr explicit Register(u32 index)
|
constexpr explicit Register(u32 index)
|
||||||
: m_index(index)
|
: m_index(index)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue