58
58
import com .oracle .graal .python .builtins .objects .common .SequenceNodes .LenNode ;
59
59
import com .oracle .graal .python .builtins .objects .dict .PDict ;
60
60
import com .oracle .graal .python .builtins .objects .function .PArguments .ThreadState ;
61
+ import com .oracle .graal .python .builtins .objects .function .PBuiltinFunction ;
61
62
import com .oracle .graal .python .builtins .objects .function .PKeyword ;
63
+ import com .oracle .graal .python .builtins .objects .method .PBuiltinMethod ;
62
64
import com .oracle .graal .python .builtins .objects .object .PythonObject ;
63
65
import com .oracle .graal .python .builtins .objects .object .PythonObjectLibrary ;
64
66
import com .oracle .graal .python .nodes .ErrorMessages ;
@@ -163,16 +165,18 @@ protected boolean hasKeysAttribute(Object o) {
163
165
return lookupKeysAttributeNode .execute (o ) != PNone .NO_VALUE ;
164
166
}
165
167
166
- @ Specialization (guards = "isEmpty(kwargs)" )
168
+ @ Specialization (guards = { "isEmpty(kwargs)" , "!hasIterAttrButNotBuiltin(dictLike, dictLib)" }, limit = "1 " )
167
169
HashingStorage doPDict (PHashingCollection dictLike , @ SuppressWarnings ("unused" ) PKeyword [] kwargs ,
170
+ @ SuppressWarnings ("unused" ) @ CachedLibrary ("dictLike" ) PythonObjectLibrary dictLib ,
168
171
@ CachedLibrary (limit = "3" ) HashingStorageLibrary lib ,
169
172
@ Cached HashingCollectionNodes .GetDictStorageNode getDictStorageNode ) {
170
173
return lib .copy (getDictStorageNode .execute (dictLike ));
171
174
}
172
175
173
- @ Specialization (guards = "!isEmpty(kwargs)" )
176
+ @ Specialization (guards = { "!isEmpty(kwargs)" , "!hasIterAttrButNotBuiltin(iterable, iterLib)" }, limit = "1 " )
174
177
HashingStorage doPDictKwargs (VirtualFrame frame , PHashingCollection iterable , PKeyword [] kwargs ,
175
178
@ CachedContext (PythonLanguage .class ) PythonContext context ,
179
+ @ SuppressWarnings ("unused" ) @ CachedLibrary ("iterable" ) PythonObjectLibrary iterLib ,
176
180
@ CachedLibrary (limit = "2" ) HashingStorageLibrary lib ,
177
181
@ Cached ("create()" ) HashingCollectionNodes .GetDictStorageNode getDictStorageNode ) {
178
182
Object state = IndirectCallContext .enter (frame , context , this );
@@ -185,6 +189,26 @@ HashingStorage doPDictKwargs(VirtualFrame frame, PHashingCollection iterable, PK
185
189
}
186
190
}
187
191
192
+ @ Specialization (guards = "hasIterAttrButNotBuiltin(col, colLib)" , limit = "1" )
193
+ HashingStorage doNoBuiltinKeysAttr (VirtualFrame frame , PHashingCollection col ,
194
+ @ SuppressWarnings ("unused" ) PKeyword [] kwargs ,
195
+ @ SuppressWarnings ("unused" ) @ CachedLibrary ("col" ) PythonObjectLibrary colLib ,
196
+ @ CachedLibrary (limit = "3" ) HashingStorageLibrary lib ,
197
+ @ Cached ("create(KEYS)" ) LookupAndCallUnaryNode callKeysNode ,
198
+ @ Cached ("create(__GETITEM__)" ) LookupAndCallBinaryNode callGetItemNode ,
199
+ @ Cached GetIteratorNode getIteratorNode ,
200
+ @ Cached GetNextNode nextNode ,
201
+ @ Cached IsBuiltinClassProfile errorProfile ) {
202
+ HashingStorage curStorage = PDict .createNewStorage (false , 0 );
203
+ return copyToStorage (frame , col , kwargs , curStorage , callKeysNode , callGetItemNode ,
204
+ getIteratorNode , nextNode , errorProfile , lib );
205
+ }
206
+
207
+ protected boolean hasIterAttrButNotBuiltin (PHashingCollection col , PythonObjectLibrary lib ) {
208
+ Object attr = lib .lookupAttribute (col , SpecialMethodNames .__ITER__ );
209
+ return attr != PNone .NO_VALUE && !(attr instanceof PBuiltinMethod || attr instanceof PBuiltinFunction );
210
+ }
211
+
188
212
@ Specialization (guards = {"!isPDict(mapping)" , "hasKeysAttribute(mapping)" })
189
213
HashingStorage doMapping (VirtualFrame frame , Object mapping , PKeyword [] kwargs ,
190
214
@ CachedLibrary (limit = "3" ) HashingStorageLibrary lib ,
@@ -194,7 +218,7 @@ HashingStorage doMapping(VirtualFrame frame, Object mapping, PKeyword[] kwargs,
194
218
@ Cached GetNextNode nextNode ,
195
219
@ Cached IsBuiltinClassProfile errorProfile ) {
196
220
HashingStorage curStorage = PDict .createNewStorage (false , 0 );
197
- return addMappingToStorage (frame , mapping , kwargs , curStorage , callKeysNode , callGetItemNode , getIteratorNode , nextNode , errorProfile , lib );
221
+ return copyToStorage (frame , mapping , kwargs , curStorage , callKeysNode , callGetItemNode , getIteratorNode , nextNode , errorProfile , lib );
198
222
}
199
223
200
224
@ Specialization (guards = {"!isNoValue(iterable)" , "!isPDict(iterable)" , "!hasKeysAttribute(iterable)" })
@@ -623,7 +647,7 @@ protected long getHashWithState(Object key, PythonObjectLibrary lib, ThreadState
623
647
* Adds all items from the given mapping object to storage. It is the caller responsibility to
624
648
* ensure, that mapping has the 'keys' attribute.
625
649
*/
626
- public static HashingStorage addMappingToStorage (VirtualFrame frame , Object mapping , PKeyword [] kwargs , HashingStorage storage ,
650
+ public static HashingStorage copyToStorage (VirtualFrame frame , Object mapping , PKeyword [] kwargs , HashingStorage storage ,
627
651
LookupAndCallUnaryNode callKeysNode , LookupAndCallBinaryNode callGetItemNode ,
628
652
GetIteratorNode getIteratorNode , GetNextNode nextNode ,
629
653
IsBuiltinClassProfile errorProfile , HashingStorageLibrary lib ) {
0 commit comments