summaryrefslogtreecommitdiffstats
path: root/Objects/typeobject.c
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2020-01-30 08:02:14 (GMT)
committerGitHub <noreply@github.com>2020-01-30 08:02:14 (GMT)
commit7a1f6c2da46a04d0ff0acc01542f30bfeaf0e0c7 (patch)
tree97f3f57ed5557bb6eef9bc0fd3071f0fdaf3acd8 /Objects/typeobject.c
parent5eb8bff7e4aa7e4d8580a30323641388c8ff59a5 (diff)
downloadcpython-7a1f6c2da46a04d0ff0acc01542f30bfeaf0e0c7.zip
cpython-7a1f6c2da46a04d0ff0acc01542f30bfeaf0e0c7.tar.gz
cpython-7a1f6c2da46a04d0ff0acc01542f30bfeaf0e0c7.tar.bz2
bpo-38631: Avoid Py_FatalError() in init_slotdefs() (GH-18263)
Rename init_slotdefs() to _PyTypes_InitSlotDefs() and add a return value of type PyStatus. The function is now called exactly once from _PyTypes_Init(). Replace calls to init_slotdefs() with an assertion checking that slotdefs is initialized.
Diffstat (limited to 'Objects/typeobject.c')
-rw-r--r--Objects/typeobject.c35
1 files changed, 19 insertions, 16 deletions
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 5773eb7..b095e29 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -2,6 +2,7 @@
#include "Python.h"
#include "pycore_call.h"
+#include "pycore_initconfig.h"
#include "pycore_object.h"
#include "pycore_pyerrors.h"
#include "pycore_pystate.h"
@@ -6932,7 +6933,8 @@ which incorporates the additional structures used for numbers, sequences and
mappings. Note that multiple names may map to the same slot (e.g. __eq__,
__ne__ etc. all map to tp_richcompare) and one name may map to multiple slots
(e.g. __str__ affects tp_str as well as tp_repr). The table is terminated with
-an all-zero entry. (This table is further initialized in init_slotdefs().)
+an all-zero entry. (This table is further initialized in
+_PyTypes_InitSlotDefs().)
*/
typedef struct wrapperbase slotdef;
@@ -7423,28 +7425,29 @@ update_slots_callback(PyTypeObject *type, void *data)
static int slotdefs_initialized = 0;
/* Initialize the slotdefs table by adding interned string objects for the
names. */
-static void
-init_slotdefs(void)
+PyStatus
+_PyTypes_InitSlotDefs(void)
{
- slotdef *p;
+ if (slotdefs_initialized) {
+ return _PyStatus_OK();
+ }
- if (slotdefs_initialized)
- return;
- for (p = slotdefs; p->name; p++) {
+ for (slotdef *p = slotdefs; p->name; p++) {
/* Slots must be ordered by their offset in the PyHeapTypeObject. */
assert(!p[1].name || p->offset <= p[1].offset);
p->name_strobj = PyUnicode_InternFromString(p->name);
- if (!p->name_strobj || !PyUnicode_CHECK_INTERNED(p->name_strobj))
- Py_FatalError("Out of memory interning slotdef names");
+ if (!p->name_strobj || !PyUnicode_CHECK_INTERNED(p->name_strobj)) {
+ return _PyStatus_NO_MEMORY();
+ }
}
slotdefs_initialized = 1;
+ return _PyStatus_OK();
}
-/* Undo init_slotdefs, releasing the interned strings. */
+/* Undo _PyTypes_InitSlotDefs(), releasing the interned strings. */
static void clear_slotdefs(void)
{
- slotdef *p;
- for (p = slotdefs; p->name; p++) {
+ for (slotdef *p = slotdefs; p->name; p++) {
Py_CLEAR(p->name_strobj);
}
slotdefs_initialized = 0;
@@ -7462,7 +7465,7 @@ update_slot(PyTypeObject *type, PyObject *name)
assert(PyUnicode_CheckExact(name));
assert(PyUnicode_CHECK_INTERNED(name));
- init_slotdefs();
+ assert(slotdefs_initialized);
pp = ptrs;
for (p = slotdefs; p->name; p++) {
if (p->name_strobj == name)
@@ -7490,7 +7493,7 @@ fixup_slot_dispatchers(PyTypeObject *type)
{
slotdef *p;
- init_slotdefs();
+ assert(slotdefs_initialized);
for (p = slotdefs; p->name; )
p = update_one_slot(type, p);
}
@@ -7503,7 +7506,7 @@ update_all_slots(PyTypeObject* type)
/* Clear the VALID_VERSION flag of 'type' and all its subclasses. */
PyType_Modified(type);
- init_slotdefs();
+ assert(slotdefs_initialized);
for (p = slotdefs; p->name; p++) {
/* update_slot returns int but can't actually fail */
update_slot(type, p->name_strobj);
@@ -7663,7 +7666,7 @@ add_operators(PyTypeObject *type)
PyObject *descr;
void **ptr;
- init_slotdefs();
+ assert(slotdefs_initialized);
for (p = slotdefs; p->name; p++) {
if (p->wrapper == NULL)
continue;