To: vim_dev@googlegroups.com Subject: Patch 7.3.965 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.3.965 Problem: Python garbage collection not working properly. Solution: Add support for garbage collection. (ZyX) Files: src/if_py_both.h *** ../vim-7.3.964/src/if_py_both.h 2013-05-17 16:18:27.000000000 +0200 --- src/if_py_both.h 2013-05-17 16:21:05.000000000 +0200 *************** *** 543,548 **** --- 543,550 ---- 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,563 **** void *cur; nextfun next; destructorfun destruct; } IterObject; static PyObject * ! IterNew(void *start, destructorfun destruct, nextfun next) { IterObject *self; --- 556,568 ---- void *cur; nextfun next; destructorfun destruct; + traversefun traverse; + clearfun clear; } IterObject; static PyObject * ! IterNew(void *start, destructorfun destruct, nextfun next, traversefun traverse, ! clearfun clear) { IterObject *self; *************** *** 565,570 **** --- 570,577 ---- self->cur = start; self->next = next; self->destruct = destruct; + self->traverse = traverse; + self->clear = clear; return (PyObject *)(self); } *************** *** 579,584 **** --- 586,613 ---- 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,1040 **** lii->list = l; return IterNew(lii, ! (destructorfun) ListIterDestruct, (nextfun) ListIterNext); } static int --- 1063,1070 ---- lii->list = l; return IterNew(lii, ! (destructorfun) ListIterDestruct, (nextfun) ListIterNext, ! NULL, NULL); } static int *************** *** 1348,1353 **** --- 1378,1430 ---- 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,1600 **** 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, --- 1639,1644 ---- *************** *** 1843,1848 **** --- 1887,1905 ---- 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,3198 **** --- 3250,3269 ---- } } + 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,3234 **** buffer = BufferNew(firstbuf); return IterNew(buffer, ! (destructorfun) BufMapIterDestruct, (nextfun) BufMapIterNext); } static PyMappingMethods BufMapAsMapping = { --- 3299,3306 ---- buffer = BufferNew(firstbuf); return IterNew(buffer, ! (destructorfun) BufMapIterDestruct, (nextfun) BufMapIterNext, ! (traversefun) BufMapIterTraverse, (clearfun) BufMapIterClear); } static PyMappingMethods BufMapAsMapping = { *************** *** 3837,3842 **** --- 3909,3916 ---- 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,3870 **** --- 3939,3946 ---- 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,4008 **** --- 4079,4086 ---- 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)); *** ../vim-7.3.964/src/version.c 2013-05-17 16:18:27.000000000 +0200 --- src/version.c 2013-05-17 16:21:24.000000000 +0200 *************** *** 730,731 **** --- 730,733 ---- { /* Add new patch number below this line */ + /**/ + 965, /**/ -- ARTHUR: Charge! [They all charge with swords drawn towards the RABBIT. A tremendous twenty second fight with Peckinpahish shots and borrowing heavily also on the Kung Fu and karate-type films ensues, in which some four KNIGHTS are comprehensively killed.] ARTHUR: Run away! Run away! "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///