Skip to content

Commit 1874dfa

Browse files
committed
Fix clearing storage of __dict__
1 parent c94f64d commit 1874dfa

File tree

1 file changed

+26
-3
lines changed

1 file changed

+26
-3
lines changed

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

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,10 @@
4848
import com.oracle.graal.python.builtins.objects.PNone;
4949
import com.oracle.graal.python.builtins.objects.common.HashingStorageLibrary.ForEachNode;
5050
import com.oracle.graal.python.builtins.objects.common.HashingStorageLibrary.HashingStorageIterable;
51+
import com.oracle.graal.python.builtins.objects.dict.PDict;
5152
import com.oracle.graal.python.builtins.objects.function.PArguments;
5253
import com.oracle.graal.python.builtins.objects.function.PArguments.ThreadState;
54+
import com.oracle.graal.python.builtins.objects.object.PythonObject;
5355
import com.oracle.graal.python.builtins.objects.str.PString;
5456
import com.oracle.graal.python.lib.PyObjectHashNode;
5557
import com.oracle.graal.python.lib.PyObjectRichCompareBool;
@@ -394,9 +396,30 @@ private static Object runNode(DynamicObjectStorage self, Object key, Object acc,
394396
}
395397

396398
@ExportMessage
397-
public HashingStorage clear(@Shared("dylib") @CachedLibrary(limit = "3") DynamicObjectLibrary dylib) {
398-
dylib.resetShape(store, PythonLanguage.get(dylib).getEmptyShape());
399-
return this;
399+
@ImportStatic(PGuards.class)
400+
static class Clear {
401+
@Specialization(guards = "!isPythonObject(receiver.getStore())")
402+
static HashingStorage clearPlain(DynamicObjectStorage receiver,
403+
@Shared("dylib") @CachedLibrary(limit = "3") DynamicObjectLibrary dylib) {
404+
dylib.resetShape(receiver.getStore(), PythonLanguage.get(dylib).getEmptyShape());
405+
return receiver;
406+
}
407+
408+
@Specialization(guards = "isPythonObject(receiver.getStore())")
409+
static HashingStorage clearObjectBacked(DynamicObjectStorage receiver,
410+
@Shared("dylib") @CachedLibrary(limit = "3") DynamicObjectLibrary dylib) {
411+
/*
412+
* We cannot use resetShape as that would lose hidden keys, such as CLASS or OBJ_ID.
413+
* Construct a new storage instead and set it as the object's __dict__'s storage.
414+
*/
415+
DynamicObjectStorage newStorage = new DynamicObjectStorage(new Store(PythonLanguage.get(dylib).getEmptyShape()));
416+
PythonObject owner = (PythonObject) receiver.getStore();
417+
PDict dict = (PDict) dylib.getOrDefault(owner, PythonObject.DICT, null);
418+
if (dict != null && dict.getDictStorage() == receiver) {
419+
dict.setDictStorage(newStorage);
420+
}
421+
return newStorage;
422+
}
400423
}
401424

402425
@ExportMessage

0 commit comments

Comments
 (0)