|
@@ -33,7 +33,7 @@ namespace JS {
|
|
|
|
|
|
JS_DEFINE_ALLOCATOR(ECMAScriptFunctionObject);
|
|
|
|
|
|
-NonnullGCPtr<ECMAScriptFunctionObject> ECMAScriptFunctionObject::create(Realm& realm, DeprecatedFlyString name, ByteString source_text, Statement const& ecmascript_code, Vector<FunctionParameter> parameters, i32 m_function_length, Vector<DeprecatedFlyString> local_variables_names, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind kind, bool is_strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name)
|
|
|
+NonnullGCPtr<ECMAScriptFunctionObject> ECMAScriptFunctionObject::create(Realm& realm, DeprecatedFlyString name, ByteString source_text, Statement const& ecmascript_code, Vector<FunctionParameter> parameters, i32 m_function_length, Vector<DeprecatedFlyString> local_variables_names, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind kind, bool is_strict, UsesThis uses_this, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name)
|
|
|
{
|
|
|
Object* prototype = nullptr;
|
|
|
switch (kind) {
|
|
@@ -50,15 +50,15 @@ NonnullGCPtr<ECMAScriptFunctionObject> ECMAScriptFunctionObject::create(Realm& r
|
|
|
prototype = realm.intrinsics().async_generator_function_prototype();
|
|
|
break;
|
|
|
}
|
|
|
- return realm.heap().allocate<ECMAScriptFunctionObject>(realm, move(name), move(source_text), ecmascript_code, move(parameters), m_function_length, move(local_variables_names), parent_environment, private_environment, *prototype, kind, is_strict, might_need_arguments_object, contains_direct_call_to_eval, is_arrow_function, move(class_field_initializer_name));
|
|
|
+ return realm.heap().allocate<ECMAScriptFunctionObject>(realm, move(name), move(source_text), ecmascript_code, move(parameters), m_function_length, move(local_variables_names), parent_environment, private_environment, *prototype, kind, is_strict, uses_this, might_need_arguments_object, contains_direct_call_to_eval, is_arrow_function, move(class_field_initializer_name));
|
|
|
}
|
|
|
|
|
|
-NonnullGCPtr<ECMAScriptFunctionObject> ECMAScriptFunctionObject::create(Realm& realm, DeprecatedFlyString name, Object& prototype, ByteString source_text, Statement const& ecmascript_code, Vector<FunctionParameter> parameters, i32 m_function_length, Vector<DeprecatedFlyString> local_variables_names, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind kind, bool is_strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name)
|
|
|
+NonnullGCPtr<ECMAScriptFunctionObject> ECMAScriptFunctionObject::create(Realm& realm, DeprecatedFlyString name, Object& prototype, ByteString source_text, Statement const& ecmascript_code, Vector<FunctionParameter> parameters, i32 m_function_length, Vector<DeprecatedFlyString> local_variables_names, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind kind, bool is_strict, UsesThis uses_this, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name)
|
|
|
{
|
|
|
- return realm.heap().allocate<ECMAScriptFunctionObject>(realm, move(name), move(source_text), ecmascript_code, move(parameters), m_function_length, move(local_variables_names), parent_environment, private_environment, prototype, kind, is_strict, might_need_arguments_object, contains_direct_call_to_eval, is_arrow_function, move(class_field_initializer_name));
|
|
|
+ return realm.heap().allocate<ECMAScriptFunctionObject>(realm, move(name), move(source_text), ecmascript_code, move(parameters), m_function_length, move(local_variables_names), parent_environment, private_environment, prototype, kind, is_strict, uses_this, might_need_arguments_object, contains_direct_call_to_eval, is_arrow_function, move(class_field_initializer_name));
|
|
|
}
|
|
|
|
|
|
-ECMAScriptFunctionObject::ECMAScriptFunctionObject(DeprecatedFlyString name, ByteString source_text, Statement const& ecmascript_code, Vector<FunctionParameter> formal_parameters, i32 function_length, Vector<DeprecatedFlyString> local_variables_names, Environment* parent_environment, PrivateEnvironment* private_environment, Object& prototype, FunctionKind kind, bool strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name)
|
|
|
+ECMAScriptFunctionObject::ECMAScriptFunctionObject(DeprecatedFlyString name, ByteString source_text, Statement const& ecmascript_code, Vector<FunctionParameter> formal_parameters, i32 function_length, Vector<DeprecatedFlyString> local_variables_names, Environment* parent_environment, PrivateEnvironment* private_environment, Object& prototype, FunctionKind kind, bool strict, UsesThis uses_this, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name)
|
|
|
: FunctionObject(prototype)
|
|
|
, m_name(move(name))
|
|
|
, m_function_length(function_length)
|
|
@@ -327,6 +327,8 @@ ECMAScriptFunctionObject::ECMAScriptFunctionObject(DeprecatedFlyString name, Byt
|
|
|
(*lex_environment_size)++;
|
|
|
}));
|
|
|
}
|
|
|
+
|
|
|
+ m_function_environment_needed = m_arguments_object_needed || m_function_environment_bindings_count > 0 || m_var_environment_bindings_count > 0 || m_lex_environment_bindings_count > 0 || uses_this == UsesThis::Yes || m_contains_direct_call_to_eval;
|
|
|
}
|
|
|
|
|
|
void ECMAScriptFunctionObject::initialize(Realm& realm)
|
|
@@ -405,7 +407,8 @@ ThrowCompletionOr<Value> ECMAScriptFunctionObject::internal_call(Value this_argu
|
|
|
}
|
|
|
|
|
|
// 5. Perform OrdinaryCallBindThis(F, calleeContext, thisArgument).
|
|
|
- ordinary_call_bind_this(*callee_context, this_argument);
|
|
|
+ if (m_function_environment_needed)
|
|
|
+ ordinary_call_bind_this(*callee_context, this_argument);
|
|
|
|
|
|
// 6. Let result be Completion(OrdinaryCallEvaluateBody(F, argumentsList)).
|
|
|
auto result = ordinary_call_evaluate_body();
|
|
@@ -464,7 +467,8 @@ ThrowCompletionOr<NonnullGCPtr<Object>> ECMAScriptFunctionObject::internal_const
|
|
|
// 6. If kind is base, then
|
|
|
if (kind == ConstructorKind::Base) {
|
|
|
// a. Perform OrdinaryCallBindThis(F, calleeContext, thisArgument).
|
|
|
- ordinary_call_bind_this(*callee_context, this_argument);
|
|
|
+ if (m_function_environment_needed)
|
|
|
+ ordinary_call_bind_this(*callee_context, this_argument);
|
|
|
|
|
|
// b. Let initializeResult be Completion(InitializeInstanceElements(thisArgument, F)).
|
|
|
auto initialize_result = this_argument->initialize_instance_elements(*this);
|
|
@@ -929,7 +933,7 @@ ThrowCompletionOr<void> ECMAScriptFunctionObject::function_declaration_instantia
|
|
|
for (auto& declaration : m_functions_to_initialize) {
|
|
|
// a. Let fn be the sole element of the BoundNames of f.
|
|
|
// b. Let fo be InstantiateFunctionObject of f with arguments lexEnv and privateEnv.
|
|
|
- auto function = ECMAScriptFunctionObject::create(realm, declaration.name(), declaration.source_text(), declaration.body(), declaration.parameters(), declaration.function_length(), declaration.local_variables_names(), lex_environment, private_environment, declaration.kind(), declaration.is_strict_mode(), declaration.might_need_arguments_object(), declaration.contains_direct_call_to_eval());
|
|
|
+ auto function = ECMAScriptFunctionObject::create(realm, declaration.name(), declaration.source_text(), declaration.body(), declaration.parameters(), declaration.function_length(), declaration.local_variables_names(), lex_environment, private_environment, declaration.kind(), declaration.is_strict_mode(), declaration.uses_this(), declaration.might_need_arguments_object(), declaration.contains_direct_call_to_eval());
|
|
|
|
|
|
// c. Perform ! varEnv.SetMutableBinding(fn, fo, false).
|
|
|
if (declaration.name_identifier()->is_local()) {
|
|
@@ -984,15 +988,20 @@ ThrowCompletionOr<void> ECMAScriptFunctionObject::prepare_for_ordinary_call(Exec
|
|
|
// 6. Set the ScriptOrModule of calleeContext to F.[[ScriptOrModule]].
|
|
|
callee_context.script_or_module = m_script_or_module;
|
|
|
|
|
|
- // 7. Let localEnv be NewFunctionEnvironment(F, newTarget).
|
|
|
- auto local_environment = new_function_environment(*this, new_target);
|
|
|
- local_environment->ensure_capacity(m_function_environment_bindings_count);
|
|
|
+ if (m_function_environment_needed) {
|
|
|
+ // 7. Let localEnv be NewFunctionEnvironment(F, newTarget).
|
|
|
+ auto local_environment = new_function_environment(*this, new_target);
|
|
|
+ local_environment->ensure_capacity(m_function_environment_bindings_count);
|
|
|
|
|
|
- // 8. Set the LexicalEnvironment of calleeContext to localEnv.
|
|
|
- callee_context.lexical_environment = local_environment;
|
|
|
+ // 8. Set the LexicalEnvironment of calleeContext to localEnv.
|
|
|
+ callee_context.lexical_environment = local_environment;
|
|
|
|
|
|
- // 9. Set the VariableEnvironment of calleeContext to localEnv.
|
|
|
- callee_context.variable_environment = local_environment;
|
|
|
+ // 9. Set the VariableEnvironment of calleeContext to localEnv.
|
|
|
+ callee_context.variable_environment = local_environment;
|
|
|
+ } else {
|
|
|
+ callee_context.lexical_environment = environment();
|
|
|
+ callee_context.variable_environment = environment();
|
|
|
+ }
|
|
|
|
|
|
// 10. Set the PrivateEnvironment of calleeContext to F.[[PrivateEnvironment]].
|
|
|
callee_context.private_environment = m_private_environment;
|