diff --git a/Include/internal/pycore_list.h b/Include/internal/pycore_list.h index 56ddb545d37b55e..12b42c1b788607c 100644 --- a/Include/internal/pycore_list.h +++ b/Include/internal/pycore_list.h @@ -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 } diff --git a/Objects/listobject.c b/Objects/listobject.c index 4d654c2ed33177a..067d1a18d3bb75e 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -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; } diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 70c7d82b090468f..7c448f430796d71 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -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); } diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index d64ef0cbeee3be1..9102d684b14bae6 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -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; diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index a290e1ed81aa326..11ebd25da0fea35 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -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()); diff --git a/Tools/cases_generator/analyzer.py b/Tools/cases_generator/analyzer.py index c91edff24bc6659..db302296502fdde 100644 --- a/Tools/cases_generator/analyzer.py +++ b/Tools/cases_generator/analyzer.py @@ -534,7 +534,7 @@ def has_error_without_pop(op: parser.InstDef) -> bool: "STACKREFS_TO_PYOBJECTS", "STACKREFS_TO_PYOBJECTS_CLEANUP", "CONVERSION_FAILED", - "_PyList_FromArraySteal", + "_PyList_FromStackRefSteal", "_PyTuple_FromArraySteal", "_PyTuple_FromStackRefSteal", )