Skip to content

Commit 9ab1fa8

Browse files
committed
Reinstate "evaluating-async" state of a module record.
1 parent 15621ed commit 9ab1fa8

File tree

4 files changed

+49
-40
lines changed

4 files changed

+49
-40
lines changed

graal-js/src/com.oracle.truffle.js.parser/src/com/oracle/truffle/js/parser/GraalJSEvaluator.java

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -610,13 +610,14 @@ public void moduleInstantiation(JSRealm realm, JSModuleRecord moduleRecord) {
610610
throw e;
611611
}
612612

613-
assert moduleRecord.getStatus() == Status.Linked || moduleRecord.getStatus() == Status.Evaluated;
613+
assert moduleRecord.getStatus() == Status.Linked || moduleRecord.getStatus() == Status.EvaluatingAsync || moduleRecord.getStatus() == Status.Evaluated;
614614
assert stack.isEmpty();
615615
}
616616

617617
private int innerModuleInstantiation(JSRealm realm, JSModuleRecord moduleRecord, Deque<JSModuleRecord> stack, int index0) {
618618
int index = index0;
619-
if (moduleRecord.getStatus() == Status.Linking || moduleRecord.getStatus() == Status.Linked || moduleRecord.getStatus() == Status.Evaluated) {
619+
if (moduleRecord.getStatus() == Status.Linking || moduleRecord.getStatus() == Status.Linked || moduleRecord.getStatus() == Status.EvaluatingAsync ||
620+
moduleRecord.getStatus() == Status.Evaluated) {
620621
return index;
621622
}
622623
assert moduleRecord.getStatus() == Status.Unlinked;
@@ -631,7 +632,7 @@ private int innerModuleInstantiation(JSRealm realm, JSModuleRecord moduleRecord,
631632
JSModuleRecord requiredModule = hostResolveImportedModule(moduleRecord, requestedModule);
632633
index = innerModuleInstantiation(realm, requiredModule, stack, index);
633634
assert requiredModule.getStatus() == Status.Linking || requiredModule.getStatus() == Status.Linked ||
634-
requiredModule.getStatus() == Status.Evaluated : requiredModule.getStatus();
635+
requiredModule.getStatus() == Status.EvaluatingAsync || requiredModule.getStatus() == Status.Evaluated : requiredModule.getStatus();
635636
assert (requiredModule.getStatus() == Status.Linking) == stack.contains(requiredModule);
636637
if (requiredModule.getStatus() == Status.Linking) {
637638
moduleRecord.setDFSAncestorIndex(Math.min(moduleRecord.getDFSAncestorIndex(), requiredModule.getDFSAncestorIndex()));
@@ -675,8 +676,8 @@ public Object moduleEvaluation(JSRealm realm, JSModuleRecord moduleRecord) {
675676
JSModuleRecord module = moduleRecord;
676677
Deque<JSModuleRecord> stack = new ArrayDeque<>(4);
677678
if (realm.getContext().isOptionTopLevelAwait()) {
678-
assert module.getStatus() == Status.Linked || module.getStatus() == Status.Evaluated;
679-
if (module.getStatus() == Status.Evaluated) {
679+
assert module.getStatus() == Status.Linked || module.getStatus() == Status.EvaluatingAsync || module.getStatus() == Status.Evaluated;
680+
if (module.getStatus() == Status.EvaluatingAsync || module.getStatus() == Status.Evaluated) {
680681
module = module.getCycleRoot();
681682
}
682683
if (module.getTopLevelCapability() != null) {
@@ -686,9 +687,10 @@ public Object moduleEvaluation(JSRealm realm, JSModuleRecord moduleRecord) {
686687
module.setTopLevelCapability(capability);
687688
try {
688689
innerModuleEvaluation(realm, module, stack, 0);
689-
assert module.getStatus() == Status.Evaluated;
690+
assert module.getStatus() == Status.EvaluatingAsync || module.getStatus() == Status.Evaluated;
690691
assert module.getEvaluationError() == null;
691692
if (!module.isAsyncEvaluation()) {
693+
assert module.getStatus() == Status.Evaluated;
692694
JSFunction.call(JSArguments.create(Undefined.instance, capability.getResolve(), Undefined.instance));
693695
}
694696
assert stack.isEmpty();
@@ -721,7 +723,8 @@ public Object moduleEvaluation(JSRealm realm, JSModuleRecord moduleRecord) {
721723
}
722724
throw e;
723725
}
724-
assert module.getStatus() == Status.Evaluated && module.getEvaluationError() == null;
726+
assert module.getStatus() == Status.EvaluatingAsync || module.getStatus() == Status.Evaluated;
727+
assert module.getEvaluationError() == null;
725728

726729
assert stack.isEmpty();
727730
Object result = module.getExecutionResult();
@@ -733,7 +736,7 @@ public Object moduleEvaluation(JSRealm realm, JSModuleRecord moduleRecord) {
733736
private int innerModuleEvaluation(JSRealm realm, JSModuleRecord moduleRecord, Deque<JSModuleRecord> stack, int index0) {
734737
// InnerModuleEvaluation( module, stack, index )
735738
int index = index0;
736-
if (moduleRecord.getStatus() == Status.Evaluated) {
739+
if (moduleRecord.getStatus() == Status.EvaluatingAsync || moduleRecord.getStatus() == Status.Evaluated) {
737740
if (moduleRecord.getEvaluationError() == null) {
738741
return index;
739742
} else {
@@ -758,13 +761,14 @@ private int innerModuleEvaluation(JSRealm realm, JSModuleRecord moduleRecord, De
758761
// Note: Instantiate must have completed successfully prior to invoking this method,
759762
// so every requested module is guaranteed to resolve successfully.
760763
index = innerModuleEvaluation(realm, requiredModule, stack, index);
761-
assert requiredModule.getStatus() == Status.Evaluating || requiredModule.getStatus() == Status.Evaluated : requiredModule.getStatus();
764+
assert requiredModule.getStatus() == Status.Evaluating || requiredModule.getStatus() == Status.EvaluatingAsync ||
765+
requiredModule.getStatus() == Status.Evaluated : requiredModule.getStatus();
762766
assert (requiredModule.getStatus() == Status.Evaluating) == stack.contains(requiredModule);
763767
if (requiredModule.getStatus() == Status.Evaluating) {
764768
moduleRecord.setDFSAncestorIndex(Math.min(moduleRecord.getDFSAncestorIndex(), requiredModule.getDFSAncestorIndex()));
765769
} else {
766770
requiredModule = requiredModule.getCycleRoot();
767-
assert requiredModule.getStatus() == Status.Evaluated;
771+
assert requiredModule.getStatus() == Status.EvaluatingAsync || requiredModule.getStatus() == Status.Evaluated;
768772
if (requiredModule.getEvaluationError() != null) {
769773
throw JSRuntime.rethrow(moduleRecord.getEvaluationError());
770774
}
@@ -775,8 +779,7 @@ private int innerModuleEvaluation(JSRealm realm, JSModuleRecord moduleRecord, De
775779
}
776780
}
777781
if (moduleRecord.getPendingAsyncDependencies() > 0 || moduleRecord.hasTLA()) {
778-
assert !moduleRecord.isAsyncEvaluation() && moduleRecord.getAsyncEvaluatingOrder() == 0;
779-
moduleRecord.setAsyncEvaluation(true);
782+
assert !moduleRecord.isAsyncEvaluation();
780783
moduleRecord.setAsyncEvaluatingOrder(realm.nextAsyncEvaluationOrder());
781784
if (moduleRecord.getPendingAsyncDependencies() == 0) {
782785
moduleAsyncExecution(realm, moduleRecord);
@@ -789,11 +792,14 @@ private int innerModuleEvaluation(JSRealm realm, JSModuleRecord moduleRecord, De
789792
assert occursExactlyOnce(moduleRecord, stack);
790793
assert moduleRecord.getDFSAncestorIndex() <= moduleRecord.getDFSIndex();
791794
if (moduleRecord.getDFSAncestorIndex() == moduleRecord.getDFSIndex()) {
792-
JSModuleRecord cycleRoot = moduleRecord;
793795
while (true) {
794796
JSModuleRecord requiredModule = stack.pop();
795-
requiredModule.setStatus(Status.Evaluated);
796-
requiredModule.setCycleRoot(cycleRoot);
797+
if (!requiredModule.isAsyncEvaluation()) {
798+
requiredModule.setStatus(Status.Evaluated);
799+
} else {
800+
requiredModule.setStatus(Status.EvaluatingAsync);
801+
}
802+
requiredModule.setCycleRoot(moduleRecord);
797803
if (requiredModule.equals(moduleRecord)) {
798804
break;
799805
}
@@ -805,7 +811,7 @@ private int innerModuleEvaluation(JSRealm realm, JSModuleRecord moduleRecord, De
805811
@TruffleBoundary
806812
private static void moduleAsyncExecution(JSRealm realm, JSModuleRecord module) {
807813
// ExecuteAsyncModule ( module )
808-
assert module.getStatus() == Status.Evaluating || module.getStatus() == Status.Evaluated;
814+
assert module.getStatus() == Status.Evaluating || module.getStatus() == Status.EvaluatingAsync;
809815
assert module.hasTLA();
810816
PromiseCapabilityRecord capability = NewPromiseCapabilityNode.createDefault(realm);
811817
DynamicObject onFulfilled = createCallAsyncModuleFulfilled(realm, module);
@@ -872,9 +878,9 @@ public Object execute(VirtualFrame frame) {
872878

873879
private static void gatherAvailableAncestors(JSModuleRecord module, Set<JSModuleRecord> execList) {
874880
// GatherAvailableAncestors ( module, execList )
875-
assert module.getStatus() == Status.Evaluated;
876881
for (JSModuleRecord m : module.getAsyncParentModules()) {
877882
if (!execList.contains(m) && m.getCycleRoot().getEvaluationError() == null) {
883+
assert m.getStatus() == Status.EvaluatingAsync;
878884
assert m.getEvaluationError() == null;
879885
assert m.isAsyncEvaluation();
880886
assert m.getPendingAsyncDependencies() > 0;
@@ -891,9 +897,14 @@ private static void gatherAvailableAncestors(JSModuleRecord module, Set<JSModule
891897

892898
@TruffleBoundary
893899
private static Object asyncModuleExecutionFulfilled(JSRealm realm, JSModuleRecord module, Object dynamicImportResolutionResult) {
900+
if (module.getStatus() == Status.Evaluated) {
901+
assert module.getEvaluationError() != null;
902+
return Undefined.instance;
903+
}
904+
assert module.getStatus() == Status.EvaluatingAsync;
894905
assert module.isAsyncEvaluation();
895906
assert module.getEvaluationError() == null;
896-
module.setAsyncEvaluation(false);
907+
module.setStatus(Status.Evaluated);
897908
if (module.getTopLevelCapability() != null) {
898909
assert module.getCycleRoot() == module;
899910
JSFunction.call(JSArguments.create(Undefined.instance, module.getTopLevelCapability().getResolve(), dynamicImportResolutionResult));
@@ -906,14 +917,14 @@ public int compare(JSModuleRecord o1, JSModuleRecord o2) {
906917
});
907918
gatherAvailableAncestors(module, execList);
908919
for (JSModuleRecord m : execList) {
909-
if (!m.isAsyncEvaluation()) {
920+
if (m.getStatus() == Status.Evaluated) {
910921
assert m.getEvaluationError() != null;
911922
} else if (m.hasTLA()) {
912923
moduleAsyncExecution(realm, m);
913924
} else {
914925
try {
915926
moduleExecution(realm, m, null);
916-
m.setAsyncEvaluation(false);
927+
m.setStatus(Status.Evaluated);
917928
if (m.getTopLevelCapability() != null) {
918929
assert m.getCycleRoot() == m;
919930
JSFunction.call(JSArguments.create(Undefined.instance, m.getTopLevelCapability().getResolve(), dynamicImportResolutionResult));
@@ -929,14 +940,15 @@ public int compare(JSModuleRecord o1, JSModuleRecord o2) {
929940
@TruffleBoundary
930941
private static Object asyncModuleExecutionRejected(JSRealm realm, JSModuleRecord module, Object error) {
931942
assert error != null : "Cannot reject a module creation with null error";
932-
assert module.getStatus() == Status.Evaluated;
933-
if (!module.isAsyncEvaluation()) {
943+
if (module.getStatus() == Status.Evaluated) {
934944
assert module.getEvaluationError() != null;
935945
return Undefined.instance;
936946
}
947+
assert module.getStatus() == Status.EvaluatingAsync;
948+
assert module.isAsyncEvaluation();
937949
assert module.getEvaluationError() == null;
938950
module.setEvaluationError(JSRuntime.getException(error));
939-
module.setAsyncEvaluation(false);
951+
module.setStatus(Status.Evaluated);
940952
for (JSModuleRecord m : module.getAsyncParentModules()) {
941953
asyncModuleExecutionRejected(realm, m, error);
942954
}

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/nodes/promise/ImportCallNode.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ protected Object finishDynamicImport(JSRealm realm, JSModuleRecord moduleRecord,
335335
// Note: PromiseReactionJob performs the promise rejection and resolution.
336336
assert moduleRecord == context.getEvaluator().hostResolveImportedModule(context, referencingScriptOrModule, moduleRequest);
337337
// Evaluate has already been invoked on moduleRecord and successfully completed.
338-
assert moduleRecord.isEvaluated();
338+
assert moduleRecord.hasBeenEvaluated();
339339
return context.getEvaluator().getModuleNamespace(moduleRecord);
340340
}
341341
}

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/runtime/objects/JSModuleRecord.java

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ public enum Status {
6060
Linking,
6161
Linked,
6262
Evaluating,
63+
EvaluatingAsync,
6364
Evaluated,
6465
}
6566

@@ -145,17 +146,17 @@ public void setStatus(Status status) {
145146
this.status = status;
146147
}
147148

148-
public boolean isEvaluated() {
149-
return getStatus() == Status.Evaluated;
149+
public boolean hasBeenEvaluated() {
150+
return getStatus() == Status.Evaluated || getStatus() == Status.EvaluatingAsync;
150151
}
151152

152153
public Throwable getEvaluationError() {
153-
assert isEvaluated();
154+
assert hasBeenEvaluated();
154155
return evaluationError;
155156
}
156157

157158
public void setEvaluationError(Throwable evaluationError) {
158-
assert isEvaluated();
159+
assert hasBeenEvaluated();
159160
this.evaluationError = evaluationError;
160161
}
161162

@@ -243,9 +244,8 @@ public void setUninstantiated() {
243244
private JSModuleRecord cycleRoot = this;
244245
// [[HasTLA]]
245246
private final boolean hasTLA;
246-
// [[AsyncEvaluation]]
247-
private boolean asyncEvaluation = false;
248-
private long asyncEvaluatingOrder;
247+
// [[AsyncEvaluation]] (true when asyncEvaluationOrder > 0)
248+
private long asyncEvaluationOrder;
249249
// [[TopLevelCapability]]
250250
private PromiseCapabilityRecord topLevelPromiseCapability = null;
251251
// [[AsyncParentModules]]
@@ -262,7 +262,7 @@ public void setTopLevelCapability(PromiseCapabilityRecord capability) {
262262
}
263263

264264
public boolean isAsyncEvaluation() {
265-
return asyncEvaluation;
265+
return asyncEvaluationOrder > 0;
266266
}
267267

268268
public List<JSModuleRecord> getAsyncParentModules() {
@@ -294,16 +294,12 @@ public int getPendingAsyncDependencies() {
294294
return pendingAsyncDependencies;
295295
}
296296

297-
public void setAsyncEvaluation(boolean value) {
298-
asyncEvaluation = value;
299-
}
300-
301297
public void setAsyncEvaluatingOrder(long order) {
302-
asyncEvaluatingOrder = order;
298+
asyncEvaluationOrder = order;
303299
}
304300

305301
public long getAsyncEvaluatingOrder() {
306-
return asyncEvaluatingOrder;
302+
return asyncEvaluationOrder;
307303
}
308304

309305
public boolean hasTLA() {

graal-nodejs/mx.graal-nodejs/com.oracle.truffle.trufflenode/src/com/oracle/truffle/trufflenode/GraalJSAccess.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3497,7 +3497,7 @@ public Object moduleEvaluate(Object context, Object module) {
34973497
JSContext jsContext = jsRealm.getContext();
34983498
JSModuleRecord moduleRecord = (JSModuleRecord) module;
34993499

3500-
if (!moduleRecord.isEvaluated()) {
3500+
if (!moduleRecord.hasBeenEvaluated()) {
35013501
jsContext.getEvaluator().moduleEvaluation(jsRealm, moduleRecord);
35023502
}
35033503

@@ -3526,9 +3526,10 @@ public int moduleGetStatus(Object module) {
35263526
return 2; // v8::Module::Status::kInstantiated
35273527
case Evaluating:
35283528
return 3; // v8::Module::Status::Evaluating
3529+
case EvaluatingAsync:
35293530
case Evaluated:
35303531
default:
3531-
assert record.getStatus() == JSModuleRecord.Status.Evaluated;
3532+
assert (record.getStatus() == JSModuleRecord.Status.Evaluated || record.getStatus() == JSModuleRecord.Status.EvaluatingAsync);
35323533
if (record.getEvaluationError() == null) {
35333534
return 4; // v8::Module::Status::kEvaluated
35343535
} else {

0 commit comments

Comments
 (0)