1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-06-01 02:28:12 +00:00

LibJS: Allow statements to have multiple labels

This is a curious thing that occurs more often than you'd think in
minified JavaScript:

    a: b: c: for (...) { ... break b; ... }
This commit is contained in:
Andreas Kling 2021-09-26 18:16:06 +02:00
parent ababcc5725
commit 3252d984ae
6 changed files with 31 additions and 21 deletions

View file

@ -395,9 +395,9 @@ Value WhileStatement::execute(Interpreter& interpreter, GlobalObject& global_obj
if (interpreter.exception())
return {};
if (interpreter.vm().should_unwind()) {
if (interpreter.vm().should_unwind_until(ScopeType::Continuable, m_label)) {
if (interpreter.vm().should_unwind_until(ScopeType::Continuable, m_labels)) {
interpreter.vm().stop_unwind();
} else if (interpreter.vm().should_unwind_until(ScopeType::Breakable, m_label)) {
} else if (interpreter.vm().should_unwind_until(ScopeType::Breakable, m_labels)) {
interpreter.vm().stop_unwind();
break;
} else {
@ -421,9 +421,9 @@ Value DoWhileStatement::execute(Interpreter& interpreter, GlobalObject& global_o
if (interpreter.exception())
return {};
if (interpreter.vm().should_unwind()) {
if (interpreter.vm().should_unwind_until(ScopeType::Continuable, m_label)) {
if (interpreter.vm().should_unwind_until(ScopeType::Continuable, m_labels)) {
interpreter.vm().stop_unwind();
} else if (interpreter.vm().should_unwind_until(ScopeType::Breakable, m_label)) {
} else if (interpreter.vm().should_unwind_until(ScopeType::Breakable, m_labels)) {
interpreter.vm().stop_unwind();
break;
} else {
@ -477,9 +477,9 @@ Value ForStatement::execute(Interpreter& interpreter, GlobalObject& global_objec
if (interpreter.exception())
return {};
if (interpreter.vm().should_unwind()) {
if (interpreter.vm().should_unwind_until(ScopeType::Continuable, m_label)) {
if (interpreter.vm().should_unwind_until(ScopeType::Continuable, m_labels)) {
interpreter.vm().stop_unwind();
} else if (interpreter.vm().should_unwind_until(ScopeType::Breakable, m_label)) {
} else if (interpreter.vm().should_unwind_until(ScopeType::Breakable, m_labels)) {
interpreter.vm().stop_unwind();
break;
} else {
@ -498,9 +498,9 @@ Value ForStatement::execute(Interpreter& interpreter, GlobalObject& global_objec
if (interpreter.exception())
return {};
if (interpreter.vm().should_unwind()) {
if (interpreter.vm().should_unwind_until(ScopeType::Continuable, m_label)) {
if (interpreter.vm().should_unwind_until(ScopeType::Continuable, m_labels)) {
interpreter.vm().stop_unwind();
} else if (interpreter.vm().should_unwind_until(ScopeType::Breakable, m_label)) {
} else if (interpreter.vm().should_unwind_until(ScopeType::Breakable, m_labels)) {
interpreter.vm().stop_unwind();
break;
} else {
@ -570,9 +570,9 @@ Value ForInStatement::execute(Interpreter& interpreter, GlobalObject& global_obj
if (interpreter.exception())
return {};
if (interpreter.vm().should_unwind()) {
if (interpreter.vm().should_unwind_until(ScopeType::Continuable, m_label)) {
if (interpreter.vm().should_unwind_until(ScopeType::Continuable, m_labels)) {
interpreter.vm().stop_unwind();
} else if (interpreter.vm().should_unwind_until(ScopeType::Breakable, m_label)) {
} else if (interpreter.vm().should_unwind_until(ScopeType::Breakable, m_labels)) {
interpreter.vm().stop_unwind();
break;
} else {
@ -613,9 +613,9 @@ Value ForOfStatement::execute(Interpreter& interpreter, GlobalObject& global_obj
if (interpreter.exception())
return IterationDecision::Break;
if (interpreter.vm().should_unwind()) {
if (interpreter.vm().should_unwind_until(ScopeType::Continuable, m_label)) {
if (interpreter.vm().should_unwind_until(ScopeType::Continuable, m_labels)) {
interpreter.vm().stop_unwind();
} else if (interpreter.vm().should_unwind_until(ScopeType::Breakable, m_label)) {
} else if (interpreter.vm().should_unwind_until(ScopeType::Breakable, m_labels)) {
interpreter.vm().stop_unwind();
return IterationDecision::Break;
} else {
@ -2429,10 +2429,10 @@ Value SwitchStatement::execute(Interpreter& interpreter, GlobalObject& global_ob
if (interpreter.exception())
return Value {};
if (interpreter.vm().should_unwind()) {
if (interpreter.vm().should_unwind_until(ScopeType::Continuable, m_label)) {
if (interpreter.vm().should_unwind_until(ScopeType::Continuable, m_labels)) {
// No stop_unwind(), the outer loop will handle that - we just need to break out of the switch/case.
return last_value;
} else if (interpreter.vm().should_unwind_until(ScopeType::Breakable, m_label)) {
} else if (interpreter.vm().should_unwind_until(ScopeType::Breakable, m_labels)) {
interpreter.vm().stop_unwind();
return last_value;
} else {