mirror of https://github.com/python/cpython
Close #18469: Replace PyDict_GetItemString() with _PyDict_GetItemId() in structseq.c
_PyDict_GetItemId() is more efficient: it only builds the Unicode string once. Identifiers (dictionary keys) are now created at Python initialization, and if the creation failed, Python does exit with a fatal error. Before, PyDict_GetItemString() failure was not handled: structseq_new() could call PyObject_GC_NewVar() with a negative size, and structseq_dealloc() could also crash.
This commit is contained in:
parent
b8f602a60a
commit
26f91999b4
|
@ -11,17 +11,20 @@ static char unnamed_fields_key[] = "n_unnamed_fields";
|
||||||
/* Fields with this name have only a field index, not a field name.
|
/* Fields with this name have only a field index, not a field name.
|
||||||
They are only allowed for indices < n_visible_fields. */
|
They are only allowed for indices < n_visible_fields. */
|
||||||
char *PyStructSequence_UnnamedField = "unnamed field";
|
char *PyStructSequence_UnnamedField = "unnamed field";
|
||||||
|
_Py_IDENTIFIER(n_sequence_fields);
|
||||||
|
_Py_IDENTIFIER(n_fields);
|
||||||
|
_Py_IDENTIFIER(n_unnamed_fields);
|
||||||
|
|
||||||
#define VISIBLE_SIZE(op) Py_SIZE(op)
|
#define VISIBLE_SIZE(op) Py_SIZE(op)
|
||||||
#define VISIBLE_SIZE_TP(tp) PyLong_AsLong( \
|
#define VISIBLE_SIZE_TP(tp) PyLong_AsLong( \
|
||||||
PyDict_GetItemString((tp)->tp_dict, visible_length_key))
|
_PyDict_GetItemId((tp)->tp_dict, &PyId_n_sequence_fields))
|
||||||
|
|
||||||
#define REAL_SIZE_TP(tp) PyLong_AsLong( \
|
#define REAL_SIZE_TP(tp) PyLong_AsLong( \
|
||||||
PyDict_GetItemString((tp)->tp_dict, real_length_key))
|
_PyDict_GetItemId((tp)->tp_dict, &PyId_n_fields))
|
||||||
#define REAL_SIZE(op) REAL_SIZE_TP(Py_TYPE(op))
|
#define REAL_SIZE(op) REAL_SIZE_TP(Py_TYPE(op))
|
||||||
|
|
||||||
#define UNNAMED_FIELDS_TP(tp) PyLong_AsLong( \
|
#define UNNAMED_FIELDS_TP(tp) PyLong_AsLong( \
|
||||||
PyDict_GetItemString((tp)->tp_dict, unnamed_fields_key))
|
_PyDict_GetItemId((tp)->tp_dict, &PyId_n_unnamed_fields))
|
||||||
#define UNNAMED_FIELDS(op) UNNAMED_FIELDS_TP(Py_TYPE(op))
|
#define UNNAMED_FIELDS(op) UNNAMED_FIELDS_TP(Py_TYPE(op))
|
||||||
|
|
||||||
|
|
||||||
|
@ -382,9 +385,21 @@ PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc)
|
||||||
PyTypeObject*
|
PyTypeObject*
|
||||||
PyStructSequence_NewType(PyStructSequence_Desc *desc)
|
PyStructSequence_NewType(PyStructSequence_Desc *desc)
|
||||||
{
|
{
|
||||||
PyTypeObject *result = (PyTypeObject*)PyType_GenericAlloc(&PyType_Type, 0);
|
PyTypeObject *result;
|
||||||
|
|
||||||
|
result = (PyTypeObject*)PyType_GenericAlloc(&PyType_Type, 0);
|
||||||
if (result != NULL) {
|
if (result != NULL) {
|
||||||
PyStructSequence_InitType(result, desc);
|
PyStructSequence_InitType(result, desc);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _PyStructSequence_Init(void)
|
||||||
|
{
|
||||||
|
if (_PyUnicode_FromId(&PyId_n_sequence_fields) == NULL
|
||||||
|
|| _PyUnicode_FromId(&PyId_n_fields) == NULL
|
||||||
|
|| _PyUnicode_FromId(&PyId_n_unnamed_fields) == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -86,6 +86,7 @@ static void call_py_exitfuncs(void);
|
||||||
static void wait_for_thread_shutdown(void);
|
static void wait_for_thread_shutdown(void);
|
||||||
static void call_ll_exitfuncs(void);
|
static void call_ll_exitfuncs(void);
|
||||||
extern int _PyUnicode_Init(void);
|
extern int _PyUnicode_Init(void);
|
||||||
|
extern int _PyStructSequence_Init(void);
|
||||||
extern void _PyUnicode_Fini(void);
|
extern void _PyUnicode_Fini(void);
|
||||||
extern int _PyLong_Init(void);
|
extern int _PyLong_Init(void);
|
||||||
extern void PyLong_Fini(void);
|
extern void PyLong_Fini(void);
|
||||||
|
@ -336,6 +337,8 @@ _Py_InitializeEx_Private(int install_sigs, int install_importlib)
|
||||||
/* Init Unicode implementation; relies on the codec registry */
|
/* Init Unicode implementation; relies on the codec registry */
|
||||||
if (_PyUnicode_Init() < 0)
|
if (_PyUnicode_Init() < 0)
|
||||||
Py_FatalError("Py_Initialize: can't initialize unicode");
|
Py_FatalError("Py_Initialize: can't initialize unicode");
|
||||||
|
if (_PyStructSequence_Init() < 0)
|
||||||
|
Py_FatalError("Py_Initialize: can't initialize structseq");
|
||||||
|
|
||||||
bimod = _PyBuiltin_Init();
|
bimod = _PyBuiltin_Init();
|
||||||
if (bimod == NULL)
|
if (bimod == NULL)
|
||||||
|
|
Loading…
Reference in New Issue