mirror of
https://github.com/RGBCube/serenity
synced 2025-05-30 23:58:12 +00:00
LibJS/Bytecode: Return the proper result for iteration statements
This commit is contained in:
parent
b162c9117e
commit
c5f3b3ae02
1 changed files with 34 additions and 8 deletions
|
@ -638,12 +638,12 @@ Bytecode::CodeGenerationErrorOr<void> WhileStatement::generate_labelled_evaluati
|
||||||
// end
|
// end
|
||||||
auto& test_block = generator.make_block();
|
auto& test_block = generator.make_block();
|
||||||
auto& body_block = generator.make_block();
|
auto& body_block = generator.make_block();
|
||||||
|
auto& load_result_and_jump_to_end_block = generator.make_block();
|
||||||
auto& end_block = generator.make_block();
|
auto& end_block = generator.make_block();
|
||||||
|
|
||||||
// Init result register
|
// Init result register
|
||||||
generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
|
generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
|
||||||
auto result_reg = generator.allocate_register();
|
auto result_reg = generator.allocate_register();
|
||||||
generator.emit<Bytecode::Op::Store>(result_reg);
|
|
||||||
|
|
||||||
// jump to the test block
|
// jump to the test block
|
||||||
generator.emit<Bytecode::Op::Jump>().set_targets(
|
generator.emit<Bytecode::Op::Jump>().set_targets(
|
||||||
|
@ -651,10 +651,11 @@ Bytecode::CodeGenerationErrorOr<void> WhileStatement::generate_labelled_evaluati
|
||||||
{});
|
{});
|
||||||
|
|
||||||
generator.switch_to_basic_block(test_block);
|
generator.switch_to_basic_block(test_block);
|
||||||
|
generator.emit<Bytecode::Op::Store>(result_reg);
|
||||||
TRY(m_test->generate_bytecode(generator));
|
TRY(m_test->generate_bytecode(generator));
|
||||||
generator.emit<Bytecode::Op::JumpConditional>().set_targets(
|
generator.emit<Bytecode::Op::JumpConditional>().set_targets(
|
||||||
Bytecode::Label { body_block },
|
Bytecode::Label { body_block },
|
||||||
Bytecode::Label { end_block });
|
Bytecode::Label { load_result_and_jump_to_end_block });
|
||||||
|
|
||||||
generator.switch_to_basic_block(body_block);
|
generator.switch_to_basic_block(body_block);
|
||||||
generator.begin_continuable_scope(Bytecode::Label { test_block }, label_set);
|
generator.begin_continuable_scope(Bytecode::Label { test_block }, label_set);
|
||||||
|
@ -669,8 +670,11 @@ Bytecode::CodeGenerationErrorOr<void> WhileStatement::generate_labelled_evaluati
|
||||||
{});
|
{});
|
||||||
}
|
}
|
||||||
|
|
||||||
generator.switch_to_basic_block(end_block);
|
generator.switch_to_basic_block(load_result_and_jump_to_end_block);
|
||||||
generator.emit<Bytecode::Op::Load>(result_reg);
|
generator.emit<Bytecode::Op::Load>(result_reg);
|
||||||
|
generator.emit<Bytecode::Op::Jump>(Bytecode::Label { end_block });
|
||||||
|
|
||||||
|
generator.switch_to_basic_block(end_block);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -689,6 +693,7 @@ Bytecode::CodeGenerationErrorOr<void> DoWhileStatement::generate_labelled_evalua
|
||||||
// end
|
// end
|
||||||
auto& test_block = generator.make_block();
|
auto& test_block = generator.make_block();
|
||||||
auto& body_block = generator.make_block();
|
auto& body_block = generator.make_block();
|
||||||
|
auto& load_result_and_jump_to_end_block = generator.make_block();
|
||||||
auto& end_block = generator.make_block();
|
auto& end_block = generator.make_block();
|
||||||
|
|
||||||
// Init result register
|
// Init result register
|
||||||
|
@ -702,10 +707,11 @@ Bytecode::CodeGenerationErrorOr<void> DoWhileStatement::generate_labelled_evalua
|
||||||
{});
|
{});
|
||||||
|
|
||||||
generator.switch_to_basic_block(test_block);
|
generator.switch_to_basic_block(test_block);
|
||||||
|
generator.emit<Bytecode::Op::Store>(result_reg);
|
||||||
TRY(m_test->generate_bytecode(generator));
|
TRY(m_test->generate_bytecode(generator));
|
||||||
generator.emit<Bytecode::Op::JumpConditional>().set_targets(
|
generator.emit<Bytecode::Op::JumpConditional>().set_targets(
|
||||||
Bytecode::Label { body_block },
|
Bytecode::Label { body_block },
|
||||||
Bytecode::Label { end_block });
|
Bytecode::Label { load_result_and_jump_to_end_block });
|
||||||
|
|
||||||
generator.switch_to_basic_block(body_block);
|
generator.switch_to_basic_block(body_block);
|
||||||
generator.begin_continuable_scope(Bytecode::Label { test_block }, label_set);
|
generator.begin_continuable_scope(Bytecode::Label { test_block }, label_set);
|
||||||
|
@ -720,8 +726,11 @@ Bytecode::CodeGenerationErrorOr<void> DoWhileStatement::generate_labelled_evalua
|
||||||
{});
|
{});
|
||||||
}
|
}
|
||||||
|
|
||||||
generator.switch_to_basic_block(end_block);
|
generator.switch_to_basic_block(load_result_and_jump_to_end_block);
|
||||||
generator.emit<Bytecode::Op::Load>(result_reg);
|
generator.emit<Bytecode::Op::Load>(result_reg);
|
||||||
|
generator.emit<Bytecode::Op::Jump>(Bytecode::Label { end_block });
|
||||||
|
|
||||||
|
generator.switch_to_basic_block(end_block);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -748,6 +757,7 @@ Bytecode::CodeGenerationErrorOr<void> ForStatement::generate_labelled_evaluation
|
||||||
Bytecode::BasicBlock* test_block_ptr { nullptr };
|
Bytecode::BasicBlock* test_block_ptr { nullptr };
|
||||||
Bytecode::BasicBlock* body_block_ptr { nullptr };
|
Bytecode::BasicBlock* body_block_ptr { nullptr };
|
||||||
Bytecode::BasicBlock* update_block_ptr { nullptr };
|
Bytecode::BasicBlock* update_block_ptr { nullptr };
|
||||||
|
Bytecode::BasicBlock* load_result_and_jump_to_end_block_ptr { nullptr };
|
||||||
|
|
||||||
auto& end_block = generator.make_block();
|
auto& end_block = generator.make_block();
|
||||||
|
|
||||||
|
@ -789,22 +799,33 @@ Bytecode::CodeGenerationErrorOr<void> ForStatement::generate_labelled_evaluation
|
||||||
|
|
||||||
generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
|
generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
|
||||||
auto result_reg = generator.allocate_register();
|
auto result_reg = generator.allocate_register();
|
||||||
generator.emit<Bytecode::Op::Store>(result_reg);
|
|
||||||
|
if (m_test && m_update)
|
||||||
|
generator.emit<Bytecode::Op::Store>(result_reg);
|
||||||
|
|
||||||
generator.emit<Bytecode::Op::Jump>().set_targets(
|
generator.emit<Bytecode::Op::Jump>().set_targets(
|
||||||
Bytecode::Label { *test_block_ptr },
|
Bytecode::Label { *test_block_ptr },
|
||||||
{});
|
{});
|
||||||
|
|
||||||
if (m_test) {
|
if (m_test) {
|
||||||
|
load_result_and_jump_to_end_block_ptr = &generator.make_block();
|
||||||
generator.switch_to_basic_block(*test_block_ptr);
|
generator.switch_to_basic_block(*test_block_ptr);
|
||||||
|
|
||||||
|
if (!m_update)
|
||||||
|
generator.emit<Bytecode::Op::Store>(result_reg);
|
||||||
|
|
||||||
TRY(m_test->generate_bytecode(generator));
|
TRY(m_test->generate_bytecode(generator));
|
||||||
generator.emit<Bytecode::Op::JumpConditional>().set_targets(
|
generator.emit<Bytecode::Op::JumpConditional>().set_targets(
|
||||||
Bytecode::Label { *body_block_ptr },
|
Bytecode::Label { *body_block_ptr },
|
||||||
Bytecode::Label { end_block });
|
Bytecode::Label { *load_result_and_jump_to_end_block_ptr });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_update) {
|
if (m_update) {
|
||||||
generator.switch_to_basic_block(*update_block_ptr);
|
generator.switch_to_basic_block(*update_block_ptr);
|
||||||
|
|
||||||
|
if (m_test)
|
||||||
|
generator.emit<Bytecode::Op::Store>(result_reg);
|
||||||
|
|
||||||
TRY(m_update->generate_bytecode(generator));
|
TRY(m_update->generate_bytecode(generator));
|
||||||
generator.emit<Bytecode::Op::Jump>().set_targets(
|
generator.emit<Bytecode::Op::Jump>().set_targets(
|
||||||
Bytecode::Label { *test_block_ptr },
|
Bytecode::Label { *test_block_ptr },
|
||||||
|
@ -830,8 +851,13 @@ Bytecode::CodeGenerationErrorOr<void> ForStatement::generate_labelled_evaluation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (load_result_and_jump_to_end_block_ptr) {
|
||||||
|
generator.switch_to_basic_block(*load_result_and_jump_to_end_block_ptr);
|
||||||
|
generator.emit<Bytecode::Op::Load>(result_reg);
|
||||||
|
generator.emit<Bytecode::Op::Jump>(Bytecode::Label { end_block });
|
||||||
|
}
|
||||||
|
|
||||||
generator.switch_to_basic_block(end_block);
|
generator.switch_to_basic_block(end_block);
|
||||||
generator.emit<Bytecode::Op::Load>(result_reg);
|
|
||||||
|
|
||||||
if (has_lexical_environment)
|
if (has_lexical_environment)
|
||||||
generator.end_variable_scope();
|
generator.end_variable_scope();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue