Karsten Hopp 98f576
To: vim_dev@googlegroups.com
Karsten Hopp 98f576
Subject: Patch 7.3.965
Karsten Hopp 98f576
Fcc: outbox
Karsten Hopp 98f576
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp 98f576
Mime-Version: 1.0
Karsten Hopp 98f576
Content-Type: text/plain; charset=UTF-8
Karsten Hopp 98f576
Content-Transfer-Encoding: 8bit
Karsten Hopp 98f576
------------
Karsten Hopp 98f576
Karsten Hopp 98f576
Patch 7.3.965
Karsten Hopp 98f576
Problem:    Python garbage collection not working properly.
Karsten Hopp 98f576
Solution:   Add support for garbage collection. (ZyX)
Karsten Hopp 98f576
Files:	    src/if_py_both.h
Karsten Hopp 98f576
Karsten Hopp 98f576
Karsten Hopp 98f576
*** ../vim-7.3.964/src/if_py_both.h	2013-05-17 16:18:27.000000000 +0200
Karsten Hopp 98f576
--- src/if_py_both.h	2013-05-17 16:21:05.000000000 +0200
Karsten Hopp 98f576
***************
Karsten Hopp 98f576
*** 543,548 ****
Karsten Hopp 98f576
--- 543,550 ----
Karsten Hopp 98f576
  
Karsten Hopp 98f576
  typedef PyObject *(*nextfun)(void **);
Karsten Hopp 98f576
  typedef void (*destructorfun)(void *);
Karsten Hopp 98f576
+ typedef int (*traversefun)(void *, visitproc, void *);
Karsten Hopp 98f576
+ typedef int (*clearfun)(void **);
Karsten Hopp 98f576
  
