8080import com .oracle .graal .python .runtime .sequence .storage .SequenceStorage ;
8181import com .oracle .truffle .api .CompilerDirectives ;
8282import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
83+ import com .oracle .truffle .api .dsl .Bind ;
8384import com .oracle .truffle .api .dsl .Cached ;
8485import com .oracle .truffle .api .dsl .Fallback ;
8586import com .oracle .truffle .api .dsl .GenerateNodeFactory ;
@@ -188,6 +189,7 @@ int length(VirtualFrame frame, Object iterable,
188189 }
189190
190191 @ ImportStatic (PGuards .class )
192+ @ GenerateUncached
191193 public abstract static class GetInternalIteratorSequenceStorage extends Node {
192194 public static GetInternalIteratorSequenceStorage getUncached () {
193195 return GetInternalIteratorSequenceStorageNodeGen .getUncached ();
@@ -200,7 +202,7 @@ public static GetInternalIteratorSequenceStorage getUncached() {
200202 */
201203 public final SequenceStorage execute (PBuiltinIterator iterator ) {
202204 assert GetClassNode .getUncached ().execute (iterator ) == PIterator ;
203- assert iterator .index == 0 ;
205+ assert iterator .index == 0 && ! iterator . isExhausted () ;
204206 return executeInternal (iterator );
205207 }
206208
@@ -244,43 +246,54 @@ static SequenceStorage doOthers(PBuiltinIterator it) {
244246
245247 @ ImportStatic (PGuards .class )
246248 public abstract static class BuiltinIteratorLengthHint extends Node {
247- @ Child GetInternalIteratorSequenceStorage getSeqStorage = GetInternalIteratorSequenceStorageNodeGen .create ();
248- private final ConditionProfile noStorageProfile = ConditionProfile .createBinaryProfile ();
249-
250249 /**
251250 * The argument must be a builtin iterator. Returns {@code -1} if the length hint is not
252- * available.
251+ * available and rewrites itself to generic fallback that always returns {@code -1} .
253252 */
254253 public final int execute (PBuiltinIterator iterator ) {
255254 assert GetClassNode .getUncached ().execute (iterator ) == PIterator ;
256- SequenceStorage result = getSeqStorage .execute (iterator );
257- if (noStorageProfile .profile (result != null )) {
258- return result .length ();
259- }
260255 return executeInternal (iterator );
261256 }
262257
263258 protected abstract int executeInternal (PBuiltinIterator iterator );
264259
260+ protected static SequenceStorage getStorage (GetInternalIteratorSequenceStorage getSeqStorage , PBuiltinIterator it ) {
261+ return it .index != 0 || it .isExhausted () ? null : getSeqStorage .execute (it );
262+ }
263+
264+ @ Specialization (guards = "storage != null" )
265+ static int doSeqStorage (@ SuppressWarnings ("unused" ) PBuiltinIterator it ,
266+ @ SuppressWarnings ("unused" ) @ Cached GetInternalIteratorSequenceStorage getSeqStorage ,
267+ @ Bind ("getStorage(getSeqStorage, it)" ) SequenceStorage storage ) {
268+ return ensurePositive (storage .length ());
269+ }
270+
265271 @ Specialization
266272 static int doString (PStringIterator it ) {
267- return it .value .length ();
273+ return ensurePositive ( it .value .length () );
268274 }
269275
270276 @ Specialization
271277 static int doSequenceArr (PArrayIterator it ) {
272- return it .array .getLength ();
278+ return ensurePositive ( it .array .getLength () );
273279 }
274280
275281 @ Specialization
276282 static int doSequenceIntRange (PIntRangeIterator it ) {
277- return it .getLength ();
283+ return ensurePositive ( it .getLength () );
278284 }
279285
280- @ Fallback
281- static int doOthers ( PBuiltinIterator it ) {
286+ @ Specialization ( replaces = { "doSeqStorage" , "doString" , "doSequenceArr" , "doSequenceIntRange" })
287+ static int doGeneric ( @ SuppressWarnings ( "unused" ) PBuiltinIterator it ) {
282288 return -1 ;
283289 }
290+
291+ static int ensurePositive (int len ) {
292+ if (len < 0 ) {
293+ throw CompilerDirectives .shouldNotReachHere ();
294+ }
295+ return len ;
296+ }
284297 }
285298
286299 @ GenerateUncached
0 commit comments