Bläddra i källkod

LibJS: Implement GetImportedModule and call it where appropriate

This breaks module loading temporarily while transitioning.
Andreas Kling 1 år sedan
förälder
incheckning
82977ab44b

+ 31 - 9
Userland/Libraries/LibJS/CyclicModule.cpp

@@ -254,8 +254,8 @@ ThrowCompletionOr<u32> CyclicModule::inner_module_linking(VM& vm, Vector<Module*
     for (auto& required_string : m_requested_modules) {
         ModuleRequest required { required_string };
 
-        // a. Let requiredModule be ? HostResolveImportedModule(module, required).
-        auto required_module = TRY(vm.host_resolve_imported_module(NonnullGCPtr<Module>(*this), required));
+        // a. Let requiredModule be GetImportedModule(module, required).
+        auto required_module = get_imported_module(required);
 
         // b. Set index to ? InnerModuleLinking(requiredModule, stack, index).
         index = TRY(required_module->inner_module_linking(vm, stack, index));
@@ -461,18 +461,17 @@ ThrowCompletionOr<u32> CyclicModule::inner_module_evaluation(VM& vm, Vector<Modu
     // 11. For each String required of module.[[RequestedModules]], do
     for (auto& required : m_requested_modules) {
 
-        // a. Let requiredModule be ! HostResolveImportedModule(module, required).
-        auto* required_module = MUST(vm.host_resolve_imported_module(NonnullGCPtr<Module>(*this), required)).ptr();
-        // b. NOTE: Link must be completed successfully prior to invoking this method, so every requested module is guaranteed to resolve successfully.
+        // a. Let requiredModule be GetImportedModule(module, required).
+        auto required_module = get_imported_module(required);
 
-        // c. Set index to ? InnerModuleEvaluation(requiredModule, stack, index).
+        // b. Set index to ? InnerModuleEvaluation(requiredModule, stack, index).
         index = TRY(required_module->inner_module_evaluation(vm, stack, index));
 
-        // d. If requiredModule is a Cyclic Module Record, then
+        // c. If requiredModule is a Cyclic Module Record, then
         if (!is<CyclicModule>(*required_module))
             continue;
 
-        auto* cyclic_module = static_cast<CyclicModule*>(required_module);
+        JS::NonnullGCPtr<CyclicModule> cyclic_module = verify_cast<CyclicModule>(*required_module);
         // i. Assert: requiredModule.[[Status]] is either evaluating, evaluating-async, or evaluated.
         VERIFY(cyclic_module->m_status == ModuleStatus::Evaluating || cyclic_module->m_status == ModuleStatus::EvaluatingAsync || cyclic_module->m_status == ModuleStatus::Evaluated);
 
@@ -487,7 +486,8 @@ ThrowCompletionOr<u32> CyclicModule::inner_module_evaluation(VM& vm, Vector<Modu
         // iv. Else,
         else {
             // 1. Set requiredModule to requiredModule.[[CycleRoot]].
-            cyclic_module = cyclic_module->m_cycle_root;
+            VERIFY(cyclic_module->m_cycle_root);
+            cyclic_module = *cyclic_module->m_cycle_root;
 
             // 2. Assert: requiredModule.[[Status]] is evaluating-async or evaluated.
             VERIFY(cyclic_module->m_status == ModuleStatus::EvaluatingAsync || cyclic_module->m_status == ModuleStatus::Evaluated);
@@ -808,4 +808,26 @@ void CyclicModule::async_module_execution_rejected(VM& vm, Value error)
     // 9. Return unused.
 }
 
+// 16.2.1.7 GetImportedModule ( referrer, specifier ), https://tc39.es/ecma262/#sec-GetImportedModule
+NonnullGCPtr<Module> CyclicModule::get_imported_module(ModuleRequest const& request)
+{
+    // 1. Assert: Exactly one element of referrer.[[LoadedModules]] is a Record whose [[Specifier]] is specifier,
+    //    since LoadRequestedModules has completed successfully on referrer prior to invoking this abstract operation.
+    size_t element_with_specifier_count = 0;
+    for (auto const& loaded_module : m_loaded_modules) {
+        if (loaded_module.specifier == request.module_specifier)
+            ++element_with_specifier_count;
+    }
+    VERIFY(element_with_specifier_count == 1);
+
+    for (auto const& loaded_module : m_loaded_modules) {
+        if (loaded_module.specifier == request.module_specifier) {
+            // 2. Let record be the Record in referrer.[[LoadedModules]] whose [[Specifier]] is specifier.
+            // 3. Return record.[[Module]].
+            return loaded_module.module;
+        }
+    }
+    VERIFY_NOT_REACHED();
+}
+
 }

+ 2 - 0
Userland/Libraries/LibJS/CyclicModule.h

@@ -82,6 +82,8 @@ protected:
     virtual ThrowCompletionOr<void> initialize_environment(VM& vm);
     virtual ThrowCompletionOr<void> execute_module(VM& vm, GCPtr<PromiseCapability> capability = {});
 
+    [[nodiscard]] NonnullGCPtr<Module> get_imported_module(ModuleRequest const&);
+
     void execute_async_module(VM& vm);
     void gather_available_ancestors(Vector<CyclicModule*>& exec_list);
     void async_module_execution_fulfilled(VM& vm);

+ 8 - 8
Userland/Libraries/LibJS/SourceTextModule.cpp

@@ -314,8 +314,8 @@ ThrowCompletionOr<Vector<DeprecatedFlyString>> SourceTextModule::get_exported_na
     // 8. For each ExportEntry Record e of module.[[StarExportEntries]], do
     for (auto& entry : m_star_export_entries) {
         // a. Assert: e.[[ModuleRequest]] is not null.
-        // b. Let requestedModule be ? HostResolveImportedModule(module, e.[[ModuleRequest]]).
-        auto requested_module = TRY(vm.host_resolve_imported_module(NonnullGCPtr<Module>(*this), entry.module_request()));
+        // b. Let requestedModule be GetImportedModule(module, e.[[ModuleRequest]]).
+        auto requested_module = get_imported_module(entry.module_request());
 
         // c. Let starNames be ? requestedModule.GetExportedNames(exportStarSet).
         auto star_names = TRY(requested_module->get_exported_names(vm, export_star_set));
@@ -368,8 +368,8 @@ ThrowCompletionOr<void> SourceTextModule::initialize_environment(VM& vm)
 
     // 7. For each ImportEntry Record in of module.[[ImportEntries]], do
     for (auto& import_entry : m_import_entries) {
-        // a. Let importedModule be ! HostResolveImportedModule(module, in.[[ModuleRequest]]).
-        auto imported_module = MUST(vm.host_resolve_imported_module(NonnullGCPtr<Module>(*this), import_entry.module_request()));
+        // a. Let importedModule be GetImportedModule(module, in.[[ModuleRequest]]).
+        auto imported_module = get_imported_module(import_entry.module_request());
         // 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.
 
         // c. If in.[[ImportName]] is namespace-object, then
@@ -584,8 +584,8 @@ ThrowCompletionOr<ResolvedBinding> SourceTextModule::resolve_export(VM& vm, Depr
             continue;
 
         // i. Assert: e.[[ModuleRequest]] is not null.
-        // ii. Let importedModule be ? HostResolveImportedModule(module, e.[[ModuleRequest]]).
-        auto imported_module = TRY(vm.host_resolve_imported_module(NonnullGCPtr<Module>(*this), entry.module_request()));
+        // ii. Let importedModule be GetImportedModule(module, e.[[ModuleRequest]]).
+        auto imported_module = get_imported_module(entry.module_request());
 
         // iii. If e.[[ImportName]] is all, then
         if (entry.kind == ExportEntry::Kind::ModuleRequestAll) {
@@ -625,8 +625,8 @@ ThrowCompletionOr<ResolvedBinding> SourceTextModule::resolve_export(VM& vm, Depr
     // 9. For each ExportEntry Record e of module.[[StarExportEntries]], do
     for (auto& entry : m_star_export_entries) {
         // a. Assert: e.[[ModuleRequest]] is not null.
-        // b. Let importedModule be ? HostResolveImportedModule(module, e.[[ModuleRequest]]).
-        auto imported_module = TRY(vm.host_resolve_imported_module(NonnullGCPtr<Module>(*this), entry.module_request()));
+        // b. Let importedModule be GetImportedModule(module, e.[[ModuleRequest]]).
+        auto imported_module = get_imported_module(entry.module_request());
 
         // c. Let resolution be ? importedModule.ResolveExport(exportName, resolveSet).
         auto resolution = TRY(imported_module->resolve_export(vm, export_name, resolve_set));