diff options
author | Andreas Kling <kling@serenityos.org> | 2021-10-24 14:43:00 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-10-24 17:18:06 +0200 |
commit | 3117182c2ed010417d528421d727db4e97c2b2ce (patch) | |
tree | a76fe12ac959c0936ea1ff1fcbc51241d261b13d | |
parent | 7c7bc4f44a97e11243e82b8dc733fb47e5ed34c4 (diff) | |
download | serenity-3117182c2ed010417d528421d727db4e97c2b2ce.zip |
LibJS: Implement 'this' in the bytecode VM
ThisExpression now emits a "ResolveThisBinding" bytecode op, which
simply loads the VM's current 'this' binding into the accumulator.
-rw-r--r-- | Userland/Libraries/LibJS/AST.h | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp | 5 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Bytecode/Instruction.h | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Bytecode/Op.cpp | 10 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Bytecode/Op.h | 12 |
5 files changed, 29 insertions, 0 deletions
diff --git a/Userland/Libraries/LibJS/AST.h b/Userland/Libraries/LibJS/AST.h index 6b8b46bd9a..47ba73e5c5 100644 --- a/Userland/Libraries/LibJS/AST.h +++ b/Userland/Libraries/LibJS/AST.h @@ -1214,6 +1214,7 @@ public: } virtual Value execute(Interpreter&, GlobalObject&) const override; virtual void dump(int indent) const override; + virtual void generate_bytecode(Bytecode::Generator&) const override; }; class CallExpression : public Expression { diff --git a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp index 78a43d7fe4..f7c47751e8 100644 --- a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp +++ b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp @@ -1298,4 +1298,9 @@ void ClassDeclaration::generate_bytecode(Bytecode::Generator& generator) const generator.emit<Bytecode::Op::SetVariable>(generator.intern_string(m_class_expression.ptr()->name())); } +void ThisExpression::generate_bytecode(Bytecode::Generator& generator) const +{ + generator.emit<Bytecode::Op::ResolveThisBinding>(); +} + } diff --git a/Userland/Libraries/LibJS/Bytecode/Instruction.h b/Userland/Libraries/LibJS/Bytecode/Instruction.h index d677ad143b..31776b7d3f 100644 --- a/Userland/Libraries/LibJS/Bytecode/Instruction.h +++ b/Userland/Libraries/LibJS/Bytecode/Instruction.h @@ -61,6 +61,7 @@ O(PushDeclarativeEnvironment) \ O(PutById) \ O(PutByValue) \ + O(ResolveThisBinding) \ O(Return) \ O(RightShift) \ O(SetVariable) \ diff --git a/Userland/Libraries/LibJS/Bytecode/Op.cpp b/Userland/Libraries/LibJS/Bytecode/Op.cpp index 99e72bf0eb..7082dfdef3 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Op.cpp @@ -282,6 +282,11 @@ void Jump::execute_impl(Bytecode::Interpreter& interpreter) const interpreter.jump(*m_true_target); } +void ResolveThisBinding::execute_impl(Bytecode::Interpreter& interpreter) const +{ + interpreter.accumulator() = interpreter.vm().resolve_this_binding(interpreter.global_object()); +} + void Jump::replace_references_impl(BasicBlock const& from, BasicBlock const& to) { if (m_true_target.has_value() && &m_true_target->block() == &from) @@ -785,4 +790,9 @@ String IteratorResultValue::to_string_impl(Executable const&) const return "IteratorResultValue"; } +String ResolveThisBinding::to_string_impl(Bytecode::Executable const&) const +{ + return "ResolveThisBinding"sv; +} + } diff --git a/Userland/Libraries/LibJS/Bytecode/Op.h b/Userland/Libraries/LibJS/Bytecode/Op.h index 23f14bc026..1a22f4ef3f 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.h +++ b/Userland/Libraries/LibJS/Bytecode/Op.h @@ -715,6 +715,18 @@ public: void replace_references_impl(BasicBlock const&, BasicBlock const&) { } }; +class ResolveThisBinding final : public Instruction { +public: + explicit ResolveThisBinding() + : Instruction(Type::ResolveThisBinding) + { + } + + void execute_impl(Bytecode::Interpreter&) const; + String to_string_impl(Bytecode::Executable const&) const; + void replace_references_impl(BasicBlock const&, BasicBlock const&) { } +}; + } namespace JS::Bytecode { |