Karsten Hopp 98f576
  /* Main purpose of this object is removing the need for do python initialization 
Karsten Hopp 98f576
   * (i.e. PyType_Ready and setting type attributes) for a big bunch of objects.
Karsten Hopp 98f576
***************
Karsten Hopp 98f576
*** 554,563 ****
Karsten Hopp 98f576
      void *cur;
Karsten Hopp 98f576
      nextfun next;
Karsten Hopp 98f576
      destructorfun destruct;
Karsten Hopp 98f576
  } IterObject;
Karsten Hopp 98f576
  
Karsten Hopp 98f576
      static PyObject *
Karsten Hopp 98f576
! IterNew(void *start, destructorfun destruct, nextfun next)
Karsten Hopp 98f576
  {
Karsten Hopp 98f576
      IterObject *self;
Karsten Hopp 98f576
  
Karsten Hopp 98f576
--- 556,568 ----
Karsten Hopp 98f576
      void *cur;
Karsten Hopp 98f576
      nextfun next;
Karsten Hopp 98f576
      destructorfun destruct;
Karsten Hopp 98f576
+     traversefun traverse;
Karsten Hopp 98f576
+     clearfun clear;
Karsten Hopp 98f576
  } IterObject;
Karsten Hopp 98f576
  
Karsten Hopp 98f576
      static PyObject *
Karsten Hopp 98f576
! IterNew(void *start, destructorfun destruct, nextfun next, traversefun traverse,
Karsten Hopp 98f576
! 	clearfun clear)
Karsten Hopp 98f576
  {
Karsten Hopp 98f576
      IterObject *self;
Karsten Hopp 98f576
  
Karsten Hopp 98f576
***************
Karsten Hopp 98f576
*** 565,570 ****
Karsten Hopp 98f576
--- 570,577 ----
Karsten Hopp 98f576
      self->cur = start;
Karsten Hopp 98f576
      self->next = next;
Karsten Hopp 98f576
      self->destruct = destruct;
Karsten Hopp 98f576
+     self->traverse = traverse;
Karsten Hopp 98f576
+     self->clear = clear;
Karsten Hopp 98f576
  
Karsten Hopp 98f576
      return (PyObject *)(self);
Karsten Hopp 98f576
  }
Karsten Hopp 98f576
***************
Karsten Hopp 98f576
*** 579,584 ****
Karsten Hopp 98f576
--- 586,613 ----
Karsten Hopp 98f576
      DESTRUCTOR_FINISH(self);
Karsten Hopp 98f576
  }
Karsten Hopp 98f576
  
Karsten Hopp 98f576
+     static int
Karsten Hopp 98f576
+ IterTraverse(PyObject *self, visitproc visit, void *arg)
Karsten Hopp 98f576
+ {
Karsten Hopp 98f576
+     IterObject *this = (IterObject *)(self);
Karsten Hopp 98f576
+ 
Karsten Hopp 98f576
+     if (this->traverse != NULL)
Karsten Hopp 98f576
+ 	return this->traverse(this->cur, visit, arg);
Karsten Hopp 98f576
+     else
Karsten Hopp 98f576
+ 	return 0;
Karsten Hopp 98f576
+ }
Karsten Hopp 98f576
+ 
Karsten Hopp 98f576
+     static int
Karsten Hopp 98f576
+ IterClear(PyObject *self)
Karsten Hopp 98f576
+ {
Karsten Hopp 98f576
+     IterObject *this = (IterObject *)(self);
Karsten Hopp 98f576
+ 
Karsten Hopp 98f576
+     if (this->clear != NULL)
Karsten Hopp 98f576
+ 	return this->clear(&this->cur);
Karsten Hopp 98f576
+     else
Karsten Hopp 98f576
+ 	return 0;
Karsten Hopp 98f576
+ }
Karsten Hopp 98f576
+ 
Karsten Hopp 98f576
      static PyObject *
Karsten Hopp 98f576
  IterNext(PyObject *self)
Karsten Hopp 98f576
  {
Karsten Hopp 98f576
***************
Karsten Hopp 98f576
*** 1034,1040 ****
Karsten Hopp 98f576
      lii->list = l;
Karsten Hopp 98f576
  
Karsten Hopp 98f576
      return IterNew(lii,
Karsten Hopp 98f576
! 	    (destructorfun) ListIterDestruct, (nextfun) ListIterNext);
Karsten Hopp 98f576
  }
Karsten Hopp 98f576
  
Karsten Hopp 98f576
      static int
Karsten Hopp 98f576
--- 1063,1070 ----
Karsten Hopp 98f576
      lii->list = l;
Karsten Hopp 98f576
  
Karsten Hopp 98f576
      return IterNew(lii,
Karsten Hopp 98f576
! 	    (destructorfun) ListIterDestruct, (nextfun) ListIterNext,
Karsten Hopp 98f576
! 	    NULL, NULL);
Karsten Hopp 98f576
  }
Karsten Hopp 98f576
  
Karsten Hopp 98f576
      static int
Karsten Hopp 98f576
***************
Karsten Hopp 98f576
*** 1348,1353 ****
Karsten Hopp 98f576
--- 1378,1430 ----
Karsten Hopp 98f576
      PyObject *fromObj;
Karsten Hopp 98f576
  } OptionsObject;
Karsten Hopp 98f576
  
Karsten Hopp 98f576
+     static int
Karsten Hopp 98f576
+ dummy_check(void *arg UNUSED)
Karsten Hopp 98f576
+ {
Karsten Hopp 98f576
+     return 0;
Karsten Hopp 98f576
+ }
Karsten Hopp 98f576
+ 
Karsten Hopp 98f576
+     static PyObject *
Karsten Hopp 98f576
+ OptionsNew(int opt_type, void *from, checkfun Check, PyObject *fromObj)
Karsten Hopp 98f576
+ {
Karsten Hopp 98f576
+     OptionsObject	*self;
Karsten Hopp 98f576
+ 
Karsten Hopp 98f576
+     self = PyObject_NEW(OptionsObject, &OptionsType);
Karsten Hopp 98f576
+     if (self == NULL)
Karsten Hopp 98f576
+ 	return NULL;
Karsten Hopp 98f576
+ 
Karsten Hopp 98f576
+     self->opt_type = opt_type;
Karsten Hopp 98f576
+     self->from = from;
Karsten Hopp 98f576
+     self->Check = Check;
Karsten Hopp 98f576
+     self->fromObj = fromObj;
Karsten Hopp 98f576
+     if (fromObj)
Karsten Hopp 98f576
+ 	Py_INCREF(fromObj);
Karsten Hopp 98f576
+ 
Karsten Hopp 98f576
+     return (PyObject *)(self);
Karsten Hopp 98f576
+ }
Karsten Hopp 98f576
+ 
Karsten Hopp 98f576
+     static void
Karsten Hopp 98f576
+ OptionsDestructor(PyObject *self)
Karsten Hopp 98f576
+ {
Karsten Hopp 98f576
+     if (((OptionsObject *)(self))->fromObj)
Karsten Hopp 98f576
+ 	Py_DECREF(((OptionsObject *)(self))->fromObj);
Karsten Hopp 98f576
+     DESTRUCTOR_FINISH(self);
Karsten Hopp 98f576
+ }
Karsten Hopp 98f576
+ 
Karsten Hopp 98f576
+     static int
Karsten Hopp 98f576
+ OptionsTraverse(PyObject *self, visitproc visit, void *arg)
Karsten Hopp 98f576
+ {
Karsten Hopp 98f576
+     Py_VISIT(((OptionsObject *)(self))->fromObj);
Karsten Hopp 98f576
+     return 0;
Karsten Hopp 98f576
+ }
Karsten Hopp 98f576
+ 
Karsten Hopp 98f576
+     static int
Karsten Hopp 98f576
+ OptionsClear(PyObject *self)
Karsten Hopp 98f576
+ {
Karsten Hopp 98f576
+     Py_CLEAR(((OptionsObject *)(self))->fromObj);
Karsten Hopp 98f576
+     return 0;
Karsten Hopp 98f576
+ }
Karsten Hopp 98f576
+ 
Karsten Hopp 98f576
      static PyObject *
Karsten Hopp 98f576
  OptionsItem(OptionsObject *this, PyObject *keyObject)
Karsten Hopp 98f576
  {
Karsten Hopp 98f576
***************
Karsten Hopp 98f576
*** 1562,1600 ****
Karsten Hopp 98f576
      return r;
Karsten Hopp 98f576
  }
Karsten Hopp 98f576
  
Karsten Hopp 98f576
-     static int
Karsten Hopp 98f576
- dummy_check(void *arg UNUSED)
Karsten Hopp 98f576
- {
Karsten Hopp 98f576
-     return 0;
Karsten Hopp 98f576
- }
Karsten Hopp 98f576
- 
Karsten Hopp 98f576
-     static PyObject *
Karsten Hopp 98f576
- OptionsNew(int opt_type, void *from, checkfun Check, PyObject *fromObj)
Karsten Hopp 98f576
- {
Karsten Hopp 98f576
-     OptionsObject	*self;
Karsten Hopp 98f576
- 
Karsten Hopp 98f576
-     self = PyObject_NEW(OptionsObject, &OptionsType);
Karsten Hopp 98f576
-     if (self == NULL)
Karsten Hopp 98f576
- 	return NULL;
Karsten Hopp 98f576
- 
Karsten Hopp 98f576
-     self->opt_type = opt_type;
Karsten Hopp 98f576
-     self->from = from;
Karsten Hopp 98f576
-     self->Check = Check;
Karsten Hopp 98f576
-     self->fromObj = fromObj;
Karsten Hopp 98f576
-     if (fromObj)
Karsten Hopp 98f576
- 	Py_INCREF(fromObj);
Karsten Hopp 98f576
- 
Karsten Hopp 98f576
-     return (PyObject *)(self);
Karsten Hopp 98f576
- }
Karsten Hopp 98f576
- 
Karsten Hopp 98f576
-     static void
Karsten Hopp 98f576
- OptionsDestructor(PyObject *self)
Karsten Hopp 98f576
- {
Karsten Hopp 98f576
-     if (((OptionsObject *)(self))->fromObj)
Karsten Hopp 98f576
- 	Py_DECREF(((OptionsObject *)(self))->fromObj);
Karsten Hopp 98f576
-     DESTRUCTOR_FINISH(self);
Karsten Hopp 98f576
- }
Karsten Hopp 98f576
- 
Karsten Hopp 98f576
  static PyMappingMethods OptionsAsMapping = {
Karsten Hopp 98f576
      (lenfunc)       NULL,
Karsten Hopp 98f576
      (binaryfunc)    OptionsItem,
Karsten Hopp 98f576
--- 1639,1644 ----
Karsten Hopp 98f576
***************
Karsten Hopp 98f576
*** 1843,1848 ****
Karsten Hopp 98f576
--- 1887,1905 ----
Karsten Hopp 98f576
      else
Karsten Hopp 98f576
  	return firstwin;
Karsten Hopp 98f576
  }
Karsten Hopp 98f576
+     static int
Karsten Hopp 98f576
+ WindowTraverse(PyObject *self, visitproc visit, void *arg)
Karsten Hopp 98f576
+ {
Karsten Hopp 98f576
+     Py_VISIT(((PyObject *)(((WindowObject *)(self))->tabObject)));
Karsten Hopp 98f576
+     return 0;
Karsten Hopp 98f576
+ }
Karsten Hopp 98f576
+ 
Karsten Hopp 98f576
+     static int
Karsten Hopp 98f576
+ WindowClear(PyObject *self)
Karsten Hopp 98f576
+ {
Karsten Hopp 98f576
+     Py_CLEAR((((WindowObject *)(self))->tabObject));
Karsten Hopp 98f576
+     return 0;
Karsten Hopp 98f576
+ }
Karsten Hopp 98f576
  
Karsten Hopp 98f576
      static PyObject *
Karsten Hopp 98f576
  WindowAttr(WindowObject *this, char *name)
Karsten Hopp 98f576
***************
Karsten Hopp 98f576
*** 3193,3198 ****
Karsten Hopp 98f576
--- 3250,3269 ----
Karsten Hopp 98f576
      }
Karsten Hopp 98f576
  }
Karsten Hopp 98f576
  
Karsten Hopp 98f576
+     static int
Karsten Hopp 98f576
+ BufMapIterTraverse(PyObject *buffer, visitproc visit, void *arg)
Karsten Hopp 98f576
+ {
Karsten Hopp 98f576
+     Py_VISIT(buffer);
Karsten Hopp 98f576
+     return 0;
Karsten Hopp 98f576
+ }
Karsten Hopp 98f576
+ 
Karsten Hopp 98f576
+     static int
Karsten Hopp 98f576
+ BufMapIterClear(PyObject **buffer)
Karsten Hopp 98f576
+ {
Karsten Hopp 98f576
+     Py_CLEAR(*buffer);
Karsten Hopp 98f576
+     return 0;
Karsten Hopp 98f576
+ }
Karsten Hopp 98f576
+ 
Karsten Hopp 98f576
      static PyObject *
Karsten Hopp 98f576
  BufMapIterNext(PyObject **buffer)
Karsten Hopp 98f576
  {
Karsten Hopp 98f576
***************
Karsten Hopp 98f576
*** 3228,3234 ****
Karsten Hopp 98f576
  
Karsten Hopp 98f576
      buffer = BufferNew(firstbuf);
Karsten Hopp 98f576
      return IterNew(buffer,
Karsten Hopp 98f576
! 	    (destructorfun) BufMapIterDestruct, (nextfun) BufMapIterNext);
Karsten Hopp 98f576
  }
Karsten Hopp 98f576
  
Karsten Hopp 98f576
  static PyMappingMethods BufMapAsMapping = {
Karsten Hopp 98f576
--- 3299,3306 ----
Karsten Hopp 98f576
  
Karsten Hopp 98f576
      buffer = BufferNew(firstbuf);
Karsten Hopp 98f576
      return IterNew(buffer,
Karsten Hopp 98f576
! 	    (destructorfun) BufMapIterDestruct, (nextfun) BufMapIterNext,
Karsten Hopp 98f576
! 	    (traversefun) BufMapIterTraverse, (clearfun) BufMapIterClear);
Karsten Hopp 98f576
  }
Karsten Hopp 98f576
  
Karsten Hopp 98f576
  static PyMappingMethods BufMapAsMapping = {
Karsten Hopp 98f576
***************
Karsten Hopp 98f576
*** 3837,3842 ****
Karsten Hopp 98f576
--- 3909,3916 ----
Karsten Hopp 98f576
      IterType.tp_iter = IterIter;
Karsten Hopp 98f576
      IterType.tp_iternext = IterNext;
Karsten Hopp 98f576
      IterType.tp_dealloc = IterDestructor;
Karsten Hopp 98f576
+     IterType.tp_traverse = IterTraverse;
Karsten Hopp 98f576
+     IterType.tp_clear = IterClear;
Karsten Hopp 98f576
  
Karsten Hopp 98f576
      vim_memset(&BufferType, 0, sizeof(BufferType));
Karsten Hopp 98f576
      BufferType.tp_name = "vim.buffer";
Karsten Hopp 98f576
***************
Karsten Hopp 98f576
*** 3865,3870 ****
Karsten Hopp 98f576
--- 3939,3946 ----
Karsten Hopp 98f576
      WindowType.tp_flags = Py_TPFLAGS_DEFAULT;
Karsten Hopp 98f576
      WindowType.tp_doc = "vim Window object";
Karsten Hopp 98f576
      WindowType.tp_methods = WindowMethods;
Karsten Hopp 98f576
+     WindowType.tp_traverse = WindowTraverse;
Karsten Hopp 98f576
+     WindowType.tp_clear = WindowClear;
Karsten Hopp 98f576
  #if PY_MAJOR_VERSION >= 3
Karsten Hopp 98f576
      WindowType.tp_getattro = WindowGetattro;
Karsten Hopp 98f576
      WindowType.tp_setattro = WindowSetattro;
Karsten Hopp 98f576
***************
Karsten Hopp 98f576
*** 4003,4008 ****
Karsten Hopp 98f576
--- 4079,4086 ----
Karsten Hopp 98f576
      OptionsType.tp_doc = "object for manipulating options";
Karsten Hopp 98f576
      OptionsType.tp_as_mapping = &OptionsAsMapping;
Karsten Hopp 98f576
      OptionsType.tp_dealloc = OptionsDestructor;
Karsten Hopp 98f576
+     OptionsType.tp_traverse = OptionsTraverse;
Karsten Hopp 98f576
+     OptionsType.tp_clear = OptionsClear;
Karsten Hopp 98f576
  
Karsten Hopp 98f576
  #if PY_MAJOR_VERSION >= 3
Karsten Hopp 98f576
      vim_memset(&vimmodule, 0, sizeof(vimmodule));
Karsten Hopp 98f576
*** ../vim-7.3.964/src/version.c	2013-05-17 16:18:27.000000000 +0200
Karsten Hopp 98f576
--- src/version.c	2013-05-17 16:21:24.000000000 +0200
Karsten Hopp 98f576
***************
Karsten Hopp 98f576
*** 730,731 ****
Karsten Hopp 98f576
--- 730,733 ----
Karsten Hopp 98f576
  {   /* Add new patch number below this line */
Karsten Hopp 98f576
+ /**/
Karsten Hopp 98f576
+     965,
Karsten Hopp 98f576
  /**/
Karsten Hopp 98f576
Karsten Hopp 98f576
-- 
Karsten Hopp 98f576
ARTHUR: Charge!
Karsten Hopp 98f576
   [They all charge with swords drawn towards the RABBIT.  A tremendous twenty
Karsten Hopp 98f576
   second fight with Peckinpahish shots and borrowing heavily also on the
Karsten Hopp 98f576
   Kung Fu and karate-type films ensues, in which some four KNIGHTS are
Karsten Hopp 98f576
   comprehensively killed.]
Karsten Hopp 98f576
ARTHUR: Run away!  Run away!
Karsten Hopp 98f576
                 "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD
Karsten Hopp 98f576
Karsten Hopp 98f576
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp 98f576
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp 98f576
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
Karsten Hopp 98f576
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///