5656import java .util .List ;
5757import java .util .Map ;
5858import java .util .Set ;
59+ import java .util .TreeSet ;
5960import java .util .function .Supplier ;
6061
6162import com .oracle .js .parser .ir .Expression ;
@@ -793,10 +794,13 @@ private int innerModuleEvaluation(JSRealm realm, JSModuleRecord moduleRecord, De
793794 requiredModule .appendAsyncParentModules (moduleRecord );
794795 }
795796 }
796- if (moduleRecord .getPendingAsyncDependencies () > 0 ) {
797+ if (moduleRecord .getPendingAsyncDependencies () > 0 || moduleRecord .isTopLevelAsync ()) {
798+ assert !moduleRecord .isAsyncEvaluating () && moduleRecord .getAsyncEvaluatingOrder () == 0 ;
797799 moduleRecord .setAsyncEvaluating (true );
798- } else if (moduleRecord .isTopLevelAsync ()) {
799- moduleAsyncExecution (realm , moduleRecord );
800+ moduleRecord .setAsyncEvaluatingOrder (realm .nextAsyncEvaluationOrder ());
801+ if (moduleRecord .getPendingAsyncDependencies () == 0 ) {
802+ moduleAsyncExecution (realm , moduleRecord );
803+ }
800804 } else {
801805 Object result = moduleExecution (realm , moduleRecord , null );
802806 moduleRecord .setExecutionResult (result );
@@ -821,7 +825,6 @@ private static void moduleAsyncExecution(JSRealm realm, JSModuleRecord module) {
821825 // ExecuteAsyncModule ( module )
822826 assert module .getStatus () == Status .Evaluating || module .getStatus () == Status .Evaluated ;
823827 assert module .isTopLevelAsync ();
824- module .setAsyncEvaluating (true );
825828 PromiseCapabilityRecord capability = NewPromiseCapabilityNode .createDefault (realm );
826829 DynamicObject onFulfilled = createCallAsyncModuleFulfilled (realm , module );
827830 DynamicObject onRejected = createCallAsyncModuleRejected (realm , module );
@@ -885,42 +888,58 @@ public Object execute(VirtualFrame frame) {
885888 return JSFunctionData .createCallOnly (context , callTarget , 1 , "" );
886889 }
887890
888- @ TruffleBoundary
889- private static Object asyncModuleExecutionFulfilled ( JSRealm realm , JSModuleRecord module , Object dynamicImportResolutionResult ) {
891+ private static void gatherAvailableAncestors ( JSModuleRecord module , Set < JSModuleRecord > execList ) {
892+ // GatherAvailableAncestors ( module, execList )
890893 assert module .getStatus () == Status .Evaluated ;
891- if (!module .isAsyncEvaluating ()) {
892- assert module .getEvaluationError () != null ;
893- return Undefined .instance ;
894- }
895- assert module .getEvaluationError () == null ;
896- module .setAsyncEvaluating (false );
897894 for (JSModuleRecord m : module .getAsyncParentModules ()) {
898- if (module .getDFSIndex () != module .getDFSAncestorIndex ()) {
899- assert m .getDFSAncestorIndex () <= module .getDFSAncestorIndex ();
900- }
901- m .decPendingAsyncDependencies ();
902- if (m .getPendingAsyncDependencies () == 0 && m .getEvaluationError () == null ) {
895+ if (!execList .contains (m ) && getAsyncCycleRoot (m ).getEvaluationError () == null ) {
896+ assert m .getEvaluationError () == null ;
903897 assert m .isAsyncEvaluating ();
904- JSModuleRecord cycleRoot = getAsyncCycleRoot (m );
905- if (cycleRoot .getEvaluationError () != null ) {
906- return Undefined .instance ;
907- }
908- if (m .isTopLevelAsync ()) {
909- moduleAsyncExecution (realm , m );
910- } else {
911- try {
912- moduleExecution (realm , m , null );
913- asyncModuleExecutionFulfilled (realm , m , dynamicImportResolutionResult );
914- } catch (Exception e ) {
915- asyncModuleExecutionRejected (realm , m , e );
898+ assert m .getPendingAsyncDependencies () > 0 ;
899+ m .decPendingAsyncDependencies ();
900+ if (m .getPendingAsyncDependencies () == 0 ) {
901+ execList .add (m );
902+ if (!m .isTopLevelAsync ()) {
903+ gatherAvailableAncestors (m , execList );
916904 }
917905 }
918906 }
919907 }
908+ }
909+
910+ @ TruffleBoundary
911+ private static Object asyncModuleExecutionFulfilled (JSRealm realm , JSModuleRecord module , Object dynamicImportResolutionResult ) {
912+ assert module .isAsyncEvaluating ();
913+ assert module .getEvaluationError () == null ;
914+ module .setAsyncEvaluating (false );
920915 if (module .getTopLevelCapability () != null ) {
921916 assert module .getDFSIndex () == module .getDFSAncestorIndex ();
922917 JSFunction .call (JSArguments .create (Undefined .instance , module .getTopLevelCapability ().getResolve (), dynamicImportResolutionResult ));
923918 }
919+ Set <JSModuleRecord > execList = new TreeSet <>(new Comparator <JSModuleRecord >() {
920+ @ Override
921+ public int compare (JSModuleRecord o1 , JSModuleRecord o2 ) {
922+ return Long .compare (o1 .getAsyncEvaluatingOrder (), o2 .getAsyncEvaluatingOrder ());
923+ }
924+ });
925+ gatherAvailableAncestors (module , execList );
926+ for (JSModuleRecord m : execList ) {
927+ if (!m .isAsyncEvaluating ()) {
928+ assert m .getEvaluationError () != null ;
929+ } else if (m .isTopLevelAsync ()) {
930+ moduleAsyncExecution (realm , m );
931+ } else {
932+ try {
933+ moduleExecution (realm , m , null );
934+ m .setAsyncEvaluating (false );
935+ if (m .getTopLevelCapability () != null ) {
936+ JSFunction .call (JSArguments .create (Undefined .instance , m .getTopLevelCapability ().getResolve (), dynamicImportResolutionResult ));
937+ }
938+ } catch (Exception e ) {
939+ asyncModuleExecutionRejected (realm , m , e );
940+ }
941+ }
942+ }
924943 return Undefined .instance ;
925944 }
926945
0 commit comments