@@ -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,39 @@ 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
+ for ( let idx = 0 ; idx < this [ kWrap ] . moduleRequests . length ; idx ++ ) {
317
+ const { specifier, attributes } = this [ kWrap ] . moduleRequests [ idx ] ;
318
+
319
+ const linkerResult = linker ( specifier , this , {
320
+ attributes,
321
+ assert : attributes ,
322
+ } ) ;
323
+ const promise = PromisePrototypeThen (
324
+ PromiseResolve ( linkerResult ) , async ( module ) => {
325
+ if ( module [ kWrap ] === undefined ) {
326
+ throw new ERR_VM_MODULE_NOT_MODULE ( ) ;
327
+ }
328
+ if ( module . context !== this . context ) {
329
+ throw new ERR_VM_MODULE_DIFFERENT_CONTEXT ( ) ;
330
+ }
331
+ if ( module . status === 'errored' ) {
332
+ throw new ERR_VM_MODULE_LINK_FAILURE ( `request for '${ specifier } ' resolved to an errored module` , module . error ) ;
333
+ }
334
+ if ( module . status === 'unlinked' ) {
335
+ await module [ kLink ] ( linker ) ;
336
+ }
337
+ return module [ kWrap ] ;
338
+ } ) ;
339
+
340
+ this [ kWrap ] . linkModule ( specifier , promise , /** finished */ idx === this [ kWrap ] . moduleRequests . length - 1 ) ;
341
+ ArrayPrototypePush ( promises , promise ) ;
342
+ }
325
343
326
344
try {
327
- if ( promises !== undefined ) {
328
- await SafePromiseAllReturnVoid ( promises ) ;
329
- }
345
+ await SafePromiseAllReturnVoid ( promises ) ;
330
346
} catch ( e ) {
331
347
this . #error = e ;
332
348
throw e ;
@@ -342,7 +358,8 @@ class SourceTextModule extends Module {
342
358
if ( this [ kWrap ] === undefined ) {
343
359
throw new ERR_VM_MODULE_NOT_MODULE ( ) ;
344
360
}
345
- this [ kDependencySpecifiers ] ??= ObjectFreeze ( this [ kWrap ] . getStaticDependencySpecifiers ( ) ) ;
361
+ this [ kDependencySpecifiers ] ??= ObjectFreeze (
362
+ ArrayPrototypeMap ( this [ kWrap ] . moduleRequests , ( request ) => request . specifier ) ) ;
346
363
return this [ kDependencySpecifiers ] ;
347
364
}
348
365
@@ -409,9 +426,7 @@ class SyntheticModule extends Module {
409
426
identifier,
410
427
} ) ;
411
428
412
- this [ kLink ] = ( ) => this [ kWrap ] . link ( ( ) => {
413
- assert . fail ( 'link callback should not be called' ) ;
414
- } ) ;
429
+ this [ kLink ] = ( ) => this [ kWrap ] . markLinked ( ) ;
415
430
}
416
431
417
432
setExport ( name , value ) {
0 commit comments