mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 08:48:11 +00:00
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.
This commit is contained in:
parent
53af66d57d
commit
fe5c2b7bb9
11 changed files with 30 additions and 43 deletions
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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(); }
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue