mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 15:37:46 +00:00
LibJS: Implement bytecode generation for BreakStatement
This commit is contained in:
parent
73cf16f643
commit
a0412e0d5e
4 changed files with 31 additions and 3 deletions
|
@ -1300,6 +1300,7 @@ public:
|
||||||
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
||||||
|
|
||||||
const FlyString& target_label() const { return m_target_label; }
|
const FlyString& target_label() const { return m_target_label; }
|
||||||
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FlyString m_target_label;
|
FlyString m_target_label;
|
||||||
|
|
|
@ -376,13 +376,14 @@ void WhileStatement::generate_bytecode(Bytecode::Generator& generator) const
|
||||||
|
|
||||||
generator.switch_to_basic_block(body_block);
|
generator.switch_to_basic_block(body_block);
|
||||||
generator.begin_continuable_scope(Bytecode::Label { test_block });
|
generator.begin_continuable_scope(Bytecode::Label { test_block });
|
||||||
|
generator.begin_breakable_scope(Bytecode::Label { end_block });
|
||||||
m_body->generate_bytecode(generator);
|
m_body->generate_bytecode(generator);
|
||||||
if (!generator.is_current_block_terminated()) {
|
if (!generator.is_current_block_terminated()) {
|
||||||
generator.emit<Bytecode::Op::Jump>().set_targets(
|
generator.emit<Bytecode::Op::Jump>().set_targets(
|
||||||
Bytecode::Label { test_block },
|
Bytecode::Label { test_block },
|
||||||
{});
|
{});
|
||||||
generator.end_continuable_scope();
|
generator.end_continuable_scope();
|
||||||
|
generator.end_breakable_scope();
|
||||||
generator.switch_to_basic_block(end_block);
|
generator.switch_to_basic_block(end_block);
|
||||||
generator.emit<Bytecode::Op::Load>(result_reg);
|
generator.emit<Bytecode::Op::Load>(result_reg);
|
||||||
}
|
}
|
||||||
|
@ -418,13 +419,14 @@ void DoWhileStatement::generate_bytecode(Bytecode::Generator& generator) const
|
||||||
|
|
||||||
generator.switch_to_basic_block(body_block);
|
generator.switch_to_basic_block(body_block);
|
||||||
generator.begin_continuable_scope(Bytecode::Label { test_block });
|
generator.begin_continuable_scope(Bytecode::Label { test_block });
|
||||||
|
generator.begin_breakable_scope(Bytecode::Label { end_block });
|
||||||
m_body->generate_bytecode(generator);
|
m_body->generate_bytecode(generator);
|
||||||
if (!generator.is_current_block_terminated()) {
|
if (!generator.is_current_block_terminated()) {
|
||||||
generator.emit<Bytecode::Op::Jump>().set_targets(
|
generator.emit<Bytecode::Op::Jump>().set_targets(
|
||||||
Bytecode::Label { test_block },
|
Bytecode::Label { test_block },
|
||||||
{});
|
{});
|
||||||
generator.end_continuable_scope();
|
generator.end_continuable_scope();
|
||||||
|
generator.end_breakable_scope();
|
||||||
generator.switch_to_basic_block(end_block);
|
generator.switch_to_basic_block(end_block);
|
||||||
generator.emit<Bytecode::Op::Load>(result_reg);
|
generator.emit<Bytecode::Op::Load>(result_reg);
|
||||||
}
|
}
|
||||||
|
@ -484,6 +486,7 @@ void ForStatement::generate_bytecode(Bytecode::Generator& generator) const
|
||||||
|
|
||||||
generator.switch_to_basic_block(*body_block_ptr);
|
generator.switch_to_basic_block(*body_block_ptr);
|
||||||
generator.begin_continuable_scope(Bytecode::Label { *update_block_ptr });
|
generator.begin_continuable_scope(Bytecode::Label { *update_block_ptr });
|
||||||
|
generator.begin_breakable_scope(Bytecode::Label { end_block });
|
||||||
m_body->generate_bytecode(generator);
|
m_body->generate_bytecode(generator);
|
||||||
generator.end_continuable_scope();
|
generator.end_continuable_scope();
|
||||||
|
|
||||||
|
@ -501,6 +504,7 @@ void ForStatement::generate_bytecode(Bytecode::Generator& generator) const
|
||||||
Bytecode::Label { *test_block_ptr },
|
Bytecode::Label { *test_block_ptr },
|
||||||
{});
|
{});
|
||||||
|
|
||||||
|
generator.end_breakable_scope();
|
||||||
generator.switch_to_basic_block(end_block);
|
generator.switch_to_basic_block(end_block);
|
||||||
generator.emit<Bytecode::Op::Load>(result_reg);
|
generator.emit<Bytecode::Op::Load>(result_reg);
|
||||||
}
|
}
|
||||||
|
@ -787,4 +791,11 @@ void ThrowStatement::generate_bytecode(Bytecode::Generator& generator) const
|
||||||
generator.emit<Bytecode::Op::Throw>();
|
generator.emit<Bytecode::Op::Throw>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BreakStatement::generate_bytecode(Bytecode::Generator& generator) const
|
||||||
|
{
|
||||||
|
generator.emit<Bytecode::Op::Jump>().set_targets(
|
||||||
|
generator.nearest_breakable_scope(),
|
||||||
|
{});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,5 +62,17 @@ void Generator::end_continuable_scope()
|
||||||
{
|
{
|
||||||
m_continuable_scopes.take_last();
|
m_continuable_scopes.take_last();
|
||||||
}
|
}
|
||||||
|
Label Generator::nearest_breakable_scope() const
|
||||||
|
{
|
||||||
|
return m_breakable_scopes.last();
|
||||||
|
}
|
||||||
|
void Generator::begin_breakable_scope(Label breakable_target)
|
||||||
|
{
|
||||||
|
m_breakable_scopes.append(breakable_target);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Generator::end_breakable_scope()
|
||||||
|
{
|
||||||
|
m_breakable_scopes.take_last();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,8 +57,11 @@ public:
|
||||||
|
|
||||||
void begin_continuable_scope(Label continue_target);
|
void begin_continuable_scope(Label continue_target);
|
||||||
void end_continuable_scope();
|
void end_continuable_scope();
|
||||||
|
void begin_breakable_scope(Label breakable_target);
|
||||||
|
void end_breakable_scope();
|
||||||
|
|
||||||
[[nodiscard]] Label nearest_continuable_scope() const;
|
[[nodiscard]] Label nearest_continuable_scope() const;
|
||||||
|
[[nodiscard]] Label nearest_breakable_scope() const;
|
||||||
|
|
||||||
void switch_to_basic_block(BasicBlock& block)
|
void switch_to_basic_block(BasicBlock& block)
|
||||||
{
|
{
|
||||||
|
@ -97,6 +100,7 @@ private:
|
||||||
u32 m_next_register { 1 };
|
u32 m_next_register { 1 };
|
||||||
u32 m_next_block { 1 };
|
u32 m_next_block { 1 };
|
||||||
Vector<Label> m_continuable_scopes;
|
Vector<Label> m_continuable_scopes;
|
||||||
|
Vector<Label> m_breakable_scopes;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue