mirror of
https://github.com/RGBCube/serenity
synced 2025-05-29 06:55:07 +00:00
LibJS: Intercept returns through finally blocks in Bytecode
This is still not perfect, as we now actually crash in the `try-finally-continue` tests, while we now succeed all `try-catch-finally-*` tests. Note that we do not yet go through the finally block when exiting the unwind context through a break or continue.
This commit is contained in:
parent
c2108489a5
commit
fcc3348bc8
5 changed files with 81 additions and 9 deletions
|
@ -268,12 +268,17 @@ Label Generator::perform_needed_unwinds_for_labelled_break_and_return_target_blo
|
|||
for (auto& breakable_scope : m_breakable_scopes.in_reverse()) {
|
||||
for (; current_boundary > 0; --current_boundary) {
|
||||
auto boundary = m_boundaries[current_boundary - 1];
|
||||
// FIXME: Handle ReturnToFinally in a graceful manner
|
||||
// We need to execute the finally block, but tell it to resume
|
||||
// execution at the designated label
|
||||
if (boundary == BlockBoundaryType::Unwind) {
|
||||
emit<Bytecode::Op::LeaveUnwindContext>();
|
||||
} else if (boundary == BlockBoundaryType::LeaveLexicalEnvironment) {
|
||||
emit<Bytecode::Op::LeaveEnvironment>(Bytecode::Op::EnvironmentMode::Lexical);
|
||||
} else if (boundary == BlockBoundaryType::LeaveVariableEnvironment) {
|
||||
emit<Bytecode::Op::LeaveEnvironment>(Bytecode::Op::EnvironmentMode::Var);
|
||||
} else if (boundary == BlockBoundaryType::ReturnToFinally) {
|
||||
// FIXME: We need to enter the `finally`, while still scheduling the break to happen
|
||||
} else if (boundary == BlockBoundaryType::Break) {
|
||||
// Make sure we don't process this boundary twice if the current breakable scope doesn't contain the target label.
|
||||
--current_boundary;
|
||||
|
@ -295,12 +300,17 @@ Label Generator::perform_needed_unwinds_for_labelled_continue_and_return_target_
|
|||
for (auto& continuable_scope : m_continuable_scopes.in_reverse()) {
|
||||
for (; current_boundary > 0; --current_boundary) {
|
||||
auto boundary = m_boundaries[current_boundary - 1];
|
||||
// FIXME: Handle ReturnToFinally in a graceful manner
|
||||
// We need to execute the finally block, but tell it to resume
|
||||
// execution at the designated label
|
||||
if (boundary == BlockBoundaryType::Unwind) {
|
||||
emit<Bytecode::Op::LeaveUnwindContext>();
|
||||
} else if (boundary == BlockBoundaryType::LeaveLexicalEnvironment) {
|
||||
emit<Bytecode::Op::LeaveEnvironment>(Bytecode::Op::EnvironmentMode::Lexical);
|
||||
} else if (boundary == BlockBoundaryType::LeaveVariableEnvironment) {
|
||||
emit<Bytecode::Op::LeaveEnvironment>(Bytecode::Op::EnvironmentMode::Var);
|
||||
} else if (boundary == BlockBoundaryType::ReturnToFinally) {
|
||||
// FIXME: We need to enter the `finally`, while still scheduling the continue to happen
|
||||
} else if (boundary == BlockBoundaryType::Continue) {
|
||||
// Make sure we don't process this boundary twice if the current continuable scope doesn't contain the target label.
|
||||
--current_boundary;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue