Skip to content

Commit 50fc426

Browse files
committed
reimplemented in java the update, fromkeys and repr methods from lib-graalpython/dict.py
1 parent af0d219 commit 50fc426

File tree

7 files changed

+588
-257
lines changed

7 files changed

+588
-257
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/Python3Core.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@
106106
import com.oracle.graal.python.builtins.objects.dict.DictBuiltins;
107107
import com.oracle.graal.python.builtins.objects.dict.DictItemsIteratorBuiltins;
108108
import com.oracle.graal.python.builtins.objects.dict.DictKeysIteratorBuiltins;
109+
import com.oracle.graal.python.builtins.objects.dict.DictReprBuiltin;
109110
import com.oracle.graal.python.builtins.objects.dict.DictValuesBuiltins;
110111
import com.oracle.graal.python.builtins.objects.dict.DictValuesIteratorBuiltins;
111112
import com.oracle.graal.python.builtins.objects.dict.DictViewBuiltins;
@@ -209,7 +210,6 @@ private static final String[] initializeCoreFiles() {
209210
"_descriptor",
210211
"object",
211212
"sys",
212-
"dict",
213213
"_mappingproxy",
214214
"str",
215215
"type",
@@ -318,6 +318,7 @@ private static final PythonBuiltins[] initializeBuiltins() {
318318
new ForeignObjectBuiltins(),
319319
new ListBuiltins(),
320320
new DictBuiltins(),
321+
new DictReprBuiltin(),
321322
new DictViewBuiltins(),
322323
new DictValuesBuiltins(),
323324
new DictKeysIteratorBuiltins(),

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,12 @@ public enum PythonBuiltinClassType implements LazyPythonClass {
6969
PCell("cell"),
7070
PComplex("complex", BuiltinNames.BUILTINS),
7171
PDict("dict", BuiltinNames.BUILTINS),
72-
PDictKeysView("dict_keys"),
72+
PDictKeysView(BuiltinNames.DICT_KEYS),
7373
PDictItemsIterator(BuiltinNames.DICT_ITEMITERATOR),
74-
PDictItemsView("dict_items"),
74+
PDictItemsView(BuiltinNames.DICT_ITEMS),
7575
PDictKeysIterator(BuiltinNames.DICT_KEYITERATOR),
7676
PDictValuesIterator(BuiltinNames.DICT_VALUEITERATOR),
77-
PDictValuesView("dict_values"),
77+
PDictValuesView(BuiltinNames.DICT_VALUES),
7878
PEllipsis("ellipsis"),
7979
PEnumerate("enumerate", BuiltinNames.BUILTINS),
8080
PMap("map", BuiltinNames.BUILTINS),

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/HashingStorage.java

Lines changed: 110 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
import com.oracle.graal.python.builtins.objects.common.HashingStorageLibrary.HashingStorageIterable;
5656
import com.oracle.graal.python.builtins.objects.common.HashingStorageLibrary.HashingStorageIterator;
5757
import com.oracle.graal.python.builtins.objects.common.HashingStorageLibrary.InjectIntoNode;
58+
import com.oracle.graal.python.builtins.objects.common.SequenceNodes.LenNode;
5859
import com.oracle.graal.python.builtins.objects.dict.PDict;
5960
import com.oracle.graal.python.builtins.objects.function.PArguments.ThreadState;
6061
import com.oracle.graal.python.builtins.objects.function.PKeyword;
@@ -134,7 +135,6 @@ public Assumption needNotPassExceptionAssumption() {
134135

135136
public abstract HashingStorage execute(VirtualFrame frame, Object mapping, PKeyword[] kwargs);
136137

137-
@Child private GetNextNode nextNode;
138138
@Child private LookupInheritedAttributeNode lookupKeysAttributeNode;
139139

140140
protected boolean isEmpty(PKeyword[] kwargs) {
@@ -186,114 +186,36 @@ HashingStorage doPDictKwargs(VirtualFrame frame, PHashingCollection iterable, PK
186186
}
187187

188188
@Specialization(guards = {"!isPDict(mapping)", "hasKeysAttribute(mapping)"})
189-
HashingStorage doMapping(VirtualFrame frame, Object mapping, @SuppressWarnings("unused") PKeyword[] kwargs,
189+
HashingStorage doMapping(VirtualFrame frame, Object mapping, PKeyword[] kwargs,
190190
@CachedLibrary(limit = "3") HashingStorageLibrary lib,
191191
@Cached("create(KEYS)") LookupAndCallUnaryNode callKeysNode,
192192
@Cached("create(__GETITEM__)") LookupAndCallBinaryNode callGetItemNode,
193-
@Cached("create()") GetIteratorNode getIteratorNode,
194-
@Cached("create()") IsBuiltinClassProfile errorProfile) {
193+
@Cached GetIteratorNode getIteratorNode,
194+
@Cached GetNextNode nextNode,
195+
@Cached IsBuiltinClassProfile errorProfile) {
195196
HashingStorage curStorage = PDict.createNewStorage(false, 0);
196-
// That call must work since 'hasKeysAttribute' checks if it has the 'keys' attribute
197-
// before.
198-
Object keysIterable = callKeysNode.executeObject(frame, mapping);
199-
Object keysIt = getIteratorNode.executeWith(frame, keysIterable);
200-
while (true) {
201-
try {
202-
Object keyObj = getNextNode().execute(frame, keysIt);
203-
Object valueObj = callGetItemNode.executeObject(frame, mapping, keyObj);
204-
205-
curStorage = lib.setItem(curStorage, keyObj, valueObj);
206-
} catch (PException e) {
207-
e.expectStopIteration(errorProfile);
208-
break;
209-
}
210-
}
211-
if (kwargs.length > 0) {
212-
curStorage = lib.addAllToOther(new KeywordsStorage(kwargs), curStorage);
213-
}
214-
return curStorage;
215-
}
216-
217-
private GetNextNode getNextNode() {
218-
if (nextNode == null) {
219-
CompilerDirectives.transferToInterpreterAndInvalidate();
220-
nextNode = insert(GetNextNode.create());
221-
}
222-
return nextNode;
197+
return addMappingToStorage(frame, mapping, kwargs, curStorage, callKeysNode, callGetItemNode, getIteratorNode, nextNode, errorProfile, lib);
223198
}
224199

225200
@Specialization(guards = {"!isNoValue(iterable)", "!isPDict(iterable)", "!hasKeysAttribute(iterable)"})
226201
HashingStorage doSequence(VirtualFrame frame, PythonObject iterable, PKeyword[] kwargs,
227202
@CachedLibrary(limit = "3") HashingStorageLibrary lib,
228203
@Cached PRaiseNode raise,
229-
@Cached("create()") GetIteratorNode getIterator,
230-
@Cached("create()") FastConstructListNode createListNode,
204+
@Cached GetIteratorNode getIterator,
205+
@Cached GetNextNode nextNode,
206+
@Cached FastConstructListNode createListNode,
231207
@Cached("create(__GETITEM__)") LookupAndCallBinaryNode getItemNode,
232-
@Cached("create()") SequenceNodes.LenNode seqLenNode,
208+
@Cached SequenceNodes.LenNode seqLenNode,
233209
@Cached("createBinaryProfile()") ConditionProfile lengthTwoProfile,
234-
@Cached("create()") IsBuiltinClassProfile errorProfile,
235-
@Cached("create()") IsBuiltinClassProfile isTypeErrorProfile) {
236-
237-
Object it = getIterator.executeWith(frame, iterable);
238-
239-
ArrayList<PSequence> elements = new ArrayList<>();
240-
boolean isStringKey = false;
241-
try {
242-
while (true) {
243-
Object next = getNextNode().execute(frame, it);
244-
PSequence element = null;
245-
int len = 1;
246-
element = createListNode.execute(next);
247-
assert element != null;
248-
// This constructs a new list using the builtin type. So, the object cannot
249-
// be subclassed and we can directly call 'len()'.
250-
len = seqLenNode.execute(element);
251-
252-
if (lengthTwoProfile.profile(len != 2)) {
253-
throw raise.raise(ValueError, ErrorMessages.DICT_UPDATE_SEQ_ELEM_HAS_LENGTH_2_REQUIRED, arrayListSize(elements), len);
254-
}
255-
256-
// really check for Java String since PString can be subclassed
257-
isStringKey = isStringKey || getItemNode.executeObject(frame, element, 0) instanceof String;
258-
259-
arrayListAdd(elements, element);
260-
}
261-
} catch (PException e) {
262-
if (isTypeErrorProfile.profileException(e, TypeError)) {
263-
throw raise.raise(TypeError, ErrorMessages.CANNOT_CONVERT_DICT_UPDATE_SEQ, arrayListSize(elements));
264-
} else {
265-
e.expectStopIteration(errorProfile);
266-
}
267-
}
210+
@Cached IsBuiltinClassProfile errorProfile,
211+
@Cached IsBuiltinClassProfile isTypeErrorProfile) {
268212

269-
HashingStorage storage = PDict.createNewStorage(isStringKey, arrayListSize(elements) + kwargs.length);
270-
for (int j = 0; j < arrayListSize(elements); j++) {
271-
PSequence element = arrayListGet(elements, j);
272-
Object key = getItemNode.executeObject(frame, element, 0);
273-
Object value = getItemNode.executeObject(frame, element, 1);
274-
storage = lib.setItem(storage, key, value);
275-
}
276-
if (kwargs.length > 0) {
277-
storage = lib.addAllToOther(new KeywordsStorage(kwargs), storage);
278-
}
213+
StorageSupplier newStorage = (boolean isStringKey, int length) -> PDict.createNewStorage(isStringKey, length);
214+
HashingStorage storage = addSequenceToStorage(frame, iterable, kwargs, newStorage,
215+
getIterator, nextNode, createListNode, seqLenNode, lengthTwoProfile, raise, getItemNode, isTypeErrorProfile, errorProfile, lib);
279216
return storage;
280217
}
281218

282-
@TruffleBoundary(allowInlining = true)
283-
private static PSequence arrayListGet(ArrayList<PSequence> elements, int j) {
284-
return elements.get(j);
285-
}
286-
287-
@TruffleBoundary(allowInlining = true)
288-
private static boolean arrayListAdd(ArrayList<PSequence> elements, PSequence element) {
289-
return elements.add(element);
290-
}
291-
292-
@TruffleBoundary(allowInlining = true)
293-
private static int arrayListSize(ArrayList<PSequence> elements) {
294-
return elements.size();
295-
}
296-
297219
public static InitNode create() {
298220
return InitNodeGen.create();
299221
}
@@ -680,4 +602,99 @@ protected long getHashWithState(Object key, PythonObjectLibrary lib, ThreadState
680602
}
681603
return lib.hashWithState(key, state);
682604
}
605+
606+
/**
607+
* Adds all items from the given mapping object to storage. It is the caller responsibility to
608+
* ensure, that mapping has the 'keys' attribute.
609+
*/
610+
public static HashingStorage addMappingToStorage(VirtualFrame frame, Object mapping, PKeyword[] kwargs, HashingStorage storage,
611+
LookupAndCallUnaryNode callKeysNode, LookupAndCallBinaryNode callGetItemNode,
612+
GetIteratorNode getIteratorNode, GetNextNode nextNode,
613+
IsBuiltinClassProfile errorProfile, HashingStorageLibrary lib) {
614+
Object keysIterable = callKeysNode.executeObject(frame, mapping);
615+
Object keysIt = getIteratorNode.executeWith(frame, keysIterable);
616+
HashingStorage curStorage = storage;
617+
while (true) {
618+
try {
619+
Object keyObj = nextNode.execute(frame, keysIt);
620+
Object valueObj = callGetItemNode.executeObject(frame, mapping, keyObj);
621+
622+
curStorage = lib.setItem(curStorage, keyObj, valueObj);
623+
} catch (PException e) {
624+
e.expectStopIteration(errorProfile);
625+
break;
626+
}
627+
}
628+
if (kwargs.length > 0) {
629+
curStorage = lib.addAllToOther(new KeywordsStorage(kwargs), curStorage);
630+
}
631+
return curStorage;
632+
}
633+
634+
@FunctionalInterface
635+
public interface StorageSupplier {
636+
HashingStorage get(boolean isStringKey, int length);
637+
}
638+
639+
public static HashingStorage addSequenceToStorage(VirtualFrame frame, Object iterable, PKeyword[] kwargs, StorageSupplier storageSupplier,
640+
GetIteratorNode getIterator, GetNextNode nextNode, FastConstructListNode createListNode, LenNode seqLenNode,
641+
ConditionProfile lengthTwoProfile, PRaiseNode raise, LookupAndCallBinaryNode getItemNode, IsBuiltinClassProfile isTypeErrorProfile,
642+
IsBuiltinClassProfile errorProfile, HashingStorageLibrary lib) throws PException {
643+
Object it = getIterator.executeWith(frame, iterable);
644+
ArrayList<PSequence> elements = new ArrayList<>();
645+
boolean isStringKey = false;
646+
try {
647+
while (true) {
648+
Object next = nextNode.execute(frame, it);
649+
PSequence element = null;
650+
int len = 1;
651+
element = createListNode.execute(next);
652+
assert element != null;
653+
// This constructs a new list using the builtin type. So, the object cannot
654+
// be subclassed and we can directly call 'len()'.
655+
len = seqLenNode.execute(element);
656+
657+
if (lengthTwoProfile.profile(len != 2)) {
658+
throw raise.raise(ValueError, ErrorMessages.DICT_UPDATE_SEQ_ELEM_HAS_LENGTH_2_REQUIRED, arrayListSize(elements), len);
659+
}
660+
661+
// really check for Java String since PString can be subclassed
662+
isStringKey = isStringKey || getItemNode.executeObject(frame, element, 0) instanceof String;
663+
664+
arrayListAdd(elements, element);
665+
}
666+
} catch (PException e) {
667+
if (isTypeErrorProfile.profileException(e, TypeError)) {
668+
throw raise.raise(TypeError, ErrorMessages.CANNOT_CONVERT_DICT_UPDATE_SEQ, arrayListSize(elements));
669+
} else {
670+
e.expectStopIteration(errorProfile);
671+
}
672+
}
673+
HashingStorage storage = storageSupplier.get(isStringKey, arrayListSize(elements) + kwargs.length);
674+
for (int j = 0; j < arrayListSize(elements); j++) {
675+
PSequence element = arrayListGet(elements, j);
676+
Object key = getItemNode.executeObject(frame, element, 0);
677+
Object value = getItemNode.executeObject(frame, element, 1);
678+
storage = lib.setItem(storage, key, value);
679+
}
680+
if (kwargs.length > 0) {
681+
storage = lib.addAllToOther(new KeywordsStorage(kwargs), storage);
682+
}
683+
return storage;
684+
}
685+
686+
@TruffleBoundary(allowInlining = true)
687+
private static PSequence arrayListGet(ArrayList<PSequence> elements, int j) {
688+
return elements.get(j);
689+
}
690+
691+
@TruffleBoundary(allowInlining = true)
692+
private static boolean arrayListAdd(ArrayList<PSequence> elements, PSequence element) {
693+
return elements.add(element);
694+
}
695+
696+
@TruffleBoundary(allowInlining = true)
697+
private static int arrayListSize(ArrayList<PSequence> elements) {
698+
return elements.size();
699+
}
683700
}

0 commit comments

Comments
 (0)