gh-117139: Replace _PyList_FromArraySteal with stack ref variant (#122830)

This replaces `_PyList_FromArraySteal` with `_PyList_FromStackRefSteal`.
It's functionally equivalent, but takes a `_PyStackRef` array instead of
an array of `PyObject` pointers.

Co-authored-by: Ken Jin <kenjin@python.org>
This commit is contained in:
Sam Gross 2024-08-12 14:49:49 -04:00 committed by GitHub
parent 736fe4d23e
commit ab094d1b2b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 13 additions and 34 deletions

View File

@ -56,7 +56,10 @@ typedef struct {
PyListObject *it_seq; /* Set to NULL when iterator is exhausted */
} _PyListIterObject;
PyAPI_FUNC(PyObject *)_PyList_FromArraySteal(PyObject *const *src, Py_ssize_t n);
union _PyStackRef;
PyAPI_FUNC(PyObject *)_PyList_FromStackRefSteal(const union _PyStackRef *src, Py_ssize_t n);
#ifdef __cplusplus
}

View File

@ -3142,7 +3142,7 @@ PyList_AsTuple(PyObject *v)
}
PyObject *
_PyList_FromArraySteal(PyObject *const *src, Py_ssize_t n)
_PyList_FromStackRefSteal(const _PyStackRef *src, Py_ssize_t n)
{
if (n == 0) {
return PyList_New(0);
@ -3151,13 +3151,15 @@ _PyList_FromArraySteal(PyObject *const *src, Py_ssize_t n)
PyListObject *list = (PyListObject *)PyList_New(n);
if (list == NULL) {
for (Py_ssize_t i = 0; i < n; i++) {
Py_DECREF(src[i]);
PyStackRef_CLOSE(src[i]);
}
return NULL;
}
PyObject **dst = list->ob_item;
memcpy(dst, src, n * sizeof(PyObject *));
for (Py_ssize_t i = 0; i < n; i++) {
dst[i] = PyStackRef_AsPyObjectSteal(src[i]);
}
return (PyObject *)list;
}

View File

@ -1666,13 +1666,7 @@ dummy_func(
}
inst(BUILD_LIST, (values[oparg] -- list)) {
STACKREFS_TO_PYOBJECTS(values, oparg, values_o);
if (CONVERSION_FAILED(values_o)) {
DECREF_INPUTS();
ERROR_IF(true, error);
}
PyObject *list_o = _PyList_FromArraySteal(values_o, oparg);
STACKREFS_TO_PYOBJECTS_CLEANUP(values_o);
PyObject *list_o = _PyList_FromStackRefSteal(values, oparg);
ERROR_IF(list_o == NULL, error);
list = PyStackRef_FromPyObjectSteal(list_o);
}

View File

@ -1882,15 +1882,7 @@
_PyStackRef list;
oparg = CURRENT_OPARG();
values = &stack_pointer[-oparg];
STACKREFS_TO_PYOBJECTS(values, oparg, values_o);
if (CONVERSION_FAILED(values_o)) {
for (int _i = oparg; --_i >= 0;) {
PyStackRef_CLOSE(values[_i]);
}
if (true) JUMP_TO_ERROR();
}
PyObject *list_o = _PyList_FromArraySteal(values_o, oparg);
STACKREFS_TO_PYOBJECTS_CLEANUP(values_o);
PyObject *list_o = _PyList_FromStackRefSteal(values, oparg);
if (list_o == NULL) JUMP_TO_ERROR();
list = PyStackRef_FromPyObjectSteal(list_o);
stack_pointer[-oparg] = list;

View File

@ -631,19 +631,7 @@
_PyStackRef *values;
_PyStackRef list;
values = &stack_pointer[-oparg];
STACKREFS_TO_PYOBJECTS(values, oparg, values_o);
if (CONVERSION_FAILED(values_o)) {
for (int _i = oparg; --_i >= 0;) {
PyStackRef_CLOSE(values[_i]);
}
if (true) {
stack_pointer += -oparg;
assert(WITHIN_STACK_BOUNDS());
goto error;
}
}
PyObject *list_o = _PyList_FromArraySteal(values_o, oparg);
STACKREFS_TO_PYOBJECTS_CLEANUP(values_o);
PyObject *list_o = _PyList_FromStackRefSteal(values, oparg);
if (list_o == NULL) {
stack_pointer += -oparg;
assert(WITHIN_STACK_BOUNDS());

View File

@ -534,7 +534,7 @@ NON_ESCAPING_FUNCTIONS = (
"STACKREFS_TO_PYOBJECTS",
"STACKREFS_TO_PYOBJECTS_CLEANUP",
"CONVERSION_FAILED",
"_PyList_FromArraySteal",
"_PyList_FromStackRefSteal",
"_PyTuple_FromArraySteal",
"_PyTuple_FromStackRefSteal",
)