|
55 | 55 | import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PY_UNICODE_PTR;
|
56 | 56 | import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.Pointer;
|
57 | 57 | import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObject;
|
58 |
| -import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObjectBorrowed; |
59 | 58 | import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObjectTransfer;
|
60 | 59 | import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.Py_ssize_t;
|
61 | 60 | import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.SIZE_T;
|
|
85 | 84 | import com.oracle.graal.python.builtins.modules.BuiltinFunctions.ChrNode;
|
86 | 85 | import com.oracle.graal.python.builtins.modules.CodecsModuleBuiltins;
|
87 | 86 | import com.oracle.graal.python.builtins.modules.CodecsModuleBuiltins.CodecsEncodeNode;
|
88 |
| -import com.oracle.graal.python.builtins.modules.SysModuleBuiltins.InternNode; |
89 | 87 | import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApi5BuiltinNode;
|
90 | 88 | import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApi6BuiltinNode;
|
91 | 89 | import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBinaryBuiltinNode;
|
|
103 | 101 | import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.UnicodeFromFormatNode;
|
104 | 102 | import com.oracle.graal.python.builtins.objects.cext.capi.PySequenceArrayWrapper;
|
105 | 103 | import com.oracle.graal.python.builtins.objects.cext.capi.UnicodeObjectNodes.UnicodeAsWideCharNode;
|
106 |
| -import com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor; |
107 | 104 | import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes;
|
108 | 105 | import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.Charsets;
|
109 | 106 | import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.EncodeNativeStringNode;
|
110 | 107 | import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.GetByteArrayNode;
|
111 | 108 | import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.UnicodeFromWcharNode;
|
| 109 | +import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageGetItem; |
| 110 | +import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageSetItem; |
| 111 | +import com.oracle.graal.python.builtins.objects.dict.PDict; |
112 | 112 | import com.oracle.graal.python.builtins.objects.ints.PInt;
|
113 | 113 | import com.oracle.graal.python.builtins.objects.memoryview.PMemoryView;
|
114 | 114 | import com.oracle.graal.python.builtins.objects.str.NativeCharSequence;
|
|
123 | 123 | import com.oracle.graal.python.builtins.objects.str.StringBuiltins.RFindNode;
|
124 | 124 | import com.oracle.graal.python.builtins.objects.str.StringBuiltins.ReplaceNode;
|
125 | 125 | import com.oracle.graal.python.builtins.objects.str.StringBuiltins.StartsWithNode;
|
| 126 | +import com.oracle.graal.python.builtins.objects.str.StringNodes; |
126 | 127 | import com.oracle.graal.python.lib.PyObjectIsTrueNode;
|
127 | 128 | import com.oracle.graal.python.lib.PyObjectLookupAttr;
|
128 | 129 | import com.oracle.graal.python.lib.PySliceNew;
|
129 | 130 | import com.oracle.graal.python.nodes.ErrorMessages;
|
130 | 131 | import com.oracle.graal.python.nodes.PGuards;
|
131 | 132 | import com.oracle.graal.python.nodes.PRaiseNode;
|
132 | 133 | import com.oracle.graal.python.nodes.StringLiterals;
|
| 134 | +import com.oracle.graal.python.nodes.attributes.ReadAttributeFromDynamicObjectNode; |
133 | 135 | import com.oracle.graal.python.nodes.call.CallNode;
|
134 | 136 | import com.oracle.graal.python.nodes.classes.IsSubtypeNode;
|
| 137 | +import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; |
135 | 138 | import com.oracle.graal.python.nodes.object.GetClassNode;
|
136 | 139 | import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes;
|
137 | 140 | import com.oracle.graal.python.nodes.truffle.PythonTypes;
|
@@ -278,26 +281,51 @@ protected boolean isStringSubtype(Object obj, GetClassNode getClassNode, IsSubty
|
278 | 281 | }
|
279 | 282 | }
|
280 | 283 |
|
281 |
| - @CApiBuiltin(ret = PyObjectBorrowed, args = {ArgDescriptor.PyObject}, call = Ignored) |
282 |
| - abstract static class PyTruffleUnicode_InternInPlace extends CApiUnaryBuiltinNode { |
283 |
| - @Specialization(guards = {"!isTruffleString(obj)", "isStringSubtype(obj, getClassNode, isSubtypeNode)"}) |
284 |
| - Object intern(Object obj, |
285 |
| - @Cached InternNode internNode, |
286 |
| - @SuppressWarnings("unused") @Cached GetClassNode getClassNode, |
287 |
| - @SuppressWarnings("unused") @Cached IsSubtypeNode isSubtypeNode) { |
288 |
| - return internNode.execute(null, obj); |
| 284 | + @CApiBuiltin(ret = PyObject, args = {PyObject}, call = Ignored) |
| 285 | + abstract static class PyTruffleUnicode_LookupAndIntern extends CApiUnaryBuiltinNode { |
| 286 | + @Specialization |
| 287 | + Object withTS(TruffleString str, |
| 288 | + @Shared @Cached StringNodes.InternStringNode internNode, |
| 289 | + @Shared @Cached HashingStorageGetItem getItem, |
| 290 | + @Shared @Cached HashingStorageSetItem setItem) { |
| 291 | + PDict dict = getCApiContext().getInternedUnicode(); |
| 292 | + if (dict == null) { |
| 293 | + dict = factory().createDict(); |
| 294 | + getCApiContext().setInternedUnicode(dict); |
| 295 | + } |
| 296 | + Object interned = getItem.execute(dict.getDictStorage(), str); |
| 297 | + if (interned == null) { |
| 298 | + interned = internNode.execute(str); |
| 299 | + dict.setDictStorage(setItem.execute(dict.getDictStorage(), str, interned)); |
| 300 | + } |
| 301 | + return interned; |
289 | 302 | }
|
290 | 303 |
|
291 |
| - @Specialization(guards = {"!isTruffleString(obj)", "!isStringSubtype(obj, getClassNode, isSubtypeNode)"}) |
292 |
| - Object intern(@SuppressWarnings("unused") Object obj, |
293 |
| - @SuppressWarnings("unused") @Cached GetClassNode getClassNode, |
294 |
| - @SuppressWarnings("unused") @Cached IsSubtypeNode isSubtypeNode) { |
295 |
| - assert false; |
296 |
| - return PNone.NONE; |
| 304 | + @Specialization |
| 305 | + Object withPString(PString str, |
| 306 | + @Bind("this") Node inliningTarget, |
| 307 | + @Cached IsBuiltinObjectProfile isBuiltinClassProfile, |
| 308 | + @Cached ReadAttributeFromDynamicObjectNode readNode, |
| 309 | + @Shared @Cached StringNodes.InternStringNode internNode, |
| 310 | + @Shared @Cached HashingStorageGetItem getItem, |
| 311 | + @Shared @Cached HashingStorageSetItem setItem) { |
| 312 | + if (!isBuiltinClassProfile.profileObject(inliningTarget, str, PythonBuiltinClassType.PString)) { |
| 313 | + return getNativeNull(); |
| 314 | + } |
| 315 | + boolean isInterned = readNode.execute(str, PString.INTERNED) != PNone.NO_VALUE; |
| 316 | + if (isInterned) { |
| 317 | + return str; |
| 318 | + } |
| 319 | + return withTS(str.getValueUncached(), internNode, getItem, setItem); |
297 | 320 | }
|
298 | 321 |
|
299 |
| - protected boolean isStringSubtype(Object obj, GetClassNode getClassNode, IsSubtypeNode isSubtypeNode) { |
300 |
| - return isSubtypeNode.execute(getClassNode.execute(obj), PythonBuiltinClassType.PString); |
| 322 | + @Fallback |
| 323 | + Object nil(@SuppressWarnings("unused") Object obj) { |
| 324 | + /* |
| 325 | + * If it's a subclass, we don't really know what putting it in the interned dict might |
| 326 | + * do. |
| 327 | + */ |
| 328 | + return getNativeNull(); |
301 | 329 | }
|
302 | 330 | }
|
303 | 331 |
|
|
0 commit comments