diff -r 2c8ea2977530 Modules/_sre.c --- a/Modules/_sre.c Wed Aug 15 16:05:32 2012 +0200 +++ b/Modules/_sre.c Wed Aug 15 16:16:53 2012 +0200 @@ -48,6 +48,45 @@ #include +typedef struct { + PyObject *Pattern_Type; + PyObject *Match_Type; + PyObject *Scanner_Type; +} srestate; + + +#define sre_state(o) ((srestate *)PyModule_GetState(o)) + +static int +sre_clear(PyObject *m) +{ + srestate *s = sre_state(m); + Py_CLEAR(s->Pattern_Type); + Py_CLEAR(s->Match_Type); + Py_CLEAR(s->Scanner_Type); + return 0; +} + +static int +sre_traverse(PyObject *m, visitproc visit, void *arg) +{ + srestate *s = sre_state(m); + Py_VISIT(s->Pattern_Type); + Py_VISIT(s->Match_Type); + Py_VISIT(s->Scanner_Type); + return 0; +} + +static void +sre_free(void *m) +{ + sre_clear((PyObject *)m); +} + +static PyModuleDef sremodule; + +#define srestate_global ((srestate *)PyModule_GetState(PyState_FindModule(&sremodule))) + /* name of this module, minus the leading underscore */ #if !defined(SRE_MODULE) #define SRE_MODULE "sre" @@ -1851,6 +1890,7 @@ static void pattern_dealloc(PatternObject* self) { + PyTypeObject *type = Py_TYPE(self); if (self->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *) self); if (self->view.buf) @@ -1859,6 +1899,9 @@ Py_XDECREF(self->groupindex); Py_XDECREF(self->indexgroup); PyObject_DEL(self); + if((void *)type->tp_dealloc == (void *)pattern_dealloc) { + Py_DECREF(type); + } } static PyObject* @@ -2482,10 +2525,12 @@ PatternObject* copy; int offset; - copy = PyObject_NEW_VAR(PatternObject, &Pattern_Type, self->codesize); + copy = PyObject_NEW_VAR(PatternObject, + (PyTypeObject *)srestate_global->Pattern_Type, + self->codesize); if (!copy) return NULL; - + Py_INCREF(srestate_global->Pattern_Type); offset = offsetof(PatternObject, groups); Py_XINCREF(self->groupindex); @@ -2594,37 +2639,25 @@ {NULL} /* Sentinel */ }; -static PyTypeObject Pattern_Type = { - PyVarObject_HEAD_INIT(NULL, 0) + +static PyType_Slot Pattern_Type_slots[] = { + {Py_tp_dealloc, (destructor)pattern_dealloc}, + {Py_tp_doc, pattern_doc}, + {Py_tp_methods, pattern_methods}, + {Py_tp_members, pattern_members}, + {Py_tp_getset, }, + {0, 0} +}; + +static PyType_Spec Pattern_Type_spec = { "_" SRE_MODULE ".SRE_Pattern", - sizeof(PatternObject), sizeof(SRE_CODE), - (destructor)pattern_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - pattern_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(PatternObject, weakreflist), /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - pattern_methods, /* tp_methods */ - pattern_members, /* tp_members */ + sizeof(PatternObject), + sizeof(SRE_CODE), + Py_TPFLAGS_DEFAULT, + Pattern_Type_slots, }; + static int _validate(PatternObject *self); /* Forward */ static PyObject * @@ -2649,7 +2682,9 @@ n = PyList_GET_SIZE(code); /* coverity[ampersand_in_size] */ - self = PyObject_NEW_VAR(PatternObject, &Pattern_Type, n); + self = PyObject_NEW_VAR(PatternObject, + (PyTypeObject *)srestate_global->Pattern_Type, + n); if (!self) return NULL; self->weakreflist = NULL; @@ -2688,7 +2723,7 @@ return NULL; } } - + Py_INCREF(srestate_global->Pattern_Type); Py_INCREF(pattern); self->pattern = pattern; @@ -3182,10 +3217,14 @@ static void match_dealloc(MatchObject* self) { + PyTypeObject *type = Py_TYPE(self); Py_XDECREF(self->regs); Py_XDECREF(self->string); Py_DECREF(self->pattern); PyObject_DEL(self); + if((void *)type->tp_dealloc == (void *)match_dealloc) { + Py_DECREF(type); + } } static PyObject* @@ -3498,9 +3537,10 @@ slots = 2 * (self->pattern->groups+1); - copy = PyObject_NEW_VAR(MatchObject, &Match_Type, slots); + copy = PyObject_NEW_VAR(MatchObject, (PyTypeObject *)srestate_global->Match_Type, slots); if (!copy) return NULL; + Py_INCREF(srestate_global->Match_Type); /* this value a constant, but any compiler should be able to figure that out all by itself */ @@ -3609,38 +3649,27 @@ /* FIXME: implement setattr("string", None) as a special case (to detach the associated string, if any */ -static PyTypeObject Match_Type = { - PyVarObject_HEAD_INIT(NULL,0) + + + +static PyType_Slot Match_Type_slots[] = { + {Py_tp_dealloc, (destructor)match_dealloc}, + {Py_tp_methods, match_methods}, + {Py_tp_members, match_members}, + {Py_tp_getset, match_getset}, + {Py_tp_base, }, + {0, 0} +}; + +static PyType_Spec Match_Type_spec = { "_" SRE_MODULE ".SRE_Match", - sizeof(MatchObject), sizeof(Py_ssize_t), - (destructor)match_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - match_methods, /* tp_methods */ - match_members, /* tp_members */ - match_getset, /* tp_getset */ + sizeof(MatchObject), + sizeof(Py_ssize_t), + Py_TPFLAGS_DEFAULT, + Match_Type_slots, }; + static PyObject* pattern_new_match(PatternObject* pattern, SRE_STATE* state, int status) { @@ -3655,11 +3684,13 @@ /* create match object (with room for extra group marks) */ /* coverity[ampersand_in_size] */ - match = PyObject_NEW_VAR(MatchObject, &Match_Type, + match = PyObject_NEW_VAR(MatchObject, + (PyTypeObject *)srestate_global->Match_Type, 2*(pattern->groups+1)); if (!match) return NULL; + Py_INCREF(srestate_global->Match_Type); Py_INCREF(pattern); match->pattern = pattern; @@ -3711,8 +3742,12 @@ static void scanner_dealloc(ScannerObject* self) { + PyTypeObject *type = Py_TYPE(self); state_fini(&self->state); Py_XDECREF(self->pattern); + if((void *)type->tp_dealloc == (void *)scanner_dealloc) { + Py_DECREF(type); + } PyObject_DEL(self); } @@ -3789,38 +3824,26 @@ {NULL} /* Sentinel */ }; -static PyTypeObject Scanner_Type = { - PyVarObject_HEAD_INIT(NULL, 0) + + + +static PyType_Slot Scanner_Type_slots[] = { + {Py_tp_dealloc, (destructor)scanner_dealloc}, + {Py_tp_methods, scanner_methods}, + {Py_tp_members, scanner_members}, + {Py_tp_base, }, + {0, 0} +}; + +static PyType_Spec Scanner_Type_spec = { "_" SRE_MODULE ".SRE_Scanner", - sizeof(ScannerObject), 0, - (destructor)scanner_dealloc,/* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - scanner_methods, /* tp_methods */ - scanner_members, /* tp_members */ - 0, /* tp_getset */ + sizeof(ScannerObject), + 0, + Py_TPFLAGS_DEFAULT, + Scanner_Type_slots, }; + static PyObject* pattern_scanner(PatternObject* pattern, PyObject* args, PyObject* kw) { @@ -3837,9 +3860,10 @@ return NULL; /* create scanner object */ - self = PyObject_NEW(ScannerObject, &Scanner_Type); + self = PyObject_NEW(ScannerObject, (PyTypeObject *)srestate_global->Scanner_Type); if (!self) return NULL; + Py_INCREF(srestate_global->Scanner_Type); self->pattern = NULL; string = state_init(&self->state, pattern, string, start, end); @@ -3861,32 +3885,40 @@ {NULL, NULL} }; -static struct PyModuleDef sremodule = { - PyModuleDef_HEAD_INIT, - "_" SRE_MODULE, - NULL, - -1, - _functions, - NULL, - NULL, - NULL, - NULL +static PyModuleDef sremodule = { + PyModuleDef_HEAD_INIT, + "_" SRE_MODULE, + NULL, + sizeof(srestate), + _functions, + NULL, + sre_traverse, + sre_clear, + sre_free }; -PyMODINIT_FUNC PyInit__sre(void) +PyMODINIT_FUNC +PyInit__sre(void) { PyObject* m; PyObject* d; PyObject* x; - /* Patch object types */ - if (PyType_Ready(&Pattern_Type) || PyType_Ready(&Match_Type) || - PyType_Ready(&Scanner_Type)) - return NULL; - m = PyModule_Create(&sremodule); if (m == NULL) return NULL; + + sre_state(m)->Pattern_Type = PyType_FromSpec(&Pattern_Type_spec); + ((PyTypeObject *)sre_state(m)->Pattern_Type)->tp_weaklistoffset = + offsetof(PatternObject, weakreflist); + sre_state(m)->Match_Type = PyType_FromSpec(&Match_Type_spec); + sre_state(m)->Scanner_Type = PyType_FromSpec(&Scanner_Type_spec); + + /* Patch object types */ + if (!sre_state(m)->Pattern_Type || !sre_state(m)->Match_Type || + !sre_state(m)->Scanner_Type) + return NULL; + d = PyModule_GetDict(m); x = PyLong_FromLong(SRE_MAGIC);