11'use strict' ; 
22
33const  { 
4+   Array, 
45  ArrayPrototypeJoin, 
5-   ArrayPrototypePush, 
66  ArrayPrototypeSome, 
77  FunctionPrototype, 
88  ObjectSetPrototypeOf, 
@@ -82,31 +82,8 @@ class ModuleJob extends ModuleJobBase {
8282      this . modulePromise  =  PromiseResolve ( this . modulePromise ) ; 
8383    } 
8484
85-     // Wait for the ModuleWrap instance being linked with all dependencies. 
86-     const  link  =  async  ( )  =>  { 
87-       this . module  =  await  this . modulePromise ; 
88-       assert ( this . module  instanceof  ModuleWrap ) ; 
89- 
90-       // Explicitly keeping track of dependency jobs is needed in order 
91-       // to flatten out the dependency graph below in `_instantiate()`, 
92-       // so that circular dependencies can't cause a deadlock by two of 
93-       // these `link` callbacks depending on each other. 
94-       const  dependencyJobs  =  [ ] ; 
95-       const  promises  =  this . module . link ( async  ( specifier ,  attributes )  =>  { 
96-         const  job  =  await  this . #loader. getModuleJob ( specifier ,  url ,  attributes ) ; 
97-         debug ( `async link() ${ this . url }   -> ${ specifier }  ` ,  job ) ; 
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-     } ; 
10885    // Promise for the list of all dependencyJobs. 
109-     this . linked  =  link ( ) ; 
86+     this . linked  =  this . _link ( ) ; 
11087    // This promise is awaited later anyway, so silence 
11188    // 'unhandled rejection' warnings. 
11289    PromisePrototypeThen ( this . linked ,  undefined ,  noop ) ; 
@@ -116,6 +93,49 @@ class ModuleJob extends ModuleJobBase {
11693    this . instantiated  =  undefined ; 
11794  } 
11895
96+   /** 
97+    * Iterates the module requests and links with the loader. 
98+    * @returns  {Promise<ModuleJob[]> } Dependency module jobs. 
99+    */ 
100+   async  _link ( )  { 
101+     this . module  =  await  this . modulePromise ; 
102+     assert ( this . module  instanceof  ModuleWrap ) ; 
103+ 
104+     const  moduleRequests  =  this . module . getModuleRequests ( ) ; 
105+     // Explicitly keeping track of dependency jobs is needed in order 
106+     // to flatten out the dependency graph below in `_instantiate()`, 
107+     // so that circular dependencies can't cause a deadlock by two of 
108+     // these `link` callbacks depending on each other. 
109+     // Create an ArrayLike to avoid calling into userspace with `.then` 
110+     // when returned from the async function. 
111+     const  dependencyJobs  =  Array ( moduleRequests . length ) ; 
112+     ObjectSetPrototypeOf ( dependencyJobs ,  null ) ; 
113+ 
114+     // Specifiers should be aligned with the moduleRequests array in order. 
115+     const  specifiers  =  Array ( moduleRequests . length ) ; 
116+     const  modulePromises  =  Array ( moduleRequests . length ) ; 
117+     // Iterate with index to avoid calling into userspace with `Symbol.iterator`. 
118+     for  ( let  idx  =  0 ;  idx  <  moduleRequests . length ;  idx ++ )  { 
119+       const  {  specifier,  attributes }  =  moduleRequests [ idx ] ; 
120+ 
121+       const  dependencyJobPromise  =  this . #loader. getModuleJob ( 
122+         specifier ,  this . url ,  attributes , 
123+       ) ; 
124+       const  modulePromise  =  PromisePrototypeThen ( dependencyJobPromise ,  ( job )  =>  { 
125+         debug ( `async link() ${ this . url }   -> ${ specifier }  ` ,  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 ( ) ; 
@@ -269,18 +289,20 @@ class ModuleJobSync extends ModuleJobBase {
269289    super ( url ,  importAttributes ,  moduleWrap ,  isMain ,  inspectBrk ,  true ) ; 
270290    assert ( this . module  instanceof  ModuleWrap ) ; 
271291    this . #loader =  loader ; 
272-     const  moduleRequests  =  this . module . getModuleRequestsSync ( ) ; 
273-     const  linked  =  [ ] ; 
292+     const  moduleRequests  =  this . module . getModuleRequests ( ) ; 
293+     // Specifiers should be aligned with the moduleRequests array in order. 
294+     const  specifiers  =  Array ( moduleRequests . length ) ; 
295+     const  modules  =  Array ( moduleRequests . length ) ; 
296+     const  jobs  =  Array ( moduleRequests . length ) ; 
274297    for  ( let  i  =  0 ;  i  <  moduleRequests . length ;  ++ i )  { 
275-       const  {  0 : specifier ,  1 : attributes  }  =  moduleRequests [ i ] ; 
276-       const  job  =  this . #loader. getModuleWrapForRequire ( specifier ,  url ,  attributes ) ; 
277-       const  isLast  =  ( i  ===  moduleRequests . length  -  1 ) ; 
278-       // TODO(joyeecheung): make the resolution callback deal with both promisified 
279-       // an raw module wraps, then we don't need to wrap it with a promise here. 
280-       this . module . cacheResolvedWrapsSync ( specifier ,  PromiseResolve ( job . module ) ,  isLast ) ; 
281-       ArrayPrototypePush ( linked ,  job ) ; 
298+       const  {  specifier,  attributes }  =  moduleRequests [ i ] ; 
299+       const  job  =  this . #loader. getModuleJobForRequire ( specifier ,  url ,  attributes ) ; 
300+       specifiers [ i ]  =  specifier ; 
301+       modules [ i ]  =  job . module ; 
302+       jobs [ i ]  =  job ; 
282303    } 
283-     this . linked  =  linked ; 
304+     this . module . link ( specifiers ,  modules ) ; 
305+     this . linked  =  jobs ; 
284306  } 
285307
286308  get  modulePromise ( )  { 
0 commit comments