diff options
author | Erlend Egeberg Aasland <erlend.aasland@innova.no> | 2021-05-27 17:23:07 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-27 17:23:07 (GMT) |
commit | fba42d11880f444bb94d9891e3949f082a57b9a9 (patch) | |
tree | 5b7ede874a087a0384add5679aad8bff56932ae4 /Modules | |
parent | 164a4f46d1606e21d82babc010e397a9116e6730 (diff) | |
download | cpython-fba42d11880f444bb94d9891e3949f082a57b9a9.zip cpython-fba42d11880f444bb94d9891e3949f082a57b9a9.tar.gz cpython-fba42d11880f444bb94d9891e3949f082a57b9a9.tar.bz2 |
bpo-42972: Fully implement GC protocol for re types (GH-26368)
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_sre.c | 100 |
1 files changed, 81 insertions, 19 deletions
diff --git a/Modules/_sre.c b/Modules/_sre.c index a313ea1..d863ae0 100644 --- a/Modules/_sre.c +++ b/Modules/_sre.c @@ -563,17 +563,36 @@ pattern_error(Py_ssize_t status) } } +static int +pattern_traverse(PatternObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + Py_VISIT(self->groupindex); + Py_VISIT(self->indexgroup); + Py_VISIT(self->pattern); + return 0; +} + +static int +pattern_clear(PatternObject *self) +{ + Py_CLEAR(self->groupindex); + Py_CLEAR(self->indexgroup); + Py_CLEAR(self->pattern); + return 0; +} + static void pattern_dealloc(PatternObject* self) { PyTypeObject *tp = Py_TYPE(self); - if (self->weakreflist != NULL) + PyObject_GC_UnTrack(self); + if (self->weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject *) self); - Py_XDECREF(self->pattern); - Py_XDECREF(self->groupindex); - Py_XDECREF(self->indexgroup); - PyObject_Free(self); + } + (void)pattern_clear(self); + tp->tp_free(self); Py_DECREF(tp); } @@ -1397,7 +1416,7 @@ _sre_compile_impl(PyObject *module, PyObject *pattern, int flags, n = PyList_GET_SIZE(code); /* coverity[ampersand_in_size] */ - self = PyObject_NewVar(PatternObject, module_state->Pattern_Type, n); + self = PyObject_GC_NewVar(PatternObject, module_state->Pattern_Type, n); if (!self) return NULL; self->weakreflist = NULL; @@ -1417,6 +1436,7 @@ _sre_compile_impl(PyObject *module, PyObject *pattern, int flags, break; } } + PyObject_GC_Track(self); if (PyErr_Occurred()) { Py_DECREF(self); @@ -1938,15 +1958,33 @@ _validate(PatternObject *self) /* -------------------------------------------------------------------- */ /* match methods */ +static int +match_traverse(MatchObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + Py_VISIT(self->string); + Py_VISIT(self->regs); + Py_VISIT(self->pattern); + return 0; +} + +static int +match_clear(MatchObject *self) +{ + Py_CLEAR(self->string); + Py_CLEAR(self->regs); + Py_CLEAR(self->pattern); + return 0; +} + static void match_dealloc(MatchObject* self) { PyTypeObject *tp = Py_TYPE(self); - Py_XDECREF(self->regs); - Py_XDECREF(self->string); - Py_DECREF(self->pattern); - PyObject_Free(self); + PyObject_GC_UnTrack(self); + (void)match_clear(self); + tp->tp_free(self); Py_DECREF(tp); } @@ -2392,9 +2430,9 @@ pattern_new_match(_sremodulestate* module_state, /* create match object (with room for extra group marks) */ /* coverity[ampersand_in_size] */ - match = PyObject_NewVar(MatchObject, - module_state->Match_Type, - 2*(pattern->groups+1)); + match = PyObject_GC_NewVar(MatchObject, + module_state->Match_Type, + 2*(pattern->groups+1)); if (!match) return NULL; @@ -2427,6 +2465,7 @@ pattern_new_match(_sremodulestate* module_state, match->lastindex = state->lastindex; + PyObject_GC_Track(match); return (PyObject*) match; } else if (status == 0) { @@ -2445,14 +2484,30 @@ pattern_new_match(_sremodulestate* module_state, /* -------------------------------------------------------------------- */ /* scanner methods (experimental) */ +static int +scanner_traverse(ScannerObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + Py_VISIT(self->pattern); + return 0; +} + +static int +scanner_clear(ScannerObject *self) +{ + Py_CLEAR(self->pattern); + return 0; +} + static void scanner_dealloc(ScannerObject* self) { PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(self); state_fini(&self->state); - Py_XDECREF(self->pattern); - PyObject_Free(self); + (void)scanner_clear(self); + tp->tp_free(self); Py_DECREF(tp); } @@ -2549,7 +2604,7 @@ pattern_scanner(_sremodulestate *module_state, ScannerObject* scanner; /* create scanner object */ - scanner = PyObject_New(ScannerObject, module_state->Scanner_Type); + scanner = PyObject_GC_New(ScannerObject, module_state->Scanner_Type); if (!scanner) return NULL; scanner->pattern = NULL; @@ -2563,6 +2618,7 @@ pattern_scanner(_sremodulestate *module_state, Py_INCREF(self); scanner->pattern = (PyObject*) self; + PyObject_GC_Track(scanner); return (PyObject*) scanner; } @@ -2684,6 +2740,8 @@ static PyType_Slot pattern_slots[] = { {Py_tp_methods, pattern_methods}, {Py_tp_members, pattern_members}, {Py_tp_getset, pattern_getset}, + {Py_tp_traverse, pattern_traverse}, + {Py_tp_clear, pattern_clear}, {0, NULL}, }; @@ -2692,7 +2750,7 @@ static PyType_Spec pattern_spec = { .basicsize = sizeof(PatternObject), .itemsize = sizeof(SRE_CODE), .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | - Py_TPFLAGS_DISALLOW_INSTANTIATION), + Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_HAVE_GC), .slots = pattern_slots, }; @@ -2742,6 +2800,8 @@ static PyType_Slot match_slots[] = { {Py_tp_methods, match_methods}, {Py_tp_members, match_members}, {Py_tp_getset, match_getset}, + {Py_tp_traverse, match_traverse}, + {Py_tp_clear, match_clear}, /* As mapping. * @@ -2758,7 +2818,7 @@ static PyType_Spec match_spec = { .basicsize = sizeof(MatchObject), .itemsize = sizeof(Py_ssize_t), .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | - Py_TPFLAGS_DISALLOW_INSTANTIATION), + Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_HAVE_GC), .slots = match_slots, }; @@ -2778,6 +2838,8 @@ static PyType_Slot scanner_slots[] = { {Py_tp_dealloc, scanner_dealloc}, {Py_tp_methods, scanner_methods}, {Py_tp_members, scanner_members}, + {Py_tp_traverse, scanner_traverse}, + {Py_tp_clear, scanner_clear}, {0, NULL}, }; @@ -2785,7 +2847,7 @@ static PyType_Spec scanner_spec = { .name = "_" SRE_MODULE ".SRE_Scanner", .basicsize = sizeof(ScannerObject), .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | - Py_TPFLAGS_DISALLOW_INSTANTIATION), + Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_HAVE_GC), .slots = scanner_slots, }; |