diff --git a/Libraries/LibJS/AST.cpp b/Libraries/LibJS/AST.cpp index a8666b5a84..b3d4005551 100644 --- a/Libraries/LibJS/AST.cpp +++ b/Libraries/LibJS/AST.cpp @@ -324,220 +324,6 @@ bool ImportStatement::has_bound_name(Utf16FlyString const& name) const return m_entries.contains([&](auto& entry) { return entry.local_name == name; }); } -// 16.1.7 GlobalDeclarationInstantiation ( script, env ), https://tc39.es/ecma262/#sec-globaldeclarationinstantiation -ThrowCompletionOr Program::global_declaration_instantiation(VM& vm, GlobalEnvironment& global_environment) const -{ - auto& realm = *vm.current_realm(); - - // 1. Let lexNames be the LexicallyDeclaredNames of script. - // 2. Let varNames be the VarDeclaredNames of script. - // 3. For each element name of lexNames, do - TRY(for_each_lexically_declared_identifier([&](Identifier const& identifier) -> ThrowCompletionOr { - auto const& name = identifier.string(); - - // a. If HasLexicalDeclaration(env, name) is true, throw a SyntaxError exception. - if (global_environment.has_lexical_declaration(name)) - return vm.throw_completion(ErrorType::TopLevelVariableAlreadyDeclared, name); - - // b. Let hasRestrictedGlobal be ? HasRestrictedGlobalProperty(env, name). - auto has_restricted_global = TRY(global_environment.has_restricted_global_property(name)); - - // c. NOTE: Global var and function bindings (except those that are introduced by non-strict direct eval) are - // non-configurable and are therefore restricted global properties. - - // d. If hasRestrictedGlobal is true, throw a SyntaxError exception. - if (has_restricted_global) - return vm.throw_completion(ErrorType::RestrictedGlobalProperty, name); - - return {}; - })); - - // 4. For each element name of varNames, do - TRY(for_each_var_declared_identifier([&](Identifier const& identifier) -> ThrowCompletionOr { - // a. If env.HasLexicalDeclaration(name) is true, throw a SyntaxError exception. - if (global_environment.has_lexical_declaration(identifier.string())) - return vm.throw_completion(ErrorType::TopLevelVariableAlreadyDeclared, identifier.string()); - - return {}; - })); - - // 5. Let varDeclarations be the VarScopedDeclarations of script. - // 6. Let functionsToInitialize be a new empty List. - Vector functions_to_initialize; - - // 7. Let declaredFunctionNames be a new empty List. - HashTable declared_function_names; - - // 8. For each element d of varDeclarations, in reverse List order, do - - TRY(for_each_var_function_declaration_in_reverse_order([&](FunctionDeclaration const& function) -> ThrowCompletionOr { - auto function_name = function.name(); - - // a. If d is neither a VariableDeclaration nor a ForBinding nor a BindingIdentifier, then - // i. Assert: d is either a FunctionDeclaration, a GeneratorDeclaration, an AsyncFunctionDeclaration, or an AsyncGeneratorDeclaration. - // Note: This is checked in for_each_var_function_declaration_in_reverse_order. - - // ii. NOTE: If there are multiple function declarations for the same name, the last declaration is used. - - // iii. Let fn be the sole element of the BoundNames of d. - - // iv. If fn is not an element of declaredFunctionNames, then - if (declared_function_names.set(function_name) != AK::HashSetResult::InsertedNewEntry) - return {}; - - // 1. Let fnDefinable be ? env.CanDeclareGlobalFunction(fn). - auto function_definable = TRY(global_environment.can_declare_global_function(function_name)); - - // 2. If fnDefinable is false, throw a TypeError exception. - if (!function_definable) - return vm.throw_completion(ErrorType::CannotDeclareGlobalFunction, function_name); - - // 3. Append fn to declaredFunctionNames. - // Note: Already done in step iv. above. - - // 4. Insert d as the first element of functionsToInitialize. - // NOTE: Since prepending is much slower, we just append - // and iterate in reverse order in step 16 below. - functions_to_initialize.append(function); - return {}; - })); - - // 9. Let declaredVarNames be a new empty List. - HashTable declared_var_names; - - // 10. For each element d of varDeclarations, do - TRY(for_each_var_scoped_variable_declaration([&](Declaration const& declaration) { - // a. If d is a VariableDeclaration, a ForBinding, or a BindingIdentifier, then - // Note: This is done in for_each_var_scoped_variable_declaration. - - // i. For each String vn of the BoundNames of d, do - return declaration.for_each_bound_identifier([&](Identifier const& identifier) -> ThrowCompletionOr { - auto const& name = identifier.string(); - - // 1. If vn is not an element of declaredFunctionNames, then - if (declared_function_names.contains(name)) - return {}; - - // a. Let vnDefinable be ? env.CanDeclareGlobalVar(vn). - auto var_definable = TRY(global_environment.can_declare_global_var(name)); - - // b. If vnDefinable is false, throw a TypeError exception. - if (!var_definable) - return vm.throw_completion(ErrorType::CannotDeclareGlobalVariable, name); - - // c. If vn is not an element of declaredVarNames, then - // i. Append vn to declaredVarNames. - declared_var_names.set(name); - return {}; - }); - })); - - // 11. NOTE: No abnormal terminations occur after this algorithm step if the global object is an ordinary object. However, if the global object is a Proxy exotic object it may exhibit behaviours that cause abnormal terminations in some of the following steps. - // 12. NOTE: Annex B.3.2.2 adds additional steps at this point. - - // 12. Let strict be IsStrict of script. - // 13. If strict is false, then - if (!m_is_strict_mode) { - // a. Let declaredFunctionOrVarNames be the list-concatenation of declaredFunctionNames and declaredVarNames. - // b. For each FunctionDeclaration f that is directly contained in the StatementList of a Block, CaseClause, or DefaultClause Contained within script, do - TRY(for_each_function_hoistable_with_annexB_extension([&](FunctionDeclaration& function_declaration) -> ThrowCompletionOr { - // i. Let F be StringValue of the BindingIdentifier of f. - auto function_name = function_declaration.name(); - - // ii. If replacing the FunctionDeclaration f with a VariableStatement that has F as a BindingIdentifier would not produce any Early Errors for script, then - // Note: This step is already performed during parsing and for_each_function_hoistable_with_annexB_extension so this always passes here. - - // 1. If env.HasLexicalDeclaration(F) is false, then - if (global_environment.has_lexical_declaration(function_name)) - return {}; - - // a. Let fnDefinable be ? env.CanDeclareGlobalVar(F). - auto function_definable = TRY(global_environment.can_declare_global_function(function_name)); - // b. If fnDefinable is true, then - - if (!function_definable) - return {}; - - // i. NOTE: A var binding for F is only instantiated here if it is neither a VarDeclaredName nor the name of another FunctionDeclaration. - - // ii. If declaredFunctionOrVarNames does not contain F, then - - if (!declared_function_names.contains(function_name) && !declared_var_names.contains(function_name)) { - // i. Perform ? env.CreateGlobalVarBinding(F, false). - TRY(global_environment.create_global_var_binding(function_name, false)); - - // ii. Append F to declaredFunctionOrVarNames. - declared_function_names.set(function_name); - } - - // iii. When the FunctionDeclaration f is evaluated, perform the following steps in place of the FunctionDeclaration Evaluation algorithm provided in 15.2.6: - // i. Let genv be the running execution context's VariableEnvironment. - // ii. Let benv be the running execution context's LexicalEnvironment. - // iii. Let fobj be ! benv.GetBindingValue(F, false). - // iv. Perform ? genv.SetMutableBinding(F, fobj, false). - // v. Return unused. - function_declaration.set_should_do_additional_annexB_steps(); - - return {}; - })); - - // We should not use declared function names below here anymore since these functions are not in there in the spec. - declared_function_names.clear(); - } - - // 13. Let lexDeclarations be the LexicallyScopedDeclarations of script. - // 14. Let privateEnv be null. - PrivateEnvironment* private_environment = nullptr; - - // 15. For each element d of lexDeclarations, do - TRY(for_each_lexically_scoped_declaration([&](Declaration const& declaration) { - // a. NOTE: Lexically declared names are only instantiated here but not initialized. - // b. For each element dn of the BoundNames of d, do - return declaration.for_each_bound_identifier([&](Identifier const& identifier) -> ThrowCompletionOr { - auto const& name = identifier.string(); - - // i. If IsConstantDeclaration of d is true, then - if (declaration.is_constant_declaration()) { - // 1. Perform ? env.CreateImmutableBinding(dn, true). - TRY(global_environment.create_immutable_binding(vm, name, true)); - } - // ii. Else, - else { - // 1. Perform ? env.CreateMutableBinding(dn, false). - TRY(global_environment.create_mutable_binding(vm, name, false)); - } - - return {}; - }); - })); - - // 16. For each Parse Node f of functionsToInitialize, do - // NOTE: We iterate in reverse order since we appended the functions - // instead of prepending. We append because prepending is much slower - // and we only use the created vector here. - for (auto& declaration : functions_to_initialize.in_reverse()) { - // a. Let fn be the sole element of the BoundNames of f. - // b. Let fo be InstantiateFunctionObject of f with arguments env and privateEnv. - auto function = ECMAScriptFunctionObject::create_from_function_data( - realm, - SharedFunctionInstanceData::create_for_function_node(vm, declaration), - &global_environment, - private_environment); - - // c. Perform ? env.CreateGlobalFunctionBinding(fn, fo, false). - TRY(global_environment.create_global_function_binding(function->name(), function, false)); - } - - // 17. For each String vn of declaredVarNames, do - for (auto& var_name : declared_var_names) { - // a. Perform ? env.CreateGlobalVarBinding(vn, false). - TRY(global_environment.create_global_var_binding(var_name, false)); - } - - // 18. Return unused. - return {}; -} - ModuleRequest::ModuleRequest(Utf16FlyString module_specifier_, Vector attributes) : module_specifier(move(module_specifier_)) , attributes(move(attributes)) diff --git a/Libraries/LibJS/AST.h b/Libraries/LibJS/AST.h index dc06816059..c49c4a8ff8 100644 --- a/Libraries/LibJS/AST.h +++ b/Libraries/LibJS/AST.h @@ -572,8 +572,6 @@ public: bool has_top_level_await() const { return m_has_top_level_await; } void set_has_top_level_await() { m_has_top_level_await = true; } - ThrowCompletionOr global_declaration_instantiation(VM&, GlobalEnvironment&) const; - private: virtual bool is_program() const override { return true; }