Skip to content

Commit c5f3b3a

Browse files
Lubrsiawesomekling
authored andcommitted
LibJS/Bytecode: Return the proper result for iteration statements
1 parent b162c91 commit c5f3b3a

File tree

1 file changed

+34
-8
lines changed

1 file changed

+34
-8
lines changed

Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -638,23 +638,24 @@ Bytecode::CodeGenerationErrorOr<void> WhileStatement::generate_labelled_evaluati
638638
// end
639639
auto& test_block = generator.make_block();
640640
auto& body_block = generator.make_block();
641+
auto& load_result_and_jump_to_end_block = generator.make_block();
641642
auto& end_block = generator.make_block();
642643

643644
// Init result register
644645
generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
645646
auto result_reg = generator.allocate_register();
646-
generator.emit<Bytecode::Op::Store>(result_reg);
647647

648648
// jump to the test block
649649
generator.emit<Bytecode::Op::Jump>().set_targets(
650650
Bytecode::Label { test_block },
651651
{});
652652

653653
generator.switch_to_basic_block(test_block);
654+
generator.emit<Bytecode::Op::Store>(result_reg);
654655
TRY(m_test->generate_bytecode(generator));
655656
generator.emit<Bytecode::Op::JumpConditional>().set_targets(
656657
Bytecode::Label { body_block },
657-
Bytecode::Label { end_block });
658+
Bytecode::Label { load_result_and_jump_to_end_block });
658659

659660
generator.switch_to_basic_block(body_block);
660661
generator.begin_continuable_scope(Bytecode::Label { test_block }, label_set);
@@ -669,8 +670,11 @@ Bytecode::CodeGenerationErrorOr<void> WhileStatement::generate_labelled_evaluati
669670
{});
670671
}
671672

672-
generator.switch_to_basic_block(end_block);
673+
generator.switch_to_basic_block(load_result_and_jump_to_end_block);
673674
generator.emit<Bytecode::Op::Load>(result_reg);
675+
generator.emit<Bytecode::Op::Jump>(Bytecode::Label { end_block });
676+
677+
generator.switch_to_basic_block(end_block);
674678
return {};
675679
}
676680

@@ -689,6 +693,7 @@ Bytecode::CodeGenerationErrorOr<void> DoWhileStatement::generate_labelled_evalua
689693
// end
690694
auto& test_block = generator.make_block();
691695
auto& body_block = generator.make_block();
696+
auto& load_result_and_jump_to_end_block = generator.make_block();
692697
auto& end_block = generator.make_block();
693698

694699
// Init result register
@@ -702,10 +707,11 @@ Bytecode::CodeGenerationErrorOr<void> DoWhileStatement::generate_labelled_evalua
702707
{});
703708

704709
generator.switch_to_basic_block(test_block);
710+
generator.emit<Bytecode::Op::Store>(result_reg);
705711
TRY(m_test->generate_bytecode(generator));
706712
generator.emit<Bytecode::Op::JumpConditional>().set_targets(
707713
Bytecode::Label { body_block },
708-
Bytecode::Label { end_block });
714+
Bytecode::Label { load_result_and_jump_to_end_block });
709715

710716
generator.switch_to_basic_block(body_block);
711717
generator.begin_continuable_scope(Bytecode::Label { test_block }, label_set);
@@ -720,8 +726,11 @@ Bytecode::CodeGenerationErrorOr<void> DoWhileStatement::generate_labelled_evalua
720726
{});
721727
}
722728

723-
generator.switch_to_basic_block(end_block);
729+
generator.switch_to_basic_block(load_result_and_jump_to_end_block);
724730
generator.emit<Bytecode::Op::Load>(result_reg);
731+
generator.emit<Bytecode::Op::Jump>(Bytecode::Label { end_block });
732+
733+
generator.switch_to_basic_block(end_block);
725734
return {};
726735
}
727736

@@ -748,6 +757,7 @@ Bytecode::CodeGenerationErrorOr<void> ForStatement::generate_labelled_evaluation
748757
Bytecode::BasicBlock* test_block_ptr { nullptr };
749758
Bytecode::BasicBlock* body_block_ptr { nullptr };
750759
Bytecode::BasicBlock* update_block_ptr { nullptr };
760+
Bytecode::BasicBlock* load_result_and_jump_to_end_block_ptr { nullptr };
751761

752762
auto& end_block = generator.make_block();
753763

@@ -789,22 +799,33 @@ Bytecode::CodeGenerationErrorOr<void> ForStatement::generate_labelled_evaluation
789799

790800
generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
791801
auto result_reg = generator.allocate_register();
792-
generator.emit<Bytecode::Op::Store>(result_reg);
802+
803+
if (m_test && m_update)
804+
generator.emit<Bytecode::Op::Store>(result_reg);
793805

794806
generator.emit<Bytecode::Op::Jump>().set_targets(
795807
Bytecode::Label { *test_block_ptr },
796808
{});
797809

798810
if (m_test) {
811+
load_result_and_jump_to_end_block_ptr = &generator.make_block();
799812
generator.switch_to_basic_block(*test_block_ptr);
813+
814+
if (!m_update)
815+
generator.emit<Bytecode::Op::Store>(result_reg);
816+
800817
TRY(m_test->generate_bytecode(generator));
801818
generator.emit<Bytecode::Op::JumpConditional>().set_targets(
802819
Bytecode::Label { *body_block_ptr },
803-
Bytecode::Label { end_block });
820+
Bytecode::Label { *load_result_and_jump_to_end_block_ptr });
804821
}
805822

806823
if (m_update) {
807824
generator.switch_to_basic_block(*update_block_ptr);
825+
826+
if (m_test)
827+
generator.emit<Bytecode::Op::Store>(result_reg);
828+
808829
TRY(m_update->generate_bytecode(generator));
809830
generator.emit<Bytecode::Op::Jump>().set_targets(
810831
Bytecode::Label { *test_block_ptr },
@@ -830,8 +851,13 @@ Bytecode::CodeGenerationErrorOr<void> ForStatement::generate_labelled_evaluation
830851
}
831852
}
832853

854+
if (load_result_and_jump_to_end_block_ptr) {
855+
generator.switch_to_basic_block(*load_result_and_jump_to_end_block_ptr);
856+
generator.emit<Bytecode::Op::Load>(result_reg);
857+
generator.emit<Bytecode::Op::Jump>(Bytecode::Label { end_block });
858+
}
859+
833860
generator.switch_to_basic_block(end_block);
834-
generator.emit<Bytecode::Op::Load>(result_reg);
835861

836862
if (has_lexical_environment)
837863
generator.end_variable_scope();

0 commit comments

Comments
 (0)