4343import static com .oracle .graal .python .builtins .PythonBuiltinClassType .AttributeError ;
4444import static com .oracle .graal .python .builtins .PythonBuiltinClassType .SystemError ;
4545import static com .oracle .graal .python .builtins .modules .cext .PythonCextBuiltins .CApiCallPath .Direct ;
46- import static com .oracle .graal .python .builtins .modules .cext .PythonCextBuiltins .CApiCallPath .Ignored ;
4746import 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 ;
4849import static com .oracle .graal .python .builtins .objects .cext .capi .transitions .ArgDescriptor .PyObject ;
4950import 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 ;
5052import static com .oracle .graal .python .builtins .objects .cext .capi .transitions .ArgDescriptor .PyObjectTransfer ;
5153import static com .oracle .graal .python .builtins .objects .cext .capi .transitions .ArgDescriptor .Py_hash_t ;
5254import static com .oracle .graal .python .builtins .objects .cext .capi .transitions .ArgDescriptor .Py_ssize_t ;
5961
6062import com .oracle .graal .python .builtins .PythonBuiltinClassType ;
6163import com .oracle .graal .python .builtins .modules .BuiltinConstructors .StrNode ;
64+ import com .oracle .graal .python .builtins .modules .cext .PythonCextBuiltins .CApi5BuiltinNode ;
6265import com .oracle .graal .python .builtins .modules .cext .PythonCextBuiltins .CApiBinaryBuiltinNode ;
6366import com .oracle .graal .python .builtins .modules .cext .PythonCextBuiltins .CApiBuiltin ;
6467import com .oracle .graal .python .builtins .modules .cext .PythonCextBuiltins .CApiNullaryBuiltinNode ;
6770import com .oracle .graal .python .builtins .modules .cext .PythonCextBuiltins .CApiUnaryBuiltinNode ;
6871import com .oracle .graal .python .builtins .modules .cext .PythonCextBuiltins .PromoteBorrowedValue ;
6972import 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 ;
7075import com .oracle .graal .python .builtins .objects .common .EconomicMapStorage ;
7176import com .oracle .graal .python .builtins .objects .common .HashingCollectionNodes .SetItemNode ;
7277import com .oracle .graal .python .builtins .objects .common .HashingStorage ;
107112import com .oracle .truffle .api .dsl .Cached .Shared ;
108113import com .oracle .truffle .api .dsl .Fallback ;
109114import com .oracle .truffle .api .dsl .Specialization ;
115+ import com .oracle .truffle .api .interop .InteropLibrary ;
116+ import com .oracle .truffle .api .library .CachedLibrary ;
110117import com .oracle .truffle .api .nodes .Node ;
111118import com .oracle .truffle .api .profiles .InlinedBranchProfile ;
112119import com .oracle .truffle .api .profiles .InlinedLoopConditionProfile ;
@@ -122,12 +129,17 @@ static Object run(@Cached PythonObjectFactory factory) {
122129 }
123130 }
124131
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 {
127134
128135 @ Specialization
129- static Object run (PDict dict , long pos ,
136+ static int next (PDict dict , Object posPtr , Object keyPtr , Object valuePtr , Object hashPtr ,
130137 @ 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 ,
131143 @ Cached InlinedBranchProfile needsRewriteProfile ,
132144 @ Cached InlinedBranchProfile economicMapProfile ,
133145 @ Cached HashingStorageLen lenNode ,
@@ -138,14 +150,14 @@ static Object run(PDict dict, long pos,
138150 @ Cached HashingStorageIteratorKeyHash itKeyHash ,
139151 @ Cached PromoteBorrowedValue promoteKeyNode ,
140152 @ Cached PromoteBorrowedValue promoteValueNode ,
141- @ Cached HashingStorageSetItem setItem ,
142- @ Cached PythonObjectFactory factory ) {
153+ @ Cached HashingStorageSetItem setItem ) {
143154 /*
144155 * We need to promote primitive values and strings to object types for borrowing to work
145156 * correctly. This is very hard to do mid-iteration, so we do all the promotion for the
146157 * whole dict at once in the first call (which is required to start with position 0). In
147158 * order to not violate the ordering, we construct a completely new storage.
148159 */
160+ long pos = readI64Node .read (posPtr );
149161 if (pos == 0 ) {
150162 HashingStorage storage = dict .getDictStorage ();
151163 int len = lenNode .execute (inliningTarget , storage );
@@ -200,20 +212,33 @@ static Object run(PDict dict, long pos,
200212 it .setState ((int ) pos - 1 );
201213 boolean hasNext = itNext .execute (inliningTarget , storage , it );
202214 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 ));
204230 }
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 ;
212236 }
213237
214238 @ 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 ;
217242 }
218243 }
219244
0 commit comments