SourceTextModule.cpp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647
  1. /*
  2. * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
  3. * Copyright (c) 2022, David Tuin <davidot@serenityos.org>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include <AK/QuickSort.h>
  8. #include <LibJS/Interpreter.h>
  9. #include <LibJS/Runtime/ECMAScriptFunctionObject.h>
  10. #include <LibJS/Runtime/ModuleEnvironment.h>
  11. #include <LibJS/SourceTextModule.h>
  12. namespace JS {
  13. // 16.2.1.3 Static Semantics: ModuleRequests, https://tc39.es/ecma262/#sec-static-semantics-modulerequests
  14. static Vector<FlyString> module_requests(Program const& program)
  15. {
  16. // A List of all the ModuleSpecifier strings used by the module represented by this record to request the importation of a module.
  17. // Note: The List is source text occurrence ordered!
  18. struct RequestedModuleAndSourceIndex {
  19. FlyString requested_module;
  20. u64 source_index;
  21. bool operator<(RequestedModuleAndSourceIndex const& rhs) const
  22. {
  23. return source_index < rhs.source_index;
  24. }
  25. };
  26. Vector<RequestedModuleAndSourceIndex> requested_modules_with_indices;
  27. for (auto const& import_statement : program.imports()) {
  28. requested_modules_with_indices.append({ import_statement.module_request().module_specifier.view(),
  29. import_statement.source_range().start.offset });
  30. }
  31. for (auto const& export_statement : program.exports()) {
  32. for (auto const& export_entry : export_statement.entries()) {
  33. if (export_entry.kind != ExportStatement::ExportEntry::Kind::ModuleRequest)
  34. continue;
  35. requested_modules_with_indices.append({ export_entry.module_request.module_specifier.view(),
  36. export_statement.source_range().start.offset });
  37. }
  38. }
  39. quick_sort(requested_modules_with_indices);
  40. Vector<FlyString> requested_modules_in_source_order;
  41. requested_modules_in_source_order.ensure_capacity(requested_modules_with_indices.size());
  42. for (auto& module : requested_modules_with_indices) {
  43. requested_modules_in_source_order.append(module.requested_module);
  44. }
  45. return requested_modules_in_source_order;
  46. }
  47. SourceTextModule::SourceTextModule(Realm& realm, StringView filename, bool has_top_level_await, NonnullRefPtr<Program> body, Vector<FlyString> requested_modules,
  48. Vector<ImportEntry> import_entries, Vector<ExportEntry> local_export_entries,
  49. Vector<ExportEntry> indirect_export_entries, Vector<ExportEntry> star_export_entries,
  50. RefPtr<ExportStatement> default_export)
  51. : CyclicModule(realm, filename, has_top_level_await, move(requested_modules))
  52. , m_ecmascript_code(move(body))
  53. , m_execution_context(realm.heap())
  54. , m_import_entries(move(import_entries))
  55. , m_local_export_entries(move(local_export_entries))
  56. , m_indirect_export_entries(move(indirect_export_entries))
  57. , m_star_export_entries(move(star_export_entries))
  58. , m_default_export(move(default_export))
  59. {
  60. }
  61. // 16.2.1.6.1 ParseModule ( sourceText, realm, hostDefined ), https://tc39.es/ecma262/#sec-parsemodule
  62. Result<NonnullRefPtr<SourceTextModule>, Vector<Parser::Error>> SourceTextModule::parse(StringView source_text, Realm& realm, StringView filename)
  63. {
  64. // 1. Let body be ParseText(sourceText, Module).
  65. auto parser = Parser(Lexer(source_text, filename), Program::Type::Module);
  66. auto body = parser.parse_program();
  67. // 2. If body is a List of errors, return body.
  68. if (parser.has_errors())
  69. return parser.errors();
  70. // 3. Let requestedModules be the ModuleRequests of body.
  71. auto requested_modules = module_requests(*body);
  72. // 4. Let importEntries be ImportEntries of body.
  73. Vector<ImportEntry> import_entries;
  74. for (auto const& import_statement : body->imports())
  75. import_entries.extend(import_statement.entries());
  76. // 5. Let importedBoundNames be ImportedLocalNames(importEntries).
  77. // Note: Since we have to potentially extract the import entry we just use importEntries
  78. // In the future it might be an optimization to have a set/map of string to speed up the search.
  79. // 6. Let indirectExportEntries be a new empty List.
  80. Vector<ExportEntry> indirect_export_entries;
  81. // 7. Let localExportEntries be a new empty List.
  82. Vector<ExportEntry> local_export_entries;
  83. // 8. Let starExportEntries be a new empty List.
  84. Vector<ExportEntry> star_export_entries;
  85. // Note: Not in the spec but makes it easier to find the default.
  86. RefPtr<ExportStatement> default_export;
  87. // 9. Let exportEntries be ExportEntries of body.
  88. // 10. For each ExportEntry Record ee of exportEntries, do
  89. for (auto const& export_statement : body->exports()) {
  90. if (export_statement.is_default_export()) {
  91. VERIFY(!default_export);
  92. VERIFY(export_statement.entries().size() == 1);
  93. VERIFY(export_statement.has_statement());
  94. auto const& entry = export_statement.entries()[0];
  95. VERIFY(entry.kind == ExportStatement::ExportEntry::Kind::LocalExport);
  96. VERIFY(import_entries.find_if(
  97. [&](ImportEntry const& import_entry) {
  98. return import_entry.local_name == entry.local_or_import_name;
  99. })
  100. .is_end());
  101. default_export = export_statement;
  102. }
  103. for (auto const& export_entry : export_statement.entries()) {
  104. // a. If ee.[[ModuleRequest]] is null, then
  105. if (export_entry.kind == ExportStatement::ExportEntry::Kind::LocalExport) {
  106. auto in_imported_bound_names = import_entries.find_if(
  107. [&](ImportEntry const& import_entry) {
  108. return import_entry.local_name == export_entry.local_or_import_name;
  109. });
  110. // i. If ee.[[LocalName]] is not an element of importedBoundNames, then
  111. if (in_imported_bound_names.is_end()) {
  112. // 1. Append ee to localExportEntries.
  113. local_export_entries.empend(export_entry);
  114. }
  115. // ii. Else,
  116. else {
  117. // 1. Let ie be the element of importEntries whose [[LocalName]] is the same as ee.[[LocalName]].
  118. auto& import_entry = *in_imported_bound_names;
  119. // 2. If ie.[[ImportName]] is namespace-object, then
  120. if (import_entry.is_namespace()) {
  121. // a. NOTE: This is a re-export of an imported module namespace object.
  122. // b. Append ee to localExportEntries.
  123. local_export_entries.empend(export_entry);
  124. }
  125. // 3. Else,
  126. else {
  127. // a. NOTE: This is a re-export of a single name.
  128. // b. Append the ExportEntry Record { [[ModuleRequest]]: ie.[[ModuleRequest]], [[ImportName]]: ie.[[ImportName]], [[LocalName]]: null, [[ExportName]]: ee.[[ExportName]] } to indirectExportEntries.
  129. indirect_export_entries.empend(import_entry.module_request(), import_entry.import_name, export_entry.export_name);
  130. }
  131. }
  132. }
  133. // b. Else if ee.[[ImportName]] is all-but-default, then
  134. else if (export_entry.is_all_but_default()) {
  135. // i. Assert: ee.[[ExportName]] is null.
  136. VERIFY(export_entry.export_name.is_null());
  137. // ii. Append ee to starExportEntries.
  138. star_export_entries.empend(export_entry);
  139. }
  140. // c. Else,
  141. else {
  142. // i. Append ee to indirectExportEntries.
  143. indirect_export_entries.empend(export_entry);
  144. }
  145. }
  146. }
  147. // 11. Let async be body Contains await.
  148. bool async = body->has_top_level_await();
  149. // 12. Return Source Text Module Record {
  150. // [[Realm]]: realm, [[Environment]]: empty, [[Namespace]]: empty, [[CycleRoot]]: empty, [[HasTLA]]: async,
  151. // [[AsyncEvaluation]]: false, [[TopLevelCapability]]: empty, [[AsyncParentModules]]: « »,
  152. // [[PendingAsyncDependencies]]: empty, [[Status]]: unlinked, [[EvaluationError]]: empty,
  153. // [[HostDefined]]: hostDefined, [[ECMAScriptCode]]: body, [[Context]]: empty, [[ImportMeta]]: empty,
  154. // [[RequestedModules]]: requestedModules, [[ImportEntries]]: importEntries, [[LocalExportEntries]]: localExportEntries,
  155. // [[IndirectExportEntries]]: indirectExportEntries, [[StarExportEntries]]: starExportEntries, [[DFSIndex]]: empty, [[DFSAncestorIndex]]: empty }.
  156. // FIXME: Add HostDefined
  157. return adopt_ref(*new SourceTextModule(realm, filename, async, move(body), move(requested_modules), move(import_entries), move(local_export_entries), move(indirect_export_entries), move(star_export_entries), move(default_export)));
  158. }
  159. // 16.2.1.6.2 GetExportedNames ( [ exportStarSet ] ), https://tc39.es/ecma262/#sec-getexportednames
  160. ThrowCompletionOr<Vector<FlyString>> SourceTextModule::get_exported_names(VM& vm, Vector<Module*> export_star_set)
  161. {
  162. dbgln_if(JS_MODULE_DEBUG, "[JS MODULE] get_export_names of {}", filename());
  163. // 1. If exportStarSet is not present, set exportStarSet to a new empty List.
  164. // Note: This is done by default argument
  165. // 2. If exportStarSet contains module, then
  166. if (export_star_set.contains_slow(this)) {
  167. // a. Assert: We've reached the starting point of an export * circularity.
  168. // FIXME: How do we check that?
  169. // b. Return a new empty List.
  170. return Vector<FlyString> {};
  171. }
  172. // 3. Append module to exportStarSet.
  173. export_star_set.append(this);
  174. // 4. Let exportedNames be a new empty List.
  175. Vector<FlyString> exported_names;
  176. // 5. For each ExportEntry Record e of module.[[LocalExportEntries]], do
  177. for (auto& entry : m_local_export_entries) {
  178. // a. Assert: module provides the direct binding for this export.
  179. // FIXME: How do we check that?
  180. // b. Append e.[[ExportName]] to exportedNames.
  181. exported_names.empend(entry.export_name);
  182. }
  183. // 6. For each ExportEntry Record e of module.[[IndirectExportEntries]], do
  184. for (auto& entry : m_indirect_export_entries) {
  185. // a. Assert: module provides the direct binding for this export.
  186. // FIXME: How do we check that?
  187. // b. Append e.[[ExportName]] to exportedNames.
  188. exported_names.empend(entry.export_name);
  189. }
  190. // 7. For each ExportEntry Record e of module.[[StarExportEntries]], do
  191. for (auto& entry : m_star_export_entries) {
  192. // a. Let requestedModule be ? HostResolveImportedModule(module, e.[[ModuleRequest]]).
  193. auto requested_module = TRY(vm.host_resolve_imported_module(this, entry.module_request));
  194. // b. Let starNames be ? requestedModule.GetExportedNames(exportStarSet).
  195. auto star_names = TRY(requested_module->get_exported_names(vm, export_star_set));
  196. // c. For each element n of starNames, do
  197. for (auto& name : star_names) {
  198. // i. If SameValue(n, "default") is false, then
  199. if (name != "default"sv) {
  200. // 1. If n is not an element of exportedNames, then
  201. if (!exported_names.contains_slow(name)) {
  202. // a. Append n to exportedNames.
  203. exported_names.empend(name);
  204. }
  205. }
  206. }
  207. }
  208. // 8. Return exportedNames.
  209. return exported_names;
  210. }
  211. // 16.2.1.6.4 InitializeEnvironment ( ), https://tc39.es/ecma262/#sec-source-text-module-record-initialize-environment
  212. Completion SourceTextModule::initialize_environment(VM& vm)
  213. {
  214. // 1. For each ExportEntry Record e of module.[[IndirectExportEntries]], do
  215. for (auto& entry : m_indirect_export_entries) {
  216. // a. Let resolution be ? module.ResolveExport(e.[[ExportName]]).
  217. auto resolution = TRY(resolve_export(vm, entry.export_name));
  218. // b. If resolution is null or ambiguous, throw a SyntaxError exception.
  219. if (!resolution.is_valid())
  220. return vm.throw_completion<SyntaxError>(realm().global_object(), ErrorType::InvalidOrAmbiguousExportEntry, entry.export_name);
  221. // c. Assert: resolution is a ResolvedBinding Record.
  222. VERIFY(resolution.is_valid());
  223. }
  224. // 2. Assert: All named exports from module are resolvable.
  225. // Note: We check all the indirect export entries above in step 1 and all
  226. // the local named exports are resolvable by construction.
  227. // 3. Let realm be module.[[Realm]].
  228. // 4. Assert: realm is not undefined.
  229. // Note: This must be true because we use a reference.
  230. auto& global_object = realm().global_object();
  231. // 5. Let env be NewModuleEnvironment(realm.[[GlobalEnv]]).
  232. auto* environment = vm.heap().allocate<ModuleEnvironment>(global_object, &realm().global_environment());
  233. // 6. Set module.[[Environment]] to env.
  234. set_environment(environment);
  235. // 7. For each ImportEntry Record in of module.[[ImportEntries]], do
  236. for (auto& import_entry : m_import_entries) {
  237. if (!import_entry.module_request().assertions.is_empty())
  238. return vm.throw_completion<InternalError>(global_object, ErrorType::NotImplemented, "import statements with assertions");
  239. // a. Let importedModule be ! HostResolveImportedModule(module, in.[[ModuleRequest]]).
  240. auto imported_module = MUST(vm.host_resolve_imported_module(this, import_entry.module_request()));
  241. // 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.
  242. // c. If in.[[ImportName]] is namespace-object, then
  243. if (import_entry.is_namespace()) {
  244. // i. Let namespace be ? GetModuleNamespace(importedModule).
  245. auto* namespace_ = TRY(imported_module->get_module_namespace(vm));
  246. // ii. Perform ! env.CreateImmutableBinding(in.[[LocalName]], true).
  247. MUST(environment->create_immutable_binding(global_object, import_entry.local_name, true));
  248. // iii. Call env.InitializeBinding(in.[[LocalName]], namespace).
  249. environment->initialize_binding(global_object, import_entry.local_name, namespace_);
  250. }
  251. // d. Else,
  252. else {
  253. // i. Let resolution be ? importedModule.ResolveExport(in.[[ImportName]]).
  254. auto resolution = TRY(imported_module->resolve_export(vm, import_entry.import_name));
  255. // ii. If resolution is null or ambiguous, throw a SyntaxError exception.
  256. if (!resolution.is_valid())
  257. return vm.throw_completion<SyntaxError>(global_object, ErrorType::InvalidOrAmbiguousExportEntry, import_entry.import_name);
  258. // iii. If resolution.[[BindingName]] is namespace, then
  259. if (resolution.is_namespace()) {
  260. // 1. Let namespace be ? GetModuleNamespace(resolution.[[Module]]).
  261. auto* namespace_ = TRY(resolution.module->get_module_namespace(vm));
  262. // 2. Perform ! env.CreateImmutableBinding(in.[[LocalName]], true).
  263. MUST(environment->create_immutable_binding(global_object, import_entry.local_name, true));
  264. // 3. Call env.InitializeBinding(in.[[LocalName]], namespace).
  265. MUST(environment->initialize_binding(global_object, import_entry.local_name, namespace_));
  266. }
  267. // iv. Else,
  268. else {
  269. // 1. Call env.CreateImportBinding(in.[[LocalName]], resolution.[[Module]], resolution.[[BindingName]]).
  270. MUST(environment->create_import_binding(import_entry.local_name, resolution.module, resolution.export_name));
  271. }
  272. }
  273. }
  274. // 8. Let moduleContext be a new ECMAScript code execution context.
  275. // Note: this has already been created during the construction of this object.
  276. // 9. Set the Function of moduleContext to null.
  277. // 10. Assert: module.[[Realm]] is not undefined.
  278. // Note: This must be true because we use a reference.
  279. // 11. Set the Realm of moduleContext to module.[[Realm]].
  280. m_execution_context.realm = &realm();
  281. // 12. Set the ScriptOrModule of moduleContext to module.
  282. m_execution_context.script_or_module = this;
  283. // 13. Set the VariableEnvironment of moduleContext to module.[[Environment]].
  284. m_execution_context.variable_environment = environment;
  285. // 14. Set the LexicalEnvironment of moduleContext to module.[[Environment]].
  286. m_execution_context.lexical_environment = environment;
  287. // 15. Set the PrivateEnvironment of moduleContext to null.
  288. // 16. Set module.[[Context]] to moduleContext.
  289. // Note: We're already working on that one.
  290. // 17. Push moduleContext onto the execution context stack; moduleContext is now the running execution context.
  291. vm.push_execution_context(m_execution_context, realm().global_object());
  292. // 18. Let code be module.[[ECMAScriptCode]].
  293. // 19. Let varDeclarations be the VarScopedDeclarations of code.
  294. // Note: We just loop through them in step 21.
  295. // 20. Let declaredVarNames be a new empty List.
  296. Vector<FlyString> declared_var_names;
  297. // 21. For each element d of varDeclarations, do
  298. // a. For each element dn of the BoundNames of d, do
  299. m_ecmascript_code->for_each_var_declared_name([&](auto const& name) {
  300. // i. If dn is not an element of declaredVarNames, then
  301. if (!declared_var_names.contains_slow(name)) {
  302. // 1. Perform ! env.CreateMutableBinding(dn, false).
  303. MUST(environment->create_mutable_binding(global_object, name, false));
  304. // 2. Call env.InitializeBinding(dn, undefined).
  305. MUST(environment->initialize_binding(global_object, name, js_undefined()));
  306. // 3. Append dn to declaredVarNames.
  307. declared_var_names.empend(name);
  308. }
  309. });
  310. // 22. Let lexDeclarations be the LexicallyScopedDeclarations of code.
  311. // Note: We only loop through them in step 24.
  312. // 23. Let privateEnv be null.
  313. PrivateEnvironment* private_environment = nullptr;
  314. // 24. For each element d of lexDeclarations, do
  315. m_ecmascript_code->for_each_lexically_scoped_declaration([&](Declaration const& declaration) {
  316. // a. For each element dn of the BoundNames of d, do
  317. declaration.for_each_bound_name([&](FlyString const& name) {
  318. // i. If IsConstantDeclaration of d is true, then
  319. if (declaration.is_constant_declaration()) {
  320. // 1. Perform ! env.CreateImmutableBinding(dn, true).
  321. MUST(environment->create_immutable_binding(global_object, name, true));
  322. }
  323. // ii. Else,
  324. else {
  325. // 1. Perform ! env.CreateMutableBinding(dn, false).
  326. MUST(environment->create_mutable_binding(global_object, name, false));
  327. }
  328. // iii. If d is a FunctionDeclaration, a GeneratorDeclaration, an AsyncFunctionDeclaration, or an AsyncGeneratorDeclaration, then
  329. if (declaration.is_function_declaration()) {
  330. VERIFY(is<FunctionDeclaration>(declaration));
  331. auto const& function_declaration = static_cast<FunctionDeclaration const&>(declaration);
  332. // 1. Let fo be InstantiateFunctionObject of d with arguments env and privateEnv.
  333. auto* function = ECMAScriptFunctionObject::create(global_object, function_declaration.name(), function_declaration.source_text(), function_declaration.body(), function_declaration.parameters(), function_declaration.function_length(), environment, private_environment, function_declaration.kind(), function_declaration.is_strict_mode(), function_declaration.might_need_arguments_object(), function_declaration.contains_direct_call_to_eval());
  334. // 2. Call env.InitializeBinding(dn, fo).
  335. environment->initialize_binding(global_object, name, function);
  336. }
  337. });
  338. });
  339. // Note: The default export name is also part of the local lexical declarations but
  340. // instead of making that a special case in the parser we just check it here.
  341. // This is only needed for things which are not declarations.
  342. // For more info check Parser::parse_export_statement.
  343. // Furthermore, that declaration is not constant. so we take 24.a.ii
  344. if (m_default_export) {
  345. VERIFY(m_default_export->has_statement());
  346. auto const& statement = m_default_export->statement();
  347. if (!is<Declaration>(statement)) {
  348. auto const& name = m_default_export->entries()[0].local_or_import_name;
  349. dbgln_if(JS_MODULE_DEBUG, "[JS MODULE] Adding default export to lexical declarations: local name: {}, Expression: {}", name, statement.class_name());
  350. // 1. Perform ! env.CreateMutableBinding(dn, false).
  351. MUST(environment->create_mutable_binding(global_object, name, false));
  352. // Note: Since this is not a function declaration 24.a.iii never applies
  353. }
  354. }
  355. // 25. Remove moduleContext from the execution context stack.
  356. vm.pop_execution_context();
  357. // 26. Return NormalCompletion(empty).
  358. return normal_completion({});
  359. }
  360. // 16.2.1.6.3 ResolveExport ( exportName [ , resolveSet ] ), https://tc39.es/ecma262/#sec-resolveexport
  361. ThrowCompletionOr<ResolvedBinding> SourceTextModule::resolve_export(VM& vm, FlyString const& export_name, Vector<ResolvedBinding> resolve_set)
  362. {
  363. // 1. If resolveSet is not present, set resolveSet to a new empty List.
  364. // Note: This is done by the default argument.
  365. // 2. For each Record { [[Module]], [[ExportName]] } r of resolveSet, do
  366. for (auto& [type, module, exported_name] : resolve_set) {
  367. // a. If module and r.[[Module]] are the same Module Record and SameValue(exportName, r.[[ExportName]]) is true, then
  368. if (module == this && exported_name == export_name) {
  369. // i. Assert: This is a circular import request.
  370. // ii. Return null.
  371. return ResolvedBinding::null();
  372. }
  373. }
  374. // 3. Append the Record { [[Module]]: module, [[ExportName]]: exportName } to resolveSet.
  375. resolve_set.append({ ResolvedBinding::Type::BindingName, this, export_name });
  376. // 4. For each ExportEntry Record e of module.[[LocalExportEntries]], do
  377. for (auto& entry : m_local_export_entries) {
  378. // a. If SameValue(exportName, e.[[ExportName]]) is true, then
  379. if (export_name != entry.export_name)
  380. continue;
  381. // i. Assert: module provides the direct binding for this export.
  382. // FIXME: What does this mean?
  383. // ii. Return ResolvedBinding Record { [[Module]]: module, [[BindingName]]: e.[[LocalName]] }.
  384. return ResolvedBinding {
  385. ResolvedBinding::Type::BindingName,
  386. this,
  387. entry.local_or_import_name,
  388. };
  389. }
  390. // 5. For each ExportEntry Record e of module.[[IndirectExportEntries]], do
  391. for (auto& entry : m_indirect_export_entries) {
  392. // a. If SameValue(exportName, e.[[ExportName]]) is true, then
  393. if (export_name != entry.export_name)
  394. continue;
  395. // i. Let importedModule be ? HostResolveImportedModule(module, e.[[ModuleRequest]]).
  396. auto imported_module = TRY(vm.host_resolve_imported_module(this, entry.module_request));
  397. // ii. If e.[[ImportName]] is all, then
  398. if (entry.is_all()) {
  399. // 1. Assert: module does not provide the direct binding for this export.
  400. // FIXME: What does this mean? / How do we check this
  401. // 2. Return ResolvedBinding Record { [[Module]]: importedModule, [[BindingName]]: namespace }.
  402. return ResolvedBinding {
  403. ResolvedBinding::Type::Namespace,
  404. imported_module.ptr(),
  405. {}
  406. };
  407. }
  408. // iii. Else,
  409. else {
  410. // 1. Assert: module imports a specific binding for this export.
  411. // FIXME: What does this mean? / How do we check this
  412. // 2. Return importedModule.ResolveExport(e.[[ImportName]], resolveSet).
  413. return imported_module->resolve_export(vm, entry.local_or_import_name, resolve_set);
  414. }
  415. }
  416. // 6. If SameValue(exportName, "default") is true, then
  417. if (export_name == "default"sv) {
  418. // a. Assert: A default export was not explicitly defined by this module.
  419. // FIXME: What does this mean? / How do we check this
  420. // b. Return null.
  421. return ResolvedBinding::null();
  422. // c. NOTE: A default export cannot be provided by an export * from "mod" declaration.
  423. }
  424. // 7. Let starResolution be null.
  425. ResolvedBinding star_resolution = ResolvedBinding::null();
  426. // 8. For each ExportEntry Record e of module.[[StarExportEntries]], do
  427. for (auto& entry : m_star_export_entries) {
  428. // a. Let importedModule be ? HostResolveImportedModule(module, e.[[ModuleRequest]]).
  429. auto imported_module = TRY(vm.host_resolve_imported_module(this, entry.module_request));
  430. // b. Let resolution be ? importedModule.ResolveExport(exportName, resolveSet).
  431. auto resolution = TRY(imported_module->resolve_export(vm, export_name, resolve_set));
  432. // c. If resolution is ambiguous, return ambiguous.
  433. if (resolution.is_ambiguous())
  434. return ResolvedBinding::ambiguous();
  435. // d. If resolution is not null, then
  436. if (resolution.type == ResolvedBinding::Null)
  437. continue;
  438. // i. Assert: resolution is a ResolvedBinding Record.
  439. VERIFY(resolution.is_valid());
  440. // ii. If starResolution is null, set starResolution to resolution.
  441. if (star_resolution.type == ResolvedBinding::Null) {
  442. star_resolution = resolution;
  443. }
  444. // iii. Else,
  445. else {
  446. // 1. Assert: There is more than one * import that includes the requested name.
  447. // FIXME: Assert this
  448. // 2. If resolution.[[Module]] and starResolution.[[Module]] are not the same Module Record, return ambiguous.
  449. if (resolution.module != star_resolution.module)
  450. return ResolvedBinding::ambiguous();
  451. // 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.
  452. if (resolution.is_namespace() != star_resolution.is_namespace())
  453. return ResolvedBinding::ambiguous();
  454. // 4. If resolution.[[BindingName]] is a String, starResolution.[[BindingName]] is a String, and SameValue(resolution.[[BindingName]], starResolution.[[BindingName]]) is false, return ambiguous.
  455. if (!resolution.is_namespace() && resolution.export_name != star_resolution.export_name) {
  456. // Note: Because we know from the previous if that either both are namespaces or both are string we can check just one
  457. return ResolvedBinding::ambiguous();
  458. }
  459. }
  460. }
  461. // 9. Return starResolution.
  462. return star_resolution;
  463. }
  464. // 16.2.1.6.5 ExecuteModule ( [ capability ] ), https://tc39.es/ecma262/#sec-source-text-module-record-execute-module
  465. Completion SourceTextModule::execute_module(VM& vm, Optional<PromiseCapability> capability)
  466. {
  467. dbgln_if(JS_MODULE_DEBUG, "[JS MODULE] SourceTextModule::execute_module({}, capability has value: {})", filename(), capability.has_value());
  468. // 1. Let moduleContext be a new ECMAScript code execution context.
  469. ExecutionContext module_context { vm.heap() };
  470. // Note: This is not in the spec but we require it.
  471. module_context.is_strict_mode = true;
  472. // 2. Set the Function of moduleContext to null.
  473. // 3. Set the Realm of moduleContext to module.[[Realm]].
  474. module_context.realm = &realm();
  475. // 4. Set the ScriptOrModule of moduleContext to module.
  476. module_context.script_or_module = this;
  477. // 5. Assert: module has been linked and declarations in its module environment have been instantiated.
  478. VERIFY(m_status != ModuleStatus::Unlinked && m_status != ModuleStatus::Linking && environment());
  479. // 6. Set the VariableEnvironment of moduleContext to module.[[Environment]].
  480. module_context.variable_environment = environment();
  481. // 7. Set the LexicalEnvironment of moduleContext to module.[[Environment]].
  482. module_context.lexical_environment = environment();
  483. // 8. Suspend the currently running execution context.
  484. // FIXME: We don't have suspend yet
  485. // 9. If module.[[HasTLA]] is false, then
  486. if (!m_has_top_level_await) {
  487. // a. Assert: capability is not present.
  488. VERIFY(!capability.has_value());
  489. // b. Push moduleContext onto the execution context stack; moduleContext is now the running execution context.
  490. vm.push_execution_context(module_context, realm().global_object());
  491. // c. Let result be the result of evaluating module.[[ECMAScriptCode]].
  492. auto result = m_ecmascript_code->execute(vm.interpreter(), realm().global_object());
  493. // d. Suspend moduleContext and remove it from the execution context stack.
  494. vm.pop_execution_context();
  495. vm.clear_exception();
  496. // e. Resume the context that is now on the top of the execution context stack as the running execution context.
  497. // FIXME: We don't have resume yet.
  498. // f. Return Completion(result).
  499. if (result.is_error())
  500. return result;
  501. // 16.2.1.11 Runtime Semantics: Evaluation, https://tc39.es/ecma262/#sec-module-semantics-runtime-semantics-evaluation
  502. // -> Replace any empty value with undefined.
  503. result = result.update_empty(js_undefined());
  504. return *result.value();
  505. }
  506. // 10. Else,
  507. // a. Assert: capability is a PromiseCapability Record.
  508. VERIFY(capability.has_value());
  509. // b. Perform ! AsyncBlockStart(capability, module.[[ECMAScriptCode]], moduleContext).
  510. async_block_start(vm, m_ecmascript_code, capability.value(), module_context);
  511. // c. Return NormalCompletion(empty).
  512. return normal_completion({});
  513. }
  514. }