Mercurial > vim
comparison src/if_py_both.h @ 4617:21a99611149b v7.3.1056
updated for version 7.3.1056
Problem: Python: possible memory leaks.
Solution: Python patch 15. (ZyX) Fix will follow later.
author | Bram Moolenaar <bram@vim.org> |
---|---|
date | Thu, 30 May 2013 12:14:49 +0200 |
parents | 49f0fcd9762c |
children | 90beab957ba9 |
comparison
equal
deleted
inserted
replaced
4616:e8bc429ce5fc | 4617:21a99611149b |
---|---|
30 #define INVALID_WINDOW_VALUE ((win_T *)(-1)) | 30 #define INVALID_WINDOW_VALUE ((win_T *)(-1)) |
31 #define INVALID_TABPAGE_VALUE ((tabpage_T *)(-1)) | 31 #define INVALID_TABPAGE_VALUE ((tabpage_T *)(-1)) |
32 | 32 |
33 #define DICTKEY_DECL \ | 33 #define DICTKEY_DECL \ |
34 PyObject *dictkey_todecref; | 34 PyObject *dictkey_todecref; |
35 #define DICTKEY_CHECK_EMPTY(err) \ | |
36 if (*key == NUL) \ | |
37 { \ | |
38 PyErr_SetString(PyExc_ValueError, _("empty keys are not allowed")); \ | |
39 return err; \ | |
40 } | |
41 #define DICTKEY_SET_KEY (key = StringToChars(keyObject, &dictkey_todecref)) | |
35 #define DICTKEY_GET(err, decref) \ | 42 #define DICTKEY_GET(err, decref) \ |
36 if (!(key = StringToChars(keyObject, &dictkey_todecref))) \ | 43 if (!DICTKEY_SET_KEY) \ |
37 { \ | 44 { \ |
38 if (decref) \ | 45 if (decref) \ |
39 { \ | 46 { \ |
40 Py_DECREF(keyObject); \ | 47 Py_DECREF(keyObject); \ |
41 } \ | 48 } \ |
42 return err; \ | 49 return err; \ |
43 } \ | 50 } \ |
44 if (decref && !dictkey_todecref) \ | 51 if (decref && !dictkey_todecref) \ |
45 dictkey_todecref = keyObject; \ | 52 dictkey_todecref = keyObject; \ |
46 if (*key == NUL) \ | 53 DICTKEY_CHECK_EMPTY(err) |
47 { \ | |
48 PyErr_SetString(PyExc_ValueError, _("empty keys are not allowed")); \ | |
49 return err; \ | |
50 } | |
51 #define DICTKEY_UNREF \ | 54 #define DICTKEY_UNREF \ |
52 Py_XDECREF(dictkey_todecref); | 55 Py_XDECREF(dictkey_todecref); |
53 | 56 |
54 typedef void (*rangeinitializer)(void *); | 57 typedef void (*rangeinitializer)(void *); |
55 typedef void (*runner)(const char *, void * | 58 typedef void (*runner)(const char *, void * |
649 return NULL; | 652 return NULL; |
650 } | 653 } |
651 | 654 |
652 /* Convert the Vim type into a Python type. Create a dictionary that's | 655 /* Convert the Vim type into a Python type. Create a dictionary that's |
653 * used to check for recursive loops. */ | 656 * used to check for recursive loops. */ |
654 lookup_dict = PyDict_New(); | 657 if (!(lookup_dict = PyDict_New())) |
655 result = VimToPython(our_tv, 1, lookup_dict); | 658 result = NULL; |
656 Py_DECREF(lookup_dict); | 659 else |
660 { | |
661 result = VimToPython(our_tv, 1, lookup_dict); | |
662 Py_DECREF(lookup_dict); | |
663 } | |
657 | 664 |
658 | 665 |
659 Py_BEGIN_ALLOW_THREADS | 666 Py_BEGIN_ALLOW_THREADS |
660 Python_Lock_Vim(); | 667 Python_Lock_Vim(); |
661 free_tv(our_tv); | 668 free_tv(our_tv); |
1399 { | 1406 { |
1400 PyErr_SetString(PyExc_TypeError, _("can only concatenate with lists")); | 1407 PyErr_SetString(PyExc_TypeError, _("can only concatenate with lists")); |
1401 return NULL; | 1408 return NULL; |
1402 } | 1409 } |
1403 | 1410 |
1404 lookup_dict = PyDict_New(); | 1411 if (!(lookup_dict = PyDict_New())) |
1412 return NULL; | |
1413 | |
1405 if (list_py_concat(l, obj, lookup_dict) == -1) | 1414 if (list_py_concat(l, obj, lookup_dict) == -1) |
1406 { | 1415 { |
1407 Py_DECREF(lookup_dict); | 1416 Py_DECREF(lookup_dict); |
1408 return NULL; | 1417 return NULL; |
1409 } | 1418 } |
4021 dictitem_T *di; | 4030 dictitem_T *di; |
4022 PyObject *keyObject; | 4031 PyObject *keyObject; |
4023 PyObject *valObject; | 4032 PyObject *valObject; |
4024 Py_ssize_t iter = 0; | 4033 Py_ssize_t iter = 0; |
4025 | 4034 |
4026 dict = dict_alloc(); | 4035 if (!(dict = dict_alloc())) |
4027 if (dict == NULL) | |
4028 { | |
4029 PyErr_NoMemory(); | |
4030 return -1; | 4036 return -1; |
4031 } | |
4032 | 4037 |
4033 tv->v_type = VAR_DICT; | 4038 tv->v_type = VAR_DICT; |
4034 tv->vval.v_dict = dict; | 4039 tv->vval.v_dict = dict; |
4035 | 4040 |
4036 while (PyDict_Next(obj, &iter, &keyObject, &valObject)) | 4041 while (PyDict_Next(obj, &iter, &keyObject, &valObject)) |
4037 { | 4042 { |
4038 DICTKEY_DECL | 4043 DICTKEY_DECL |
4039 | 4044 |
4040 if (keyObject == NULL || valObject == NULL) | 4045 if (keyObject == NULL || valObject == NULL) |
4041 return -1; | 4046 { |
4042 | 4047 dict_unref(dict); |
4043 DICTKEY_GET(-1, 0) | 4048 return -1; |
4049 } | |
4050 | |
4051 if (!DICTKEY_SET_KEY) | |
4052 { | |
4053 dict_unref(dict); | |
4054 return -1; | |
4055 } | |
4056 DICTKEY_CHECK_EMPTY(-1) | |
4044 | 4057 |
4045 di = dictitem_alloc(key); | 4058 di = dictitem_alloc(key); |
4046 | 4059 |
4047 DICTKEY_UNREF | 4060 DICTKEY_UNREF |
4048 | 4061 |
4049 if (di == NULL) | 4062 if (di == NULL) |
4050 { | 4063 { |
4051 PyErr_NoMemory(); | 4064 PyErr_NoMemory(); |
4065 dict_unref(dict); | |
4052 return -1; | 4066 return -1; |
4053 } | 4067 } |
4054 di->di_tv.v_lock = 0; | 4068 di->di_tv.v_lock = 0; |
4055 | 4069 |
4056 if (_ConvertFromPyObject(valObject, &di->di_tv, lookup_dict) == -1) | 4070 if (_ConvertFromPyObject(valObject, &di->di_tv, lookup_dict) == -1) |
4057 { | 4071 { |
4058 vim_free(di); | 4072 vim_free(di); |
4073 dict_unref(dict); | |
4059 return -1; | 4074 return -1; |
4060 } | 4075 } |
4061 | 4076 |
4062 if (dict_add(dict, di) == FAIL) | 4077 if (dict_add(dict, di) == FAIL) |
4063 { | 4078 { |
4064 clear_tv(&di->di_tv); | 4079 clear_tv(&di->di_tv); |
4065 vim_free(di); | 4080 vim_free(di); |
4081 dict_unref(dict); | |
4066 PyErr_SetVim(_("failed to add key to dictionary")); | 4082 PyErr_SetVim(_("failed to add key to dictionary")); |
4067 return -1; | 4083 return -1; |
4068 } | 4084 } |
4069 } | 4085 } |
4086 | |
4087 --dict->dv_refcount; | |
4070 return 0; | 4088 return 0; |
4071 } | 4089 } |
4072 | 4090 |
4073 static int | 4091 static int |
4074 pymap_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict) | 4092 pymap_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict) |
4080 PyObject *litem; | 4098 PyObject *litem; |
4081 PyObject *keyObject; | 4099 PyObject *keyObject; |
4082 PyObject *valObject; | 4100 PyObject *valObject; |
4083 Py_ssize_t lsize; | 4101 Py_ssize_t lsize; |
4084 | 4102 |
4085 dict = dict_alloc(); | 4103 if (!(dict = dict_alloc())) |
4086 if (dict == NULL) | |
4087 { | |
4088 PyErr_NoMemory(); | |
4089 return -1; | 4104 return -1; |
4090 } | |
4091 | 4105 |
4092 tv->v_type = VAR_DICT; | 4106 tv->v_type = VAR_DICT; |
4093 tv->vval.v_dict = dict; | 4107 tv->vval.v_dict = dict; |
4094 | 4108 |
4095 list = PyMapping_Items(obj); | 4109 list = PyMapping_Items(obj); |
4096 if (list == NULL) | 4110 if (list == NULL) |
4111 { | |
4112 dict_unref(dict); | |
4097 return -1; | 4113 return -1; |
4114 } | |
4098 lsize = PyList_Size(list); | 4115 lsize = PyList_Size(list); |
4099 while (lsize--) | 4116 while (lsize--) |
4100 { | 4117 { |
4101 DICTKEY_DECL | 4118 DICTKEY_DECL |
4102 | 4119 |
4103 litem = PyList_GetItem(list, lsize); | 4120 litem = PyList_GetItem(list, lsize); |
4104 if (litem == NULL) | 4121 if (litem == NULL) |
4105 { | 4122 { |
4106 Py_DECREF(list); | 4123 Py_DECREF(list); |
4124 dict_unref(dict); | |
4107 return -1; | 4125 return -1; |
4108 } | 4126 } |
4109 | 4127 |
4110 if (!(keyObject = PyTuple_GetItem(litem, 0))) | 4128 if (!(keyObject = PyTuple_GetItem(litem, 0))) |
4111 { | 4129 { |
4112 Py_DECREF(list); | 4130 Py_DECREF(list); |
4113 Py_DECREF(litem); | 4131 Py_DECREF(litem); |
4114 return -1; | 4132 dict_unref(dict); |
4115 } | 4133 return -1; |
4116 | 4134 } |
4117 DICTKEY_GET(-1, 1) | 4135 |
4118 | 4136 if (!DICTKEY_SET_KEY) |
4119 if (!(valObject = PyTuple_GetItem(litem, 1))) | 4137 { |
4120 { | 4138 dict_unref(dict); |
4121 Py_DECREF(list); | 4139 Py_DECREF(list); |
4122 Py_DECREF(litem); | 4140 Py_DECREF(litem); |
4123 DICTKEY_UNREF | 4141 DICTKEY_UNREF |
4124 return -1; | 4142 return -1; |
4125 } | 4143 } |
4144 DICTKEY_CHECK_EMPTY(-1) | |
4145 | |
4146 if (!(valObject = PyTuple_GetItem(litem, 1))) | |
4147 { | |
4148 Py_DECREF(list); | |
4149 Py_DECREF(litem); | |
4150 dict_unref(dict); | |
4151 DICTKEY_UNREF | |
4152 return -1; | |
4153 } | |
4126 | 4154 |
4127 Py_DECREF(litem); | 4155 Py_DECREF(litem); |
4128 | 4156 |
4129 di = dictitem_alloc(key); | 4157 di = dictitem_alloc(key); |
4130 | 4158 |
4131 DICTKEY_UNREF | 4159 DICTKEY_UNREF |
4132 | 4160 |
4133 if (di == NULL) | 4161 if (di == NULL) |
4134 { | 4162 { |
4135 Py_DECREF(list); | 4163 Py_DECREF(list); |
4136 Py_DECREF(valObject); | 4164 dict_unref(dict); |
4137 PyErr_NoMemory(); | 4165 PyErr_NoMemory(); |
4138 return -1; | 4166 return -1; |
4139 } | 4167 } |
4140 di->di_tv.v_lock = 0; | 4168 di->di_tv.v_lock = 0; |
4141 | 4169 |
4142 if (_ConvertFromPyObject(valObject, &di->di_tv, lookup_dict) == -1) | 4170 if (_ConvertFromPyObject(valObject, &di->di_tv, lookup_dict) == -1) |
4143 { | 4171 { |
4144 vim_free(di); | 4172 vim_free(di); |
4173 dict_unref(dict); | |
4145 Py_DECREF(list); | 4174 Py_DECREF(list); |
4146 Py_DECREF(valObject); | 4175 return -1; |
4147 return -1; | 4176 } |
4148 } | |
4149 | |
4150 Py_DECREF(valObject); | |
4151 | 4177 |
4152 if (dict_add(dict, di) == FAIL) | 4178 if (dict_add(dict, di) == FAIL) |
4153 { | 4179 { |
4154 clear_tv(&di->di_tv); | 4180 dictitem_free(di); |
4155 vim_free(di); | 4181 dict_unref(dict); |
4156 Py_DECREF(list); | 4182 Py_DECREF(list); |
4157 PyErr_SetVim(_("failed to add key to dictionary")); | 4183 PyErr_SetVim(_("failed to add key to dictionary")); |
4158 return -1; | 4184 return -1; |
4159 } | 4185 } |
4160 } | 4186 } |
4187 --dict->dv_refcount; | |
4161 Py_DECREF(list); | 4188 Py_DECREF(list); |
4162 return 0; | 4189 return 0; |
4163 } | 4190 } |
4164 | 4191 |
4192 static list_T * | |
4193 py_list_alloc() | |
4194 { | |
4195 list_T *r; | |
4196 | |
4197 if (!(r = list_alloc())) | |
4198 { | |
4199 PyErr_NoMemory(); | |
4200 return NULL; | |
4201 } | |
4202 ++r->lv_refcount; | |
4203 | |
4204 return r; | |
4205 } | |
4206 | |
4165 static int | 4207 static int |
4166 pyseq_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict) | 4208 pyseq_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict) |
4167 { | 4209 { |
4168 list_T *l; | 4210 list_T *l; |
4169 | 4211 |
4170 l = list_alloc(); | 4212 if (!(l = py_list_alloc())) |
4171 if (l == NULL) | |
4172 { | |
4173 PyErr_NoMemory(); | |
4174 return -1; | 4213 return -1; |
4175 } | |
4176 | 4214 |
4177 tv->v_type = VAR_LIST; | 4215 tv->v_type = VAR_LIST; |
4178 tv->vval.v_list = l; | 4216 tv->vval.v_list = l; |
4179 | 4217 |
4180 if (list_py_concat(l, obj, lookup_dict) == -1) | 4218 if (list_py_concat(l, obj, lookup_dict) == -1) |
4219 { | |
4220 list_unref(l); | |
4181 return -1; | 4221 return -1; |
4182 | 4222 } |
4223 | |
4224 --l->lv_refcount; | |
4183 return 0; | 4225 return 0; |
4184 } | 4226 } |
4185 | 4227 |
4186 static int | 4228 static int |
4187 pyiter_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict) | 4229 pyiter_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict) |
4188 { | 4230 { |
4189 PyObject *iterator = PyObject_GetIter(obj); | 4231 PyObject *iterator; |
4190 PyObject *item; | 4232 PyObject *item; |
4191 list_T *l; | 4233 list_T *l; |
4192 listitem_T *li; | 4234 listitem_T *li; |
4193 | 4235 |
4194 l = list_alloc(); | 4236 if (!(l = py_list_alloc())) |
4195 | |
4196 if (l == NULL) | |
4197 { | |
4198 PyErr_NoMemory(); | |
4199 return -1; | 4237 return -1; |
4200 } | |
4201 | 4238 |
4202 tv->vval.v_list = l; | 4239 tv->vval.v_list = l; |
4203 tv->v_type = VAR_LIST; | 4240 tv->v_type = VAR_LIST; |
4204 | 4241 |
4205 | 4242 if (!(iterator = PyObject_GetIter(obj))) |
4206 if (iterator == NULL) | 4243 { |
4244 list_unref(l); | |
4207 return -1; | 4245 return -1; |
4246 } | |
4208 | 4247 |
4209 while ((item = PyIter_Next(iterator))) | 4248 while ((item = PyIter_Next(iterator))) |
4210 { | 4249 { |
4211 li = listitem_alloc(); | 4250 li = listitem_alloc(); |
4212 if (li == NULL) | 4251 if (li == NULL) |
4213 { | 4252 { |
4253 list_unref(l); | |
4214 Py_DECREF(iterator); | 4254 Py_DECREF(iterator); |
4215 PyErr_NoMemory(); | 4255 PyErr_NoMemory(); |
4216 return -1; | 4256 return -1; |
4217 } | 4257 } |
4218 li->li_tv.v_lock = 0; | 4258 li->li_tv.v_lock = 0; |
4219 | 4259 |
4220 if (_ConvertFromPyObject(item, &li->li_tv, lookup_dict) == -1) | 4260 if (_ConvertFromPyObject(item, &li->li_tv, lookup_dict) == -1) |
4221 { | 4261 { |
4262 list_unref(l); | |
4263 listitem_free(li); | |
4222 Py_DECREF(item); | 4264 Py_DECREF(item); |
4223 Py_DECREF(iterator); | 4265 Py_DECREF(iterator); |
4224 return -1; | 4266 return -1; |
4225 } | 4267 } |
4226 | 4268 |
4228 | 4270 |
4229 Py_DECREF(item); | 4271 Py_DECREF(item); |
4230 } | 4272 } |
4231 | 4273 |
4232 Py_DECREF(iterator); | 4274 Py_DECREF(iterator); |
4275 | |
4276 /* Iterator may have finished due to an exception */ | |
4277 if (PyErr_Occurred()) | |
4278 { | |
4279 list_unref(l); | |
4280 return -1; | |
4281 } | |
4282 | |
4283 --l->lv_refcount; | |
4233 return 0; | 4284 return 0; |
4234 } | 4285 } |
4235 | 4286 |
4236 typedef int (*pytotvfunc)(PyObject *, typval_T *, PyObject *); | 4287 typedef int (*pytotvfunc)(PyObject *, typval_T *, PyObject *); |
4237 | 4288 |
4293 ConvertFromPyObject(PyObject *obj, typval_T *tv) | 4344 ConvertFromPyObject(PyObject *obj, typval_T *tv) |
4294 { | 4345 { |
4295 PyObject *lookup_dict; | 4346 PyObject *lookup_dict; |
4296 int r; | 4347 int r; |
4297 | 4348 |
4298 lookup_dict = PyDict_New(); | 4349 if (!(lookup_dict = PyDict_New())) |
4350 return -1; | |
4299 r = _ConvertFromPyObject(obj, tv, lookup_dict); | 4351 r = _ConvertFromPyObject(obj, tv, lookup_dict); |
4300 Py_DECREF(lookup_dict); | 4352 Py_DECREF(lookup_dict); |
4301 return r; | 4353 return r; |
4302 } | 4354 } |
4303 | 4355 |