Skip to content

Commit 6f00706

Browse files
pythongh-117139: Replace _PyList_FromArraySteal with stack ref variant
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>
1 parent 833eb10 commit 6f00706

File tree

6 files changed

+13
-34
lines changed

6 files changed

+13
-34
lines changed

Include/internal/pycore_list.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,10 @@ typedef struct {
5656
PyListObject *it_seq; /* Set to NULL when iterator is exhausted */
5757
} _PyListIterObject;
5858

59-
PyAPI_FUNC(PyObject *)_PyList_FromArraySteal(PyObject *const *src, Py_ssize_t n);
59+
union _PyStackRef;
60+
61+
PyAPI_FUNC(PyObject *)_PyList_FromStackRefSteal(const union _PyStackRef *src, Py_ssize_t n);
62+
6063

6164
#ifdef __cplusplus
6265
}

Objects/listobject.c

+5-3
Original file line numberDiff line numberDiff line change
@@ -3142,7 +3142,7 @@ PyList_AsTuple(PyObject *v)
31423142
}
31433143

31443144
PyObject *
3145-
_PyList_FromArraySteal(PyObject *const *src, Py_ssize_t n)
3145+
_PyList_FromStackRefSteal(const _PyStackRef *src, Py_ssize_t n)
31463146
{
31473147
if (n == 0) {
31483148
return PyList_New(0);
@@ -3151,13 +3151,15 @@ _PyList_FromArraySteal(PyObject *const *src, Py_ssize_t n)
31513151
PyListObject *list = (PyListObject *)PyList_New(n);
31523152
if (list == NULL) {
31533153
for (Py_ssize_t i = 0; i < n; i++) {
3154-
Py_DECREF(src[i]);
3154+
PyStackRef_CLOSE(src[i]);
31553155
}
31563156
return NULL;
31573157
}
31583158

31593159
PyObject **dst = list->ob_item;
3160-
memcpy(dst, src, n * sizeof(PyObject *));
3160+
for (Py_ssize_t i = 0; i < n; i++) {
3161+
dst[i] = PyStackRef_AsPyObjectSteal(src[i]);
3162+
}
31613163

31623164
return (PyObject *)list;
31633165
}

Python/bytecodes.c

+1-7
Original file line numberDiff line numberDiff line change
@@ -1666,13 +1666,7 @@ dummy_func(
16661666
}
16671667

16681668
inst(BUILD_LIST, (values[oparg] -- list)) {
1669-
STACKREFS_TO_PYOBJECTS(values, oparg, values_o);
1670-
if (CONVERSION_FAILED(values_o)) {
1671-
DECREF_INPUTS();
1672-
ERROR_IF(true, error);
1673-
}
1674-
PyObject *list_o = _PyList_FromArraySteal(values_o, oparg);
1675-
STACKREFS_TO_PYOBJECTS_CLEANUP(values_o);
1669+
PyObject *list_o = _PyList_FromStackRefSteal(values, oparg);
16761670
ERROR_IF(list_o == NULL, error);
16771671
list = PyStackRef_FromPyObjectSteal(list_o);
16781672
}

Python/executor_cases.c.h

+1-9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/generated_cases.c.h

+1-13
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Tools/cases_generator/analyzer.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@ def has_error_without_pop(op: parser.InstDef) -> bool:
534534
"STACKREFS_TO_PYOBJECTS",
535535
"STACKREFS_TO_PYOBJECTS_CLEANUP",
536536
"CONVERSION_FAILED",
537-
"_PyList_FromArraySteal",
537+
"_PyList_FromStackRefSteal",
538538
"_PyTuple_FromArraySteal",
539539
"_PyTuple_FromStackRefSteal",
540540
)

0 commit comments

Comments
 (0)