Karsten Hopp 805d61
To: vim_dev@googlegroups.com
Karsten Hopp 805d61
Subject: Patch 7.3.1056
Karsten Hopp 805d61
Fcc: outbox
Karsten Hopp 805d61
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp 805d61
Mime-Version: 1.0
Karsten Hopp 805d61
Content-Type: text/plain; charset=UTF-8
Karsten Hopp 805d61
Content-Transfer-Encoding: 8bit
Karsten Hopp 805d61
------------
Karsten Hopp 805d61
Karsten Hopp 805d61
Patch 7.3.1056
Karsten Hopp 805d61
Problem:    Python: possible memory leaks.
Karsten Hopp 805d61
Solution:   Python patch 15. (ZyX) Fix will follow later.
Karsten Hopp 805d61
Files:	    src/eval.c, src/if_py_both.h, src/proto/eval.pro
Karsten Hopp 805d61
Karsten Hopp 805d61
Karsten Hopp 805d61
*** ../vim-7.3.1055/src/eval.c	2013-05-17 16:03:53.000000000 +0200
Karsten Hopp 805d61
--- src/eval.c	2013-05-30 12:11:40.000000000 +0200
Karsten Hopp 805d61
***************
Karsten Hopp 805d61
*** 412,418 ****
Karsten Hopp 805d61
  static int get_lit_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate));
Karsten Hopp 805d61
  static int get_list_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate));
Karsten Hopp 805d61
  static int rettv_list_alloc __ARGS((typval_T *rettv));
Karsten Hopp 805d61
- static void listitem_free __ARGS((listitem_T *item));
Karsten Hopp 805d61
  static long list_len __ARGS((list_T *l));
Karsten Hopp 805d61
  static int list_equal __ARGS((list_T *l1, list_T *l2, int ic, int recursive));
Karsten Hopp 805d61
  static int dict_equal __ARGS((dict_T *d1, dict_T *d2, int ic, int recursive));
Karsten Hopp 805d61
--- 412,417 ----
Karsten Hopp 805d61
***************
Karsten Hopp 805d61
*** 428,434 ****
Karsten Hopp 805d61
  static int list_join __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo, int copyID));
Karsten Hopp 805d61
  static int free_unref_items __ARGS((int copyID));
Karsten Hopp 805d61
  static int rettv_dict_alloc __ARGS((typval_T *rettv));
Karsten Hopp 805d61
- static void dict_free __ARGS((dict_T *d, int recurse));
Karsten Hopp 805d61
  static dictitem_T *dictitem_copy __ARGS((dictitem_T *org));
Karsten Hopp 805d61
  static void dictitem_remove __ARGS((dict_T *dict, dictitem_T *item));
Karsten Hopp 805d61
  static dict_T *dict_copy __ARGS((dict_T *orig, int deep, int copyID));
Karsten Hopp 805d61
--- 427,432 ----
Karsten Hopp 805d61
***************
Karsten Hopp 805d61
*** 5955,5961 ****
Karsten Hopp 805d61
  /*
Karsten Hopp 805d61
   * Free a list item.  Also clears the value.  Does not notify watchers.
Karsten Hopp 805d61
   */
Karsten Hopp 805d61
!     static void
Karsten Hopp 805d61
  listitem_free(item)
Karsten Hopp 805d61
      listitem_T *item;
