diff options
author | Linus Groh <mail@linusgroh.de> | 2021-10-08 21:24:51 +0100 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2021-10-09 14:29:20 +0100 |
commit | fe5c2b7bb998ca4dcc15b10ca809210ae7465d3e (patch) | |
tree | 59bbe3988f284e952011b94c357e195e96657f45 /Userland/Libraries/LibJS/Runtime | |
parent | 53af66d57d0c40e81611fae4ebe665f8f390b168 (diff) | |
download | serenity-fe5c2b7bb998ca4dcc15b10ca809210ae7465d3e.zip |
LibJS: Decouple new_function_environment() from FunctionObject
Now that only ECMAScriptFunctionObject uses this, we can remove the
FunctionObject::new_function_environment() pure virtual method and just
implement it as a standalone AO with an ECMAScriptFunctionObject
parameter, next to the other NewFooEnvironment AOs.
Diffstat (limited to 'Userland/Libraries/LibJS/Runtime')
11 files changed, 30 insertions, 43 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp index 5df7232dc8..cc75f71b28 100644 --- a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp +++ b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp @@ -393,6 +393,34 @@ ObjectEnvironment* new_object_environment(Object& object, bool is_with_environme return global_object.heap().allocate<ObjectEnvironment>(global_object, object, is_with_environment ? ObjectEnvironment::IsWithEnvironment::Yes : ObjectEnvironment::IsWithEnvironment::No, environment); } +// 9.1.2.4 NewFunctionEnvironment ( F, newTarget ), https://tc39.es/ecma262/#sec-newfunctionenvironment +FunctionEnvironment* new_function_environment(ECMAScriptFunctionObject& function, Object* new_target) +{ + auto& global_object = function.global_object(); + + // 1. Let env be a new function Environment Record containing no bindings. + auto* env = global_object.heap().allocate<FunctionEnvironment>(global_object, function.environment()); + + // 2. Set env.[[FunctionObject]] to F. + env->set_function_object(function); + + // 3. If F.[[ThisMode]] is lexical, set env.[[ThisBindingStatus]] to lexical. + if (function.this_mode() == ECMAScriptFunctionObject::ThisMode::Lexical) + env->set_this_binding_status(FunctionEnvironment::ThisBindingStatus::Lexical); + // 4. Else, set env.[[ThisBindingStatus]] to uninitialized. + else + env->set_this_binding_status(FunctionEnvironment::ThisBindingStatus::Uninitialized); + + // 5. Set env.[[NewTarget]] to newTarget. + env->set_new_target(new_target ?: js_undefined()); + + // 6. Set env.[[OuterEnv]] to F.[[Environment]]. + // NOTE: Done in step 1 via the FunctionEnvironment constructor. + + // 7. Return env. + return env; +} + // 9.4.3 GetThisEnvironment ( ), https://tc39.es/ecma262/#sec-getthisenvironment Environment& get_this_environment(VM& vm) { diff --git a/Userland/Libraries/LibJS/Runtime/AbstractOperations.h b/Userland/Libraries/LibJS/Runtime/AbstractOperations.h index 206b5e1952..b70f0802ca 100644 --- a/Userland/Libraries/LibJS/Runtime/AbstractOperations.h +++ b/Userland/Libraries/LibJS/Runtime/AbstractOperations.h @@ -16,6 +16,7 @@ namespace JS { DeclarativeEnvironment* new_declarative_environment(Environment&); ObjectEnvironment* new_object_environment(Object&, bool is_with_environment, Environment*); +FunctionEnvironment* new_function_environment(ECMAScriptFunctionObject&, Object* new_target); Environment& get_this_environment(VM&); Object* get_super_constructor(VM&); ThrowCompletionOr<Reference> make_super_property_reference(GlobalObject&, Value actual_this, StringOrSymbol const& property_key, bool strict); diff --git a/Userland/Libraries/LibJS/Runtime/BoundFunction.cpp b/Userland/Libraries/LibJS/Runtime/BoundFunction.cpp index 0364ccf951..11e27b71ae 100644 --- a/Userland/Libraries/LibJS/Runtime/BoundFunction.cpp +++ b/Userland/Libraries/LibJS/Runtime/BoundFunction.cpp @@ -80,11 +80,6 @@ ThrowCompletionOr<Object*> BoundFunction::internal_construct(MarkedValueList arg return construct(global_object(), target, move(args), final_new_target); } -FunctionEnvironment* BoundFunction::new_function_environment(Object* new_target) -{ - return m_bound_target_function->new_function_environment(new_target); -} - void BoundFunction::visit_edges(Visitor& visitor) { Base::visit_edges(visitor); diff --git a/Userland/Libraries/LibJS/Runtime/BoundFunction.h b/Userland/Libraries/LibJS/Runtime/BoundFunction.h index fd09684533..46795d4a33 100644 --- a/Userland/Libraries/LibJS/Runtime/BoundFunction.h +++ b/Userland/Libraries/LibJS/Runtime/BoundFunction.h @@ -21,7 +21,6 @@ public: virtual ThrowCompletionOr<Value> internal_call(Value this_argument, MarkedValueList arguments_list) override; virtual ThrowCompletionOr<Object*> internal_construct(MarkedValueList arguments_list, FunctionObject& new_target) override; - virtual FunctionEnvironment* new_function_environment(Object* new_target) override; virtual const FlyString& name() const override { return m_name; } virtual bool is_strict_mode() const override { return m_bound_target_function->is_strict_mode(); } virtual bool has_constructor() const override { return m_bound_target_function->has_constructor(); } diff --git a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp index d3b8e2b365..c096417cf6 100644 --- a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp @@ -275,19 +275,6 @@ void ECMAScriptFunctionObject::visit_edges(Visitor& visitor) } } -// 9.1.2.4 NewFunctionEnvironment ( F, newTarget ), https://tc39.es/ecma262/#sec-newfunctionenvironment -FunctionEnvironment* ECMAScriptFunctionObject::new_function_environment(Object* new_target) -{ - auto* environment = heap().allocate<FunctionEnvironment>(global_object(), m_environment); - environment->set_function_object(*this); - if (this_mode() == ThisMode::Lexical) { - environment->set_this_binding_status(FunctionEnvironment::ThisBindingStatus::Lexical); - } - - environment->set_new_target(new_target ? new_target : js_undefined()); - return environment; -} - // 10.2.11 FunctionDeclarationInstantiation ( func, argumentsList ), https://tc39.es/ecma262/#sec-functiondeclarationinstantiation ThrowCompletionOr<void> ECMAScriptFunctionObject::function_declaration_instantiation(Interpreter* interpreter) { @@ -594,7 +581,7 @@ void ECMAScriptFunctionObject::prepare_for_ordinary_call(ExecutionContext& calle // FIXME: Our execution context struct currently does not track this item. // 7. Let localEnv be NewFunctionEnvironment(F, newTarget). - auto* local_environment = new_function_environment(new_target); + auto* local_environment = new_function_environment(*this, new_target); // 8. Set the LexicalEnvironment of calleeContext to localEnv. callee_context.lexical_environment = local_environment; diff --git a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h index 5d4d35b1fc..2d44d4bc5f 100644 --- a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h +++ b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h @@ -79,7 +79,6 @@ protected: private: virtual bool is_ecmascript_function_object() const override { return true; } - virtual FunctionEnvironment* new_function_environment(Object* new_target) override; virtual void visit_edges(Visitor&) override; void prepare_for_ordinary_call(ExecutionContext& callee_context, Object* new_target); diff --git a/Userland/Libraries/LibJS/Runtime/FunctionObject.h b/Userland/Libraries/LibJS/Runtime/FunctionObject.h index 6746b0f670..ef2267564a 100644 --- a/Userland/Libraries/LibJS/Runtime/FunctionObject.h +++ b/Userland/Libraries/LibJS/Runtime/FunctionObject.h @@ -24,7 +24,6 @@ public: virtual ThrowCompletionOr<Object*> internal_construct([[maybe_unused]] MarkedValueList arguments_list, [[maybe_unused]] FunctionObject& new_target) { VERIFY_NOT_REACHED(); } virtual const FlyString& name() const = 0; - virtual FunctionEnvironment* new_function_environment(Object* new_target) = 0; BoundFunction* bind(Value bound_this_value, Vector<Value> arguments); diff --git a/Userland/Libraries/LibJS/Runtime/NativeFunction.cpp b/Userland/Libraries/LibJS/Runtime/NativeFunction.cpp index 8932feac5d..043968f876 100644 --- a/Userland/Libraries/LibJS/Runtime/NativeFunction.cpp +++ b/Userland/Libraries/LibJS/Runtime/NativeFunction.cpp @@ -195,19 +195,6 @@ Value NativeFunction::construct(FunctionObject&) VERIFY_NOT_REACHED(); } -FunctionEnvironment* NativeFunction::new_function_environment(Object* new_target) -{ - // Simplified version of 9.1.2.4 NewFunctionEnvironment ( F, newTarget ) - Environment* parent_scope = nullptr; - if (!vm().execution_context_stack().is_empty()) - parent_scope = vm().lexical_environment(); - - auto* environment = heap().allocate<FunctionEnvironment>(global_object(), parent_scope); - environment->set_new_target(new_target ? new_target : js_undefined()); - - return environment; -} - bool NativeFunction::is_strict_mode() const { return true; diff --git a/Userland/Libraries/LibJS/Runtime/NativeFunction.h b/Userland/Libraries/LibJS/Runtime/NativeFunction.h index 26a6100d70..d88d388ce8 100644 --- a/Userland/Libraries/LibJS/Runtime/NativeFunction.h +++ b/Userland/Libraries/LibJS/Runtime/NativeFunction.h @@ -39,7 +39,6 @@ protected: explicit NativeFunction(Object& prototype); private: - virtual FunctionEnvironment* new_function_environment(Object* new_target) override final; virtual bool is_native_function() const final { return true; } FlyString m_name; diff --git a/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp b/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp index 63003ae1f5..7181b0aa9b 100644 --- a/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp @@ -857,10 +857,4 @@ const FlyString& ProxyObject::name() const return static_cast<FunctionObject&>(m_target).name(); } -FunctionEnvironment* ProxyObject::new_function_environment(Object* new_target) -{ - VERIFY(is_function()); - return static_cast<FunctionObject&>(m_target).new_function_environment(new_target); -} - } diff --git a/Userland/Libraries/LibJS/Runtime/ProxyObject.h b/Userland/Libraries/LibJS/Runtime/ProxyObject.h index fe85b37998..f8aebcf77f 100644 --- a/Userland/Libraries/LibJS/Runtime/ProxyObject.h +++ b/Userland/Libraries/LibJS/Runtime/ProxyObject.h @@ -22,7 +22,6 @@ public: virtual ~ProxyObject() override; virtual const FlyString& name() const override; - virtual FunctionEnvironment* new_function_environment(Object* new_target) override; virtual bool has_constructor() const override { return true; } const Object& target() const { return m_target; } |