@@ -2130,43 +2130,83 @@ private JavaScriptNode desugarForOf(ForNode forNode, JavaScriptNode modify, Jump
21302130 return desugarForInOrOfBody (forNode , getIterator , jumpTarget );
21312131 }
21322132
2133+ private JavaScriptNode desugarForAwaitOf (ForNode forNode , JavaScriptNode modify , JumpTargetCloseable <ContinueTarget > jumpTarget ) {
2134+ assert forNode .isForAwaitOf ();
2135+ JavaScriptNode getIterator = factory .createGetAsyncIterator (modify );
2136+ return desugarForInOrOfBody (forNode , getIterator , jumpTarget );
2137+ }
2138+
2139+ /**
2140+ * Desugars a for in/of/await-of loop body.
2141+ *
2142+ * <code>
2143+ * <pre>
2144+ * var iterator = ForIn/OfHeadEvaluation();
2145+ * break: while (true) {
2146+ * var nextResult = IteratorNext(iterator);
2147+ * var done = IteratorComplete(nextResult);
2148+ * var nextValue = IteratorValue(nextResult);
2149+ * if (done) break;
2150+ * continue: {{ // per-iteration scope
2151+ * let [[binding]];
2152+ * try {
2153+ * [[binding]] := nextValue, nextValue = undefined;
2154+ * [[for:body]];
2155+ * } catch (e) {
2156+ * IteratorClose(iterator, e);
2157+ * }
2158+ * }}
2159+ * }
2160+ * </pre>
2161+ * </code>
2162+ */
21332163 private JavaScriptNode desugarForInOrOfBody (ForNode forNode , JavaScriptNode iterator , JumpTargetCloseable <ContinueTarget > jumpTarget ) {
21342164 assert forNode .isForInOrOf ();
21352165 VarRef iteratorVar = environment .createTempVar ();
2136- JavaScriptNode iteratorInit = iteratorVar .createWriteNode (iterator );
21372166 VarRef nextResultVar = environment .createTempVar ();
2138- JavaScriptNode iteratorNext = factory .createIteratorNext (iteratorVar .createReadNode ());
2139- // nextResult = IteratorNext(iterator)
2140- // while(!(done = IteratorComplete(nextResult)))
2141- JavaScriptNode condition = factory .createDual (context ,
2142- factory .createIteratorSetDone (iteratorVar .createReadNode (), factory .createConstantBoolean (true )),
2143- factory .createUnary (UnaryOperation .NOT , factory .createIteratorComplete (context , nextResultVar .createWriteNode (iteratorNext ))));
2167+ JavaScriptNode iteratorInit = iteratorVar .createWriteNode (iterator );
2168+
2169+ JavaScriptNode iteratorNext ;
2170+ if (forNode .isForAwaitOf ()) {
2171+ // nextResult = Await(IteratorNext(iterator))
2172+ iteratorNext = awaitAsyncIteratorNext (iteratorVar .createReadNode ());
2173+ } else {
2174+ // nextResult = IteratorNext(iterator)
2175+ iteratorNext = factory .createIteratorNext (iteratorVar .createReadNode ());
2176+ }
2177+
21442178 JavaScriptNode wrappedBody ;
21452179 try (EnvironmentCloseable blockEnv = new EnvironmentCloseable (needsPerIterationScope (forNode ) ? newPerIterationEnvironment (lc .getCurrentBlock ().getScope ()) : environment )) {
2146- // var nextValue = IteratorValue(nextResult);
2147- VarRef nextResultVar2 = environment .findTempVar (nextResultVar .getFrameSlot ());
2148- VarRef nextValueVar = environment .createTempVar ();
2149- VarRef iteratorVar2 = environment .findTempVar (iteratorVar .getFrameSlot ());
2150- JavaScriptNode nextResult = nextResultVar2 .createReadNode ();
2151- JavaScriptNode nextValue = factory .createIteratorValue (nextResult );
2152- JavaScriptNode writeNextValue = nextValueVar .createWriteNode (nextValue );
2153- JavaScriptNode writeNext = tagStatement (desugarForHeadAssignment (forNode , nextValueVar .createReadNode ()), forNode );
2180+ VarRef nextValueVarInner = environment .findTempVar (nextResultVar .getFrameSlot ());
2181+ JavaScriptNode nextValue = nextValueVarInner .createReadNode ();
2182+ JavaScriptNode nextBindingInit = tagStatement (desugarForHeadAssignment (forNode , nextValue ), forNode );
2183+ JavaScriptNode clearTempSlot = nextValueVarInner .createWriteNode (factory .createConstant (JSFrameUtil .DEFAULT_VALUE ));
21542184 JavaScriptNode body = transform (forNode .getBody ());
21552185 wrappedBody = blockEnv .wrapBlockScope (createBlock (
2156- writeNextValue ,
2157- factory .createIteratorSetDone (iteratorVar2 .createReadNode (), factory .createConstantBoolean (false )),
2158- writeNext ,
2186+ factory .createTryFinally (nextBindingInit , clearTempSlot ),
21592187 body ));
21602188 }
21612189 wrappedBody = jumpTarget .wrapContinueTargetNode (wrappedBody );
2162- RepeatingNode repeatingNode = factory .createWhileDoRepeatingNode (condition , wrappedBody );
2190+
2191+ if (forNode .isForAwaitOf ()) {
2192+ wrappedBody = wrapAsyncIteratorClose (wrappedBody , iteratorVar .createReadNode ());
2193+ } else {
2194+ wrappedBody = factory .createIteratorCloseWrapper (context , wrappedBody , iteratorVar .createReadNode (), false );
2195+ }
2196+
2197+ RepeatingNode repeatingNode = factory .createForOfRepeatingNode (iteratorNext , wrappedBody ,
2198+ (JSWriteFrameSlotNode ) nextResultVar .createWriteNode (null ));
21632199 LoopNode loopNode = factory .createLoopNode (repeatingNode );
2164- JavaScriptNode whileNode = forNode .isForOf () ? factory .createDesugaredForOf (loopNode ) : factory .createDesugaredForIn (loopNode );
2165- JavaScriptNode wrappedWhile = factory .createIteratorCloseIfNotDone (context , jumpTarget .wrapBreakTargetNode (whileNode ), iteratorVar .createReadNode ());
2166- JavaScriptNode resetIterator = iteratorVar .createWriteNode (factory .createConstant (JSFrameUtil .DEFAULT_VALUE ));
2167- wrappedWhile = factory .createTryFinally (wrappedWhile , resetIterator );
2200+ JavaScriptNode whileNode = forNode .isForOf ()
2201+ ? forNode .isForAwaitOf ()
2202+ ? factory .createDesugaredForAwaitOf (loopNode )
2203+ : factory .createDesugaredForOf (loopNode )
2204+ : factory .createDesugaredForIn (loopNode );
21682205 ensureHasSourceSection (whileNode , forNode );
2169- return createBlock (iteratorInit , wrappedWhile );
2206+
2207+ JavaScriptNode wrappedWhile = jumpTarget .wrapBreakTargetNode (whileNode );
2208+ JavaScriptNode resetIterator = iteratorVar .createWriteNode (factory .createConstant (JSFrameUtil .DEFAULT_VALUE ));
2209+ return createBlock (iteratorInit , factory .createTryFinally (wrappedWhile , resetIterator ));
21702210 }
21712211
21722212 private JavaScriptNode desugarForHeadAssignment (ForNode forNode , JavaScriptNode next ) {
@@ -2179,54 +2219,24 @@ private JavaScriptNode desugarForHeadAssignment(ForNode forNode, JavaScriptNode
21792219 }
21802220 }
21812221
2182- private JavaScriptNode desugarForAwaitOf (ForNode forNode , JavaScriptNode modify , JumpTargetCloseable <ContinueTarget > jumpTarget ) {
2183- assert forNode .isForAwaitOf ();
2184- JavaScriptNode getIterator = factory .createGetAsyncIterator (modify );
2185- VarRef iteratorVar = environment .createTempVar ();
2186- JavaScriptNode iteratorInit = iteratorVar .createWriteNode (getIterator );
2187- VarRef nextResultVar = environment .createTempVar ();
2188-
2222+ private JavaScriptNode awaitAsyncIteratorNext (JavaScriptNode iterator ) {
21892223 currentFunction ().addAwait ();
2190- JSReadFrameSlotNode asyncResultNode = (JSReadFrameSlotNode ) environment .findTempVar (currentFunction ().getAsyncResultSlot ()).createReadNode ();
2191- JSReadFrameSlotNode asyncContextNode = (JSReadFrameSlotNode ) environment .findTempVar (currentFunction ().getAsyncContextSlot ()).createReadNode ();
21922224 JSFrameDescriptor functionFrameDesc = environment .getFunctionFrameDescriptor ();
2193- JSFrameSlot stateSlot = addGeneratorStateSlot (functionFrameDesc , FrameSlotKind .Int );
2194- JavaScriptNode iteratorNext = factory .createAsyncIteratorNext (context , stateSlot , iteratorVar .createReadNode (),
2225+ var iterNextStateSlot = addGeneratorStateSlot (functionFrameDesc , FrameSlotKind .Int );
2226+ var asyncResultNode = (JSReadFrameSlotNode ) environment .findTempVar (currentFunction ().getAsyncResultSlot ()).createReadNode ();
2227+ var asyncContextNode = (JSReadFrameSlotNode ) environment .findTempVar (currentFunction ().getAsyncContextSlot ()).createReadNode ();
2228+ return factory .createAsyncIteratorNext (context , iterNextStateSlot , iterator ,
21952229 asyncContextNode , asyncResultNode );
2196- // nextResult = Await(IteratorNext(iterator))
2197- // while(!(done = IteratorComplete(nextResult)))
2198- JavaScriptNode condition = factory .createDual (context ,
2199- factory .createIteratorSetDone (iteratorVar .createReadNode (), factory .createConstantBoolean (true )),
2200- factory .createUnary (UnaryOperation .NOT , factory .createIteratorComplete (context , nextResultVar .createWriteNode (iteratorNext ))));
2201- JavaScriptNode wrappedBody ;
2202- try (EnvironmentCloseable blockEnv = new EnvironmentCloseable (needsPerIterationScope (forNode ) ? newPerIterationEnvironment (lc .getCurrentBlock ().getScope ()) : environment )) {
2203- // var nextValue = IteratorValue(nextResult);
2204- VarRef nextResultVar2 = environment .findTempVar (nextResultVar .getFrameSlot ());
2205- VarRef nextValueVar = environment .createTempVar ();
2206- VarRef iteratorVar2 = environment .findTempVar (iteratorVar .getFrameSlot ());
2207- JavaScriptNode nextResult = nextResultVar2 .createReadNode ();
2208- JavaScriptNode nextValue = factory .createIteratorValue (nextResult );
2209- JavaScriptNode writeNextValue = nextValueVar .createWriteNode (nextValue );
2210- JavaScriptNode writeNext = tagStatement (desugarForHeadAssignment (forNode , nextValueVar .createReadNode ()), forNode );
2211- JavaScriptNode body = transform (forNode .getBody ());
2212- wrappedBody = blockEnv .wrapBlockScope (createBlock (
2213- writeNextValue ,
2214- factory .createIteratorSetDone (iteratorVar2 .createReadNode (), factory .createConstantBoolean (false )),
2215- writeNext ,
2216- body ));
2217- }
2218- wrappedBody = jumpTarget .wrapContinueTargetNode (wrappedBody );
2219- RepeatingNode repeatingNode = factory .createWhileDoRepeatingNode (condition , wrappedBody );
2220- LoopNode loopNode = factory .createLoopNode (repeatingNode );
2221- JavaScriptNode whileNode = factory .createDesugaredForAwaitOf (loopNode );
2230+ }
2231+
2232+ private JavaScriptNode wrapAsyncIteratorClose (JavaScriptNode body , JavaScriptNode iterator ) {
22222233 currentFunction ().addAwait ();
2223- stateSlot = addGeneratorStateSlot (functionFrameDesc , FrameSlotKind .Object );
2224- JavaScriptNode wrappedWhile = factory .createAsyncIteratorCloseWrapper (context , stateSlot , jumpTarget .wrapBreakTargetNode (whileNode ), iteratorVar .createReadNode (),
2234+ JSFrameDescriptor functionFrameDesc = environment .getFunctionFrameDescriptor ();
2235+ var iterCloseStateSlot = addGeneratorStateSlot (functionFrameDesc , FrameSlotKind .Object );
2236+ var asyncResultNode = (JSReadFrameSlotNode ) environment .findTempVar (currentFunction ().getAsyncResultSlot ()).createReadNode ();
2237+ var asyncContextNode = (JSReadFrameSlotNode ) environment .findTempVar (currentFunction ().getAsyncContextSlot ()).createReadNode ();
2238+ return factory .createAsyncIteratorCloseWrapper (context , iterCloseStateSlot , body , iterator ,
22252239 asyncContextNode , asyncResultNode );
2226- JavaScriptNode resetIterator = iteratorVar .createWriteNode (factory .createConstant (JSFrameUtil .DEFAULT_VALUE ));
2227- wrappedWhile = factory .createTryFinally (wrappedWhile , resetIterator );
2228- ensureHasSourceSection (whileNode , forNode );
2229- return createBlock (iteratorInit , wrappedWhile );
22302240 }
22312241
22322242 private boolean needsPerIterationScope (ForNode forNode ) {
@@ -3093,7 +3103,7 @@ private JavaScriptNode transformDestructuringArrayAssignment(Expression lhsExpre
30933103 initElements [i ] = rhsNode ;
30943104 }
30953105 }
3096- JavaScriptNode closeIfNotDone = factory .createIteratorCloseIfNotDone (context , createBlock (initElements ), iteratorTempVar .createReadNode ());
3106+ JavaScriptNode closeIfNotDone = factory .createIteratorCloseWrapper (context , createBlock (initElements ), iteratorTempVar .createReadNode (), true );
30973107 return factory .createExprBlock (initIteratorTempVar , closeIfNotDone , valueTempVar .createReadNode ());
30983108 }
30993109
0 commit comments