diff options
author | Luke Wilde <lukew@serenityos.org> | 2022-03-14 02:26:39 +0000 |
---|---|---|
committer | Ali Mohammad Pur <Ali.mpfard@gmail.com> | 2022-03-14 21:15:27 +0330 |
commit | 9f4cc6435d8f7533641aac3951d4b4dd87649035 (patch) | |
tree | 14864f64a4668c0004b40cb07e9a442f9fd46862 /Userland | |
parent | 858bcac4c7baa26a7a31310d5d220f60a43f5cd9 (diff) | |
download | serenity-9f4cc6435d8f7533641aac3951d4b4dd87649035.zip |
LibJS/Bytecode: Unwind to closest unwind boundary on Throw
This will leave any lexical/variable environments on the way to the
closest unwind context boundary.
This will not leave the closest unwind context, as we still need the
unwind context to perform the Throw instruction correctly.
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Bytecode/Generator.h | 2 |
2 files changed, 3 insertions, 0 deletions
diff --git a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp index cce2818b6b..2ccd183519 100644 --- a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp +++ b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp @@ -1441,6 +1441,7 @@ Bytecode::CodeGenerationErrorOr<void> UpdateExpression::generate_bytecode(Byteco Bytecode::CodeGenerationErrorOr<void> ThrowStatement::generate_bytecode(Bytecode::Generator& generator) const { TRY(m_argument->generate_bytecode(generator)); + generator.perform_needed_unwinds<Bytecode::Op::Throw>(); generator.emit<Bytecode::Op::Throw>(); return {}; } diff --git a/Userland/Libraries/LibJS/Bytecode/Generator.h b/Userland/Libraries/LibJS/Bytecode/Generator.h index 91662a9aea..6ebb9ad4a0 100644 --- a/Userland/Libraries/LibJS/Bytecode/Generator.h +++ b/Userland/Libraries/LibJS/Bytecode/Generator.h @@ -167,6 +167,8 @@ public: 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; |