Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fc8bd70

Browse files
committed
Untrack classes with managed dicts in dealloc; Fix compat function return val
1 parent ca0202f commit fc8bd70

2 files changed

Lines changed: 10 additions & 5 deletions

File tree

mypyc/codegen/emitclass.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -945,16 +945,20 @@ def generate_dealloc_for_class(
945945
emitter.emit_line("if (res < 0) {")
946946
emitter.emit_line("goto done;")
947947
emitter.emit_line("}")
948+
if not cl.is_acyclic:
949+
emitter.emit_line("PyObject_GC_UnTrack(self);")
948950
if cl.builtin_base:
951+
emitter.emit_line(f"{clear_func_name}(self);")
949952
# For native subclasses of builtins such as dict, the base deallocator
950953
# is responsible for tearing down base-owned storage and freeing memory.
951-
emitter.emit_line(f"{clear_func_name}(self);")
952-
emitter.emit_base_tp_function_call(cl, "tp_dealloc", "(PyObject *)self")
954+
# Re-track self if base is GC-aware to match cpython's subtype_dealloc.
955+
base = f"{emitter.type_struct_name(cl)}->tp_base"
956+
base_arg = "(PyObject *)self"
957+
emitter.emit_line(f"if (PyType_IS_GC({base})) PyObject_GC_Track({base_arg});")
958+
emitter.emit_base_tp_function_call(cl, "tp_dealloc", base_arg)
953959
emitter.emit_line("done: ;")
954960
emitter.emit_line("}")
955961
return
956-
if not cl.is_acyclic:
957-
emitter.emit_line("PyObject_GC_UnTrack(self);")
958962
if cl.reuse_freed_instance:
959963
emit_reuse_dealloc(cl, emitter)
960964
# The trashcan is needed to handle deep recursive deallocations

mypyc/lib-rt/pythoncapi_compat.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -922,7 +922,8 @@ PyObject_VisitManagedDict(PyObject *obj, visitproc visit, void *arg)
922922
{
923923
PyObject **dict = _PyObject_GetDictPtr(obj);
924924
if (dict == NULL || *dict == NULL) {
925-
return -1;
925+
// Nothing to do.
926+
return 0;
926927
}
927928
Py_VISIT(*dict);
928929
return 0;

0 commit comments

Comments
 (0)