changeset 4433:8a3ca4adb5d8 v7.3.965

updated for version 7.3.965 Problem: Python garbage collection not working properly. Solution: Add support for garbage collection. (ZyX)
author Bram Moolenaar <bram@vim.org>
date Fri, 17 May 2013 16:24:32 +0200
parents b2f7c4f0da0f
children edfd1b971b87
files src/if_py_both.h src/version.c
diffstat 2 files changed, 116 insertions(+), 36 deletions(-) [+]
line wrap: on
line diff
--- a/src/if_py_both.h
+++ b/src/if_py_both.h
@@ -543,6 +543,8 @@ static PyTypeObject IterType;
 
 typedef PyObject *(*nextfun)(void **);
 typedef void (*destructorfun)(void *);
+typedef int (*traversefun)(void *, visitproc, void *);
+typedef int (*clearfun)(void **);
 
 /* Main purpose of this object is removing the need for do python initialization 
  * (i.e. PyType_Ready and setting type attributes) for a big bunch of objects.
@@ -554,10 +556,13 @@ typedef struct
     void *cur;
     nextfun next;
     destructorfun destruct;
+    traversefun traverse;
+    clearfun clear;
 } IterObject;
 
     static PyObject *
-IterNew(void *start, destructorfun destruct, nextfun next)
+IterNew(void *start, destructorfun destruct, nextfun next, traversefun traverse,
+	clearfun clear)
 {
     IterObject *self;
 
@@ -565,6 +570,8 @@ IterNew(void *start, destructorfun destr
     self->cur = start;
     self->next = next;
     self->destruct = destruct;
+    self->traverse = traverse;
+    self->clear = clear;
 
     return (PyObject *)(self);
 }
@@ -579,6 +586,28 @@ IterDestructor(PyObject *self)
     DESTRUCTOR_FINISH(self);
 }
 
+    static int
+IterTraverse(PyObject *self, visitproc visit, void *arg)
+{
+    IterObject *this = (IterObject *)(self);
+
+    if (this->traverse != NULL)
+	return this->traverse(this->cur, visit, arg);
+    else
+	return 0;
+}
+
+    static int
+IterClear(PyObject *self)
+{
+    IterObject *this = (IterObject *)(self);
+
+    if (this->clear != NULL)
+	return this->clear(&this->cur);
+    else
+	return 0;
+}
+
     static PyObject *
 IterNext(PyObject *self)
 {
@@ -1034,7 +1063,8 @@ ListIter(PyObject *self)
     lii->list = l;
 
     return IterNew(lii,
-	    (destructorfun) ListIterDestruct, (nextfun) ListIterNext);
+	    (destructorfun) ListIterDestruct, (nextfun) ListIterNext,
+	    NULL, NULL);
 }
 
     static int
@@ -1348,6 +1378,53 @@ typedef struct
     PyObject *fromObj;
 } OptionsObject;
 
+    static int
+dummy_check(void *arg UNUSED)
+{
+    return 0;
+}
+
+    static PyObject *
+OptionsNew(int opt_type, void *from, checkfun Check, PyObject *fromObj)
+{
+    OptionsObject	*self;
+
+    self = PyObject_NEW(OptionsObject, &OptionsType);
+    if (self == NULL)
+	return NULL;
+
+    self->opt_type = opt_type;
+    self->from = from;
+    self->Check = Check;
+    self->fromObj = fromObj;
+    if (fromObj)
+	Py_INCREF(fromObj);
+
+    return (PyObject *)(self);
+}
+
+    static void
+OptionsDestructor(PyObject *self)
+{
+    if (((OptionsObject *)(self))->fromObj)
+	Py_DECREF(((OptionsObject *)(self))->fromObj);
+    DESTRUCTOR_FINISH(self);
+}
+
+    static int
+OptionsTraverse(PyObject *self, visitproc visit, void *arg)
+{
+    Py_VISIT(((OptionsObject *)(self))->fromObj);
+    return 0;
+}
+
+    static int
+OptionsClear(PyObject *self)
+{
+    Py_CLEAR(((OptionsObject *)(self))->fromObj);
+    return 0;
+}
+
     static PyObject *
 OptionsItem(OptionsObject *this, PyObject *keyObject)
 {
@@ -1562,39 +1639,6 @@ OptionsAssItem(OptionsObject *this, PyOb
     return r;
 }
 
-    static int
-dummy_check(void *arg UNUSED)
-{
-    return 0;
-}
-
-    static PyObject *
-OptionsNew(int opt_type, void *from, checkfun Check, PyObject *fromObj)
-{
-    OptionsObject	*self;
-
-    self = PyObject_NEW(OptionsObject, &OptionsType);
-    if (self == NULL)
-	return NULL;
-
-    self->opt_type = opt_type;
-    self->from = from;
-    self->Check = Check;
-    self->fromObj = fromObj;
-    if (fromObj)
-	Py_INCREF(fromObj);
-
-    return (PyObject *)(self);
-}
-
-    static void
-OptionsDestructor(PyObject *self)
-{
-    if (((OptionsObject *)(self))->fromObj)
-	Py_DECREF(((OptionsObject *)(self))->fromObj);
-    DESTRUCTOR_FINISH(self);
-}
-
 static PyMappingMethods OptionsAsMapping = {
     (lenfunc)       NULL,
     (binaryfunc)    OptionsItem,
@@ -1843,6 +1887,19 @@ get_firstwin(TabPageObject *tabObject)
     else
 	return firstwin;
 }
+    static int
+WindowTraverse(PyObject *self, visitproc visit, void *arg)
+{
+    Py_VISIT(((PyObject *)(((WindowObject *)(self))->tabObject)));
+    return 0;
+}
+
+    static int
+WindowClear(PyObject *self)
+{
+    Py_CLEAR((((WindowObject *)(self))->tabObject));
+    return 0;
+}
 
     static PyObject *
 WindowAttr(WindowObject *this, char *name)
@@ -3193,6 +3250,20 @@ BufMapIterDestruct(PyObject *buffer)
     }
 }
 
+    static int
+BufMapIterTraverse(PyObject *buffer, visitproc visit, void *arg)
+{
+    Py_VISIT(buffer);
+    return 0;
+}
+
+    static int
+BufMapIterClear(PyObject **buffer)
+{
+    Py_CLEAR(*buffer);
+    return 0;
+}
+
     static PyObject *
 BufMapIterNext(PyObject **buffer)
 {
@@ -3228,7 +3299,8 @@ BufMapIter(PyObject *self UNUSED)
 
     buffer = BufferNew(firstbuf);
     return IterNew(buffer,
-	    (destructorfun) BufMapIterDestruct, (nextfun) BufMapIterNext);
+	    (destructorfun) BufMapIterDestruct, (nextfun) BufMapIterNext,
+	    (traversefun) BufMapIterTraverse, (clearfun) BufMapIterClear);
 }
 
 static PyMappingMethods BufMapAsMapping = {
@@ -3837,6 +3909,8 @@ init_structs(void)
     IterType.tp_iter = IterIter;
     IterType.tp_iternext = IterNext;
     IterType.tp_dealloc = IterDestructor;
+    IterType.tp_traverse = IterTraverse;
+    IterType.tp_clear = IterClear;
 
     vim_memset(&BufferType, 0, sizeof(BufferType));
     BufferType.tp_name = "vim.buffer";
@@ -3865,6 +3939,8 @@ init_structs(void)
     WindowType.tp_flags = Py_TPFLAGS_DEFAULT;
     WindowType.tp_doc = "vim Window object";
     WindowType.tp_methods = WindowMethods;
+    WindowType.tp_traverse = WindowTraverse;
+    WindowType.tp_clear = WindowClear;
 #if PY_MAJOR_VERSION >= 3
     WindowType.tp_getattro = WindowGetattro;
     WindowType.tp_setattro = WindowSetattro;
@@ -4003,6 +4079,8 @@ init_structs(void)
     OptionsType.tp_doc = "object for manipulating options";
     OptionsType.tp_as_mapping = &OptionsAsMapping;
     OptionsType.tp_dealloc = OptionsDestructor;
+    OptionsType.tp_traverse = OptionsTraverse;
+    OptionsType.tp_clear = OptionsClear;
 
 #if PY_MAJOR_VERSION >= 3
     vim_memset(&vimmodule, 0, sizeof(vimmodule));
--- a/src/version.c
+++ b/src/version.c
@@ -729,6 +729,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    965,
+/**/
     964,
 /**/
     963,