26
26
package com .oracle .graal .python .builtins .objects .iterator ;
27
27
28
28
import static com .oracle .graal .python .builtins .PythonBuiltinClassType .RuntimeError ;
29
+ import static com .oracle .graal .python .builtins .PythonBuiltinClassType .TypeError ;
29
30
import static com .oracle .graal .python .nodes .BuiltinNames .T_ITER ;
31
+ import static com .oracle .graal .python .nodes .ErrorMessages .DESCRIPTOR_REQUIRES_S_OBJ_RECEIVED_P ;
30
32
import static com .oracle .graal .python .nodes .SpecialMethodNames .J___ITER__ ;
31
33
import static com .oracle .graal .python .nodes .SpecialMethodNames .J___LENGTH_HINT__ ;
32
34
import static com .oracle .graal .python .nodes .SpecialMethodNames .J___NEXT__ ;
64
66
import com .oracle .graal .python .lib .PyObjectSizeNode ;
65
67
import com .oracle .graal .python .lib .PySequenceGetItemNode ;
66
68
import com .oracle .graal .python .nodes .ErrorMessages ;
69
+ import com .oracle .graal .python .nodes .PNodeWithContext ;
67
70
import com .oracle .graal .python .nodes .PRaiseNode ;
68
71
import com .oracle .graal .python .nodes .function .PythonBuiltinBaseNode ;
69
72
import com .oracle .graal .python .nodes .function .builtins .PythonBinaryBuiltinNode ;
70
73
import com .oracle .graal .python .nodes .function .builtins .PythonUnaryBuiltinNode ;
74
+ import com .oracle .graal .python .nodes .interop .PForeignToPTypeNode ;
71
75
import com .oracle .graal .python .nodes .object .BuiltinClassProfiles .IsBuiltinObjectProfile ;
76
+ import com .oracle .graal .python .nodes .object .IsForeignObjectNode ;
72
77
import com .oracle .graal .python .nodes .util .CastToJavaBigIntegerNode ;
78
+ import com .oracle .graal .python .runtime .GilNode ;
73
79
import com .oracle .graal .python .runtime .PythonContext ;
74
80
import com .oracle .graal .python .runtime .exception .PException ;
75
81
import com .oracle .graal .python .runtime .object .PythonObjectFactory ;
76
82
import com .oracle .graal .python .runtime .sequence .storage .SequenceStorage ;
83
+ import com .oracle .truffle .api .CompilerDirectives ;
77
84
import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
78
85
import com .oracle .truffle .api .dsl .Bind ;
79
86
import com .oracle .truffle .api .dsl .Cached ;
80
87
import com .oracle .truffle .api .dsl .Cached .Exclusive ;
81
88
import com .oracle .truffle .api .dsl .Cached .Shared ;
89
+ import com .oracle .truffle .api .dsl .Fallback ;
82
90
import com .oracle .truffle .api .dsl .GenerateCached ;
83
91
import com .oracle .truffle .api .dsl .GenerateInline ;
84
92
import com .oracle .truffle .api .dsl .GenerateNodeFactory ;
85
93
import com .oracle .truffle .api .dsl .NodeFactory ;
86
94
import com .oracle .truffle .api .dsl .Specialization ;
87
95
import com .oracle .truffle .api .frame .VirtualFrame ;
96
+ import com .oracle .truffle .api .interop .InteropLibrary ;
97
+ import com .oracle .truffle .api .interop .StopIterationException ;
98
+ import com .oracle .truffle .api .interop .UnsupportedMessageException ;
99
+ import com .oracle .truffle .api .library .CachedLibrary ;
88
100
import com .oracle .truffle .api .nodes .Node ;
89
101
import com .oracle .truffle .api .profiles .InlinedConditionProfile ;
90
102
import com .oracle .truffle .api .profiles .InlinedExactClassProfile ;
91
103
import com .oracle .truffle .api .strings .TruffleString ;
92
104
105
+ /** NOTE: self can either be a PBuiltinIterator or a foreign iterator (isIterator()). */
93
106
@ CoreFunctions (extendClasses = {PythonBuiltinClassType .PIterator , PythonBuiltinClassType .PArrayIterator ,
94
107
PythonBuiltinClassType .PDictItemIterator , PythonBuiltinClassType .PDictReverseItemIterator ,
95
108
PythonBuiltinClassType .PDictKeyIterator , PythonBuiltinClassType .PDictReverseKeyIterator ,
@@ -111,7 +124,7 @@ protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFa
111
124
public abstract static class NextNode extends PythonUnaryBuiltinNode {
112
125
113
126
@ Specialization
114
- static Object exhausted (VirtualFrame frame , PBuiltinIterator self ,
127
+ static Object exhausted (VirtualFrame frame , Object self ,
115
128
@ Bind ("this" ) Node inliningTarget ,
116
129
@ Cached NextHelperNode nextHelperNode ) {
117
130
return nextHelperNode .execute (frame , inliningTarget , self , true );
@@ -120,11 +133,11 @@ static Object exhausted(VirtualFrame frame, PBuiltinIterator self,
120
133
121
134
@ GenerateInline
122
135
@ GenerateCached (false )
123
- public abstract static class NextHelperNode extends Node {
136
+ public abstract static class NextHelperNode extends PNodeWithContext {
124
137
125
138
public static final Object STOP_MARKER = new Object ();
126
139
127
- public abstract Object execute (VirtualFrame frame , Node inliningTarget , PBuiltinIterator iterator , boolean throwStopIteration );
140
+ public abstract Object execute (VirtualFrame frame , Node inliningTarget , Object iterator , boolean throwStopIteration );
128
141
129
142
private static Object stopIteration (Node inliningTarget , PBuiltinIterator self , boolean throwStopIteration , PRaiseNode .Lazy raiseNode ) {
130
143
self .setExhausted ();
@@ -135,6 +148,14 @@ private static Object stopIteration(Node inliningTarget, PBuiltinIterator self,
135
148
}
136
149
}
137
150
151
+ private static Object stopIterationForeign (Node inliningTarget , boolean throwStopIteration , PRaiseNode .Lazy raiseNode ) {
152
+ if (throwStopIteration ) {
153
+ throw raiseNode .get (inliningTarget ).raiseStopIteration ();
154
+ } else {
155
+ return STOP_MARKER ;
156
+ }
157
+ }
158
+
138
159
@ Specialization (guards = "self.isExhausted()" )
139
160
static Object exhausted (Node inliningTarget , @ SuppressWarnings ("unused" ) PBuiltinIterator self , boolean throwStopIteration ,
140
161
@ Exclusive @ Cached PRaiseNode .Lazy raiseNode ) {
@@ -277,6 +298,29 @@ static Object next(VirtualFrame frame, Node inliningTarget, PSequenceIterator se
277
298
}
278
299
}
279
300
301
+ @ Specialization (guards = {"isForeignObjectNode.execute(inliningTarget, self)" , "interop.isIterator(self)" }, limit = "1" )
302
+ static Object foreign (Node inliningTarget , Object self , boolean throwStopIteration ,
303
+ @ Cached IsForeignObjectNode isForeignObjectNode ,
304
+ @ CachedLibrary (limit = "getCallSiteInlineCacheMaxDepth()" ) InteropLibrary interop ,
305
+ @ Cached (inline = false ) GilNode gil ,
306
+ @ Cached (inline = false ) PForeignToPTypeNode toPythonNode ,
307
+ @ Exclusive @ Cached PRaiseNode .Lazy raiseNode ) {
308
+ final Object element ;
309
+
310
+ gil .release (true );
311
+ try {
312
+ element = interop .getIteratorNextElement (self );
313
+ } catch (StopIterationException e ) {
314
+ return stopIterationForeign (inliningTarget , throwStopIteration , raiseNode );
315
+ } catch (UnsupportedMessageException e ) {
316
+ throw CompilerDirectives .shouldNotReachHere ("iterator claimed to be iterator but wasn't" );
317
+ } finally {
318
+ gil .acquire ();
319
+ }
320
+
321
+ return toPythonNode .executeConvert (element );
322
+ }
323
+
280
324
@ GenerateInline
281
325
@ GenerateCached (false )
282
326
abstract static class PHashingStorageIteratorNextValue extends Node {
@@ -415,6 +459,22 @@ static int lengthHint(VirtualFrame frame, PSequenceIterator self,
415
459
int len = sizeNode .execute (frame , inliningTarget , self .getObject ()) - self .getIndex ();
416
460
return len < 0 ? 0 : len ;
417
461
}
462
+
463
+ @ Specialization (guards = {"isForeignObjectNode.execute(inliningTarget, self)" , "interop.isIterator(self)" }, limit = "1" )
464
+ static int foreign (Object self ,
465
+ @ Bind ("this" ) Node inliningTarget ,
466
+ @ Cached IsForeignObjectNode isForeignObjectNode ,
467
+ @ CachedLibrary (limit = "getCallSiteInlineCacheMaxDepth()" ) InteropLibrary interop ,
468
+ @ Cached (inline = false ) GilNode gil ) {
469
+ gil .release (true );
470
+ try {
471
+ return interop .hasIteratorNextElement (self ) ? 1 : 0 ;
472
+ } catch (UnsupportedMessageException e ) {
473
+ throw CompilerDirectives .shouldNotReachHere ("iterator claimed to be iterator but wasn't" );
474
+ } finally {
475
+ gil .acquire ();
476
+ }
477
+ }
418
478
}
419
479
420
480
@ Builtin (name = J___REDUCE__ , minNumOfPositionalArgs = 1 )
@@ -538,6 +598,13 @@ Object reduceNonSeq(@SuppressWarnings({"unused"}) VirtualFrame frame, PSequenceI
538
598
}
539
599
}
540
600
601
+ @ Fallback
602
+ static int other (Object self ,
603
+ @ Bind ("this" ) Node inliningTarget ,
604
+ @ Cached PRaiseNode .Lazy raiseNode ) {
605
+ throw raiseNode .get (inliningTarget ).raise (TypeError , DESCRIPTOR_REQUIRES_S_OBJ_RECEIVED_P , "iterator" , self );
606
+ }
607
+
541
608
private static PTuple reduceInternal (VirtualFrame frame , Node inliningTarget , Object arg , PythonContext context , PyObjectGetAttr getAttrNode , PythonObjectFactory factory ) {
542
609
return reduceInternal (frame , inliningTarget , arg , null , context , getAttrNode , factory );
543
610
}
@@ -560,7 +627,7 @@ private static PTuple reduceInternal(VirtualFrame frame, Node inliningTarget, Ob
560
627
public abstract static class SetStateNode extends PythonBinaryBuiltinNode {
561
628
@ Specialization
562
629
@ TruffleBoundary
563
- public static Object reduce (PBigRangeIterator self , Object index ,
630
+ static Object setstate (PBigRangeIterator self , Object index ,
564
631
@ Bind ("this" ) Node inliningTarget ,
565
632
@ Cached CastToJavaBigIntegerNode castToJavaBigIntegerNode ) {
566
633
BigInteger idx = castToJavaBigIntegerNode .execute (inliningTarget , index );
@@ -572,7 +639,7 @@ public static Object reduce(PBigRangeIterator self, Object index,
572
639
}
573
640
574
641
@ Specialization (guards = "!isPBigRangeIterator(self)" )
575
- public static Object reduce (VirtualFrame frame , PBuiltinIterator self , Object index ,
642
+ static Object setstate (VirtualFrame frame , PBuiltinIterator self , Object index ,
576
643
@ Bind ("this" ) Node inliningTarget ,
577
644
@ Cached PyNumberAsSizeNode asSizeNode ) {
578
645
int idx = asSizeNode .executeExact (frame , inliningTarget , index );
@@ -583,6 +650,13 @@ public static Object reduce(VirtualFrame frame, PBuiltinIterator self, Object in
583
650
return PNone .NONE ;
584
651
}
585
652
653
+ @ Fallback
654
+ static Object other (Object self , Object index ,
655
+ @ Bind ("this" ) Node inliningTarget ,
656
+ @ Cached PRaiseNode .Lazy raiseNode ) {
657
+ throw raiseNode .get (inliningTarget ).raise (TypeError , DESCRIPTOR_REQUIRES_S_OBJ_RECEIVED_P , "iterator" , self );
658
+ }
659
+
586
660
protected static boolean isPBigRangeIterator (Object obj ) {
587
661
return obj instanceof PBigRangeIterator ;
588
662
}
0 commit comments