mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 16:07:35 +00:00
LibJS: Simplify Generator::perform_needed_unwinds
This does not need to cater to the needs of `break` and `continue anymore, which allows us to simplify it a bit.
This commit is contained in:
parent
d65488b80c
commit
088dc1b24b
2 changed files with 5 additions and 18 deletions
|
@ -2474,8 +2474,7 @@ static Bytecode::CodeGenerationErrorOr<ForInOfHeadEvaluationResult> for_in_of_he
|
||||||
|
|
||||||
// i. Return Completion Record { [[Type]]: break, [[Value]]: empty, [[Target]]: empty }.
|
// i. Return Completion Record { [[Type]]: break, [[Value]]: empty, [[Target]]: empty }.
|
||||||
generator.switch_to_basic_block(nullish_block);
|
generator.switch_to_basic_block(nullish_block);
|
||||||
generator.perform_needed_unwinds<Bytecode::Op::Jump>(true);
|
generator.generate_break();
|
||||||
generator.emit<Bytecode::Op::Jump>().set_targets(generator.nearest_breakable_scope(), {});
|
|
||||||
|
|
||||||
generator.switch_to_basic_block(continuation_block);
|
generator.switch_to_basic_block(continuation_block);
|
||||||
// b. Let obj be ! ToObject(exprValue).
|
// b. Let obj be ! ToObject(exprValue).
|
||||||
|
|
|
@ -174,24 +174,16 @@ public:
|
||||||
LeaveVariableEnvironment,
|
LeaveVariableEnvironment,
|
||||||
};
|
};
|
||||||
template<typename OpType>
|
template<typename OpType>
|
||||||
void perform_needed_unwinds(bool is_break_node = false)
|
void perform_needed_unwinds()
|
||||||
requires(OpType::IsTerminator)
|
requires(OpType::IsTerminator && !IsSame<OpType, Op::Jump>)
|
||||||
{
|
{
|
||||||
Optional<BlockBoundaryType> boundary_to_stop_at;
|
|
||||||
if constexpr (IsSame<OpType, Bytecode::Op::Return> || IsSame<OpType, Bytecode::Op::Yield>)
|
|
||||||
VERIFY(!is_break_node);
|
|
||||||
else if constexpr (IsSame<OpType, Bytecode::Op::Throw>)
|
|
||||||
boundary_to_stop_at = BlockBoundaryType::Unwind;
|
|
||||||
else
|
|
||||||
boundary_to_stop_at = is_break_node ? BlockBoundaryType::Break : BlockBoundaryType::Continue;
|
|
||||||
|
|
||||||
for (size_t i = m_boundaries.size(); i > 0; --i) {
|
for (size_t i = m_boundaries.size(); i > 0; --i) {
|
||||||
auto boundary = m_boundaries[i - 1];
|
auto boundary = m_boundaries[i - 1];
|
||||||
if (boundary_to_stop_at.has_value() && boundary == *boundary_to_stop_at)
|
|
||||||
break;
|
|
||||||
using enum BlockBoundaryType;
|
using enum BlockBoundaryType;
|
||||||
switch (boundary) {
|
switch (boundary) {
|
||||||
case Unwind:
|
case Unwind:
|
||||||
|
if constexpr (IsSame<OpType, Bytecode::Op::Throw>)
|
||||||
|
return;
|
||||||
emit<Bytecode::Op::LeaveUnwindContext>();
|
emit<Bytecode::Op::LeaveUnwindContext>();
|
||||||
break;
|
break;
|
||||||
case LeaveLexicalEnvironment:
|
case LeaveLexicalEnvironment:
|
||||||
|
@ -204,10 +196,6 @@ public:
|
||||||
case Continue:
|
case Continue:
|
||||||
break;
|
break;
|
||||||
case ReturnToFinally:
|
case ReturnToFinally:
|
||||||
// FIXME: In the case of breaks/continues we need to tell the `finally` to break/continue
|
|
||||||
// For now let's ignore the finally to avoid a crash
|
|
||||||
if (IsSame<OpType, Bytecode::Op::Jump>)
|
|
||||||
break;
|
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue