summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSam Gross <colesbury@gmail.com>2024-08-12 18:49:49 (GMT)
committerGitHub <noreply@github.com>2024-08-12 18:49:49 (GMT)
commitab094d1b2b348f670743f88e52d1a3f2cab5abd5 (patch)
tree4b428aee12b8eb286e1405527846c40206adef05
parent736fe4d23e267a70d3b769046f03c1f3bdc0f430 (diff)
downloadcpython-ab094d1b2b348f670743f88e52d1a3f2cab5abd5.zip
cpython-ab094d1b2b348f670743f88e52d1a3f2cab5abd5.tar.gz
cpython-ab094d1b2b348f670743f88e52d1a3f2cab5abd5.tar.bz2
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>
-rw-r--r--Include/internal/pycore_list.h5
-rw-r--r--Objects/listobject.c8
-rw-r--r--Python/bytecodes.c8
-rw-r--r--Python/executor_cases.c.h10
-rw-r--r--Python/generated_cases.c.h14
-rw-r--r--Tools/cases_generator/analyzer.py2
6 files changed, 13 insertions, 34 deletions
diff --git a/Include/internal/pycore_list.h b/Include/internal/pycore_list.h
index 56ddb54..12b42c1 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 4d654c2..067d1a1 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 70c7d82..7c448f4 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 d64ef0c..9102d68 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 a290e1e..11ebd25 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 c91edff..db30229 100644
--- a/Tools/cases_generator/analyzer.py
+++ b/Tools/cases_generator/analyzer.py
@@ -534,7 +534,7 @@ NON_ESCAPING_FUNCTIONS = (
"STACKREFS_TO_PYOBJECTS",
"STACKREFS_TO_PYOBJECTS_CLEANUP",
"CONVERSION_FAILED",
- "_PyList_FromArraySteal",
+ "_PyList_FromStackRefSteal",
"_PyTuple_FromArraySteal",
"_PyTuple_FromStackRefSteal",
)