mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 20:07:35 +00:00
LibJS: Add JumpUndefined bytecode
This commit is contained in:
parent
3ee627909a
commit
f39ab2e60a
4 changed files with 31 additions and 1 deletions
|
@ -40,6 +40,7 @@
|
||||||
O(Jump) \
|
O(Jump) \
|
||||||
O(JumpConditional) \
|
O(JumpConditional) \
|
||||||
O(JumpNullish) \
|
O(JumpNullish) \
|
||||||
|
O(JumpUndefined) \
|
||||||
O(Call) \
|
O(Call) \
|
||||||
O(NewFunction) \
|
O(NewFunction) \
|
||||||
O(Return) \
|
O(Return) \
|
||||||
|
|
|
@ -195,6 +195,17 @@ void JumpNullish::execute_impl(Bytecode::Interpreter& interpreter) const
|
||||||
interpreter.jump(m_false_target.value());
|
interpreter.jump(m_false_target.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JumpUndefined::execute_impl(Bytecode::Interpreter& interpreter) const
|
||||||
|
{
|
||||||
|
VERIFY(m_true_target.has_value());
|
||||||
|
VERIFY(m_false_target.has_value());
|
||||||
|
auto result = interpreter.accumulator();
|
||||||
|
if (result.is_undefined())
|
||||||
|
interpreter.jump(m_true_target.value());
|
||||||
|
else
|
||||||
|
interpreter.jump(m_false_target.value());
|
||||||
|
}
|
||||||
|
|
||||||
void Call::execute_impl(Bytecode::Interpreter& interpreter) const
|
void Call::execute_impl(Bytecode::Interpreter& interpreter) const
|
||||||
{
|
{
|
||||||
auto callee = interpreter.reg(m_callee);
|
auto callee = interpreter.reg(m_callee);
|
||||||
|
@ -439,6 +450,13 @@ String JumpNullish::to_string_impl(Bytecode::Executable const&) const
|
||||||
return String::formatted("JumpNullish null:{} nonnull:{}", true_string, false_string);
|
return String::formatted("JumpNullish null:{} nonnull:{}", true_string, false_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String JumpUndefined::to_string_impl(Bytecode::Executable const&) const
|
||||||
|
{
|
||||||
|
auto true_string = m_true_target.has_value() ? String::formatted("{}", *m_true_target) : "<empty>";
|
||||||
|
auto false_string = m_false_target.has_value() ? String::formatted("{}", *m_false_target) : "<empty>";
|
||||||
|
return String::formatted("JumpUndefined undefined:{} not undefined:{}", true_string, false_string);
|
||||||
|
}
|
||||||
|
|
||||||
String Call::to_string_impl(Bytecode::Executable const&) const
|
String Call::to_string_impl(Bytecode::Executable const&) const
|
||||||
{
|
{
|
||||||
StringBuilder builder;
|
StringBuilder builder;
|
||||||
|
|
|
@ -377,6 +377,17 @@ public:
|
||||||
String to_string_impl(Bytecode::Executable const&) const;
|
String to_string_impl(Bytecode::Executable const&) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class JumpUndefined final : public Jump {
|
||||||
|
public:
|
||||||
|
explicit JumpUndefined(Optional<Label> true_target = {}, Optional<Label> false_target = {})
|
||||||
|
: Jump(Type::JumpUndefined, move(true_target), move(false_target))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void execute_impl(Bytecode::Interpreter&) const;
|
||||||
|
String to_string_impl(Bytecode::Executable const&) const;
|
||||||
|
};
|
||||||
|
|
||||||
// NOTE: This instruction is variable-width depending on the number of arguments!
|
// NOTE: This instruction is variable-width depending on the number of arguments!
|
||||||
class Call final : public Instruction {
|
class Call final : public Instruction {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -58,7 +58,7 @@ void GenerateCFG::perform(PassPipelineExecutable& executable)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instruction.type() == Instruction::Type::JumpConditional || instruction.type() == Instruction::Type::JumpNullish) {
|
if (instruction.type() == Instruction::Type::JumpConditional || instruction.type() == Instruction::Type::JumpNullish || instruction.type() == Instruction::Type::JumpUndefined) {
|
||||||
auto& true_target = static_cast<Op::Jump const&>(instruction).true_target();
|
auto& true_target = static_cast<Op::Jump const&>(instruction).true_target();
|
||||||
enter_label(true_target, current_block);
|
enter_label(true_target, current_block);
|
||||||
auto& false_target = static_cast<Op::Jump const&>(instruction).false_target();
|
auto& false_target = static_cast<Op::Jump const&>(instruction).false_target();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue