mirror of
https://github.com/RGBCube/serenity
synced 2025-05-18 21:35:06 +00:00
LibJS: Propagate exceptions across bytecode executable boundaries
To support situations like this: function foo() { throw 1; } try { foo(); } catch (e) { } Each unwind context now keeps track of its origin executable. When an exception is thrown, we return from run() immediately if the nearest unwind context isn't in the current executable. This causes a natural unwind to the point where we find the catch/finally block(s) to jump into.
This commit is contained in:
parent
5a099b98cd
commit
3618ca2420
2 changed files with 4 additions and 1 deletions
|
@ -82,6 +82,8 @@ Value Interpreter::run(Executable const& executable, BasicBlock const* entry_poi
|
|||
if (m_unwind_contexts.is_empty())
|
||||
break;
|
||||
auto& unwind_context = m_unwind_contexts.last();
|
||||
if (unwind_context.executable != m_current_executable)
|
||||
break;
|
||||
if (unwind_context.handler) {
|
||||
block = unwind_context.handler;
|
||||
unwind_context.handler = nullptr;
|
||||
|
@ -156,7 +158,7 @@ Value Interpreter::run(Executable const& executable, BasicBlock const* entry_poi
|
|||
|
||||
void Interpreter::enter_unwind_context(Optional<Label> handler_target, Optional<Label> finalizer_target)
|
||||
{
|
||||
m_unwind_contexts.empend(handler_target.has_value() ? &handler_target->block() : nullptr, finalizer_target.has_value() ? &finalizer_target->block() : nullptr);
|
||||
m_unwind_contexts.empend(m_current_executable, handler_target.has_value() ? &handler_target->block() : nullptr, finalizer_target.has_value() ? &finalizer_target->block() : nullptr);
|
||||
}
|
||||
|
||||
void Interpreter::leave_unwind_context()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue