|
83 | 83 | import com.oracle.graal.python.builtins.objects.cext.UnicodeObjectNodes.UnicodeAsWideCharNode;
|
84 | 84 | import com.oracle.graal.python.builtins.objects.common.DynamicObjectStorage;
|
85 | 85 | import com.oracle.graal.python.builtins.objects.common.DynamicObjectStorage.PythonObjectDictStorage;
|
| 86 | +import com.oracle.graal.python.builtins.objects.common.DynamicObjectStorage.PythonObjectHybridDictStorage; |
86 | 87 | import com.oracle.graal.python.builtins.objects.common.HashingCollectionNodes;
|
87 | 88 | import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes;
|
88 | 89 | import com.oracle.graal.python.builtins.objects.common.PHashingCollection;
|
@@ -305,10 +306,10 @@ Object doTpName(PythonManagedClass object, @SuppressWarnings("unused") String ke
|
305 | 306 |
|
306 | 307 | @Specialization(guards = "eq(TP_DOC, key)")
|
307 | 308 | Object doTpDoc(PythonManagedClass object, @SuppressWarnings("unused") String key,
|
308 |
| - @Cached("createForceType()") ReadAttributeFromObjectNode readAttrNode, |
| 309 | + @Cached PInteropGetAttributeNode getAttrNode, |
309 | 310 | @Shared("getNativeNullNode") @Cached GetNativeNullNode getNativeNullNode) {
|
310 | 311 | // return a C string wrapper that really allocates 'char*' on TO_NATIVE
|
311 |
| - Object docObj = readAttrNode.execute(object, SpecialAttributeNames.__DOC__); |
| 312 | + Object docObj = getAttrNode.execute(object, SpecialAttributeNames.__DOC__); |
312 | 313 | if (docObj instanceof String) {
|
313 | 314 | return new CStringWrapper((String) docObj);
|
314 | 315 | } else if (docObj instanceof PString) {
|
@@ -513,9 +514,17 @@ Object doTpRepr(PythonManagedClass object, @SuppressWarnings("unused") String ke
|
513 | 514 |
|
514 | 515 | @Specialization(guards = "eq(TP_DICT, key)")
|
515 | 516 | Object doTpDict(PythonManagedClass object, @SuppressWarnings("unused") String key,
|
516 |
| - @Cached("createForceType()") ReadAttributeFromObjectNode readAttrNode, |
| 517 | + @Cached PythonObjectFactory factory, |
517 | 518 | @Shared("toSulongNode") @Cached CExtNodes.ToSulongNode toSulongNode) {
|
518 |
| - return toSulongNode.execute(readAttrNode.execute(object, __DICT__)); |
| 519 | + // TODO(fa): we could cache the dict instance on the class' native wrapper |
| 520 | + PHashingCollection dict = object.getDict(); |
| 521 | + if (dict != null && dict.getDictStorage() instanceof PythonObjectHybridDictStorage) { |
| 522 | + // reuse the existing and modifiable storage |
| 523 | + return toSulongNode.execute(factory.createDict(dict.getDictStorage())); |
| 524 | + } |
| 525 | + PythonObjectHybridDictStorage storage = new PythonObjectHybridDictStorage(object.getStorage()); |
| 526 | + object.setDict(factory.createMappingproxy(storage)); |
| 527 | + return toSulongNode.execute(factory.createDict(storage)); |
519 | 528 | }
|
520 | 529 |
|
521 | 530 | @Specialization(guards = "eq(TP_TRAVERSE, key) || eq(TP_CLEAR, key)")
|
|
0 commit comments