summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHendiadyoin1 <leon.a@serenityos.org>2022-11-25 16:42:29 +0100
committerLinus Groh <mail@linusgroh.de>2023-02-26 19:40:09 +0100
commit088dc1b24b8160da93946b60d5eab56e9f6fe692 (patch)
treec9b661c16a950376b12d0e1e5ffe93a95fdd14ac
parentd65488b80c19123cd34e169a1d27093221a504f0 (diff)
downloadserenity-088dc1b24b8160da93946b60d5eab56e9f6fe692.zip
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.
-rw-r--r--Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp3
-rw-r--r--Userland/Libraries/LibJS/Bytecode/Generator.h20
2 files changed, 5 insertions, 18 deletions
diff --git a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp
index 49aa9e640f..bdbd344963 100644
--- a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp
+++ b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp
@@ -2474,8 +2474,7 @@ static Bytecode::CodeGenerationErrorOr<ForInOfHeadEvaluationResult> for_in_of_he
// i. Return Completion Record { [[Type]]: break, [[Value]]: empty, [[Target]]: empty }.
generator.switch_to_basic_block(nullish_block);
- generator.perform_needed_unwinds<Bytecode::Op::Jump>(true);
- generator.emit<Bytecode::Op::Jump>().set_targets(generator.nearest_breakable_scope(), {});
+ generator.generate_break();
generator.switch_to_basic_block(continuation_block);
// b. Let obj be ! ToObject(exprValue).
diff --git a/Userland/Libraries/LibJS/Bytecode/Generator.h b/Userland/Libraries/LibJS/Bytecode/Generator.h
index 12bb4c9e6c..c56af24b01 100644
--- a/Userland/Libraries/LibJS/Bytecode/Generator.h
+++ b/Userland/Libraries/LibJS/Bytecode/Generator.h
@@ -174,24 +174,16 @@ public:
LeaveVariableEnvironment,
};
template<typename OpType>
- void perform_needed_unwinds(bool is_break_node = false)
- requires(OpType::IsTerminator)
+ void perform_needed_unwinds()
+ 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) {
auto boundary = m_boundaries[i - 1];
- if (boundary_to_stop_at.has_value() && boundary == *boundary_to_stop_at)
- break;
using enum BlockBoundaryType;
switch (boundary) {
case Unwind:
+ if constexpr (IsSame<OpType, Bytecode::Op::Throw>)
+ return;
emit<Bytecode::Op::LeaveUnwindContext>();
break;
case LeaveLexicalEnvironment:
@@ -204,10 +196,6 @@ public:
case Continue:
break;
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;
};
}