43
43
import static com .oracle .graal .python .builtins .PythonBuiltinClassType .AttributeError ;
44
44
import static com .oracle .graal .python .builtins .PythonBuiltinClassType .SystemError ;
45
45
import static com .oracle .graal .python .builtins .modules .cext .PythonCextBuiltins .CApiCallPath .Direct ;
46
- import static com .oracle .graal .python .builtins .modules .cext .PythonCextBuiltins .CApiCallPath .Ignored ;
47
46
import static com .oracle .graal .python .builtins .objects .cext .capi .transitions .ArgDescriptor .Int ;
47
+ import static com .oracle .graal .python .builtins .objects .cext .capi .transitions .ArgDescriptor .PY_HASH_T_PTR ;
48
+ import static com .oracle .graal .python .builtins .objects .cext .capi .transitions .ArgDescriptor .PY_SSIZE_T_PTR ;
48
49
import static com .oracle .graal .python .builtins .objects .cext .capi .transitions .ArgDescriptor .PyObject ;
49
50
import static com .oracle .graal .python .builtins .objects .cext .capi .transitions .ArgDescriptor .PyObjectBorrowed ;
51
+ import static com .oracle .graal .python .builtins .objects .cext .capi .transitions .ArgDescriptor .PyObjectPtr ;
50
52
import static com .oracle .graal .python .builtins .objects .cext .capi .transitions .ArgDescriptor .PyObjectTransfer ;
51
53
import static com .oracle .graal .python .builtins .objects .cext .capi .transitions .ArgDescriptor .Py_hash_t ;
52
54
import static com .oracle .graal .python .builtins .objects .cext .capi .transitions .ArgDescriptor .Py_ssize_t ;
59
61
60
62
import com .oracle .graal .python .builtins .PythonBuiltinClassType ;
61
63
import com .oracle .graal .python .builtins .modules .BuiltinConstructors .StrNode ;
64
+ import com .oracle .graal .python .builtins .modules .cext .PythonCextBuiltins .CApi5BuiltinNode ;
62
65
import com .oracle .graal .python .builtins .modules .cext .PythonCextBuiltins .CApiBinaryBuiltinNode ;
63
66
import com .oracle .graal .python .builtins .modules .cext .PythonCextBuiltins .CApiBuiltin ;
64
67
import com .oracle .graal .python .builtins .modules .cext .PythonCextBuiltins .CApiNullaryBuiltinNode ;
67
70
import com .oracle .graal .python .builtins .modules .cext .PythonCextBuiltins .CApiUnaryBuiltinNode ;
68
71
import com .oracle .graal .python .builtins .modules .cext .PythonCextBuiltins .PromoteBorrowedValue ;
69
72
import com .oracle .graal .python .builtins .objects .PNone ;
73
+ import com .oracle .graal .python .builtins .objects .cext .capi .transitions .CApiTransitions ;
74
+ import com .oracle .graal .python .builtins .objects .cext .structs .CStructAccess ;
70
75
import com .oracle .graal .python .builtins .objects .common .EconomicMapStorage ;
71
76
import com .oracle .graal .python .builtins .objects .common .HashingCollectionNodes .SetItemNode ;
72
77
import com .oracle .graal .python .builtins .objects .common .HashingStorage ;
107
112
import com .oracle .truffle .api .dsl .Cached .Shared ;
108
113
import com .oracle .truffle .api .dsl .Fallback ;
109
114
import com .oracle .truffle .api .dsl .Specialization ;
115
+ import com .oracle .truffle .api .interop .InteropLibrary ;
116
+ import com .oracle .truffle .api .library .CachedLibrary ;
110
117
import com .oracle .truffle .api .nodes .Node ;
111
118
import com .oracle .truffle .api .profiles .InlinedBranchProfile ;
112
119
import com .oracle .truffle .api .profiles .InlinedLoopConditionProfile ;
@@ -122,12 +129,17 @@ static Object run(@Cached PythonObjectFactory factory) {
122
129
}
123
130
}
124
131
125
- @ CApiBuiltin (ret = PyObjectTransfer , args = {PyObject , Py_ssize_t }, call = Ignored )
126
- abstract static class PyTruffleDict_Next extends CApiBinaryBuiltinNode {
132
+ @ CApiBuiltin (ret = Int , args = {PyObject , PY_SSIZE_T_PTR , PyObjectPtr , PyObjectPtr , PY_HASH_T_PTR }, call = Direct )
133
+ abstract static class _PyDict_Next extends CApi5BuiltinNode {
127
134
128
135
@ Specialization
129
- static Object run (PDict dict , long pos ,
136
+ static int next (PDict dict , Object posPtr , Object keyPtr , Object valuePtr , Object hashPtr ,
130
137
@ Bind ("this" ) Node inliningTarget ,
138
+ @ CachedLibrary (limit = "2" ) InteropLibrary lib ,
139
+ @ Cached CStructAccess .ReadI64Node readI64Node ,
140
+ @ Cached CStructAccess .WriteLongNode writeLongNode ,
141
+ @ Cached CStructAccess .WritePointerNode writePointerNode ,
142
+ @ Cached CApiTransitions .PythonToNativeNode toNativeNode ,
131
143
@ Cached InlinedBranchProfile needsRewriteProfile ,
132
144
@ Cached InlinedBranchProfile economicMapProfile ,
133
145
@ Cached HashingStorageLen lenNode ,
@@ -138,14 +150,14 @@ static Object run(PDict dict, long pos,
138
150
@ Cached HashingStorageIteratorKeyHash itKeyHash ,
139
151
@ Cached PromoteBorrowedValue promoteKeyNode ,
140
152
@ Cached PromoteBorrowedValue promoteValueNode ,
141
- @ Cached HashingStorageSetItem setItem ,
142
- @ Cached PythonObjectFactory factory ) {
153
+ @ Cached HashingStorageSetItem setItem ) {
143
154
/*
144
155
* We need to promote primitive values and strings to object types for borrowing to work
145
156
* correctly. This is very hard to do mid-iteration, so we do all the promotion for the
146
157
* whole dict at once in the first call (which is required to start with position 0). In
147
158
* order to not violate the ordering, we construct a completely new storage.
148
159
*/
160
+ long pos = readI64Node .read (posPtr );
149
161
if (pos == 0 ) {
150
162
HashingStorage storage = dict .getDictStorage ();
151
163
int len = lenNode .execute (inliningTarget , storage );
@@ -200,20 +212,33 @@ static Object run(PDict dict, long pos,
200
212
it .setState ((int ) pos - 1 );
201
213
boolean hasNext = itNext .execute (inliningTarget , storage , it );
202
214
if (!hasNext ) {
203
- return getNativeNull (inliningTarget );
215
+ return 0 ;
216
+ }
217
+ long newPos = it .getState () + 1 ;
218
+ writeLongNode .write (posPtr , newPos );
219
+ if (!lib .isNull (keyPtr )) {
220
+ Object key = itKey .execute (inliningTarget , storage , it );
221
+ assert promoteKeyNode .execute (inliningTarget , key ) == null ;
222
+ // Borrowed reference
223
+ writePointerNode .write (keyPtr , toNativeNode .execute (key ));
224
+ }
225
+ if (!lib .isNull (valuePtr )) {
226
+ Object value = itValue .execute (inliningTarget , storage , it );
227
+ assert promoteValueNode .execute (inliningTarget , value ) == null ;
228
+ // Borrowed reference
229
+ writePointerNode .write (valuePtr , toNativeNode .execute (value ));
204
230
}
205
- Object key = itKey .execute (inliningTarget , storage , it );
206
- Object value = itValue .execute (inliningTarget , storage , it );
207
- assert promoteKeyNode .execute (inliningTarget , key ) == null ;
208
- assert promoteValueNode .execute (inliningTarget , value ) == null ;
209
- long hash = itKeyHash .execute (inliningTarget , storage , it );
210
- int newPos = it .getState () + 1 ;
211
- return factory .createTuple (new Object []{key , value , hash , newPos });
231
+ if (!lib .isNull (hashPtr )) {
232
+ long hash = itKeyHash .execute (inliningTarget , storage , it );
233
+ writeLongNode .write (hashPtr , hash );
234
+ }
235
+ return 1 ;
212
236
}
213
237
214
238
@ Fallback
215
- Object run (@ SuppressWarnings ("unused" ) Object dict , @ SuppressWarnings ("unused" ) Object pos ) {
216
- return getNativeNull ();
239
+ @ SuppressWarnings ("unused" )
240
+ static int run (Object dict , Object posPtr , Object keyPtr , Object valuePtr , Object hashPtr ) {
241
+ return 0 ;
217
242
}
218
243
}
219
244
0 commit comments