@@ -100,6 +100,9 @@ function createLoadRecord (state, key, registration) {
100100 // will be the array of dependency load record or a module namespace
101101 dependencyInstantiations : undefined ,
102102
103+ // top-level await!
104+ evaluatePromise : undefined ,
105+
103106 // NB optimization and way of ensuring module objects in setters
104107 // indicates setters which should run pre-execution of that dependency
105108 // setters is then just for completely executed module objects
@@ -117,7 +120,7 @@ RegisterLoader.prototype[Loader.resolveInstantiate] = function (key, parentKey)
117120
118121 return resolveInstantiate ( loader , key , parentKey , registry , state )
119122 . then ( function ( instantiated ) {
120- if ( instantiated instanceof ModuleNamespace )
123+ if ( instantiated instanceof ModuleNamespace || instantiated [ toStringTag ] === 'module' )
121124 return instantiated ;
122125
123126 // resolveInstantiate always returns a load record with a link record and no module value
@@ -132,7 +135,7 @@ RegisterLoader.prototype[Loader.resolveInstantiate] = function (key, parentKey)
132135
133136 return deepInstantiateDeps ( loader , instantiated , link , registry , state )
134137 . then ( function ( ) {
135- return ensureEvaluate ( loader , instantiated , link , registry , state , undefined ) ;
138+ return ensureEvaluate ( loader , instantiated , link , registry , state ) ;
136139 } ) ;
137140 } ) ;
138141} ;
@@ -496,23 +499,22 @@ ContextualLoader.prototype.import = function (key) {
496499 return this.loader.resolve(key, this.key);
497500};*/
498501
499- // this is the execution function bound to the Module namespace record
500- function ensureEvaluate ( loader , load , link , registry , state , seen ) {
502+ function ensureEvaluate ( loader , load , link , registry , state ) {
501503 if ( load . module )
502504 return load . module ;
503-
504505 if ( load . evalError )
505506 throw load . evalError ;
507+ if ( link . evaluatePromise )
508+ return link . evaluatePromise ;
506509
507- if ( seen && seen . indexOf ( load ) !== - 1 )
508- return load . linkRecord . moduleObj ;
509-
510- // for ES loads we always run ensureEvaluate on top-level, so empty seen is passed regardless
511- // for dynamic loads, we pass seen if also dynamic
512- var err = doEvaluate ( loader , load , link , registry , state , link . setters ? [ ] : seen || [ ] ) ;
513- if ( err )
514- throw err ;
515-
510+ if ( link . setters ) {
511+ var evaluatePromise = doEvaluateDeclarative ( loader , load , link , registry , state , [ load ] ) ;
512+ if ( evaluatePromise )
513+ return evaluatePromise ;
514+ }
515+ else {
516+ doEvaluateDynamic ( loader , load , link , registry , state , [ load ] ) ;
517+ }
516518 return load . module ;
517519}
518520
@@ -524,10 +526,23 @@ function makeDynamicRequire (loader, key, dependencies, dependencyInstantiations
524526 var depLoad = dependencyInstantiations [ i ] ;
525527 var module ;
526528
527- if ( depLoad instanceof ModuleNamespace || depLoad [ toStringTag ] === 'module' )
529+ if ( depLoad instanceof ModuleNamespace || depLoad [ toStringTag ] === 'module' ) {
528530 module = depLoad ;
529- else
530- module = ensureEvaluate ( loader , depLoad , depLoad . linkRecord , registry , state , seen ) ;
531+ }
532+ else {
533+ if ( depLoad . evalError )
534+ throw depLoad . evalError ;
535+ if ( depLoad . module === undefined && seen . indexOf ( depLoad ) === - 1 && ! depLoad . linkRecord . evaluatePromise ) {
536+ if ( depLoad . linkRecord . setters ) {
537+ doEvaluateDeclarative ( loader , depLoad , depLoad . linkRecord , registry , state , [ depLoad ] ) ;
538+ }
539+ else {
540+ seen . push ( depLoad ) ;
541+ doEvaluateDynamic ( loader , depLoad , depLoad . linkRecord , registry , state , seen ) ;
542+ }
543+ }
544+ module = depLoad . module || depLoad . linkRecord . moduleObj ;
545+ }
531546
532547 return '__useDefault' in module ? module . __useDefault : module ;
533548 }
@@ -536,129 +551,161 @@ function makeDynamicRequire (loader, key, dependencies, dependencyInstantiations
536551 } ;
537552}
538553
539- // ensures the given es load is evaluated
540- // returns the error if any
541- function doEvaluate ( loader , load , link , registry , state , seen ) {
542- seen . push ( load ) ;
543-
544- var err ;
554+ function evalError ( load , err ) {
555+ load . linkRecord = undefined ;
556+ var evalError = addToError ( err , 'Evaluating ' + load . key ) ;
557+ if ( load . evalError === undefined )
558+ load . evalError = evalError ;
559+ throw evalError ;
560+ }
545561
546- // es modules evaluate dependencies first
547- // non es modules explicitly call moduleEvaluate through require
548- if ( link . setters ) {
549- var depLoad , depLink ;
550- for ( var i = 0 ; i < link . dependencies . length ; i ++ ) {
551- depLoad = link . dependencyInstantiations [ i ] ;
552-
553- if ( depLoad instanceof ModuleNamespace || depLoad [ toStringTag ] === 'module' )
554- continue ;
555-
556- // custom Module returned from instantiate
557- depLink = depLoad . linkRecord ;
558- if ( depLink && seen . indexOf ( depLoad ) === - 1 ) {
559- if ( depLoad . evalError )
560- err = depLoad . evalError ;
561- else
562- // dynamic / declarative boundaries clear the "seen" list
563- // we just let cross format circular throw as would happen in real implementations
564- err = doEvaluate ( loader , depLoad , depLink , registry , state , depLink . setters ? seen : [ ] ) ;
562+ // es modules evaluate dependencies first
563+ // returns the error if any
564+ function doEvaluateDeclarative ( loader , load , link , registry , state , seen ) {
565+ var depLoad , depLink ;
566+ var depLoadPromises ;
567+ for ( var i = 0 ; i < link . dependencies . length ; i ++ ) {
568+ var depLoad = link . dependencyInstantiations [ i ] ;
569+ if ( depLoad instanceof ModuleNamespace || depLoad [ toStringTag ] === 'module' )
570+ continue ;
571+
572+ // custom Module returned from instantiate
573+ depLink = depLoad . linkRecord ;
574+ if ( depLink ) {
575+ if ( depLoad . evalError ) {
576+ evalError ( load , depLoad . evalError ) ;
565577 }
566-
567- if ( err ) {
568- load . linkRecord = undefined ;
569- load . evalError = addToError ( err , 'Evaluating ' + load . key ) ;
570- return load . evalError ;
578+ else if ( depLink . setters ) {
579+ if ( seen . indexOf ( depLoad ) === - 1 ) {
580+ seen . push ( depLoad ) ;
581+ try {
582+ var depLoadPromise = doEvaluateDeclarative ( loader , depLoad , depLink , registry , state , seen ) ;
583+ }
584+ catch ( e ) {
585+ evalError ( load , e ) ;
586+ }
587+ if ( depLoadPromise ) {
588+ depLoadPromises = depLoadPromises || [ ] ;
589+ depLoadPromises . push ( depLoadPromise . catch ( function ( err ) {
590+ evalError ( load , err ) ;
591+ } ) ) ;
592+ }
593+ }
594+ }
595+ else {
596+ try {
597+ doEvaluateDynamic ( loader , depLoad , depLink , registry , state , [ depLoad ] ) ;
598+ }
599+ catch ( e ) {
600+ evalError ( load , e ) ;
601+ }
571602 }
572603 }
573604 }
574605
575- // link.execute won't exist for Module returns from instantiate on top-level load
606+ if ( depLoadPromises )
607+ return Promise . all ( depLoadPromises )
608+ . then ( function ( ) {
609+ if ( link . execute ) {
610+ // ES System.register execute
611+ // "this" is null in ES
612+ try {
613+ var execPromise = link . execute . call ( nullContext ) ;
614+ }
615+ catch ( e ) {
616+ evalError ( load , e ) ;
617+ }
618+ if ( execPromise )
619+ return execPromise . catch ( function ( e ) {
620+ evalError ( load , e ) ;
621+ } ) ;
622+ }
623+
624+ // dispose link record
625+ load . linkRecord = undefined ;
626+ registry [ load . key ] = load . module = new ModuleNamespace ( link . moduleObj ) ;
627+ } ) ;
628+
576629 if ( link . execute ) {
577630 // ES System.register execute
578631 // "this" is null in ES
579- if ( link . setters ) {
580- err = declarativeExecute ( link . execute ) ;
632+ try {
633+ var execPromise = link . execute . call ( nullContext ) ;
581634 }
582- // System.registerDynamic execute
583- // "this" is "exports" in CJS
584- else {
585- var module = { id : load . key } ;
586- var moduleObj = link . moduleObj ;
587- Object . defineProperty ( module , 'exports' , {
588- configurable : true ,
589- set : function ( exports ) {
590- moduleObj . default = moduleObj . __useDefault = exports ;
591- } ,
592- get : function ( ) {
593- return moduleObj . __useDefault ;
594- }
635+ catch ( e ) {
636+ evalError ( load , e ) ;
637+ }
638+ if ( execPromise )
639+ return execPromise . catch ( function ( e ) {
640+ evalError ( load , e ) ;
595641 } ) ;
642+ }
596643
597- var require = makeDynamicRequire ( loader , load . key , link . dependencies , link . dependencyInstantiations , registry , state , seen ) ;
598-
599- // evaluate deps first
600- if ( ! link . executingRequire )
601- for ( var i = 0 ; i < link . dependencies . length ; i ++ )
602- require ( link . dependencies [ i ] ) ;
644+ // dispose link record
645+ load . linkRecord = undefined ;
646+ registry [ load . key ] = load . module = new ModuleNamespace ( link . moduleObj ) ;
647+ }
603648
604- err = dynamicExecute ( link . execute , require , moduleObj . default , module ) ;
649+ // non es modules explicitly call moduleEvaluate through require
650+ function doEvaluateDynamic ( loader , load , link , registry , state , seen ) {
651+ // System.registerDynamic execute
652+ // "this" is "exports" in CJS
653+ var module = { id : load . key } ;
654+ var moduleObj = link . moduleObj ;
655+ Object . defineProperty ( module , 'exports' , {
656+ configurable : true ,
657+ set : function ( exports ) {
658+ moduleObj . default = moduleObj . __useDefault = exports ;
659+ } ,
660+ get : function ( ) {
661+ return moduleObj . __useDefault ;
662+ }
663+ } ) ;
605664
606- // pick up defineProperty calls to module.exports when we can
607- if ( module . exports !== moduleObj . __useDefault )
608- moduleObj . default = moduleObj . __useDefault = module . exports ;
665+ var require = makeDynamicRequire ( loader , load . key , link . dependencies , link . dependencyInstantiations , registry , state , seen ) ;
609666
610- var moduleDefault = moduleObj . default ;
667+ // evaluate deps first
668+ if ( ! link . executingRequire )
669+ for ( var i = 0 ; i < link . dependencies . length ; i ++ )
670+ require ( link . dependencies [ i ] ) ;
611671
612- // __esModule flag extension support via lifting
613- if ( moduleDefault && moduleDefault . __esModule ) {
614- for ( var p in moduleDefault ) {
615- if ( Object . hasOwnProperty . call ( moduleDefault , p ) )
616- moduleObj [ p ] = moduleDefault [ p ] ;
617- }
618- }
619- }
672+ try {
673+ var output = link . execute . call ( global , require , moduleObj . default , module ) ;
674+ if ( output !== undefined )
675+ module . exports = output ;
676+ }
677+ catch ( e ) {
678+ evalError ( load , e ) ;
620679 }
621680
622- // dispose link record
623681 load . linkRecord = undefined ;
624682
625- if ( err )
626- return load . evalError = addToError ( err , 'Evaluating ' + load . key ) ;
683+ // pick up defineProperty calls to module.exports when we can
684+ if ( module . exports !== moduleObj . __useDefault )
685+ moduleObj . default = moduleObj . __useDefault = module . exports ;
686+
687+ var moduleDefault = moduleObj . default ;
688+
689+ // __esModule flag extension support via lifting
690+ if ( moduleDefault && moduleDefault . __esModule ) {
691+ for ( var p in moduleDefault ) {
692+ if ( Object . hasOwnProperty . call ( moduleDefault , p ) )
693+ moduleObj [ p ] = moduleDefault [ p ] ;
694+ }
695+ }
627696
628697 registry [ load . key ] = load . module = new ModuleNamespace ( link . moduleObj ) ;
629698
630- // if not an esm module, run importer setters and clear them
699+ // run importer setters and clear them
631700 // this allows dynamic modules to update themselves into es modules
632701 // as soon as execution has completed
633- if ( ! link . setters ) {
634- if ( load . importerSetters )
635- for ( var i = 0 ; i < load . importerSetters . length ; i ++ )
636- load . importerSetters [ i ] ( load . module ) ;
637- load . importerSetters = undefined ;
638- }
702+ if ( load . importerSetters )
703+ for ( var i = 0 ; i < load . importerSetters . length ; i ++ )
704+ load . importerSetters [ i ] ( load . module ) ;
705+ load . importerSetters = undefined ;
639706}
640707
641- // {} is the closest we can get to call(undefined)
642- var nullContext = { } ;
708+ // the closest we can get to call(undefined)
709+ var nullContext = Object . create ( null ) ;
643710if ( Object . freeze )
644711 Object . freeze ( nullContext ) ;
645-
646- function declarativeExecute ( execute ) {
647- try {
648- execute . call ( nullContext ) ;
649- }
650- catch ( e ) {
651- return e ;
652- }
653- }
654-
655- function dynamicExecute ( execute , require , exports , module ) {
656- try {
657- var output = execute . call ( global , require , exports , module ) ;
658- if ( output !== undefined )
659- module . exports = output ;
660- }
661- catch ( e ) {
662- return e ;
663- }
664- }
0 commit comments