1
Fork 0
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:
Matthew Olsson 2021-06-13 12:24:40 -07:00 committed by Andreas Kling
parent 3ee627909a
commit f39ab2e60a
4 changed files with 31 additions and 1 deletions

View file

@ -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) \

View file

@ -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;

View file

@ -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:

View file

@ -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();