Mercurial > vim
comparison src/if_py_both.h @ 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 | 7d81f4e96728 |
children | 9b800f0a757f |
comparison
equal
deleted
inserted
replaced
4432:b2f7c4f0da0f | 4433:8a3ca4adb5d8 |
---|---|
541 | 541 |
542 static PyTypeObject IterType; | 542 static PyTypeObject IterType; |
543 | 543 |
544 typedef PyObject *(*nextfun)(void **); | 544 typedef PyObject *(*nextfun)(void **); |
545 typedef void (*destructorfun)(void *); | 545 typedef void (*destructorfun)(void *); |
546 typedef int (*traversefun)(void *, visitproc, void *); | |
547 typedef int (*clearfun)(void **); | |
546 | 548 |
547 /* Main purpose of this object is removing the need for do python initialization | 549 /* Main purpose of this object is removing the need for do python initialization |
548 * (i.e. PyType_Ready and setting type attributes) for a big bunch of objects. | 550 * (i.e. PyType_Ready and setting type attributes) for a big bunch of objects. |
549 */ | 551 */ |
550 | 552 |
552 { | 554 { |
553 PyObject_HEAD | 555 PyObject_HEAD |
554 void *cur; | 556 void *cur; |
555 nextfun next; | 557 nextfun next; |
556 destructorfun destruct; | 558 destructorfun destruct; |
559 traversefun traverse; | |
560 clearfun clear; | |
557 } IterObject; | 561 } IterObject; |
558 | 562 |
559 static PyObject * | 563 static PyObject * |
560 IterNew(void *start, destructorfun destruct, nextfun next) | 564 IterNew(void *start, destructorfun destruct, nextfun next, traversefun traverse, |
565 clearfun clear) | |
561 { | 566 { |
562 IterObject *self; | 567 IterObject *self; |
563 | 568 |
564 self = PyObject_NEW(IterObject, &IterType); | 569 self = PyObject_NEW(IterObject, &IterType); |
565 self->cur = start; | 570 self->cur = start; |
566 self->next = next; | 571 self->next = next; |
567 self->destruct = destruct; | 572 self->destruct = destruct; |
573 self->traverse = traverse; | |
574 self->clear = clear; | |
568 | 575 |
569 return (PyObject *)(self); | 576 return (PyObject *)(self); |
570 } | 577 } |
571 | 578 |
572 static void | 579 static void |
575 IterObject *this = (IterObject *)(self); | 582 IterObject *this = (IterObject *)(self); |
576 | 583 |
577 this->destruct(this->cur); | 584 this->destruct(this->cur); |
578 | 585 |
579 DESTRUCTOR_FINISH(self); | 586 DESTRUCTOR_FINISH(self); |
587 } | |
588 | |
589 static int | |
590 IterTraverse(PyObject *self, visitproc visit, void *arg) | |
591 { | |
592 IterObject *this = (IterObject *)(self); | |
593 | |
594 if (this->traverse != NULL) | |
595 return this->traverse(this->cur, visit, arg); | |
596 else | |
597 return 0; | |
598 } | |
599 | |
600 static int | |
601 IterClear(PyObject *self) | |
602 { | |
603 IterObject *this = (IterObject *)(self); | |
604 | |
605 if (this->clear != NULL) | |
606 return this->clear(&this->cur); | |
607 else | |
608 return 0; | |
580 } | 609 } |
581 | 610 |
582 static PyObject * | 611 static PyObject * |
583 IterNext(PyObject *self) | 612 IterNext(PyObject *self) |
584 { | 613 { |
1032 list_add_watch(l, &lii->lw); | 1061 list_add_watch(l, &lii->lw); |
1033 lii->lw.lw_item = l->lv_first; | 1062 lii->lw.lw_item = l->lv_first; |
1034 lii->list = l; | 1063 lii->list = l; |
1035 | 1064 |
1036 return IterNew(lii, | 1065 return IterNew(lii, |
1037 (destructorfun) ListIterDestruct, (nextfun) ListIterNext); | 1066 (destructorfun) ListIterDestruct, (nextfun) ListIterNext, |
1067 NULL, NULL); | |
1038 } | 1068 } |
1039 | 1069 |
1040 static int | 1070 static int |
1041 ListAssItem(PyObject *self, Py_ssize_t index, PyObject *obj) | 1071 ListAssItem(PyObject *self, Py_ssize_t index, PyObject *obj) |
1042 { | 1072 { |
1345 int opt_type; | 1375 int opt_type; |
1346 void *from; | 1376 void *from; |
1347 checkfun Check; | 1377 checkfun Check; |
1348 PyObject *fromObj; | 1378 PyObject *fromObj; |
1349 } OptionsObject; | 1379 } OptionsObject; |
1380 | |
1381 static int | |
1382 dummy_check(void *arg UNUSED) | |
1383 { | |
1384 return 0; | |
1385 } | |
1386 | |
1387 static PyObject * | |
1388 OptionsNew(int opt_type, void *from, checkfun Check, PyObject *fromObj) | |
1389 { | |
1390 OptionsObject *self; | |
1391 | |
1392 self = PyObject_NEW(OptionsObject, &OptionsType); | |
1393 if (self == NULL) | |
1394 return NULL; | |
1395 | |
1396 self->opt_type = opt_type; | |
1397 self->from = from; | |
1398 self->Check = Check; | |
1399 self->fromObj = fromObj; | |
1400 if (fromObj) | |
1401 Py_INCREF(fromObj); | |
1402 | |
1403 return (PyObject *)(self); | |
1404 } | |
1405 | |
1406 static void | |
1407 OptionsDestructor(PyObject *self) | |
1408 { | |
1409 if (((OptionsObject *)(self))->fromObj) | |
1410 Py_DECREF(((OptionsObject *)(self))->fromObj); | |
1411 DESTRUCTOR_FINISH(self); | |
1412 } | |
1413 | |
1414 static int | |
1415 OptionsTraverse(PyObject *self, visitproc visit, void *arg) | |
1416 { | |
1417 Py_VISIT(((OptionsObject *)(self))->fromObj); | |
1418 return 0; | |
1419 } | |
1420 | |
1421 static int | |
1422 OptionsClear(PyObject *self) | |
1423 { | |
1424 Py_CLEAR(((OptionsObject *)(self))->fromObj); | |
1425 return 0; | |
1426 } | |
1350 | 1427 |
1351 static PyObject * | 1428 static PyObject * |
1352 OptionsItem(OptionsObject *this, PyObject *keyObject) | 1429 OptionsItem(OptionsObject *this, PyObject *keyObject) |
1353 { | 1430 { |
1354 char_u *key; | 1431 char_u *key; |
1560 } | 1637 } |
1561 | 1638 |
1562 return r; | 1639 return r; |
1563 } | 1640 } |
1564 | 1641 |
1565 static int | |
1566 dummy_check(void *arg UNUSED) | |
1567 { | |
1568 return 0; | |
1569 } | |
1570 | |
1571 static PyObject * | |
1572 OptionsNew(int opt_type, void *from, checkfun Check, PyObject *fromObj) | |
1573 { | |
1574 OptionsObject *self; | |
1575 | |
1576 self = PyObject_NEW(OptionsObject, &OptionsType); | |
1577 if (self == NULL) | |
1578 return NULL; | |
1579 | |
1580 self->opt_type = opt_type; | |
1581 self->from = from; | |
1582 self->Check = Check; | |
1583 self->fromObj = fromObj; | |
1584 if (fromObj) | |
1585 Py_INCREF(fromObj); | |
1586 | |
1587 return (PyObject *)(self); | |
1588 } | |
1589 | |
1590 static void | |
1591 OptionsDestructor(PyObject *self) | |
1592 { | |
1593 if (((OptionsObject *)(self))->fromObj) | |
1594 Py_DECREF(((OptionsObject *)(self))->fromObj); | |
1595 DESTRUCTOR_FINISH(self); | |
1596 } | |
1597 | |
1598 static PyMappingMethods OptionsAsMapping = { | 1642 static PyMappingMethods OptionsAsMapping = { |
1599 (lenfunc) NULL, | 1643 (lenfunc) NULL, |
1600 (binaryfunc) OptionsItem, | 1644 (binaryfunc) OptionsItem, |
1601 (objobjargproc) OptionsAssItem, | 1645 (objobjargproc) OptionsAssItem, |
1602 }; | 1646 }; |
1840 else | 1884 else |
1841 return tabObject->tab->tp_firstwin; | 1885 return tabObject->tab->tp_firstwin; |
1842 } | 1886 } |
1843 else | 1887 else |
1844 return firstwin; | 1888 return firstwin; |
1889 } | |
1890 static int | |
1891 WindowTraverse(PyObject *self, visitproc visit, void *arg) | |
1892 { | |
1893 Py_VISIT(((PyObject *)(((WindowObject *)(self))->tabObject))); | |
1894 return 0; | |
1895 } | |
1896 | |
1897 static int | |
1898 WindowClear(PyObject *self) | |
1899 { | |
1900 Py_CLEAR((((WindowObject *)(self))->tabObject)); | |
1901 return 0; | |
1845 } | 1902 } |
1846 | 1903 |
1847 static PyObject * | 1904 static PyObject * |
1848 WindowAttr(WindowObject *this, char *name) | 1905 WindowAttr(WindowObject *this, char *name) |
1849 { | 1906 { |
3191 { | 3248 { |
3192 Py_DECREF(buffer); | 3249 Py_DECREF(buffer); |
3193 } | 3250 } |
3194 } | 3251 } |
3195 | 3252 |
3253 static int | |
3254 BufMapIterTraverse(PyObject *buffer, visitproc visit, void *arg) | |
3255 { | |
3256 Py_VISIT(buffer); | |
3257 return 0; | |
3258 } | |
3259 | |
3260 static int | |
3261 BufMapIterClear(PyObject **buffer) | |
3262 { | |
3263 Py_CLEAR(*buffer); | |
3264 return 0; | |
3265 } | |
3266 | |
3196 static PyObject * | 3267 static PyObject * |
3197 BufMapIterNext(PyObject **buffer) | 3268 BufMapIterNext(PyObject **buffer) |
3198 { | 3269 { |
3199 PyObject *next; | 3270 PyObject *next; |
3200 PyObject *r; | 3271 PyObject *r; |
3226 { | 3297 { |
3227 PyObject *buffer; | 3298 PyObject *buffer; |
3228 | 3299 |
3229 buffer = BufferNew(firstbuf); | 3300 buffer = BufferNew(firstbuf); |
3230 return IterNew(buffer, | 3301 return IterNew(buffer, |
3231 (destructorfun) BufMapIterDestruct, (nextfun) BufMapIterNext); | 3302 (destructorfun) BufMapIterDestruct, (nextfun) BufMapIterNext, |
3303 (traversefun) BufMapIterTraverse, (clearfun) BufMapIterClear); | |
3232 } | 3304 } |
3233 | 3305 |
3234 static PyMappingMethods BufMapAsMapping = { | 3306 static PyMappingMethods BufMapAsMapping = { |
3235 (lenfunc) BufMapLength, | 3307 (lenfunc) BufMapLength, |
3236 (binaryfunc) BufMapItem, | 3308 (binaryfunc) BufMapItem, |
3835 IterType.tp_flags = Py_TPFLAGS_DEFAULT; | 3907 IterType.tp_flags = Py_TPFLAGS_DEFAULT; |
3836 IterType.tp_doc = "generic iterator object"; | 3908 IterType.tp_doc = "generic iterator object"; |
3837 IterType.tp_iter = IterIter; | 3909 IterType.tp_iter = IterIter; |
3838 IterType.tp_iternext = IterNext; | 3910 IterType.tp_iternext = IterNext; |
3839 IterType.tp_dealloc = IterDestructor; | 3911 IterType.tp_dealloc = IterDestructor; |
3912 IterType.tp_traverse = IterTraverse; | |
3913 IterType.tp_clear = IterClear; | |
3840 | 3914 |
3841 vim_memset(&BufferType, 0, sizeof(BufferType)); | 3915 vim_memset(&BufferType, 0, sizeof(BufferType)); |
3842 BufferType.tp_name = "vim.buffer"; | 3916 BufferType.tp_name = "vim.buffer"; |
3843 BufferType.tp_basicsize = sizeof(BufferType); | 3917 BufferType.tp_basicsize = sizeof(BufferType); |
3844 BufferType.tp_dealloc = BufferDestructor; | 3918 BufferType.tp_dealloc = BufferDestructor; |
3863 WindowType.tp_dealloc = WindowDestructor; | 3937 WindowType.tp_dealloc = WindowDestructor; |
3864 WindowType.tp_repr = WindowRepr; | 3938 WindowType.tp_repr = WindowRepr; |
3865 WindowType.tp_flags = Py_TPFLAGS_DEFAULT; | 3939 WindowType.tp_flags = Py_TPFLAGS_DEFAULT; |
3866 WindowType.tp_doc = "vim Window object"; | 3940 WindowType.tp_doc = "vim Window object"; |
3867 WindowType.tp_methods = WindowMethods; | 3941 WindowType.tp_methods = WindowMethods; |
3942 WindowType.tp_traverse = WindowTraverse; | |
3943 WindowType.tp_clear = WindowClear; | |
3868 #if PY_MAJOR_VERSION >= 3 | 3944 #if PY_MAJOR_VERSION >= 3 |
3869 WindowType.tp_getattro = WindowGetattro; | 3945 WindowType.tp_getattro = WindowGetattro; |
3870 WindowType.tp_setattro = WindowSetattro; | 3946 WindowType.tp_setattro = WindowSetattro; |
3871 WindowType.tp_alloc = call_PyType_GenericAlloc; | 3947 WindowType.tp_alloc = call_PyType_GenericAlloc; |
3872 WindowType.tp_new = call_PyType_GenericNew; | 3948 WindowType.tp_new = call_PyType_GenericNew; |
4001 OptionsType.tp_basicsize = sizeof(OptionsObject); | 4077 OptionsType.tp_basicsize = sizeof(OptionsObject); |
4002 OptionsType.tp_flags = Py_TPFLAGS_DEFAULT; | 4078 OptionsType.tp_flags = Py_TPFLAGS_DEFAULT; |
4003 OptionsType.tp_doc = "object for manipulating options"; | 4079 OptionsType.tp_doc = "object for manipulating options"; |
4004 OptionsType.tp_as_mapping = &OptionsAsMapping; | 4080 OptionsType.tp_as_mapping = &OptionsAsMapping; |
4005 OptionsType.tp_dealloc = OptionsDestructor; | 4081 OptionsType.tp_dealloc = OptionsDestructor; |
4082 OptionsType.tp_traverse = OptionsTraverse; | |
4083 OptionsType.tp_clear = OptionsClear; | |
4006 | 4084 |
4007 #if PY_MAJOR_VERSION >= 3 | 4085 #if PY_MAJOR_VERSION >= 3 |
4008 vim_memset(&vimmodule, 0, sizeof(vimmodule)); | 4086 vim_memset(&vimmodule, 0, sizeof(vimmodule)); |
4009 vimmodule.m_name = "vim"; | 4087 vimmodule.m_name = "vim"; |
4010 vimmodule.m_doc = "Vim Python interface\n"; | 4088 vimmodule.m_doc = "Vim Python interface\n"; |