11'use strict' ;
22
33const {
4+ Array,
45 ArrayPrototypeJoin,
5- ArrayPrototypePush,
66 ArrayPrototypeSome,
77 FunctionPrototype,
88 ObjectSetPrototypeOf,
@@ -83,30 +83,8 @@ class ModuleJob extends ModuleJobBase {
8383 this . modulePromise = PromiseResolve ( this . modulePromise ) ;
8484 }
8585
86- // Wait for the ModuleWrap instance being linked with all dependencies.
87- const link = async ( ) => {
88- this . module = await this . modulePromise ;
89- assert ( this . module instanceof ModuleWrap ) ;
90-
91- // Explicitly keeping track of dependency jobs is needed in order
92- // to flatten out the dependency graph below in `_instantiate()`,
93- // so that circular dependencies can't cause a deadlock by two of
94- // these `link` callbacks depending on each other.
95- const dependencyJobs = [ ] ;
96- const promises = this . module . link ( async ( specifier , attributes ) => {
97- const job = await this . loader . getModuleJob ( specifier , url , attributes ) ;
98- ArrayPrototypePush ( dependencyJobs , job ) ;
99- return job . modulePromise ;
100- } ) ;
101-
102- if ( promises !== undefined ) {
103- await SafePromiseAllReturnVoid ( promises ) ;
104- }
105-
106- return SafePromiseAllReturnArrayLike ( dependencyJobs ) ;
107- } ;
10886 // Promise for the list of all dependencyJobs.
109- this . linked = link ( ) ;
87+ this . linked = this . _link ( ) ;
11088 // This promise is awaited later anyway, so silence
11189 // 'unhandled rejection' warnings.
11290 PromisePrototypeThen ( this . linked , undefined , noop ) ;
@@ -116,6 +94,48 @@ class ModuleJob extends ModuleJobBase {
11694 this . instantiated = undefined ;
11795 }
11896
97+ /**
98+ * Iterates the module requests and links with the loader.
99+ * @returns {Promise<ModuleJob[]> } Dependency module jobs.
100+ */
101+ async _link ( ) {
102+ this . module = await this . modulePromise ;
103+ assert ( this . module instanceof ModuleWrap ) ;
104+
105+ const moduleRequests = this . module . getModuleRequests ( ) ;
106+ // Explicitly keeping track of dependency jobs is needed in order
107+ // to flatten out the dependency graph below in `_instantiate()`,
108+ // so that circular dependencies can't cause a deadlock by two of
109+ // these `link` callbacks depending on each other.
110+ // Create an ArrayLike to avoid calling into userspace with `.then`
111+ // when returned from the async function.
112+ const dependencyJobs = Array ( moduleRequests . length ) ;
113+ ObjectSetPrototypeOf ( dependencyJobs , null ) ;
114+
115+ // Specifiers should be aligned with the moduleRequests array in order.
116+ const specifiers = Array ( moduleRequests . length ) ;
117+ const modulePromises = Array ( moduleRequests . length ) ;
118+ // Iterate with index to avoid calling into userspace with `Symbol.iterator`.
119+ for ( let idx = 0 ; idx < moduleRequests . length ; idx ++ ) {
120+ const { specifier, attributes } = moduleRequests [ idx ] ;
121+
122+ const dependencyJobPromise = this . loader . getModuleJob (
123+ specifier , this . url , attributes ,
124+ ) ;
125+ const modulePromise = PromisePrototypeThen ( dependencyJobPromise , ( job ) => {
126+ dependencyJobs [ idx ] = job ;
127+ return job . modulePromise ;
128+ } ) ;
129+ modulePromises [ idx ] = modulePromise ;
130+ specifiers [ idx ] = specifier ;
131+ }
132+
133+ const modules = await SafePromiseAllReturnArrayLike ( modulePromises ) ;
134+ this . module . link ( specifiers , modules ) ;
135+
136+ return dependencyJobs ;
137+ }
138+
119139 instantiate ( ) {
120140 if ( this . instantiated === undefined ) {
121141 this . instantiated = this . _instantiate ( ) ;
@@ -268,15 +288,17 @@ class ModuleJobSync extends ModuleJobBase {
268288 constructor ( loader , url , importAttributes , moduleWrap , isMain , inspectBrk ) {
269289 super ( loader , url , importAttributes , moduleWrap , isMain , inspectBrk , true ) ;
270290 assert ( this . module instanceof ModuleWrap ) ;
271- const moduleRequests = this . module . getModuleRequestsSync ( ) ;
291+ const moduleRequests = this . module . getModuleRequests ( ) ;
292+ // Specifiers should be aligned with the moduleRequests array in order.
293+ const specifiers = Array ( moduleRequests . length ) ;
294+ const modules = Array ( moduleRequests . length ) ;
272295 for ( let i = 0 ; i < moduleRequests . length ; ++ i ) {
273- const { 0 : specifier , 1 : attributes } = moduleRequests [ i ] ;
296+ const { specifier, attributes } = moduleRequests [ i ] ;
274297 const wrap = this . loader . getModuleWrapForRequire ( specifier , url , attributes ) ;
275- const isLast = ( i === moduleRequests . length - 1 ) ;
276- // TODO(joyeecheung): make the resolution callback deal with both promisified
277- // an raw module wraps, then we don't need to wrap it with a promise here.
278- this . module . cacheResolvedWrapsSync ( specifier , PromiseResolve ( wrap ) , isLast ) ;
298+ specifiers [ i ] = specifier ;
299+ modules [ i ] = wrap ;
279300 }
301+ this . module . link ( specifiers , modules ) ;
280302 }
281303
282304 async run ( ) {
0 commit comments