168168import com .oracle .graal .python .builtins .objects .type .slots .TpSlotIterNext .CallSlotTpIterNextNode ;
169169import com .oracle .graal .python .compiler .Compiler ;
170170import com .oracle .graal .python .compiler .RaisePythonExceptionErrorCallback ;
171+ import com .oracle .graal .python .lib .IteratorExhausted ;
171172import com .oracle .graal .python .lib .PyCallableCheckNode ;
172173import com .oracle .graal .python .lib .PyEvalGetGlobals ;
173174import com .oracle .graal .python .lib .PyEvalGetLocals ;
@@ -486,13 +487,12 @@ static boolean doObject(VirtualFrame frame, Object object,
486487 while (true ) {
487488 try {
488489 Object next = nextNode .execute (frame , inliningTarget , iterator );
489- if (PyIterNextNode .isExhausted (next )) {
490- break ;
491- }
492490 nbrIter ++;
493491 if (!isTrueNode .execute (frame , next )) {
494492 return false ;
495493 }
494+ } catch (IteratorExhausted e ) {
495+ break ;
496496 } finally {
497497 LoopNode .reportLoopCount (inliningTarget , nbrIter );
498498 }
@@ -538,13 +538,12 @@ static boolean doObject(VirtualFrame frame, Object object,
538538 while (true ) {
539539 try {
540540 Object next = nextNode .execute (frame , inliningTarget , iterator );
541- if (PyIterNextNode .isExhausted (next )) {
542- break ;
543- }
544541 nbrIter ++;
545542 if (isTrueNode .execute (frame , next )) {
546543 return true ;
547544 }
545+ } catch (IteratorExhausted e ) {
546+ break ;
548547 } finally {
549548 LoopNode .reportLoopCount (inliningTarget , nbrIter );
550549 }
@@ -1583,8 +1582,10 @@ static Object minmaxSequenceWithKey(VirtualFrame frame, Node inliningTarget, Obj
15831582 Object keywordArg = kwArgsAreNone ? null : keywordArgIn ;
15841583
15851584 Object iterator = getIter .execute (frame , inliningTarget , arg1 );
1586- Object currentValue = nextNode .execute (frame , inliningTarget , iterator );
1587- if (PyIterNextNode .isExhausted (currentValue )) {
1585+ Object currentValue ;
1586+ try {
1587+ currentValue = nextNode .execute (frame , inliningTarget , iterator );
1588+ } catch (IteratorExhausted e ) {
15881589 if (hasDefaultProfile .profile (inliningTarget , isNoValue (defaultVal ))) {
15891590 throw raiseNode .raise (inliningTarget , PythonErrorType .ValueError , ErrorMessages .ARG_IS_EMPTY_SEQ , name );
15901591 } else {
@@ -1593,12 +1594,9 @@ static Object minmaxSequenceWithKey(VirtualFrame frame, Node inliningTarget, Obj
15931594 }
15941595 Object currentKey = applyKeyFunction (frame , inliningTarget , keywordArg , keyCall , currentValue );
15951596 int loopCount = 0 ;
1596- try {
1597- while ( true ) {
1597+ while ( true ) {
1598+ try {
15981599 Object nextValue = nextNode .execute (frame , inliningTarget , iterator );
1599- if (PyIterNextNode .isExhausted (nextValue )) {
1600- break ;
1601- }
16021600 Object nextKey = applyKeyFunction (frame , inliningTarget , keywordArg , keyCall , nextValue );
16031601 boolean isTrue ;
16041602 if (!seenNonBoolean .wasEntered (inliningTarget )) {
@@ -1616,10 +1614,13 @@ static Object minmaxSequenceWithKey(VirtualFrame frame, Node inliningTarget, Obj
16161614 currentValue = nextValue ;
16171615 }
16181616 loopCount ++;
1617+ } catch (IteratorExhausted e ) {
1618+ break ;
1619+ } finally {
1620+ LoopNode .reportLoopCount (inliningTarget , loopCount < 0 ? Integer .MAX_VALUE : loopCount );
16191621 }
1620- } finally {
1621- LoopNode .reportLoopCount (inliningTarget , loopCount < 0 ? Integer .MAX_VALUE : loopCount );
16221622 }
1623+
16231624 return currentValue ;
16241625 }
16251626
@@ -1737,29 +1738,26 @@ static Object next(VirtualFrame frame, Object iterator, Object defaultObject,
17371738 if (!PyIterCheckNode .checkSlots (slots )) {
17381739 throw raiseTypeError .raise (inliningTarget , TypeError , ErrorMessages .OBJ_ISNT_ITERATOR , iterator );
17391740 }
1740- Object result ;
17411741 try {
1742- result = callIterNext .execute (frame , inliningTarget , slots .tp_iternext (), iterator );
1743- } catch (PException e ) {
1742+ return callIterNext .execute (frame , inliningTarget , slots .tp_iternext (), iterator );
1743+ } catch (IteratorExhausted e ) {
17441744 if (defaultIsNoValue .profile (inliningTarget , defaultObject == NO_VALUE )) {
1745- throw e ;
1745+ throw raiseStopIteration . raise ( inliningTarget , StopIteration ) ;
17461746 } else {
1747- e .expectStopIteration (inliningTarget , stopIterationProfile );
17481747 return defaultObject ;
17491748 }
1750- }
1751- if (PyIterNextNode .isExhausted (result )) {
1749+ } catch (PException e ) {
17521750 if (defaultIsNoValue .profile (inliningTarget , defaultObject == NO_VALUE )) {
1753- throw raiseStopIteration . raise ( inliningTarget , StopIteration ) ;
1751+ throw e ;
17541752 } else {
1753+ e .expectStopIteration (inliningTarget , stopIterationProfile );
17551754 return defaultObject ;
17561755 }
17571756 }
1758- return result ;
17591757 }
17601758 }
17611759
1762- // ord(c)
1760+ // ord(c)
17631761 @ Builtin (name = J_ORD , minNumOfPositionalArgs = 1 )
17641762 @ GenerateNodeFactory
17651763 @ ImportStatic (PGuards .class )
@@ -1805,7 +1803,7 @@ static Object ord(@SuppressWarnings("unused") Object obj,
18051803 }
18061804 }
18071805
1808- // print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)
1806+ // print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)
18091807 @ Builtin (name = J_PRINT , takesVarArgs = true , keywordOnlyNames = {"sep" , "end" , "file" , "flush" }, doc = "\n " +
18101808 "print(value, ..., sep=' ', end='\\ n', file=sys.stdout, flush=False)\n " +
18111809 "\n " +
@@ -2219,61 +2217,90 @@ static Object sumGeneric(VirtualFrame frame, Node inliningTarget, Object iterato
22192217 @ Cached PyIterNextNode nextNode ,
22202218 @ Shared @ Cached PyNumberAddNode addNode ,
22212219 @ Shared @ Cached InlinedConditionProfile resultFitsInInt ,
2220+ @ Exclusive @ Cached InlinedBranchProfile seenObject ,
22222221 @ Exclusive @ Cached InlinedBranchProfile seenInt ,
22232222 @ Exclusive @ Cached InlinedBranchProfile seenDouble ,
2224- @ Exclusive @ Cached InlinedBranchProfile seenObject ) {
2223+ @ Exclusive @ Cached InlinedBranchProfile genericBranch ) {
22252224 /*
22262225 * Peel the first iteration to see what's the type.
22272226 */
2228- Object next = nextNode .execute (frame , inliningTarget , iterator );
2229- if (!PyIterNextNode .isExhausted (next )) {
2230- Object acc = addNode .execute (frame , inliningTarget , start , next );
2231- /*
2232- * We try to process integers/longs/doubles as long as we can. Then we always
2233- * fall through to the generic path. `next` and `acc` are always properly set so
2234- * that the generic path can check if there are remaining items and resume if
2235- * necessary.
2236- */
2237- if (acc instanceof Integer || acc instanceof Long ) {
2238- seenInt .enter (inliningTarget );
2239- long longAcc = acc instanceof Integer ? (int ) acc : (long ) acc ;
2240- while (loopProfilePrimitive .profile (inliningTarget , !PyIterNextNode .isExhausted (next = nextNode .execute (frame , inliningTarget , iterator )))) {
2241- try {
2242- if (next instanceof Integer nextInt ) {
2243- longAcc = PythonUtils .addExact (longAcc , nextInt );
2244- } else if (next instanceof Long nextLong ) {
2245- longAcc = PythonUtils .addExact (longAcc , nextLong );
2246- } else {
2247- break ;
2248- }
2249- } catch (OverflowException e ) {
2250- break ;
2227+ Object next ;
2228+ try {
2229+ next = nextNode .execute (frame , inliningTarget , iterator );
2230+ } catch (IteratorExhausted e ) {
2231+ return start ;
2232+ }
2233+ Object acc = addNode .execute (frame , inliningTarget , start , next );
2234+ /*
2235+ * We try to process integers/longs/doubles as long as we can. Then we always fall
2236+ * through to the generic path. `next` and `acc` are always properly set so that the
2237+ * generic path can check if there are remaining items and resume if necessary.
2238+ */
2239+ if (acc instanceof Integer || acc instanceof Long ) {
2240+ seenInt .enter (inliningTarget );
2241+ long longAcc = acc instanceof Integer ? (int ) acc : (long ) acc ;
2242+ boolean exitLoop = false , exhausted = false ;
2243+ while (loopProfilePrimitive .profile (inliningTarget , !exitLoop )) {
2244+ try {
2245+ next = nextNode .execute (frame , inliningTarget , iterator );
2246+ if (next instanceof Integer nextInt ) {
2247+ longAcc = PythonUtils .addExact (longAcc , nextInt );
2248+ } else if (next instanceof Long nextLong ) {
2249+ longAcc = PythonUtils .addExact (longAcc , nextLong );
2250+ } else {
2251+ exitLoop = true ;
22512252 }
2253+ } catch (OverflowException e ) {
2254+ exitLoop = true ;
2255+ } catch (IteratorExhausted e ) {
2256+ exitLoop = true ;
2257+ exhausted = true ;
22522258 }
2253- acc = maybeInt (inliningTarget , resultFitsInInt , longAcc );
2254- } else if (acc instanceof Double doubleAcc ) {
2255- seenDouble .enter (inliningTarget );
2256- while (loopProfilePrimitive .profile (inliningTarget , !PyIterNextNode .isExhausted (next = nextNode .execute (frame , inliningTarget , iterator )))) {
2259+ }
2260+ if (exhausted ) {
2261+ return maybeInt (inliningTarget , resultFitsInInt , longAcc );
2262+ }
2263+ genericBranch .enter (inliningTarget );
2264+ acc = longAcc ;
2265+ } else if (acc instanceof Double doubleAcc ) {
2266+ seenDouble .enter (inliningTarget );
2267+ boolean exitLoop = false , exhausted = false ;
2268+ while (loopProfilePrimitive .profile (inliningTarget , !exitLoop )) {
2269+ try {
2270+ next = nextNode .execute (frame , inliningTarget , iterator );
22572271 if (next instanceof Double nextDouble ) {
22582272 doubleAcc += nextDouble ;
22592273 } else {
2260- break ;
2274+ exitLoop = true ;
22612275 }
2276+ } catch (IteratorExhausted e ) {
2277+ exitLoop = true ;
2278+ exhausted = true ;
22622279 }
2263- acc = doubleAcc ;
2264- } else {
2265- next = nextNode .execute (frame , inliningTarget , iterator );
22662280 }
2267- if (!PyIterNextNode .isExhausted (next )) {
2268- seenObject .enter (inliningTarget );
2269- do {
2270- acc = addNode .execute (frame , inliningTarget , acc , next );
2271- } while (loopProfileGeneric .profile (inliningTarget , !PyIterNextNode .isExhausted (next = nextNode .execute (frame , inliningTarget , iterator ))));
2281+ if (exhausted ) {
2282+ return doubleAcc ;
22722283 }
2273- return acc ;
2284+ genericBranch .enter (inliningTarget );
2285+ acc = doubleAcc ;
22742286 } else {
2275- return start ;
2287+ seenObject .enter (inliningTarget );
2288+ try {
2289+ next = nextNode .execute (frame , inliningTarget , iterator );
2290+ } catch (IteratorExhausted e ) {
2291+ return acc ;
2292+ }
22762293 }
2294+ boolean exhausted = false ;
2295+ do {
2296+ acc = addNode .execute (frame , inliningTarget , acc , next );
2297+ try {
2298+ next = nextNode .execute (frame , inliningTarget , iterator );
2299+ } catch (IteratorExhausted e ) {
2300+ exhausted = true ;
2301+ }
2302+ } while (loopProfileGeneric .profile (inliningTarget , !exhausted ));
2303+ return acc ;
22772304 }
22782305
22792306 private static long maybeInt (Node inliningTarget , InlinedConditionProfile resultFitsInInt , long result ) {
0 commit comments