|
| 1 | +// Copyright (C) 2025 Igalia, S.L. All rights reserved. |
| 2 | +// This code is governed by the BSD license found in the LICENSE file. |
| 3 | + |
| 4 | +/*--- |
| 5 | +esid: sec-ContinueDynamicImport |
| 6 | +description: > |
| 7 | + `import.defer` causes eager evaluation of synchronous dependencies of async dependencies |
| 8 | +info: | |
| 9 | + 13.3.10.1.1 ContinueDynamicImport ( |
| 10 | + _payload_: a DynamicImportState Record, |
| 11 | + _moduleCompletion_: either a normal completion containing a Module Record or a throw completion, |
| 12 | + ): ~UNUSED~ |
| 13 | + 1. Let _promiseCapability_ be _payload_.[[PromiseCapability]]. |
| 14 | + 1. Let _phase_ be _payload_.[[Phase]]. |
| 15 | + 1. ... |
| 16 | + 1. Let _module_ be _moduleCompletion_.[[Value]]. |
| 17 | + 1. Let _loadPromise_ be _module_.LoadRequestedModules(). |
| 18 | + 1. ... |
| 19 | + 1. Let _linkAndEvaluateClosure_ be a new Abstract Closure with no parameters that captures _module_, _promiseCapability_, _phase_ and _onRejected_ and performs the following steps when called: |
| 20 | + 1. ... |
| 21 | + 1. Let _fulfilledClosure_ be a new Abstract Closure with no parameters that captures _module_, _phase_, and _promiseCapability_ and performs the following steps when called: |
| 22 | + 1. Let _namespace_ be GetModuleNamespace(_module_, _phase_). |
| 23 | + 1. Perform ! Call(_promiseCapability_.[[Resolve]], *undefined*, « _namespace_ »). |
| 24 | + 1. Return ~UNUSED~. |
| 25 | + 1. If _phase_ is ~defer~, then |
| 26 | + 1. Let _evaluationList_ be GatherAsynchronousTransitiveDependencies(_module_). |
| 27 | + 1. If _evaluationList_ is empty, then |
| 28 | + 1. Perform _fulfilledClosure_(). |
| 29 | + 1. Return ~UNUSED~. |
| 30 | + 1. Let _asyncDepsEvaluationPromises_ be a new empty List. |
| 31 | + 1. For each Module Record _dep_ of _evaluationList_, append _dep_.Evaluate() to _asyncDepsEvaluationPromises_. |
| 32 | + 1. Let _iterator_ be CreateListIteratorRecord(_asyncDepsEvaluationPromises_). |
| 33 | + 1. Let _pc_ be ! NewPromiseCapability(%Promise%). |
| 34 | + 1. Let _evaluatePromise_ be ! PerformPromiseAll(_iterator_, %Promise%, _pc_, %Promise.resolve%). |
| 35 | + 1. Else, |
| 36 | + 1. ... |
| 37 | + 1. Let _onFulfilled_ be CreateBuiltinFunction(_fulfilledClosure_, *""*, 0, « »). |
| 38 | + 1. Perform PerformPromiseThen(_evaluatePromise_, _onFulfilled_, _onRejected_). |
| 39 | + 1. Return ~UNUSED~. |
| 40 | + 1. Let _linkAndEvaluate_ be CreateBuiltinFunction(_linkAndEvaluateClosure_, *""*, 0, « »). |
| 41 | + 1. Perform PerformPromiseThen(_loadPromise_, _linkAndEvaluate_, _onRejected_). |
| 42 | + 1. Return ~UNUSED~. |
| 43 | +
|
| 44 | + GatherAsynchronousTransitiveDependencies ( _module_, [ _seen_ ] ) |
| 45 | + 1. If _seen_ is not specified, let _seen_ be a new empty List. |
| 46 | + 1. Let _result_ be a new empty List. |
| 47 | + 1. If _seen_ contains _module_, return _result_. |
| 48 | + 1. Append _module_ to _seen_. |
| 49 | + 1. If _module_ is not a Cyclic Module Record, return _result_. |
| 50 | + 1. If _module_.[[Status]] is either ~evaluating~ or ~evaluated~, return _result_. |
| 51 | + 1. If _module_.[[HasTLA]] is *true*, then |
| 52 | + 1. Append _module_ to _result_. |
| 53 | + 1. Return _result_. |
| 54 | + 1. For each ModuleRequest Record _required_ of _module_.[[RequestedModules]], do |
| 55 | + 1. Let _requiredModule_ be GetImportedModule(_module_, _required_.[[Specifier]]). |
| 56 | + 1. Let _additionalModules_ be GatherAsynchronousTransitiveDependencies(_requiredModule_, _seen_). |
| 57 | + 1. For each Module Record _m_ of _additionalModules_, do |
| 58 | + 1. If _result_ does not contain _m_, append _m_ to _result_. |
| 59 | + 1. Return _result_. |
| 60 | +
|
| 61 | +flags: [module, async] |
| 62 | +features: [import-defer, top-level-await] |
| 63 | +includes: [compareArray.js] |
| 64 | +---*/ |
| 65 | + |
| 66 | +import "./setup_FIXTURE.js"; |
| 67 | +import defer * as ns from "./imports-tla-with-dep_FIXTURE.js"; |
| 68 | + |
| 69 | +import.defer("./imports-tla-with-dep_FIXTURE.js").then(ns => { |
| 70 | + assert.compareArray( |
| 71 | + globalThis.evaluations, |
| 72 | + ["dep", "tla-with-dep start", "tla-with-dep end"] |
| 73 | + ); |
| 74 | + ns.x; |
| 75 | + assert.compareArray( |
| 76 | + globalThis.evaluations, |
| 77 | + ["dep", "tla-with-dep start", "tla-with-dep end", "imports-tla-with-dep"] |
| 78 | + ); |
| 79 | +}).then($DONE, $DONE); |
0 commit comments