@@ -5,11 +5,15 @@ const {
5
5
ArrayIsArray,
6
6
ArrayPrototypeForEach,
7
7
ArrayPrototypeIndexOf,
8
+ ArrayPrototypeMap,
9
+ ArrayPrototypePush,
8
10
ArrayPrototypeSome,
9
11
ObjectDefineProperty,
10
12
ObjectFreeze,
11
13
ObjectGetPrototypeOf,
12
14
ObjectSetPrototypeOf,
15
+ PromiseResolve,
16
+ PromisePrototypeThen,
13
17
ReflectApply,
14
18
SafePromiseAllReturnVoid,
15
19
Symbol,
@@ -306,27 +310,40 @@ class SourceTextModule extends Module {
306
310
this [ kLink ] = async ( linker ) => {
307
311
this . #statusOverride = 'linking' ;
308
312
309
- const promises = this [ kWrap ] . link ( async ( identifier , attributes ) => {
310
- const module = await linker ( identifier , this , { attributes, assert : attributes } ) ;
311
- if ( module [ kWrap ] === undefined ) {
312
- throw new ERR_VM_MODULE_NOT_MODULE ( ) ;
313
- }
314
- if ( module . context !== this . context ) {
315
- throw new ERR_VM_MODULE_DIFFERENT_CONTEXT ( ) ;
316
- }
317
- if ( module . status === 'errored' ) {
318
- throw new ERR_VM_MODULE_LINK_FAILURE ( `request for '${ identifier } ' resolved to an errored module` , module . error ) ;
319
- }
320
- if ( module . status === 'unlinked' ) {
321
- await module [ kLink ] ( linker ) ;
322
- }
323
- return module [ kWrap ] ;
324
- } ) ;
313
+ // Iterates the module requests and links with the linker.
314
+ const promises = [ ] ;
315
+ // Iterate with index to avoid calling into userspace with `Symbol.iterator`.
316
+ const moduleRequestsLength = this [ kWrap ] . moduleRequests . length ;
317
+ for ( let idx = 0 ; idx < moduleRequestsLength ; idx ++ ) {
318
+ const { specifier, attributes } = this [ kWrap ] . moduleRequests [ idx ] ;
319
+
320
+ const linkerResult = linker ( specifier , this , {
321
+ attributes,
322
+ assert : attributes ,
323
+ } ) ;
324
+ const promise = PromisePrototypeThen (
325
+ PromiseResolve ( linkerResult ) , async ( module ) => {
326
+ if ( module [ kWrap ] === undefined ) {
327
+ throw new ERR_VM_MODULE_NOT_MODULE ( ) ;
328
+ }
329
+ if ( module . context !== this . context ) {
330
+ throw new ERR_VM_MODULE_DIFFERENT_CONTEXT ( ) ;
331
+ }
332
+ if ( module . status === 'errored' ) {
333
+ throw new ERR_VM_MODULE_LINK_FAILURE ( `request for '${ specifier } ' resolved to an errored module` , module . error ) ;
334
+ }
335
+ if ( module . status === 'unlinked' ) {
336
+ await module [ kLink ] ( linker ) ;
337
+ }
338
+ return module [ kWrap ] ;
339
+ } ) ;
340
+
341
+ this [ kWrap ] . linkModule ( specifier , promise , /** finished */ idx === moduleRequestsLength - 1 ) ;
342
+ ArrayPrototypePush ( promises , promise ) ;
343
+ }
325
344
326
345
try {
327
- if ( promises !== undefined ) {
328
- await SafePromiseAllReturnVoid ( promises ) ;
329
- }
346
+ await SafePromiseAllReturnVoid ( promises ) ;
330
347
} catch ( e ) {
331
348
this . #error = e ;
332
349
throw e ;
@@ -342,7 +359,8 @@ class SourceTextModule extends Module {
342
359
if ( this [ kWrap ] === undefined ) {
343
360
throw new ERR_VM_MODULE_NOT_MODULE ( ) ;
344
361
}
345
- this [ kDependencySpecifiers ] ??= ObjectFreeze ( this [ kWrap ] . getStaticDependencySpecifiers ( ) ) ;
362
+ this [ kDependencySpecifiers ] ??= ObjectFreeze (
363
+ ArrayPrototypeMap ( this [ kWrap ] . moduleRequests , ( request ) => request . specifier ) ) ;
346
364
return this [ kDependencySpecifiers ] ;
347
365
}
348
366
@@ -409,9 +427,7 @@ class SyntheticModule extends Module {
409
427
identifier,
410
428
} ) ;
411
429
412
- this [ kLink ] = ( ) => this [ kWrap ] . link ( ( ) => {
413
- assert . fail ( 'link callback should not be called' ) ;
414
- } ) ;
430
+ this [ kLink ] = ( ) => this [ kWrap ] . markLinked ( ) ;
415
431
}
416
432
417
433
setExport ( name , value ) {
0 commit comments