From 5750edd859a375a7a8e8f1e5d1131b3d92502fcc Mon Sep 17 00:00:00 2001 From: Jack Karamanian Date: Sun, 19 Apr 2020 14:42:00 -0500 Subject: [PATCH] LibJS: Allow Function objects to be constructed with a bound |this| value and bound arguments This allows Function objects produced by Function.prototype.bind, as well as arrow functions to track their |this| values and bound arguments. --- Libraries/LibJS/Runtime/Function.cpp | 22 +++++++++++++++++++++- Libraries/LibJS/Runtime/Function.h | 15 +++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/Libraries/LibJS/Runtime/Function.cpp b/Libraries/LibJS/Runtime/Function.cpp index 18f3018e18..d5f5e813b9 100644 --- a/Libraries/LibJS/Runtime/Function.cpp +++ b/Libraries/LibJS/Runtime/Function.cpp @@ -30,10 +30,30 @@ namespace JS { Function::Function(Object& prototype) - : Object(&prototype) + : Function(prototype, {}, {}) { } +Function::Function(Object& prototype, Optional bound_this, Vector bound_arguments) + : Object(&prototype) + , m_bound_this(bound_this) + , m_bound_arguments(move(bound_arguments)) +{ +} + +void Function::visit_children(Visitor& visitor) +{ + Object::visit_children(visitor); + + if (m_bound_this.has_value()) { + visitor.visit(m_bound_this.value()); + } + + for (auto argument : m_bound_arguments) { + visitor.visit(argument); + } +} + Function::~Function() { } diff --git a/Libraries/LibJS/Runtime/Function.h b/Libraries/LibJS/Runtime/Function.h index f06182a42a..f42ab49b67 100644 --- a/Libraries/LibJS/Runtime/Function.h +++ b/Libraries/LibJS/Runtime/Function.h @@ -40,12 +40,27 @@ public: virtual const FlyString& name() const = 0; virtual LexicalEnvironment* create_environment() = 0; + virtual void visit_children(Visitor&) override; + + Optional bound_this() const + { + return m_bound_this; + } + + const Vector& bound_arguments() const + { + return m_bound_arguments; + } + protected: explicit Function(Object& prototype); + explicit Function(Object& prototype, Optional bound_this, Vector bound_arguments); virtual const char* class_name() const override { return "Function"; } private: virtual bool is_function() const final { return true; } + Optional m_bound_this; + Vector m_bound_arguments; }; }