mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 22:37:35 +00:00
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.
This commit is contained in:
parent
7c7bc4f44a
commit
3117182c2e
5 changed files with 29 additions and 0 deletions
|
@ -1214,6 +1214,7 @@ public:
|
||||||
}
|
}
|
||||||
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
||||||
virtual void dump(int indent) const override;
|
virtual void dump(int indent) const override;
|
||||||
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CallExpression : public Expression {
|
class CallExpression : public Expression {
|
||||||
|
|
|
@ -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()));
|
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>();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
O(PushDeclarativeEnvironment) \
|
O(PushDeclarativeEnvironment) \
|
||||||
O(PutById) \
|
O(PutById) \
|
||||||
O(PutByValue) \
|
O(PutByValue) \
|
||||||
|
O(ResolveThisBinding) \
|
||||||
O(Return) \
|
O(Return) \
|
||||||
O(RightShift) \
|
O(RightShift) \
|
||||||
O(SetVariable) \
|
O(SetVariable) \
|
||||||
|
|
|
@ -282,6 +282,11 @@ void Jump::execute_impl(Bytecode::Interpreter& interpreter) const
|
||||||
interpreter.jump(*m_true_target);
|
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)
|
void Jump::replace_references_impl(BasicBlock const& from, BasicBlock const& to)
|
||||||
{
|
{
|
||||||
if (m_true_target.has_value() && &m_true_target->block() == &from)
|
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";
|
return "IteratorResultValue";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String ResolveThisBinding::to_string_impl(Bytecode::Executable const&) const
|
||||||
|
{
|
||||||
|
return "ResolveThisBinding"sv;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -715,6 +715,18 @@ public:
|
||||||
void replace_references_impl(BasicBlock const&, BasicBlock const&) { }
|
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 {
|
namespace JS::Bytecode {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue