/* * Copyright (c) 2021, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include namespace JS::Bytecode::Op { class Load final : public Instruction { public: Load(Register dst, Value value) : Instruction(Type::Load) , m_dst(dst) , m_value(value) { } void execute(Bytecode::Interpreter&) const; String to_string() const; private: Register m_dst; Value m_value; }; class Add final : public Instruction { public: Add(Register dst, Register src1, Register src2) : Instruction(Type::Add) , m_dst(dst) , m_src1(src1) , m_src2(src2) { } void execute(Bytecode::Interpreter&) const; String to_string() const; private: Register m_dst; Register m_src1; Register m_src2; }; class Sub final : public Instruction { public: Sub(Register dst, Register src1, Register src2) : Instruction(Type::Sub) , m_dst(dst) , m_src1(src1) , m_src2(src2) { } void execute(Bytecode::Interpreter&) const; String to_string() const; private: Register m_dst; Register m_src1; Register m_src2; }; class Mul final : public Instruction { public: Mul(Register dst, Register src1, Register src2) : Instruction(Type::Mul) , m_dst(dst) , m_src1(src1) , m_src2(src2) { } void execute(Bytecode::Interpreter&) const; String to_string() const; private: Register m_dst; Register m_src1; Register m_src2; }; class Div final : public Instruction { public: Div(Register dst, Register src1, Register src2) : Instruction(Type::Div) , m_dst(dst) , m_src1(src1) , m_src2(src2) { } void execute(Bytecode::Interpreter&) const; String to_string() const; private: Register m_dst; Register m_src1; Register m_src2; }; class Mod final : public Instruction { public: Mod(Register dst, Register src1, Register src2) : Instruction(Type::Mod) , m_dst(dst) , m_src1(src1) , m_src2(src2) { } void execute(Bytecode::Interpreter&) const; String to_string() const; private: Register m_dst; Register m_src1; Register m_src2; }; class Exp final : public Instruction { public: Exp(Register dst, Register src1, Register src2) : Instruction(Type::Exp) , m_dst(dst) , m_src1(src1) , m_src2(src2) { } void execute(Bytecode::Interpreter&) const; String to_string() const; private: Register m_dst; Register m_src1; Register m_src2; }; class GreaterThan final : public Instruction { public: GreaterThan(Register dst, Register src1, Register src2) : Instruction(Type::GreaterThan) , m_dst(dst) , m_src1(src1) , m_src2(src2) { } void execute(Bytecode::Interpreter&) const; String to_string() const; private: Register m_dst; Register m_src1; Register m_src2; }; class GreaterThanEquals final : public Instruction { public: GreaterThanEquals(Register dst, Register src1, Register src2) : Instruction(Type::GreaterThanEquals) , m_dst(dst) , m_src1(src1) , m_src2(src2) { } void execute(Bytecode::Interpreter&) const; String to_string() const; private: Register m_dst; Register m_src1; Register m_src2; }; class LessThan final : public Instruction { public: LessThan(Register dst, Register src1, Register src2) : Instruction(Type::LessThan) , m_dst(dst) , m_src1(src1) , m_src2(src2) { } void execute(Bytecode::Interpreter&) const; String to_string() const; private: Register m_dst; Register m_src1; Register m_src2; }; class LessThanEquals final : public Instruction { public: LessThanEquals(Register dst, Register src1, Register src2) : Instruction(Type::LessThanEquals) , m_dst(dst) , m_src1(src1) , m_src2(src2) { } void execute(Bytecode::Interpreter&) const; String to_string() const; private: Register m_dst; Register m_src1; Register m_src2; }; class AbstractInequals final : public Instruction { public: AbstractInequals(Register dst, Register src1, Register src2) : Instruction(Type::AbstractEquals) , m_dst(dst) , m_src1(src1) , m_src2(src2) { } void execute(Bytecode::Interpreter&) const; String to_string() const; private: Register m_dst; Register m_src1; Register m_src2; }; class AbstractEquals final : public Instruction { public: AbstractEquals(Register dst, Register src1, Register src2) : Instruction(Type::AbstractEquals) , m_dst(dst) , m_src1(src1) , m_src2(src2) { } void execute(Bytecode::Interpreter&) const; String to_string() const; private: Register m_dst; Register m_src1; Register m_src2; }; class NewString final : public Instruction { public: NewString(Register dst, String string) : Instruction(Type::NewString) , m_dst(dst) , m_string(move(string)) { } void execute(Bytecode::Interpreter&) const; String to_string() const; private: Register m_dst; String m_string; }; class NewObject final : public Instruction { public: explicit NewObject(Register dst) : Instruction(Type::NewObject) , m_dst(dst) { } void execute(Bytecode::Interpreter&) const; String to_string() const; private: Register m_dst; }; class SetVariable final : public Instruction { public: SetVariable(FlyString identifier, Register src) : Instruction(Type::SetVariable) , m_identifier(move(identifier)) , m_src(src) { } void execute(Bytecode::Interpreter&) const; String to_string() const; private: FlyString m_identifier; Register m_src; }; class GetVariable final : public Instruction { public: GetVariable(Register dst, FlyString identifier) : Instruction(Type::GetVariable) , m_dst(dst) , m_identifier(move(identifier)) { } void execute(Bytecode::Interpreter&) const; String to_string() const; private: Register m_dst; FlyString m_identifier; }; class GetById final : public Instruction { public: GetById(Register dst, Register base, FlyString property) : Instruction(Type::GetById) , m_dst(dst) , m_base(base) , m_property(move(property)) { } void execute(Bytecode::Interpreter&) const; String to_string() const; private: Register m_dst; Register m_base; FlyString m_property; }; class PutById final : public Instruction { public: PutById(Register base, FlyString property, Register src) : Instruction(Type::PutById) , m_base(base) , m_property(move(property)) , m_src(src) { } void execute(Bytecode::Interpreter&) const; String to_string() const; private: Register m_base; FlyString m_property; Register m_src; }; class Jump final : public Instruction { public: explicit Jump(Optional