Karsten Hopp 805d61
  {
Karsten Hopp 805d61
--- 5953,5959 ----
Karsten Hopp 805d61
  /*
Karsten Hopp 805d61
   * Free a list item.  Also clears the value.  Does not notify watchers.
Karsten Hopp 805d61
   */
Karsten Hopp 805d61
!     void
Karsten Hopp 805d61
  listitem_free(item)
Karsten Hopp 805d61
      listitem_T *item;
Karsten Hopp 805d61
  {
Karsten Hopp 805d61
***************
Karsten Hopp 805d61
*** 7031,7037 ****
Karsten Hopp 805d61
   * Free a Dictionary, including all items it contains.
Karsten Hopp 805d61
   * Ignores the reference count.
Karsten Hopp 805d61
   */
Karsten Hopp 805d61
!     static void
Karsten Hopp 805d61
  dict_free(d, recurse)
Karsten Hopp 805d61
      dict_T  *d;
Karsten Hopp 805d61
      int	    recurse;	/* Free Lists and Dictionaries recursively. */
Karsten Hopp 805d61
--- 7029,7035 ----
Karsten Hopp 805d61
   * Free a Dictionary, including all items it contains.
Karsten Hopp 805d61
   * Ignores the reference count.
Karsten Hopp 805d61
   */
Karsten Hopp 805d61
!     void
Karsten Hopp 805d61
  dict_free(d, recurse)
Karsten Hopp 805d61
      dict_T  *d;
Karsten Hopp 805d61
      int	    recurse;	/* Free Lists and Dictionaries recursively. */
Karsten Hopp 805d61
***************
Karsten Hopp 805d61
*** 8353,8359 ****
Karsten Hopp 805d61
  
Karsten Hopp 805d61
  /*
Karsten Hopp 805d61
   * Call a function with its resolved parameters
Karsten Hopp 805d61
!  * Return OK when the function can't be called,  FAIL otherwise.
Karsten Hopp 805d61
   * Also returns OK when an error was encountered while executing the function.
Karsten Hopp 805d61
   */
Karsten Hopp 805d61
      static int
Karsten Hopp 805d61
--- 8351,8357 ----
Karsten Hopp 805d61
  
Karsten Hopp 805d61
  /*
Karsten Hopp 805d61
   * Call a function with its resolved parameters
Karsten Hopp 805d61
!  * Return FAIL when the function can't be called,  OK otherwise.
Karsten Hopp 805d61
   * Also returns OK when an error was encountered while executing the function.
Karsten Hopp 805d61
   */
Karsten Hopp 805d61
      static int
Karsten Hopp 805d61
*** ../vim-7.3.1055/src/if_py_both.h	2013-05-29 22:58:28.000000000 +0200
Karsten Hopp 805d61
--- src/if_py_both.h	2013-05-30 12:13:37.000000000 +0200
Karsten Hopp 805d61
***************
Karsten Hopp 805d61
*** 32,39 ****
Karsten Hopp 805d61
  
Karsten Hopp 805d61
  #define DICTKEY_DECL \
Karsten Hopp 805d61
      PyObject	*dictkey_todecref;
Karsten Hopp 805d61
  #define DICTKEY_GET(err, decref) \
Karsten Hopp 805d61
!     if (!(key = StringToChars(keyObject, &dictkey_todecref))) \
Karsten Hopp 805d61
      { \
Karsten Hopp 805d61
  	if (decref) \
Karsten Hopp 805d61
  	{ \
Karsten Hopp 805d61
--- 32,46 ----
Karsten Hopp 805d61
  
Karsten Hopp 805d61
  #define DICTKEY_DECL \
Karsten Hopp 805d61
      PyObject	*dictkey_todecref;
Karsten Hopp 805d61
+ #define DICTKEY_CHECK_EMPTY(err) \
Karsten Hopp 805d61
+     if (*key == NUL) \
Karsten Hopp 805d61
+     { \
Karsten Hopp 805d61
+ 	PyErr_SetString(PyExc_ValueError, _("empty keys are not allowed")); \
Karsten Hopp 805d61
+ 	return err; \
Karsten Hopp 805d61
+     }
Karsten Hopp 805d61
+ #define DICTKEY_SET_KEY (key = StringToChars(keyObject, &dictkey_todecref))
Karsten Hopp 805d61
  #define DICTKEY_GET(err, decref) \
Karsten Hopp 805d61
!     if (!DICTKEY_SET_KEY) \
Karsten Hopp 805d61
      { \
Karsten Hopp 805d61
  	if (decref) \
Karsten Hopp 805d61
  	{ \
Karsten Hopp 805d61
***************
Karsten Hopp 805d61
*** 43,53 ****
Karsten Hopp 805d61
      } \
Karsten Hopp 805d61
      if (decref && !dictkey_todecref) \
Karsten Hopp 805d61
  	dictkey_todecref = keyObject; \
Karsten Hopp 805d61
!     if (*key == NUL) \
Karsten Hopp 805d61
!     { \
Karsten Hopp 805d61
! 	PyErr_SetString(PyExc_ValueError, _("empty keys are not allowed")); \
Karsten Hopp 805d61
! 	return err; \
Karsten Hopp 805d61
!     }
Karsten Hopp 805d61
  #define DICTKEY_UNREF \
Karsten Hopp 805d61
      Py_XDECREF(dictkey_todecref);
Karsten Hopp 805d61
  
Karsten Hopp 805d61
--- 50,56 ----
Karsten Hopp 805d61
      } \
Karsten Hopp 805d61
      if (decref && !dictkey_todecref) \
Karsten Hopp 805d61
  	dictkey_todecref = keyObject; \
Karsten Hopp 805d61
!     DICTKEY_CHECK_EMPTY(err)
Karsten Hopp 805d61
  #define DICTKEY_UNREF \
Karsten Hopp 805d61
      Py_XDECREF(dictkey_todecref);
Karsten Hopp 805d61
  
Karsten Hopp 805d61
***************
Karsten Hopp 805d61
*** 651,659 ****
Karsten Hopp 805d61
  
Karsten Hopp 805d61
      /* Convert the Vim type into a Python type.  Create a dictionary that's
Karsten Hopp 805d61
       * used to check for recursive loops. */
Karsten Hopp 805d61
!     lookup_dict = PyDict_New();
Karsten Hopp 805d61
!     result = VimToPython(our_tv, 1, lookup_dict);
Karsten Hopp 805d61
!     Py_DECREF(lookup_dict);
Karsten Hopp 805d61
  
Karsten Hopp 805d61
  
Karsten Hopp 805d61
      Py_BEGIN_ALLOW_THREADS
Karsten Hopp 805d61
--- 654,666 ----
Karsten Hopp 805d61
  
Karsten Hopp 805d61
      /* Convert the Vim type into a Python type.  Create a dictionary that's
Karsten Hopp 805d61
       * used to check for recursive loops. */
Karsten Hopp 805d61
!     if (!(lookup_dict = PyDict_New()))
Karsten Hopp 805d61
! 	result = NULL;
Karsten Hopp 805d61
!     else
Karsten Hopp 805d61
!     {
Karsten Hopp 805d61
! 	result = VimToPython(our_tv, 1, lookup_dict);
Karsten Hopp 805d61
! 	Py_DECREF(lookup_dict);
Karsten Hopp 805d61
!     }
Karsten Hopp 805d61
  
Karsten Hopp 805d61
  
Karsten Hopp 805d61
      Py_BEGIN_ALLOW_THREADS
Karsten Hopp 805d61
***************
Karsten Hopp 805d61
*** 1401,1407 ****
Karsten Hopp 805d61
  	return NULL;
Karsten Hopp 805d61
      }
Karsten Hopp 805d61
  
Karsten Hopp 805d61
!     lookup_dict = PyDict_New();
Karsten Hopp 805d61
      if (list_py_concat(l, obj, lookup_dict) == -1)
Karsten Hopp 805d61
      {
Karsten Hopp 805d61
  	Py_DECREF(lookup_dict);
Karsten Hopp 805d61
--- 1408,1416 ----
Karsten Hopp 805d61
  	return NULL;
Karsten Hopp 805d61
      }
Karsten Hopp 805d61
  
Karsten Hopp 805d61
!     if (!(lookup_dict = PyDict_New()))
Karsten Hopp 805d61
! 	return NULL;
Karsten Hopp 805d61
! 
Karsten Hopp 805d61
      if (list_py_concat(l, obj, lookup_dict) == -1)
Karsten Hopp 805d61
      {
Karsten Hopp 805d61
  	Py_DECREF(lookup_dict);
Karsten Hopp 805d61
***************
Karsten Hopp 805d61
*** 4023,4034 ****
Karsten Hopp 805d61
      PyObject	*valObject;
Karsten Hopp 805d61
      Py_ssize_t	iter = 0;
Karsten Hopp 805d61
  
Karsten Hopp 805d61
!     dict = dict_alloc();
Karsten Hopp 805d61
!     if (dict == NULL)
Karsten Hopp 805d61
!     {
Karsten Hopp 805d61
! 	PyErr_NoMemory();
Karsten Hopp 805d61
  	return -1;
Karsten Hopp 805d61
-     }
Karsten Hopp 805d61
  
Karsten Hopp 805d61
      tv->v_type = VAR_DICT;
Karsten Hopp 805d61
      tv->vval.v_dict = dict;
Karsten Hopp 805d61
--- 4032,4039 ----
Karsten Hopp 805d61
      PyObject	*valObject;
Karsten Hopp 805d61
      Py_ssize_t	iter = 0;
Karsten Hopp 805d61
  
Karsten Hopp 805d61
!     if (!(dict = dict_alloc()))
Karsten Hopp 805d61
  	return -1;
Karsten Hopp 805d61
  
Karsten Hopp 805d61
      tv->v_type = VAR_DICT;
Karsten Hopp 805d61
      tv->vval.v_dict = dict;
Karsten Hopp 805d61
***************
Karsten Hopp 805d61
*** 4038,4046 ****
Karsten Hopp 805d61
  	DICTKEY_DECL
Karsten Hopp 805d61
  
Karsten Hopp 805d61
  	if (keyObject == NULL || valObject == NULL)
Karsten Hopp 805d61
  	    return -1;
Karsten Hopp 805d61
  
Karsten Hopp 805d61
! 	DICTKEY_GET(-1, 0)
Karsten Hopp 805d61
  
Karsten Hopp 805d61
  	di = dictitem_alloc(key);
Karsten Hopp 805d61
  
Karsten Hopp 805d61
--- 4043,4059 ----
Karsten Hopp 805d61
  	DICTKEY_DECL
Karsten Hopp 805d61
  
Karsten Hopp 805d61
  	if (keyObject == NULL || valObject == NULL)
Karsten Hopp 805d61
+ 	{
Karsten Hopp 805d61
+ 	    dict_unref(dict);
Karsten Hopp 805d61
  	    return -1;
Karsten Hopp 805d61
+ 	}
Karsten Hopp 805d61
  
Karsten Hopp 805d61
! 	if (!DICTKEY_SET_KEY)
Karsten Hopp 805d61
! 	{
Karsten Hopp 805d61
! 	    dict_unref(dict);
Karsten Hopp 805d61
! 	    return -1;
Karsten Hopp 805d61
! 	}
Karsten Hopp 805d61
! 	DICTKEY_CHECK_EMPTY(-1)
Karsten Hopp 805d61
  
Karsten Hopp 805d61
  	di = dictitem_alloc(key);
Karsten Hopp 805d61
  
Karsten Hopp 805d61
***************
Karsten Hopp 805d61
*** 4049,4054 ****
Karsten Hopp 805d61
--- 4062,4068 ----
Karsten Hopp 805d61
  	if (di == NULL)
Karsten Hopp 805d61
  	{
Karsten Hopp 805d61
  	    PyErr_NoMemory();
Karsten Hopp 805d61
+ 	    dict_unref(dict);
Karsten Hopp 805d61
  	    return -1;
Karsten Hopp 805d61
  	}
Karsten Hopp 805d61
  	di->di_tv.v_lock = 0;
Karsten Hopp 805d61
***************
Karsten Hopp 805d61
*** 4056,4061 ****
Karsten Hopp 805d61
--- 4070,4076 ----
Karsten Hopp 805d61
  	if (_ConvertFromPyObject(valObject, &di->di_tv, lookup_dict) == -1)
Karsten Hopp 805d61
  	{
Karsten Hopp 805d61
  	    vim_free(di);
Karsten Hopp 805d61
+ 	    dict_unref(dict);
Karsten Hopp 805d61
  	    return -1;
Karsten Hopp 805d61
  	}
Karsten Hopp 805d61
  
Karsten Hopp 805d61
***************
Karsten Hopp 805d61
*** 4063,4072 ****
Karsten Hopp 805d61
--- 4078,4090 ----
Karsten Hopp 805d61
  	{
Karsten Hopp 805d61
  	    clear_tv(&di->di_tv);
Karsten Hopp 805d61
  	    vim_free(di);
Karsten Hopp 805d61
+ 	    dict_unref(dict);
Karsten Hopp 805d61
  	    PyErr_SetVim(_("failed to add key to dictionary"));
Karsten Hopp 805d61
  	    return -1;
Karsten Hopp 805d61
  	}
Karsten Hopp 805d61
      }
Karsten Hopp 805d61
+ 
Karsten Hopp 805d61
+     --dict->dv_refcount;
Karsten Hopp 805d61
      return 0;
Karsten Hopp 805d61
  }
Karsten Hopp 805d61
  
Karsten Hopp 805d61
***************
Karsten Hopp 805d61
*** 4082,4100 ****
Karsten Hopp 805d61
      PyObject	*valObject;
Karsten Hopp 805d61
      Py_ssize_t	lsize;
Karsten Hopp 805d61
  
Karsten Hopp 805d61
!     dict = dict_alloc();
Karsten Hopp 805d61
!     if (dict == NULL)
Karsten Hopp 805d61
!     {
Karsten Hopp 805d61
! 	PyErr_NoMemory();
Karsten Hopp 805d61
  	return -1;
Karsten Hopp 805d61
-     }
Karsten Hopp 805d61
  
Karsten Hopp 805d61
      tv->v_type = VAR_DICT;
Karsten Hopp 805d61
      tv->vval.v_dict = dict;
Karsten Hopp 805d61
  
Karsten Hopp 805d61
      list = PyMapping_Items(obj);
Karsten Hopp 805d61
      if (list == NULL)
Karsten Hopp 805d61
  	return -1;
Karsten Hopp 805d61
      lsize = PyList_Size(list);
Karsten Hopp 805d61
      while (lsize--)
Karsten Hopp 805d61
      {
Karsten Hopp 805d61
--- 4100,4117 ----
Karsten Hopp 805d61
      PyObject	*valObject;
Karsten Hopp 805d61
      Py_ssize_t	lsize;
Karsten Hopp 805d61
  
Karsten Hopp 805d61
!     if (!(dict = dict_alloc()))
Karsten Hopp 805d61
  	return -1;
Karsten Hopp 805d61
  
Karsten Hopp 805d61
      tv->v_type = VAR_DICT;
Karsten Hopp 805d61
      tv->vval.v_dict = dict;
Karsten Hopp 805d61
  
Karsten Hopp 805d61
      list = PyMapping_Items(obj);
Karsten Hopp 805d61
      if (list == NULL)
Karsten Hopp 805d61
+     {
Karsten Hopp 805d61
+ 	dict_unref(dict);
Karsten Hopp 805d61
  	return -1;
Karsten Hopp 805d61
+     }
Karsten Hopp 805d61
      lsize = PyList_Size(list);
Karsten Hopp 805d61
      while (lsize--)
Karsten Hopp 805d61
      {
Karsten Hopp 805d61
***************
Karsten Hopp 805d61
*** 4104,4109 ****
Karsten Hopp 805d61
--- 4121,4127 ----
Karsten Hopp 805d61
  	if (litem == NULL)
Karsten Hopp 805d61
  	{
Karsten Hopp 805d61
  	    Py_DECREF(list);
Karsten Hopp 805d61
+ 	    dict_unref(dict);
Karsten Hopp 805d61
  	    return -1;
Karsten Hopp 805d61
  	}
Karsten Hopp 805d61
  
Karsten Hopp 805d61
***************
Karsten Hopp 805d61
*** 4111,4125 ****
Karsten Hopp 805d61
  	{
Karsten Hopp 805d61
  	    Py_DECREF(list);
Karsten Hopp 805d61
  	    Py_DECREF(litem);
Karsten Hopp 805d61
  	    return -1;
Karsten Hopp 805d61
  	}
Karsten Hopp 805d61
  
Karsten Hopp 805d61
! 	DICTKEY_GET(-1, 1)
Karsten Hopp 805d61
  
Karsten Hopp 805d61
  	if (!(valObject = PyTuple_GetItem(litem, 1)))
Karsten Hopp 805d61
  	{
Karsten Hopp 805d61
  	    Py_DECREF(list);
Karsten Hopp 805d61
  	    Py_DECREF(litem);
Karsten Hopp 805d61
  	    DICTKEY_UNREF
Karsten Hopp 805d61
  	    return -1;
Karsten Hopp 805d61
  	}
Karsten Hopp 805d61
--- 4129,4153 ----
Karsten Hopp 805d61
  	{
Karsten Hopp 805d61
  	    Py_DECREF(list);
Karsten Hopp 805d61
  	    Py_DECREF(litem);
Karsten Hopp 805d61
+ 	    dict_unref(dict);
Karsten Hopp 805d61
  	    return -1;
Karsten Hopp 805d61
  	}
Karsten Hopp 805d61
  
Karsten Hopp 805d61
! 	if (!DICTKEY_SET_KEY)
Karsten Hopp 805d61
! 	{
Karsten Hopp 805d61
! 	    dict_unref(dict);
Karsten Hopp 805d61
! 	    Py_DECREF(list);
Karsten Hopp 805d61
! 	    Py_DECREF(litem);
Karsten Hopp 805d61
! 	    DICTKEY_UNREF
Karsten Hopp 805d61
! 	    return -1;
Karsten Hopp 805d61
! 	}
Karsten Hopp 805d61
! 	DICTKEY_CHECK_EMPTY(-1)
Karsten Hopp 805d61
  
Karsten Hopp 805d61
  	if (!(valObject = PyTuple_GetItem(litem, 1)))
Karsten Hopp 805d61
  	{
Karsten Hopp 805d61
  	    Py_DECREF(list);
Karsten Hopp 805d61
  	    Py_DECREF(litem);
Karsten Hopp 805d61
+ 	    dict_unref(dict);
Karsten Hopp 805d61
  	    DICTKEY_UNREF
Karsten Hopp 805d61
  	    return -1;
Karsten Hopp 805d61
  	}
Karsten Hopp 805d61
***************
Karsten Hopp 805d61
*** 4133,4139 ****
Karsten Hopp 805d61
  	if (di == NULL)
Karsten Hopp 805d61
  	{
Karsten Hopp 805d61
  	    Py_DECREF(list);
Karsten Hopp 805d61
! 	    Py_DECREF(valObject);
Karsten Hopp 805d61
  	    PyErr_NoMemory();
Karsten Hopp 805d61
  	    return -1;
Karsten Hopp 805d61
  	}
Karsten Hopp 805d61
--- 4161,4167 ----
Karsten Hopp 805d61
  	if (di == NULL)
Karsten Hopp 805d61
  	{
Karsten Hopp 805d61
  	    Py_DECREF(list);
Karsten Hopp 805d61
! 	    dict_unref(dict);
Karsten Hopp 805d61
  	    PyErr_NoMemory();
Karsten Hopp 805d61
  	    return -1;
Karsten Hopp 805d61
  	}
Karsten Hopp 805d61
***************
Karsten Hopp 805d61
*** 4142,4216 ****
Karsten Hopp 805d61
  	if (_ConvertFromPyObject(valObject, &di->di_tv, lookup_dict) == -1)
Karsten Hopp 805d61
  	{
Karsten Hopp 805d61
  	    vim_free(di);
Karsten Hopp 805d61
  	    Py_DECREF(list);
Karsten Hopp 805d61
- 	    Py_DECREF(valObject);
Karsten Hopp 805d61
  	    return -1;
Karsten Hopp 805d61
  	}
Karsten Hopp 805d61
  
Karsten Hopp 805d61
- 	Py_DECREF(valObject);
Karsten Hopp 805d61
- 
Karsten Hopp 805d61
  	if (dict_add(dict, di) == FAIL)
Karsten Hopp 805d61
  	{
Karsten Hopp 805d61
! 	    clear_tv(&di->di_tv);
Karsten Hopp 805d61
! 	    vim_free(di);
Karsten Hopp 805d61
  	    Py_DECREF(list);
Karsten Hopp 805d61
  	    PyErr_SetVim(_("failed to add key to dictionary"));
Karsten Hopp 805d61
  	    return -1;
Karsten Hopp 805d61
  	}
Karsten Hopp 805d61
      }
Karsten Hopp 805d61
      Py_DECREF(list);
Karsten Hopp 805d61
      return 0;
Karsten Hopp 805d61
  }
Karsten Hopp 805d61
  
Karsten Hopp 805d61
      static int
Karsten Hopp 805d61
  pyseq_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Karsten Hopp 805d61
  {
Karsten Hopp 805d61
      list_T	*l;
Karsten Hopp 805d61
  
Karsten Hopp 805d61
!     l = list_alloc();
Karsten Hopp 805d61
!     if (l == NULL)
Karsten Hopp 805d61
!     {
Karsten Hopp 805d61
! 	PyErr_NoMemory();
Karsten Hopp 805d61
  	return -1;
Karsten Hopp 805d61
-     }
Karsten Hopp 805d61
  
Karsten Hopp 805d61
      tv->v_type = VAR_LIST;
Karsten Hopp 805d61
      tv->vval.v_list = l;
Karsten Hopp 805d61
  
Karsten Hopp 805d61
      if (list_py_concat(l, obj, lookup_dict) == -1)
Karsten Hopp 805d61
  	return -1;
Karsten Hopp 805d61
  
Karsten Hopp 805d61
      return 0;
Karsten Hopp 805d61
  }
Karsten Hopp 805d61
  
Karsten Hopp 805d61
      static int
Karsten Hopp 805d61
  pyiter_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Karsten Hopp 805d61
  {
Karsten Hopp 805d61
!     PyObject	*iterator = PyObject_GetIter(obj);
Karsten Hopp 805d61
      PyObject	*item;
Karsten Hopp 805d61
      list_T	*l;
Karsten Hopp 805d61
      listitem_T	*li;
Karsten Hopp 805d61
  
Karsten Hopp 805d61
!     l = list_alloc();
Karsten Hopp 805d61
! 
Karsten Hopp 805d61
!     if (l == NULL)
Karsten Hopp 805d61
!     {
Karsten Hopp 805d61
! 	PyErr_NoMemory();
Karsten Hopp 805d61
  	return -1;
Karsten Hopp 805d61
-     }
Karsten Hopp 805d61
  
Karsten Hopp 805d61
      tv->vval.v_list = l;
Karsten Hopp 805d61
      tv->v_type = VAR_LIST;
Karsten Hopp 805d61
  
Karsten Hopp 805d61
! 
Karsten Hopp 805d61
!     if (iterator == NULL)
Karsten Hopp 805d61
  	return -1;
Karsten Hopp 805d61
  
Karsten Hopp 805d61
      while ((item = PyIter_Next(iterator)))
Karsten Hopp 805d61
      {
Karsten Hopp 805d61
  	li = listitem_alloc();
Karsten Hopp 805d61
  	if (li == NULL)
Karsten Hopp 805d61
  	{
Karsten Hopp 805d61
  	    Py_DECREF(iterator);
Karsten Hopp 805d61
  	    PyErr_NoMemory();
Karsten Hopp 805d61
  	    return -1;
Karsten Hopp 805d61
--- 4170,4256 ----
Karsten Hopp 805d61
  	if (_ConvertFromPyObject(valObject, &di->di_tv, lookup_dict) == -1)
Karsten Hopp 805d61
  	{
Karsten Hopp 805d61
  	    vim_free(di);
Karsten Hopp 805d61
+ 	    dict_unref(dict);
Karsten Hopp 805d61
  	    Py_DECREF(list);
Karsten Hopp 805d61
  	    return -1;
Karsten Hopp 805d61
  	}
Karsten Hopp 805d61
  
Karsten Hopp 805d61
  	if (dict_add(dict, di) == FAIL)
Karsten Hopp 805d61
  	{
Karsten Hopp 805d61
! 	    dictitem_free(di);
Karsten Hopp 805d61
! 	    dict_unref(dict);
Karsten Hopp 805d61
  	    Py_DECREF(list);
Karsten Hopp 805d61
  	    PyErr_SetVim(_("failed to add key to dictionary"));
Karsten Hopp 805d61
  	    return -1;
Karsten Hopp 805d61
  	}
Karsten Hopp 805d61
      }
Karsten Hopp 805d61
+     --dict->dv_refcount;
Karsten Hopp 805d61
      Py_DECREF(list);
Karsten Hopp 805d61
      return 0;
Karsten Hopp 805d61
  }
Karsten Hopp 805d61
  
Karsten Hopp 805d61
+     static list_T *
Karsten Hopp 805d61
+ py_list_alloc()
Karsten Hopp 805d61
+ {
Karsten Hopp 805d61
+     list_T	*r;
Karsten Hopp 805d61
+ 
Karsten Hopp 805d61
+     if (!(r = list_alloc()))
Karsten Hopp 805d61
+     {
Karsten Hopp 805d61
+ 	PyErr_NoMemory();
Karsten Hopp 805d61
+ 	return NULL;
Karsten Hopp 805d61
+     }
Karsten Hopp 805d61
+     ++r->lv_refcount;
Karsten Hopp 805d61
+ 
Karsten Hopp 805d61
+     return r;
Karsten Hopp 805d61
+ }
Karsten Hopp 805d61
+ 
Karsten Hopp 805d61
      static int
Karsten Hopp 805d61
  pyseq_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Karsten Hopp 805d61
  {
Karsten Hopp 805d61
      list_T	*l;
Karsten Hopp 805d61
  
Karsten Hopp 805d61
!     if (!(l = py_list_alloc()))
Karsten Hopp 805d61
  	return -1;
Karsten Hopp 805d61
  
Karsten Hopp 805d61
      tv->v_type = VAR_LIST;
Karsten Hopp 805d61
      tv->vval.v_list = l;
Karsten Hopp 805d61
  
Karsten Hopp 805d61
      if (list_py_concat(l, obj, lookup_dict) == -1)
Karsten Hopp 805d61
+     {
Karsten Hopp 805d61
+ 	list_unref(l);
Karsten Hopp 805d61
  	return -1;
Karsten Hopp 805d61
+     }
Karsten Hopp 805d61
  
Karsten Hopp 805d61
+     --l->lv_refcount;
Karsten Hopp 805d61
      return 0;
Karsten Hopp 805d61
  }
Karsten Hopp 805d61
  
Karsten Hopp 805d61
      static int
Karsten Hopp 805d61
  pyiter_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Karsten Hopp 805d61
  {
Karsten Hopp 805d61
!     PyObject	*iterator;
Karsten Hopp 805d61
      PyObject	*item;
Karsten Hopp 805d61
      list_T	*l;
Karsten Hopp 805d61
      listitem_T	*li;
Karsten Hopp 805d61
  
Karsten Hopp 805d61
!     if (!(l = py_list_alloc()))
Karsten Hopp 805d61
  	return -1;
Karsten Hopp 805d61
  
Karsten Hopp 805d61
      tv->vval.v_list = l;
Karsten Hopp 805d61
      tv->v_type = VAR_LIST;
Karsten Hopp 805d61
  
Karsten Hopp 805d61
!     if (!(iterator = PyObject_GetIter(obj)))
Karsten Hopp 805d61
!     {
Karsten Hopp 805d61
! 	list_unref(l);
Karsten Hopp 805d61
  	return -1;
Karsten Hopp 805d61
+     }
Karsten Hopp 805d61
  
Karsten Hopp 805d61
      while ((item = PyIter_Next(iterator)))
Karsten Hopp 805d61
      {
Karsten Hopp 805d61
  	li = listitem_alloc();
Karsten Hopp 805d61
  	if (li == NULL)
Karsten Hopp 805d61
  	{
Karsten Hopp 805d61
+ 	    list_unref(l);
Karsten Hopp 805d61
  	    Py_DECREF(iterator);
Karsten Hopp 805d61
  	    PyErr_NoMemory();
Karsten Hopp 805d61
  	    return -1;
Karsten Hopp 805d61
***************
Karsten Hopp 805d61
*** 4219,4224 ****
Karsten Hopp 805d61
--- 4259,4266 ----
Karsten Hopp 805d61
  
Karsten Hopp 805d61
  	if (_ConvertFromPyObject(item, &li->li_tv, lookup_dict) == -1)
Karsten Hopp 805d61
  	{
Karsten Hopp 805d61
+ 	    list_unref(l);
Karsten Hopp 805d61
+ 	    listitem_free(li);
Karsten Hopp 805d61
  	    Py_DECREF(item);
Karsten Hopp 805d61
  	    Py_DECREF(iterator);
Karsten Hopp 805d61
  	    return -1;
Karsten Hopp 805d61
***************
Karsten Hopp 805d61
*** 4230,4235 ****
Karsten Hopp 805d61
--- 4272,4286 ----
Karsten Hopp 805d61
      }
Karsten Hopp 805d61
  
Karsten Hopp 805d61
      Py_DECREF(iterator);
Karsten Hopp 805d61
+ 
Karsten Hopp 805d61
+     /* Iterator may have finished due to an exception */
Karsten Hopp 805d61
+     if (PyErr_Occurred())
Karsten Hopp 805d61
+     {
Karsten Hopp 805d61
+ 	list_unref(l);
Karsten Hopp 805d61
+ 	return -1;
Karsten Hopp 805d61
+     }
Karsten Hopp 805d61
+ 
Karsten Hopp 805d61
+     --l->lv_refcount;
Karsten Hopp 805d61
      return 0;
Karsten Hopp 805d61
  }
Karsten Hopp 805d61
  
Karsten Hopp 805d61
***************
Karsten Hopp 805d61
*** 4295,4301 ****
Karsten Hopp 805d61
      PyObject	*lookup_dict;
Karsten Hopp 805d61
      int		r;
Karsten Hopp 805d61
  
Karsten Hopp 805d61
!     lookup_dict = PyDict_New();
Karsten Hopp 805d61
      r = _ConvertFromPyObject(obj, tv, lookup_dict);
Karsten Hopp 805d61
      Py_DECREF(lookup_dict);
Karsten Hopp 805d61
      return r;
Karsten Hopp 805d61
--- 4346,4353 ----
Karsten Hopp 805d61
      PyObject	*lookup_dict;
Karsten Hopp 805d61
      int		r;
Karsten Hopp 805d61
  
Karsten Hopp 805d61
!     if (!(lookup_dict = PyDict_New()))
Karsten Hopp 805d61
! 	return -1;
Karsten Hopp 805d61
      r = _ConvertFromPyObject(obj, tv, lookup_dict);
Karsten Hopp 805d61
      Py_DECREF(lookup_dict);
Karsten Hopp 805d61
      return r;
Karsten Hopp 805d61
*** ../vim-7.3.1055/src/proto/eval.pro	2013-05-17 16:03:53.000000000 +0200
Karsten Hopp 805d61
--- src/proto/eval.pro	2013-05-30 12:11:40.000000000 +0200
Karsten Hopp 805d61
***************
Karsten Hopp 805d61
*** 49,54 ****
Karsten Hopp 805d61
--- 49,55 ----
Karsten Hopp 805d61
  void list_unref __ARGS((list_T *l));
Karsten Hopp 805d61
  void list_free __ARGS((list_T *l, int recurse));
Karsten Hopp 805d61
  listitem_T *listitem_alloc __ARGS((void));
Karsten Hopp 805d61
+ void listitem_free __ARGS((listitem_T *item));
Karsten Hopp 805d61
  void listitem_remove __ARGS((list_T *l, listitem_T *item));
Karsten Hopp 805d61
  dictitem_T *dict_lookup __ARGS((hashitem_T *hi));
Karsten Hopp 805d61
  listitem_T *list_find __ARGS((list_T *l, long n));
Karsten Hopp 805d61
***************
Karsten Hopp 805d61
*** 65,70 ****
Karsten Hopp 805d61
--- 66,72 ----
Karsten Hopp 805d61
  void set_ref_in_item __ARGS((typval_T *tv, int copyID));
Karsten Hopp 805d61
  dict_T *dict_alloc __ARGS((void));
Karsten Hopp 805d61
  void dict_unref __ARGS((dict_T *d));
Karsten Hopp 805d61
+ void dict_free __ARGS((dict_T *d, int recurse));
Karsten Hopp 805d61
  dictitem_T *dictitem_alloc __ARGS((char_u *key));
Karsten Hopp 805d61
  void dictitem_free __ARGS((dictitem_T *item));
Karsten Hopp 805d61
  int dict_add __ARGS((dict_T *d, dictitem_T *item));
Karsten Hopp 805d61
*** ../vim-7.3.1055/src/version.c	2013-05-30 11:51:04.000000000 +0200
Karsten Hopp 805d61
--- src/version.c	2013-05-30 12:13:57.000000000 +0200
Karsten Hopp 805d61
***************
Karsten Hopp 805d61
*** 730,731 ****
Karsten Hopp 805d61
--- 730,733 ----
Karsten Hopp 805d61
  {   /* Add new patch number below this line */
Karsten Hopp 805d61
+ /**/
Karsten Hopp 805d61
+     1056,
Karsten Hopp 805d61
  /**/
Karsten Hopp 805d61
Karsten Hopp 805d61
-- 
Karsten Hopp 805d61
I have a drinking problem -- I can't afford it.
Karsten Hopp 805d61
Karsten Hopp 805d61
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp 805d61
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp 805d61
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
Karsten Hopp 805d61
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///