LibJS: Handle return value in switch statement unwinding

Fixes #3790.
This commit is contained in:
Linus Groh 2020-10-18 17:44:55 +01:00 committed by Andreas Kling
parent 2c888b3c6e
commit 8f54edb7a0
Notes: sideshowbarker 2024-07-19 01:51:26 +09:00
2 changed files with 22 additions and 4 deletions

View file

@ -1469,7 +1469,7 @@ Value VariableDeclaration::execute(Interpreter& interpreter, GlobalObject& globa
Value VariableDeclarator::execute(Interpreter&, GlobalObject&) const
{
// NOTE: This node is handled by VariableDeclaration.
// NOTE: VariableDeclarator execution is handled by VariableDeclaration.
ASSERT_NOT_REACHED();
}
@ -1894,15 +1894,18 @@ Value SwitchStatement::execute(Interpreter& interpreter, GlobalObject& global_ob
falling_through = true;
for (auto& statement : switch_case.consequent()) {
statement.execute(interpreter, global_object);
auto last_value = statement.execute(interpreter, global_object);
if (interpreter.exception())
return {};
if (interpreter.vm().should_unwind()) {
if (interpreter.vm().should_unwind_until(ScopeType::Breakable, m_label)) {
if (interpreter.vm().should_unwind_until(ScopeType::Continuable, m_label)) {
ASSERT_NOT_REACHED();
} else if (interpreter.vm().should_unwind_until(ScopeType::Breakable, m_label)) {
interpreter.vm().stop_unwind();
return {};
} else {
return last_value;
}
return {};
}
}
}
@ -1912,6 +1915,8 @@ Value SwitchStatement::execute(Interpreter& interpreter, GlobalObject& global_ob
Value SwitchCase::execute(Interpreter&, GlobalObject&) const
{
// NOTE: SwitchCase execution is handled by SwitchStatement.
ASSERT_NOT_REACHED();
return {};
}

View file

@ -36,4 +36,17 @@ describe("basic switch tests", () => {
expect().fail();
});
test("return from switch statement", () => {
function foo(value) {
switch (value) {
case 42:
return "return from 'case 42'";
default:
return "return from 'default'";
}
}
expect(foo(42)).toBe("return from 'case 42'");
expect(foo(43)).toBe("return from 'default'");
});
});