summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorLuke Wilde <lukew@serenityos.org>2022-03-14 02:26:39 +0000
committerAli Mohammad Pur <Ali.mpfard@gmail.com>2022-03-14 21:15:27 +0330
commit9f4cc6435d8f7533641aac3951d4b4dd87649035 (patch)
tree14864f64a4668c0004b40cb07e9a442f9fd46862 /Userland
parent858bcac4c7baa26a7a31310d5d220f60a43f5cd9 (diff)
downloadserenity-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.cpp1
-rw-r--r--Userland/Libraries/LibJS/Bytecode/Generator.h2
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;