1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 07:08:10 +00:00

LibJS: Make sure loop results are initialized

This ensures that "while", do...while, "for" expressions have a
properly initialized result value even if the user terminated
the loop body via break or the loop body wasn't executed at all.
This commit is contained in:
Gunnar Beutner 2021-06-08 22:17:00 +02:00 committed by Linus Groh
parent 624ceec04f
commit 5ff85abe8c

View file

@ -279,24 +279,32 @@ void AssignmentExpression::generate_bytecode(Bytecode::Generator& generator) con
void WhileStatement::generate_bytecode(Bytecode::Generator& generator) const
{
generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
generator.begin_continuable_scope();
auto test_label = generator.make_label();
auto result_reg = generator.allocate_register();
generator.emit<Bytecode::Op::Store>(result_reg);
m_test->generate_bytecode(generator);
auto& test_jump = generator.emit<Bytecode::Op::JumpIfFalse>();
m_body->generate_bytecode(generator);
generator.emit<Bytecode::Op::Jump>(test_label);
test_jump.set_target(generator.make_label());
generator.end_continuable_scope();
generator.emit<Bytecode::Op::Load>(result_reg);
}
void DoWhileStatement::generate_bytecode(Bytecode::Generator& generator) const
{
generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
generator.begin_continuable_scope();
auto head_label = generator.make_label();
m_body->generate_bytecode(generator);
generator.end_continuable_scope();
auto result_reg = generator.allocate_register();
generator.emit<Bytecode::Op::Store>(result_reg);
m_test->generate_bytecode(generator);
generator.emit<Bytecode::Op::JumpIfTrue>(head_label);
generator.emit<Bytecode::Op::Load>(result_reg);
}
void ForStatement::generate_bytecode(Bytecode::Generator& generator) const
@ -306,8 +314,11 @@ void ForStatement::generate_bytecode(Bytecode::Generator& generator) const
if (m_init)
m_init->generate_bytecode(generator);
generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
generator.begin_continuable_scope();
auto jump_label = generator.make_label();
auto result_reg = generator.allocate_register();
generator.emit<Bytecode::Op::Store>(result_reg);
if (m_test) {
m_test->generate_bytecode(generator);
test_jump = &generator.emit<Bytecode::Op::JumpIfFalse>();
@ -320,6 +331,7 @@ void ForStatement::generate_bytecode(Bytecode::Generator& generator) const
if (m_test)
test_jump->set_target(generator.make_label());
generator.end_continuable_scope();
generator.emit<Bytecode::Op::Load>(result_reg);
}
void ObjectExpression::generate_bytecode(Bytecode::Generator& generator) const