Mercurial > vim
diff src/if_py_both.h @ 4500:47e6dec5ce3c v7.3.998
updated for version 7.3.998
Problem: Python: garbage collection issues.
Solution: Fix the GC issues: Use proper DESTRUCTOR_FINISH: avoids negative
refcounts, use PyObject_GC_* for objects with tp_traverse and
tp_clear, add RangeTraverse and RangeClear, use Py_XDECREF in some
places. (ZyX)
author | Bram Moolenaar <bram@vim.org> |
---|---|
date | Tue, 21 May 2013 20:51:59 +0200 |
parents | ef02f32d8e53 |
children | b498224f5b41 |
line wrap: on
line diff
--- a/src/if_py_both.h +++ b/src/if_py_both.h @@ -461,7 +461,7 @@ VimToPython(typval_T *our_tv, int depth, } static PyObject * -VimEval(PyObject *self UNUSED, PyObject *args UNUSED) +VimEval(PyObject *self UNUSED, PyObject *args) { char *expr; typval_T *our_tv; @@ -602,7 +602,7 @@ IterNew(void *start, destructorfun destr { IterObject *self; - self = PyObject_NEW(IterObject, &IterType); + self = PyObject_GC_New(IterObject, &IterType); self->cur = start; self->next = next; self->destruct = destruct; @@ -615,9 +615,9 @@ IterNew(void *start, destructorfun destr static void IterDestructor(IterObject *self) { + PyObject_GC_UnTrack((void *)(self)); self->destruct(self->cur); - - DESTRUCTOR_FINISH(self); + PyObject_GC_Del((void *)(self)); } static int @@ -1414,7 +1414,7 @@ OptionsNew(int opt_type, void *from, che { OptionsObject *self; - self = PyObject_NEW(OptionsObject, &OptionsType); + self = PyObject_GC_New(OptionsObject, &OptionsType); if (self == NULL) return NULL; @@ -1431,9 +1431,9 @@ OptionsNew(int opt_type, void *from, che static void OptionsDestructor(OptionsObject *self) { - if (self->fromObj) - Py_DECREF(self->fromObj); - DESTRUCTOR_FINISH(self); + PyObject_GC_UnTrack((void *)(self)); + Py_XDECREF(self->fromObj); + PyObject_GC_Del((void *)(self)); } static int @@ -1869,7 +1869,7 @@ WindowNew(win_T *win, tabpage_T *tab) } else { - self = PyObject_NEW(WindowObject, &WindowType); + self = PyObject_GC_New(WindowObject, &WindowType); if (self == NULL) return NULL; self->win = win; @@ -1884,12 +1884,25 @@ WindowNew(win_T *win, tabpage_T *tab) static void WindowDestructor(WindowObject *self) { + PyObject_GC_UnTrack((void *)(self)); if (self->win && self->win != INVALID_WINDOW_VALUE) WIN_PYTHON_REF(self->win) = NULL; - - Py_DECREF(((PyObject *)(self->tabObject))); - - DESTRUCTOR_FINISH(self); + Py_XDECREF(((PyObject *)(self->tabObject))); + PyObject_GC_Del((void *)(self)); +} + + static int +WindowTraverse(WindowObject *self, visitproc visit, void *arg) +{ + Py_VISIT(((PyObject *)(self->tabObject))); + return 0; +} + + static int +WindowClear(WindowObject *self) +{ + Py_CLEAR(self->tabObject); + return 0; } static win_T * @@ -1909,19 +1922,6 @@ get_firstwin(TabPageObject *tabObject) else return firstwin; } - static int -WindowTraverse(WindowObject *self, visitproc visit, void *arg) -{ - Py_VISIT(((PyObject *)(self->tabObject))); - return 0; -} - - static int -WindowClear(WindowObject *self) -{ - Py_CLEAR(self->tabObject); - return 0; -} static PyObject * WindowAttr(WindowObject *self, char *name) @@ -2917,7 +2917,7 @@ RangeNew(buf_T *buf, PyInt start, PyInt { BufferObject *bufr; RangeObject *self; - self = PyObject_NEW(RangeObject, &RangeType); + self = PyObject_GC_New(RangeObject, &RangeType); if (self == NULL) return NULL; @@ -2939,8 +2939,23 @@ RangeNew(buf_T *buf, PyInt start, PyInt static void RangeDestructor(RangeObject *self) { + PyObject_GC_UnTrack((void *)(self)); Py_XDECREF(self->buf); - DESTRUCTOR_FINISH(self); + PyObject_GC_Del((void *)(self)); +} + + static int +RangeTraverse(RangeObject *self, visitproc visit, void *arg) +{ + Py_VISIT(((PyObject *)(self->buf))); + return 0; +} + + static int +RangeClear(RangeObject *self) +{ + Py_CLEAR(self->buf); + return 0; } static PyInt @@ -3267,14 +3282,16 @@ BufMapIterDestruct(PyObject *buffer) static int BufMapIterTraverse(PyObject *buffer, visitproc visit, void *arg) { - Py_VISIT(buffer); + if (buffer) + Py_VISIT(buffer); return 0; } static int BufMapIterClear(PyObject **buffer) { - Py_CLEAR(*buffer); + if (*buffer) + Py_CLEAR(*buffer); return 0; } @@ -4144,6 +4161,8 @@ init_structs(void) RangeType.tp_flags = Py_TPFLAGS_DEFAULT; RangeType.tp_doc = "vim Range object"; RangeType.tp_methods = RangeMethods; + RangeType.tp_traverse = (traverseproc)RangeTraverse; + RangeType.tp_clear = (inquiry)RangeClear; #if PY_MAJOR_VERSION >= 3 RangeType.tp_getattro = (getattrofunc)RangeGetattro; RangeType.tp_alloc = call_PyType_GenericAlloc;