|
76 | 76 | import com.oracle.graal.python.builtins.objects.cext.capi.CApiContext;
|
77 | 77 | import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions;
|
78 | 78 | import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess;
|
| 79 | +import com.oracle.graal.python.builtins.objects.common.DynamicObjectStorage; |
79 | 80 | import com.oracle.graal.python.builtins.objects.common.EconomicMapStorage;
|
80 | 81 | import com.oracle.graal.python.builtins.objects.common.HashingCollectionNodes.SetItemNode;
|
81 | 82 | import com.oracle.graal.python.builtins.objects.common.HashingStorage;
|
|
93 | 94 | import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageLen;
|
94 | 95 | import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageSetItem;
|
95 | 96 | import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageSetItemWithHash;
|
| 97 | +import com.oracle.graal.python.builtins.objects.common.KeywordsStorage; |
96 | 98 | import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.GetItemNode;
|
97 | 99 | import com.oracle.graal.python.builtins.objects.dict.DictBuiltins.ClearNode;
|
98 | 100 | import com.oracle.graal.python.builtins.objects.dict.DictBuiltins.PopNode;
|
|
105 | 107 | import com.oracle.graal.python.lib.PyDictSetDefault;
|
106 | 108 | import com.oracle.graal.python.lib.PyObjectGetAttr;
|
107 | 109 | import com.oracle.graal.python.lib.PyObjectHashNode;
|
| 110 | +import com.oracle.graal.python.lib.PyUnicodeCheckNode; |
108 | 111 | import com.oracle.graal.python.nodes.PRaiseNode;
|
109 | 112 | import com.oracle.graal.python.nodes.builtins.ListNodes.ConstructListNode;
|
110 | 113 | import com.oracle.graal.python.nodes.call.CallNode;
|
|
127 | 130 | import com.oracle.truffle.api.library.CachedLibrary;
|
128 | 131 | import com.oracle.truffle.api.nodes.Node;
|
129 | 132 | import com.oracle.truffle.api.profiles.InlinedBranchProfile;
|
| 133 | +import com.oracle.truffle.api.profiles.InlinedConditionProfile; |
130 | 134 | import com.oracle.truffle.api.profiles.InlinedLoopConditionProfile;
|
131 | 135 |
|
132 | 136 | public final class PythonCextDictBuiltins {
|
@@ -654,4 +658,32 @@ static boolean isTracked(Object object, CStructAccess.ReadI64Node readI64Node) {
|
654 | 658 | // return false;
|
655 | 659 | }
|
656 | 660 | }
|
| 661 | + |
| 662 | + @CApiBuiltin(ret = Int, args = {PyObject}, call = Direct) |
| 663 | + abstract static class _PyDict_HasOnlyStringKeys extends CApiUnaryBuiltinNode { |
| 664 | + |
| 665 | + @Specialization |
| 666 | + static int check(PDict dict, |
| 667 | + @Bind Node inliningTarget, |
| 668 | + @Cached InlinedConditionProfile storageProfile, |
| 669 | + @Cached InlinedLoopConditionProfile loopConditionProfile, |
| 670 | + @Cached HashingStorageGetIterator getIter, |
| 671 | + @Cached HashingStorageIteratorNext getIterNext, |
| 672 | + @Cached HashingStorageIteratorKey getIterKey, |
| 673 | + @Cached PyUnicodeCheckNode check) { |
| 674 | + HashingStorage storage = dict.getDictStorage(); |
| 675 | + // Keywords and dynamic object storages only allow strings |
| 676 | + if (storageProfile.profile(inliningTarget, storage instanceof KeywordsStorage || storage instanceof DynamicObjectStorage)) { |
| 677 | + return 1; |
| 678 | + } |
| 679 | + HashingStorageIterator it = getIter.execute(inliningTarget, storage); |
| 680 | + while (loopConditionProfile.profile(inliningTarget, getIterNext.execute(inliningTarget, storage, it))) { |
| 681 | + Object key = getIterKey.execute(inliningTarget, storage, it); |
| 682 | + if (!check.execute(inliningTarget, key)) { |
| 683 | + return 0; |
| 684 | + } |
| 685 | + } |
| 686 | + return 1; |
| 687 | + } |
| 688 | + } |
657 | 689 | }
|
0 commit comments