diff --git a/Userland/Libraries/LibJS/AST.h b/Userland/Libraries/LibJS/AST.h index b7a2d72e1e..b97d0c5322 100644 --- a/Userland/Libraries/LibJS/AST.h +++ b/Userland/Libraries/LibJS/AST.h @@ -1119,6 +1119,7 @@ public: virtual Value execute(Interpreter&, GlobalObject&) const override; virtual void dump(int indent) const override; virtual Reference to_reference(Interpreter&, GlobalObject&) const override; + virtual Optional generate_bytecode(Bytecode::Generator&) const override; bool is_computed() const { return m_computed; } const Expression& object() const { return *m_object; } diff --git a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp index c1254f09be..ea13482b0c 100644 --- a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp +++ b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp @@ -141,4 +141,18 @@ Optional ObjectExpression::generate_bytecode(Bytecode::Gener return reg; } +Optional MemberExpression::generate_bytecode(Bytecode::Generator& generator) const +{ + auto object_reg = object().generate_bytecode(generator); + + if (is_computed()) { + TODO(); + } else { + VERIFY(is(property())); + auto dst_reg = generator.allocate_register(); + generator.emit(dst_reg, *object_reg, static_cast(property()).string()); + return dst_reg; + } +} + } diff --git a/Userland/Libraries/LibJS/Bytecode/Op.cpp b/Userland/Libraries/LibJS/Bytecode/Op.cpp index 647c0d9f95..ab3e25bcfe 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Op.cpp @@ -56,6 +56,12 @@ void SetVariable::execute(Bytecode::Interpreter& interpreter) const interpreter.vm().set_variable(m_identifier, interpreter.reg(m_src), interpreter.global_object()); } +void GetById::execute(Bytecode::Interpreter& interpreter) const +{ + if (auto* object = interpreter.reg(m_base).to_object(interpreter.global_object())) + interpreter.reg(m_dst) = object->get(m_property); +} + void PutById::execute(Bytecode::Interpreter& interpreter) const { if (auto* object = interpreter.reg(m_base).to_object(interpreter.global_object())) @@ -133,6 +139,11 @@ String PutById::to_string() const return String::formatted("PutById base:{}, property:{}, src:{}", m_base, m_property, m_src); } +String GetById::to_string() const +{ + return String::formatted("GetById dst:{}, base:{}, property:{}", m_dst, m_base, m_property); +} + String Jump::to_string() const { return String::formatted("Jump {}", m_target); diff --git a/Userland/Libraries/LibJS/Bytecode/Op.h b/Userland/Libraries/LibJS/Bytecode/Op.h index bf06d97774..cce02b2ecc 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.h +++ b/Userland/Libraries/LibJS/Bytecode/Op.h @@ -174,6 +174,25 @@ private: FlyString m_identifier; }; +class GetById final : public Instruction { +public: + GetById(Register dst, Register base, FlyString property) + : m_dst(dst) + , m_base(base) + , m_property(move(property)) + { + } + + virtual ~GetById() override { } + virtual void execute(Bytecode::Interpreter&) const override; + virtual String to_string() const override; + +private: + Register m_dst; + Register m_base; + FlyString m_property; +}; + class PutById final : public Instruction { public: PutById(Register base, FlyString property, Register src)