SourceTextModule.cpp 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789
  1. /*
  2. * Copyright (c) 2021-2023, Andreas Kling <andreas@ladybird.org>
  3. * Copyright (c) 2022, David Tuin <davidot@serenityos.org>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include <AK/Debug.h>
  8. #include <AK/QuickSort.h>
  9. #include <LibJS/Bytecode/Interpreter.h>
  10. #include <LibJS/Parser.h>
  11. #include <LibJS/Runtime/AsyncFunctionDriverWrapper.h>
  12. #include <LibJS/Runtime/ECMAScriptFunctionObject.h>
  13. #include <LibJS/Runtime/GlobalEnvironment.h>
  14. #include <LibJS/Runtime/ModuleEnvironment.h>
  15. #include <LibJS/Runtime/PromiseCapability.h>
  16. #include <LibJS/SourceTextModule.h>
  17. namespace JS {
  18. JS_DEFINE_ALLOCATOR(SourceTextModule);
  19. // 16.2.2.2 Static Semantics: WithClauseToAttributes, https://tc39.es/proposal-import-attributes/#sec-with-clause-to-attributes
  20. static Vector<ImportAttribute> with_clause_to_assertions(Vector<ImportAttribute> const& source_attributes)
  21. {
  22. // WithClause : AttributesKeyword { WithEntries , opt }
  23. // 1. Let attributes be WithClauseToAttributes of WithEntries.
  24. Vector<ImportAttribute> attributes;
  25. // AssertEntries : AssertionKey : StringLiteral
  26. // AssertEntries : AssertionKey : StringLiteral , WithEntries
  27. for (auto const& attribute : source_attributes) {
  28. // 1. Let key be the PropName of AttributeKey.
  29. // 2. Let entry be the ImportAttribute Record { [[Key]]: key, [[Value]]: SV of StringLiteral }.
  30. // 3. Return « entry ».
  31. attributes.empend(attribute);
  32. }
  33. // 2. Sort attributes according to the lexicographic order of their [[Key]] fields, treating the value of each such field as a sequence of UTF-16 code unit values. NOTE: This sorting is observable only in that hosts are prohibited from distinguishing among attributes by the order they occur in.
  34. // Note: The sorting is done in construction of the ModuleRequest object.
  35. // 3. Return attributes.
  36. return attributes;
  37. }
  38. // 16.2.1.3 Static Semantics: ModuleRequests, https://tc39.es/ecma262/#sec-static-semantics-modulerequests
  39. static Vector<ModuleRequest> module_requests(Program& program)
  40. {
  41. // A List of all the ModuleSpecifier strings used by the module represented by this record to request the importation of a module.
  42. // Note: The List is source text occurrence ordered!
  43. struct RequestedModuleAndSourceIndex {
  44. u32 source_offset { 0 };
  45. ModuleRequest const* module_request { nullptr };
  46. };
  47. Vector<RequestedModuleAndSourceIndex> requested_modules_with_indices;
  48. for (auto& import_statement : program.imports())
  49. requested_modules_with_indices.empend(import_statement->start_offset(), &import_statement->module_request());
  50. for (auto& export_statement : program.exports()) {
  51. for (auto& export_entry : export_statement->entries()) {
  52. if (!export_entry.is_module_request())
  53. continue;
  54. requested_modules_with_indices.empend(export_statement->start_offset(), &export_statement->module_request());
  55. }
  56. }
  57. // Note: The List is source code occurrence ordered. https://tc39.es/proposal-import-attributes/#table-cyclic-module-fields
  58. quick_sort(requested_modules_with_indices, [&](RequestedModuleAndSourceIndex const& lhs, RequestedModuleAndSourceIndex const& rhs) {
  59. return lhs.source_offset < rhs.source_offset;
  60. });
  61. Vector<ModuleRequest> requested_modules_in_source_order;
  62. requested_modules_in_source_order.ensure_capacity(requested_modules_with_indices.size());
  63. for (auto& module : requested_modules_with_indices) {
  64. // 16.2.1.3 Static Semantics: ModuleRequests, https://tc39.es/proposal-import-attributes/#sec-static-semantics-modulerequests
  65. if (module.module_request->attributes.is_empty()) {
  66. // ExportDeclaration : export ExportFromClause FromClause ;
  67. // ImportDeclaration : import ImportClause FromClause ;
  68. // 2. Let specifier be SV of FromClause.
  69. // 3. Return a List whose sole element is the ModuleRequest Record { [[Specifer]]: specifier, [[Attributes]]: « » }.
  70. requested_modules_in_source_order.empend(module.module_request->module_specifier);
  71. } else {
  72. // ExportDeclaration : export ExportFromClause FromClause WithClause ;
  73. // ImportDeclaration : import ImportClause FromClause WithClause ;
  74. // 1. Let specifier be the SV of FromClause.
  75. // 2. Let attributes be WithClauseToAttributes of WithClause.
  76. auto attributes = with_clause_to_assertions(module.module_request->attributes);
  77. // NOTE: We have to modify the attributes in place because else it might keep unsupported ones.
  78. const_cast<ModuleRequest*>(module.module_request)->attributes = move(attributes);
  79. // 3. Return a List whose sole element is the ModuleRequest Record { [[Specifer]]: specifier, [[Attributes]]: attributes }.
  80. requested_modules_in_source_order.empend(module.module_request->module_specifier, module.module_request->attributes);
  81. }
  82. }
  83. return requested_modules_in_source_order;
  84. }
  85. SourceTextModule::SourceTextModule(Realm& realm, StringView filename, Script::HostDefined* host_defined, bool has_top_level_await, NonnullRefPtr<Program> body, Vector<ModuleRequest> requested_modules,
  86. Vector<ImportEntry> import_entries, Vector<ExportEntry> local_export_entries,
  87. Vector<ExportEntry> indirect_export_entries, Vector<ExportEntry> star_export_entries,
  88. RefPtr<ExportStatement const> default_export)
  89. : CyclicModule(realm, filename, has_top_level_await, move(requested_modules), host_defined)
  90. , m_ecmascript_code(move(body))
  91. , m_execution_context(ExecutionContext::create())
  92. , m_import_entries(move(import_entries))
  93. , m_local_export_entries(move(local_export_entries))
  94. , m_indirect_export_entries(move(indirect_export_entries))
  95. , m_star_export_entries(move(star_export_entries))
  96. , m_default_export(move(default_export))
  97. {
  98. }
  99. SourceTextModule::~SourceTextModule() = default;
  100. void SourceTextModule::visit_edges(Cell::Visitor& visitor)
  101. {
  102. Base::visit_edges(visitor);
  103. visitor.visit(m_import_meta);
  104. m_execution_context->visit_edges(visitor);
  105. }
  106. // 16.2.1.6.1 ParseModule ( sourceText, realm, hostDefined ), https://tc39.es/ecma262/#sec-parsemodule
  107. Result<NonnullGCPtr<SourceTextModule>, Vector<ParserError>> SourceTextModule::parse(StringView source_text, Realm& realm, StringView filename, Script::HostDefined* host_defined)
  108. {
  109. // 1. Let body be ParseText(sourceText, Module).
  110. auto parser = Parser(Lexer(source_text, filename), Program::Type::Module);
  111. auto body = parser.parse_program();
  112. // 2. If body is a List of errors, return body.
  113. if (parser.has_errors())
  114. return parser.errors();
  115. // 3. Let requestedModules be the ModuleRequests of body.
  116. auto requested_modules = module_requests(*body);
  117. // 4. Let importEntries be ImportEntries of body.
  118. Vector<ImportEntry> import_entries;
  119. for (auto const& import_statement : body->imports())
  120. import_entries.extend(import_statement->entries());
  121. // 5. Let importedBoundNames be ImportedLocalNames(importEntries).
  122. // Note: Since we have to potentially extract the import entry we just use importEntries
  123. // In the future it might be an optimization to have a set/map of string to speed up the search.
  124. // 6. Let indirectExportEntries be a new empty List.
  125. Vector<ExportEntry> indirect_export_entries;
  126. // 7. Let localExportEntries be a new empty List.
  127. Vector<ExportEntry> local_export_entries;
  128. // 8. Let starExportEntries be a new empty List.
  129. Vector<ExportEntry> star_export_entries;
  130. // Note: Not in the spec but makes it easier to find the default.
  131. RefPtr<ExportStatement const> default_export;
  132. // 9. Let exportEntries be ExportEntries of body.
  133. // 10. For each ExportEntry Record ee of exportEntries, do
  134. for (auto const& export_statement : body->exports()) {
  135. if (export_statement->is_default_export()) {
  136. VERIFY(!default_export);
  137. VERIFY(export_statement->entries().size() == 1);
  138. VERIFY(export_statement->has_statement());
  139. auto const& entry = export_statement->entries()[0];
  140. VERIFY(entry.kind == ExportEntry::Kind::NamedExport);
  141. VERIFY(!entry.is_module_request());
  142. VERIFY(import_entries.find_if(
  143. [&](ImportEntry const& import_entry) {
  144. return import_entry.local_name == entry.local_or_import_name;
  145. })
  146. .is_end());
  147. default_export = export_statement;
  148. }
  149. for (auto const& export_entry : export_statement->entries()) {
  150. // Special case, export {} from "module" should add "module" to
  151. // required_modules but not any import or export so skip here.
  152. if (export_entry.kind == ExportEntry::Kind::EmptyNamedExport) {
  153. VERIFY(export_statement->entries().size() == 1);
  154. break;
  155. }
  156. // a. If ee.[[ModuleRequest]] is null, then
  157. if (!export_entry.is_module_request()) {
  158. auto in_imported_bound_names = import_entries.find_if(
  159. [&](ImportEntry const& import_entry) {
  160. return import_entry.local_name == export_entry.local_or_import_name;
  161. });
  162. // i. If ee.[[LocalName]] is not an element of importedBoundNames, then
  163. if (in_imported_bound_names.is_end()) {
  164. // 1. Append ee to localExportEntries.
  165. local_export_entries.empend(export_entry);
  166. }
  167. // ii. Else,
  168. else {
  169. // 1. Let ie be the element of importEntries whose [[LocalName]] is the same as ee.[[LocalName]].
  170. auto& import_entry = *in_imported_bound_names;
  171. // 2. If ie.[[ImportName]] is namespace-object, then
  172. if (import_entry.is_namespace()) {
  173. // a. NOTE: This is a re-export of an imported module namespace object.
  174. // b. Append ee to localExportEntries.
  175. local_export_entries.empend(export_entry);
  176. }
  177. // 3. Else,
  178. else {
  179. // a. NOTE: This is a re-export of a single name.
  180. // b. Append the ExportEntry Record { [[ModuleRequest]]: ie.[[ModuleRequest]], [[ImportName]]: ie.[[ImportName]], [[LocalName]]: null, [[ExportName]]: ee.[[ExportName]] } to indirectExportEntries.
  181. indirect_export_entries.empend(ExportEntry::indirect_export_entry(import_entry.module_request(), export_entry.export_name, import_entry.import_name));
  182. }
  183. }
  184. }
  185. // b. Else if ee.[[ImportName]] is all-but-default, then
  186. else if (export_entry.kind == ExportEntry::Kind::ModuleRequestAllButDefault) {
  187. // i. Assert: ee.[[ExportName]] is null.
  188. VERIFY(!export_entry.export_name.has_value());
  189. // ii. Append ee to starExportEntries.
  190. star_export_entries.empend(export_entry);
  191. }
  192. // c. Else,
  193. else {
  194. // i. Append ee to indirectExportEntries.
  195. indirect_export_entries.empend(export_entry);
  196. }
  197. }
  198. }
  199. // 11. Let async be body Contains await.
  200. bool async = body->has_top_level_await();
  201. // 12. Return Source Text Module Record {
  202. // [[Realm]]: realm, [[Environment]]: empty, [[Namespace]]: empty, [[CycleRoot]]: empty, [[HasTLA]]: async,
  203. // [[AsyncEvaluation]]: false, [[TopLevelCapability]]: empty, [[AsyncParentModules]]: « »,
  204. // [[PendingAsyncDependencies]]: empty, [[Status]]: unlinked, [[EvaluationError]]: empty,
  205. // [[HostDefined]]: hostDefined, [[ECMAScriptCode]]: body, [[Context]]: empty, [[ImportMeta]]: empty,
  206. // [[RequestedModules]]: requestedModules, [[ImportEntries]]: importEntries, [[LocalExportEntries]]: localExportEntries,
  207. // [[IndirectExportEntries]]: indirectExportEntries, [[StarExportEntries]]: starExportEntries, [[DFSIndex]]: empty, [[DFSAncestorIndex]]: empty }.
  208. return realm.heap().allocate<SourceTextModule>(
  209. realm,
  210. filename,
  211. host_defined,
  212. async,
  213. move(body),
  214. move(requested_modules),
  215. move(import_entries),
  216. move(local_export_entries),
  217. move(indirect_export_entries),
  218. move(star_export_entries),
  219. move(default_export));
  220. }
  221. // 16.2.1.6.2 GetExportedNames ( [ exportStarSet ] ), https://tc39.es/ecma262/#sec-getexportednames
  222. ThrowCompletionOr<Vector<DeprecatedFlyString>> SourceTextModule::get_exported_names(VM& vm, Vector<Module*> export_star_set)
  223. {
  224. dbgln_if(JS_MODULE_DEBUG, "[JS MODULE] get_export_names of {}", filename());
  225. // 1. Assert: module.[[Status]] is not new.
  226. VERIFY(m_status != ModuleStatus::New);
  227. // 2. If exportStarSet is not present, set exportStarSet to a new empty List.
  228. // Note: This is done by default argument
  229. // 3. If exportStarSet contains module, then
  230. if (export_star_set.contains_slow(this)) {
  231. // a. Assert: We've reached the starting point of an export * circularity.
  232. // FIXME: How do we check that?
  233. // b. Return a new empty List.
  234. return Vector<DeprecatedFlyString> {};
  235. }
  236. // 4. Append module to exportStarSet.
  237. export_star_set.append(this);
  238. // 5. Let exportedNames be a new empty List.
  239. Vector<DeprecatedFlyString> exported_names;
  240. // 6. For each ExportEntry Record e of module.[[LocalExportEntries]], do
  241. for (auto& entry : m_local_export_entries) {
  242. // a. Assert: module provides the direct binding for this export.
  243. // FIXME: How do we check that?
  244. // b. Assert: e.[[ExportName]] is not null.
  245. VERIFY(entry.export_name.has_value());
  246. // c. Append e.[[ExportName]] to exportedNames.
  247. exported_names.empend(entry.export_name.value());
  248. }
  249. // 7. For each ExportEntry Record e of module.[[IndirectExportEntries]], do
  250. for (auto& entry : m_indirect_export_entries) {
  251. // a. a. Assert: module imports a specific binding for this export.
  252. // FIXME: How do we check that?
  253. // b. Assert: e.[[ExportName]] is not null.
  254. VERIFY(entry.export_name.has_value());
  255. // c. Append e.[[ExportName]] to exportedNames.
  256. exported_names.empend(entry.export_name.value());
  257. }
  258. // 8. For each ExportEntry Record e of module.[[StarExportEntries]], do
  259. for (auto& entry : m_star_export_entries) {
  260. // a. Assert: e.[[ModuleRequest]] is not null.
  261. // b. Let requestedModule be GetImportedModule(module, e.[[ModuleRequest]]).
  262. auto requested_module = get_imported_module(entry.module_request());
  263. // c. Let starNames be ? requestedModule.GetExportedNames(exportStarSet).
  264. auto star_names = TRY(requested_module->get_exported_names(vm, export_star_set));
  265. // d. For each element n of starNames, do
  266. for (auto& name : star_names) {
  267. // i. If SameValue(n, "default") is false, then
  268. if (name != "default"sv) {
  269. // 1. If n is not an element of exportedNames, then
  270. if (!exported_names.contains_slow(name)) {
  271. // a. Append n to exportedNames.
  272. exported_names.empend(name);
  273. }
  274. }
  275. }
  276. }
  277. // 9. Return exportedNames.
  278. return exported_names;
  279. }
  280. // 16.2.1.6.4 InitializeEnvironment ( ), https://tc39.es/ecma262/#sec-source-text-module-record-initialize-environment
  281. ThrowCompletionOr<void> SourceTextModule::initialize_environment(VM& vm)
  282. {
  283. // 1. For each ExportEntry Record e of module.[[IndirectExportEntries]], do
  284. for (auto& entry : m_indirect_export_entries) {
  285. // a. Let resolution be ? module.ResolveExport(e.[[ExportName]]).
  286. auto resolution = TRY(resolve_export(vm, entry.export_name.value()));
  287. // b. If resolution is null or ambiguous, throw a SyntaxError exception.
  288. if (!resolution.is_valid())
  289. return vm.throw_completion<SyntaxError>(ErrorType::InvalidOrAmbiguousExportEntry, entry.export_name);
  290. // c. Assert: resolution is a ResolvedBinding Record.
  291. VERIFY(resolution.is_valid());
  292. }
  293. // 2. Assert: All named exports from module are resolvable.
  294. // Note: We check all the indirect export entries above in step 1 and all
  295. // the local named exports are resolvable by construction.
  296. // 3. Let realm be module.[[Realm]].
  297. // 4. Assert: realm is not undefined.
  298. // Note: This must be true because we use a reference.
  299. // 5. Let env be NewModuleEnvironment(realm.[[GlobalEnv]]).
  300. auto environment = vm.heap().allocate<ModuleEnvironment>(&realm().global_environment());
  301. // 6. Set module.[[Environment]] to env.
  302. set_environment(environment);
  303. // 7. For each ImportEntry Record in of module.[[ImportEntries]], do
  304. for (auto& import_entry : m_import_entries) {
  305. // a. Let importedModule be GetImportedModule(module, in.[[ModuleRequest]]).
  306. auto imported_module = get_imported_module(import_entry.module_request());
  307. // b. NOTE: The above call cannot fail because imported module requests are a subset of module.[[RequestedModules]], and these have been resolved earlier in this algorithm.
  308. // c. If in.[[ImportName]] is namespace-object, then
  309. if (import_entry.is_namespace()) {
  310. // i. Let namespace be ? GetModuleNamespace(importedModule).
  311. auto* namespace_ = TRY(imported_module->get_module_namespace(vm));
  312. // ii. Perform ! env.CreateImmutableBinding(in.[[LocalName]], true).
  313. MUST(environment->create_immutable_binding(vm, import_entry.local_name, true));
  314. // iii. Perform ! env.InitializeBinding(in.[[LocalName]], namespace, normal).
  315. MUST(environment->initialize_binding(vm, import_entry.local_name, namespace_, Environment::InitializeBindingHint::Normal));
  316. }
  317. // d. Else,
  318. else {
  319. // i. Let resolution be ? importedModule.ResolveExport(in.[[ImportName]]).
  320. auto resolution = TRY(imported_module->resolve_export(vm, import_entry.import_name.value()));
  321. // ii. If resolution is null or ambiguous, throw a SyntaxError exception.
  322. if (!resolution.is_valid())
  323. return vm.throw_completion<SyntaxError>(ErrorType::InvalidOrAmbiguousExportEntry, import_entry.import_name);
  324. // iii. If resolution.[[BindingName]] is namespace, then
  325. if (resolution.is_namespace()) {
  326. // 1. Let namespace be ? GetModuleNamespace(resolution.[[Module]]).
  327. auto* namespace_ = TRY(resolution.module->get_module_namespace(vm));
  328. // 2. Perform ! env.CreateImmutableBinding(in.[[LocalName]], true).
  329. MUST(environment->create_immutable_binding(vm, import_entry.local_name, true));
  330. // 3. Perform ! env.InitializeBinding(in.[[LocalName]], namespace, normal).
  331. MUST(environment->initialize_binding(vm, import_entry.local_name, namespace_, Environment::InitializeBindingHint::Normal));
  332. }
  333. // iv. Else,
  334. else {
  335. // 1. Perform env.CreateImportBinding(in.[[LocalName]], resolution.[[Module]], resolution.[[BindingName]]).
  336. MUST(environment->create_import_binding(import_entry.local_name, resolution.module, resolution.export_name));
  337. }
  338. }
  339. }
  340. // 8. Let moduleContext be a new ECMAScript code execution context.
  341. // Note: this has already been created during the construction of this object.
  342. // 9. Set the Function of moduleContext to null.
  343. // 10. Assert: module.[[Realm]] is not undefined.
  344. // Note: This must be true because we use a reference.
  345. // 11. Set the Realm of moduleContext to module.[[Realm]].
  346. m_execution_context->realm = &realm();
  347. // 12. Set the ScriptOrModule of moduleContext to module.
  348. m_execution_context->script_or_module = NonnullGCPtr<Module>(*this);
  349. // 13. Set the VariableEnvironment of moduleContext to module.[[Environment]].
  350. m_execution_context->variable_environment = environment;
  351. // 14. Set the LexicalEnvironment of moduleContext to module.[[Environment]].
  352. m_execution_context->lexical_environment = environment;
  353. // 15. Set the PrivateEnvironment of moduleContext to null.
  354. // 16. Set module.[[Context]] to moduleContext.
  355. // Note: We're already working on that one.
  356. // 17. Push moduleContext onto the execution context stack; moduleContext is now the running execution context.
  357. TRY(vm.push_execution_context(*m_execution_context, {}));
  358. // 18. Let code be module.[[ECMAScriptCode]].
  359. // 19. Let varDeclarations be the VarScopedDeclarations of code.
  360. // Note: We just loop through them in step 21.
  361. // 20. Let declaredVarNames be a new empty List.
  362. Vector<DeprecatedFlyString> declared_var_names;
  363. // 21. For each element d of varDeclarations, do
  364. // a. For each element dn of the BoundNames of d, do
  365. // NOTE: Due to the use of MUST with `create_mutable_binding` and `initialize_binding` below,
  366. // an exception should not result from `for_each_var_declared_identifier`.
  367. MUST(m_ecmascript_code->for_each_var_declared_identifier([&](auto const& identifier) {
  368. auto const& name = identifier.string();
  369. // i. If dn is not an element of declaredVarNames, then
  370. if (!declared_var_names.contains_slow(name)) {
  371. // 1. Perform ! env.CreateMutableBinding(dn, false).
  372. MUST(environment->create_mutable_binding(vm, name, false));
  373. // 2. Perform ! env.InitializeBinding(dn, undefined, normal).
  374. MUST(environment->initialize_binding(vm, name, js_undefined(), Environment::InitializeBindingHint::Normal));
  375. // 3. Append dn to declaredVarNames.
  376. declared_var_names.empend(name);
  377. }
  378. }));
  379. // 22. Let lexDeclarations be the LexicallyScopedDeclarations of code.
  380. // Note: We only loop through them in step 24.
  381. // 23. Let privateEnv be null.
  382. PrivateEnvironment* private_environment = nullptr;
  383. // 24. For each element d of lexDeclarations, do
  384. // NOTE: Due to the use of MUST in the callback, an exception should not result from `for_each_lexically_scoped_declaration`.
  385. MUST(m_ecmascript_code->for_each_lexically_scoped_declaration([&](Declaration const& declaration) {
  386. // a. For each element dn of the BoundNames of d, do
  387. // NOTE: Due to the use of MUST with `create_immutable_binding`, `create_mutable_binding` and `initialize_binding` below,
  388. // an exception should not result from `for_each_bound_identifier`.
  389. MUST(declaration.for_each_bound_identifier([&](auto const& identifier) {
  390. auto const& name = identifier.string();
  391. // i. If IsConstantDeclaration of d is true, then
  392. if (declaration.is_constant_declaration()) {
  393. // 1. Perform ! env.CreateImmutableBinding(dn, true).
  394. MUST(environment->create_immutable_binding(vm, name, true));
  395. }
  396. // ii. Else,
  397. else {
  398. // 1. Perform ! env.CreateMutableBinding(dn, false).
  399. MUST(environment->create_mutable_binding(vm, name, false));
  400. }
  401. // iii. If d is a FunctionDeclaration, a GeneratorDeclaration, an AsyncFunctionDeclaration, or an AsyncGeneratorDeclaration, then
  402. if (declaration.is_function_declaration()) {
  403. VERIFY(is<FunctionDeclaration>(declaration));
  404. auto const& function_declaration = static_cast<FunctionDeclaration const&>(declaration);
  405. // 1. Let fo be InstantiateFunctionObject of d with arguments env and privateEnv.
  406. // NOTE: Special case if the function is a default export of an anonymous function
  407. // it has name "*default*" but internally should have name "default".
  408. DeprecatedFlyString function_name = function_declaration.name();
  409. if (function_name == ExportStatement::local_name_for_default)
  410. function_name = "default"sv;
  411. auto function = ECMAScriptFunctionObject::create(realm(), function_name, function_declaration.source_text(), function_declaration.body(), function_declaration.parameters(), function_declaration.function_length(), function_declaration.local_variables_names(), environment, private_environment, function_declaration.kind(), function_declaration.is_strict_mode(),
  412. function_declaration.parsing_insights());
  413. // 2. Perform ! env.InitializeBinding(dn, fo, normal).
  414. MUST(environment->initialize_binding(vm, name, function, Environment::InitializeBindingHint::Normal));
  415. }
  416. }));
  417. }));
  418. // Note: The default export name is also part of the local lexical declarations but
  419. // instead of making that a special case in the parser we just check it here.
  420. // This is only needed for things which are not declarations.
  421. // For more info check Parser::parse_export_statement.
  422. // Furthermore, that declaration is not constant. so we take 24.a.ii
  423. if (m_default_export) {
  424. VERIFY(m_default_export->has_statement());
  425. auto const& statement = m_default_export->statement();
  426. if (!is<Declaration>(statement)) {
  427. auto const& name = m_default_export->entries()[0].local_or_import_name;
  428. dbgln_if(JS_MODULE_DEBUG, "[JS MODULE] Adding default export to lexical declarations: local name: {}, Expression: {}", name, statement.class_name());
  429. // 1. Perform ! env.CreateMutableBinding(dn, false).
  430. MUST(environment->create_mutable_binding(vm, name.value(), false));
  431. // Note: Since this is not a function declaration 24.a.iii never applies
  432. }
  433. }
  434. // 25. Remove moduleContext from the execution context stack.
  435. vm.pop_execution_context();
  436. // 26. Return unused.
  437. return {};
  438. }
  439. // 16.2.1.6.3 ResolveExport ( exportName [ , resolveSet ] ), https://tc39.es/ecma262/#sec-resolveexport
  440. ThrowCompletionOr<ResolvedBinding> SourceTextModule::resolve_export(VM& vm, DeprecatedFlyString const& export_name, Vector<ResolvedBinding> resolve_set)
  441. {
  442. // 1. Assert: module.[[Status]] is not new.
  443. VERIFY(m_status != ModuleStatus::New);
  444. // 2. If resolveSet is not present, set resolveSet to a new empty List.
  445. // Note: This is done by the default argument.
  446. // 3. For each Record { [[Module]], [[ExportName]] } r of resolveSet, do
  447. for (auto& [type, module, exported_name] : resolve_set) {
  448. // a. If module and r.[[Module]] are the same Module Record and SameValue(exportName, r.[[ExportName]]) is true, then
  449. if (module == this && exported_name == export_name) {
  450. // i. Assert: This is a circular import request.
  451. // ii. Return null.
  452. return ResolvedBinding::null();
  453. }
  454. }
  455. // 4. Append the Record { [[Module]]: module, [[ExportName]]: exportName } to resolveSet.
  456. resolve_set.append({ ResolvedBinding::Type::BindingName, this, export_name });
  457. // 5. For each ExportEntry Record e of module.[[LocalExportEntries]], do
  458. for (auto& entry : m_local_export_entries) {
  459. // a. If SameValue(exportName, e.[[ExportName]]) is true, then
  460. if (export_name != entry.export_name)
  461. continue;
  462. // i. Assert: module provides the direct binding for this export.
  463. // FIXME: What does this mean?
  464. // ii. Return ResolvedBinding Record { [[Module]]: module, [[BindingName]]: e.[[LocalName]] }.
  465. return ResolvedBinding {
  466. ResolvedBinding::Type::BindingName,
  467. this,
  468. entry.local_or_import_name.value(),
  469. };
  470. }
  471. // 5. For each ExportEntry Record e of module.[[IndirectExportEntries]], do
  472. for (auto& entry : m_indirect_export_entries) {
  473. // a. If SameValue(exportName, e.[[ExportName]]) is true, then
  474. if (export_name != entry.export_name)
  475. continue;
  476. // i. Assert: e.[[ModuleRequest]] is not null.
  477. // ii. Let importedModule be GetImportedModule(module, e.[[ModuleRequest]]).
  478. auto imported_module = get_imported_module(entry.module_request());
  479. // iii. If e.[[ImportName]] is all, then
  480. if (entry.kind == ExportEntry::Kind::ModuleRequestAll) {
  481. // 1. Assert: module does not provide the direct binding for this export.
  482. // FIXME: What does this mean? / How do we check this
  483. // 2. Return ResolvedBinding Record { [[Module]]: importedModule, [[BindingName]]: namespace }.
  484. return ResolvedBinding {
  485. ResolvedBinding::Type::Namespace,
  486. imported_module.ptr(),
  487. {}
  488. };
  489. }
  490. // iv. Else,
  491. else {
  492. // 1. Assert: module imports a specific binding for this export.
  493. // FIXME: What does this mean? / How do we check this
  494. // 2. Return ? importedModule.ResolveExport(e.[[ImportName]], resolveSet).
  495. return imported_module->resolve_export(vm, entry.local_or_import_name.value(), resolve_set);
  496. }
  497. }
  498. // 7. If SameValue(exportName, "default") is true, then
  499. if (export_name == "default"sv) {
  500. // a. Assert: A default export was not explicitly defined by this module.
  501. // FIXME: What does this mean? / How do we check this
  502. // b. Return null.
  503. return ResolvedBinding::null();
  504. // c. NOTE: A default export cannot be provided by an export * from "mod" declaration.
  505. }
  506. // 8. Let starResolution be null.
  507. ResolvedBinding star_resolution = ResolvedBinding::null();
  508. // 9. For each ExportEntry Record e of module.[[StarExportEntries]], do
  509. for (auto& entry : m_star_export_entries) {
  510. // a. Assert: e.[[ModuleRequest]] is not null.
  511. // b. Let importedModule be GetImportedModule(module, e.[[ModuleRequest]]).
  512. auto imported_module = get_imported_module(entry.module_request());
  513. // c. Let resolution be ? importedModule.ResolveExport(exportName, resolveSet).
  514. auto resolution = TRY(imported_module->resolve_export(vm, export_name, resolve_set));
  515. // d. If resolution is ambiguous, return ambiguous.
  516. if (resolution.is_ambiguous())
  517. return ResolvedBinding::ambiguous();
  518. // e. If resolution is not null, then
  519. if (resolution.type == ResolvedBinding::Null)
  520. continue;
  521. // i. Assert: resolution is a ResolvedBinding Record.
  522. VERIFY(resolution.is_valid());
  523. // ii. If starResolution is null, set starResolution to resolution.
  524. if (star_resolution.type == ResolvedBinding::Null) {
  525. star_resolution = resolution;
  526. }
  527. // iii. Else,
  528. else {
  529. // 1. Assert: There is more than one * import that includes the requested name.
  530. // FIXME: Assert this
  531. // 2. If resolution.[[Module]] and starResolution.[[Module]] are not the same Module Record, return ambiguous.
  532. if (resolution.module != star_resolution.module)
  533. return ResolvedBinding::ambiguous();
  534. // 3. If resolution.[[BindingName]] is namespace and starResolution.[[BindingName]] is not namespace, or if resolution.[[BindingName]] is not namespace and starResolution.[[BindingName]] is namespace, return ambiguous.
  535. if (resolution.is_namespace() != star_resolution.is_namespace())
  536. return ResolvedBinding::ambiguous();
  537. // 4. If resolution.[[BindingName]] is a String, starResolution.[[BindingName]] is a String, and SameValue(resolution.[[BindingName]], starResolution.[[BindingName]]) is false, return ambiguous.
  538. if (!resolution.is_namespace() && resolution.export_name != star_resolution.export_name) {
  539. // Note: Because we know from the previous if that either both are namespaces or both are string we can check just one
  540. return ResolvedBinding::ambiguous();
  541. }
  542. }
  543. }
  544. // 10. Return starResolution.
  545. return star_resolution;
  546. }
  547. // 16.2.1.6.5 ExecuteModule ( [ capability ] ), https://tc39.es/ecma262/#sec-source-text-module-record-execute-module
  548. ThrowCompletionOr<void> SourceTextModule::execute_module(VM& vm, GCPtr<PromiseCapability> capability)
  549. {
  550. dbgln_if(JS_MODULE_DEBUG, "[JS MODULE] SourceTextModule::execute_module({}, PromiseCapability @ {})", filename(), capability.ptr());
  551. // 1. Let moduleContext be a new ECMAScript code execution context.
  552. auto module_context = ExecutionContext::create();
  553. // Note: This is not in the spec but we require it.
  554. module_context->is_strict_mode = true;
  555. // 2. Set the Function of moduleContext to null.
  556. // 3. Set the Realm of moduleContext to module.[[Realm]].
  557. module_context->realm = &realm();
  558. // 4. Set the ScriptOrModule of moduleContext to module.
  559. module_context->script_or_module = NonnullGCPtr<Module>(*this);
  560. // 5. Assert: module has been linked and declarations in its module environment have been instantiated.
  561. VERIFY(m_status != ModuleStatus::New);
  562. VERIFY(m_status != ModuleStatus::Unlinked);
  563. VERIFY(m_status != ModuleStatus::Linking);
  564. VERIFY(environment());
  565. // 6. Set the VariableEnvironment of moduleContext to module.[[Environment]].
  566. module_context->variable_environment = environment();
  567. // 7. Set the LexicalEnvironment of moduleContext to module.[[Environment]].
  568. module_context->lexical_environment = environment();
  569. // 8. Suspend the currently running execution context.
  570. // FIXME: We don't have suspend yet
  571. // 9. If module.[[HasTLA]] is false, then
  572. if (!m_has_top_level_await) {
  573. // a. Assert: capability is not present.
  574. VERIFY(capability == nullptr);
  575. // b. Push moduleContext onto the execution context stack; moduleContext is now the running execution context.
  576. TRY(vm.push_execution_context(*module_context, {}));
  577. // c. Let result be the result of evaluating module.[[ECMAScriptCode]].
  578. Completion result;
  579. auto maybe_executable = Bytecode::compile(vm, m_ecmascript_code, FunctionKind::Normal, "ShadowRealmEval"sv);
  580. if (maybe_executable.is_error())
  581. result = maybe_executable.release_error();
  582. else {
  583. auto executable = maybe_executable.release_value();
  584. auto result_and_return_register = vm.bytecode_interpreter().run_executable(*executable, {});
  585. if (result_and_return_register.value.is_error()) {
  586. result = result_and_return_register.value.release_error();
  587. } else {
  588. // Resulting value is in the accumulator.
  589. result = result_and_return_register.return_register_value.value_or(js_undefined());
  590. }
  591. }
  592. // d. Let env be moduleContext's LexicalEnvironment.
  593. auto env = module_context->lexical_environment;
  594. VERIFY(is<DeclarativeEnvironment>(*env));
  595. // e. Set result to DisposeResources(env, result).
  596. result = dispose_resources(vm, static_cast<DeclarativeEnvironment*>(env.ptr()), result);
  597. // f. Suspend moduleContext and remove it from the execution context stack.
  598. vm.pop_execution_context();
  599. // g. Resume the context that is now on the top of the execution context stack as the running execution context.
  600. // FIXME: We don't have resume yet.
  601. // h. If result is an abrupt completion, then
  602. if (result.is_error()) {
  603. // i. Return ? result.
  604. return result.release_error();
  605. }
  606. }
  607. // 10. Else,
  608. else {
  609. // a. Assert: capability is a PromiseCapability Record.
  610. VERIFY(capability != nullptr);
  611. // b. Perform AsyncBlockStart(capability, module.[[ECMAScriptCode]], moduleContext).
  612. // AD-HOC: We implement asynchronous execution via synthetic generator functions,
  613. // so we fake "AsyncBlockStart" here by creating an async function to wrap
  614. // the top-level module code.
  615. // FIXME: Improve this situation, so we can match the spec better.
  616. FunctionParsingInsights parsing_insights;
  617. parsing_insights.uses_this_from_environment = true;
  618. parsing_insights.uses_this = true;
  619. auto module_wrapper_function = ECMAScriptFunctionObject::create(
  620. realm(), "module code with top-level await", StringView {}, this->m_ecmascript_code,
  621. {}, 0, {}, environment(), nullptr, FunctionKind::Async, true, parsing_insights);
  622. module_wrapper_function->set_is_module_wrapper(true);
  623. // AD-HOC: We push/pop the moduleContext around the call to ensure that the async execution context
  624. // captures the module execution context.
  625. vm.push_execution_context(*module_context);
  626. auto result = call(vm, Value { module_wrapper_function }, js_undefined(), ReadonlySpan<Value> {});
  627. vm.pop_execution_context();
  628. // AD-HOC: This is basically analogous to what AsyncBlockStart would do.
  629. if (result.is_throw_completion()) {
  630. MUST(call(vm, *capability->reject(), js_undefined(), result.throw_completion().value().value()));
  631. } else {
  632. MUST(call(vm, *capability->resolve(), js_undefined(), result.value()));
  633. }
  634. }
  635. // 11. Return unused.
  636. return {};
  637. }
  638. }