diff options
author | Luke Wilde <lukew@serenityos.org> | 2022-03-14 02:13:33 +0000 |
---|---|---|
committer | Ali Mohammad Pur <Ali.mpfard@gmail.com> | 2022-03-14 21:15:27 +0330 |
commit | 0356239f3e4d31a0b19e8582403edd896100db69 (patch) | |
tree | 800395a75edd5a51357ec34001e01cb5bebca90f /Userland/Libraries | |
parent | 27904b106003a28ffe4f8a76a1500bd5fe1c2454 (diff) | |
download | serenity-0356239f3e4d31a0b19e8582403edd896100db69.zip |
LibJS/Bytecode: Unconditionally end break/continuable scopes
Previously we would only end these scopes if the block was not
terminated. If the block was generated, we would not end the scope
and would generate other bytecode with these scopes still open.
These functions do not generate any code, so they can be used even if
the current block is terminated. The enter and end scope functions are
only used to track where to unwind to when break/continue are used.
Diffstat (limited to 'Userland/Libraries')
-rw-r--r-- | Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp index b26e55cc58..cce2818b6b 100644 --- a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp +++ b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp @@ -642,12 +642,13 @@ Bytecode::CodeGenerationErrorOr<void> WhileStatement::generate_bytecode(Bytecode generator.begin_continuable_scope(Bytecode::Label { test_block }); generator.begin_breakable_scope(Bytecode::Label { end_block }); TRY(m_body->generate_bytecode(generator)); + generator.end_breakable_scope(); + generator.end_continuable_scope(); + if (!generator.is_current_block_terminated()) { generator.emit<Bytecode::Op::Jump>().set_targets( Bytecode::Label { test_block }, {}); - generator.end_continuable_scope(); - generator.end_breakable_scope(); generator.switch_to_basic_block(end_block); generator.emit<Bytecode::Op::Load>(result_reg); } @@ -687,12 +688,13 @@ Bytecode::CodeGenerationErrorOr<void> DoWhileStatement::generate_bytecode(Byteco generator.begin_continuable_scope(Bytecode::Label { test_block }); generator.begin_breakable_scope(Bytecode::Label { end_block }); TRY(m_body->generate_bytecode(generator)); + generator.end_breakable_scope(); + generator.end_continuable_scope(); + if (!generator.is_current_block_terminated()) { generator.emit<Bytecode::Op::Jump>().set_targets( Bytecode::Label { test_block }, {}); - generator.end_continuable_scope(); - generator.end_breakable_scope(); generator.switch_to_basic_block(end_block); generator.emit<Bytecode::Op::Load>(result_reg); } @@ -756,6 +758,7 @@ Bytecode::CodeGenerationErrorOr<void> ForStatement::generate_bytecode(Bytecode:: generator.begin_continuable_scope(Bytecode::Label { *update_block_ptr }); generator.begin_breakable_scope(Bytecode::Label { end_block }); TRY(m_body->generate_bytecode(generator)); + generator.end_breakable_scope(); generator.end_continuable_scope(); if (!generator.is_current_block_terminated()) { @@ -772,7 +775,6 @@ Bytecode::CodeGenerationErrorOr<void> ForStatement::generate_bytecode(Bytecode:: Bytecode::Label { *test_block_ptr }, {}); - generator.end_breakable_scope(); generator.switch_to_basic_block(end_block); generator.emit<Bytecode::Op::Load>(result_reg); } |