summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIrit Katriel <1055913+iritkatriel@users.noreply.github.com>2023-01-04 13:37:06 +0000
committerGitHub <noreply@github.com>2023-01-04 13:37:06 +0000
commitc31e356a10aa60b5967b9aaf80b9984059e46461 (patch)
tree774e48afaea4e83f9b14c46e8d20cc14e018d92d
parentdocs: fix `ssizeobjargproc` parameters (#100736) (diff)
downloadcpython-c31e356a10aa60b5967b9aaf80b9984059e46461.tar.gz
cpython-c31e356a10aa60b5967b9aaf80b9984059e46461.tar.bz2
cpython-c31e356a10aa60b5967b9aaf80b9984059e46461.zip
gh-100720: refactor calculation of number of frame slots for a code object into the new function _PyFrame_NumSlotsForCodeObject (#100722)
-rw-r--r--Include/internal/pycore_frame.h11
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2023-01-03-16-50-42.gh-issue-100720.UhE7P-.rst1
-rw-r--r--Objects/frameobject.c2
-rw-r--r--Objects/genobject.c4
-rw-r--r--Tools/build/deepfreeze.py1
5 files changed, 15 insertions, 4 deletions
diff --git a/Include/internal/pycore_frame.h b/Include/internal/pycore_frame.h
index f18723b3032..d5c1dcc82a8 100644
--- a/Include/internal/pycore_frame.h
+++ b/Include/internal/pycore_frame.h
@@ -92,7 +92,16 @@ static inline void _PyFrame_StackPush(_PyInterpreterFrame *f, PyObject *value) {
f->stacktop++;
}
-#define FRAME_SPECIALS_SIZE ((sizeof(_PyInterpreterFrame)-1)/sizeof(PyObject *))
+#define FRAME_SPECIALS_SIZE ((int)((sizeof(_PyInterpreterFrame)-1)/sizeof(PyObject *)))
+
+static inline int
+_PyFrame_NumSlotsForCodeObject(PyCodeObject *code)
+{
+ /* This function needs to remain in sync with the calculation of
+ * co_framesize in Tools/build/deepfreeze.py */
+ assert(code->co_framesize >= FRAME_SPECIALS_SIZE);
+ return code->co_framesize - FRAME_SPECIALS_SIZE;
+}
void _PyFrame_Copy(_PyInterpreterFrame *src, _PyInterpreterFrame *dest);
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-01-03-16-50-42.gh-issue-100720.UhE7P-.rst b/Misc/NEWS.d/next/Core and Builtins/2023-01-03-16-50-42.gh-issue-100720.UhE7P-.rst
new file mode 100644
index 00000000000..4c194eccf8a
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2023-01-03-16-50-42.gh-issue-100720.UhE7P-.rst
@@ -0,0 +1 @@
+Added ``_PyFrame_NumSlotsForCodeObject``, which returns the number of slots needed in a frame for a given code object.
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index eab85c08fc0..98f0b383872 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -946,7 +946,7 @@ frame_sizeof(PyFrameObject *f, PyObject *Py_UNUSED(ignored))
Py_ssize_t res;
res = offsetof(PyFrameObject, _f_frame_data) + offsetof(_PyInterpreterFrame, localsplus);
PyCodeObject *code = f->f_frame->f_code;
- res += (code->co_nlocalsplus+code->co_stacksize) * sizeof(PyObject *);
+ res += _PyFrame_NumSlotsForCodeObject(code) * sizeof(PyObject *);
return PyLong_FromSsize_t(res);
}
diff --git a/Objects/genobject.c b/Objects/genobject.c
index c006f1af217..ea3382d3e31 100644
--- a/Objects/genobject.c
+++ b/Objects/genobject.c
@@ -769,7 +769,7 @@ gen_sizeof(PyGenObject *gen, PyObject *Py_UNUSED(ignored))
Py_ssize_t res;
res = offsetof(PyGenObject, gi_iframe) + offsetof(_PyInterpreterFrame, localsplus);
PyCodeObject *code = gen->gi_code;
- res += (code->co_nlocalsplus+code->co_stacksize) * sizeof(PyObject *);
+ res += _PyFrame_NumSlotsForCodeObject(code) * sizeof(PyObject *);
return PyLong_FromSsize_t(res);
}
@@ -850,7 +850,7 @@ static PyObject *
make_gen(PyTypeObject *type, PyFunctionObject *func)
{
PyCodeObject *code = (PyCodeObject *)func->func_code;
- int slots = code->co_nlocalsplus + code->co_stacksize;
+ int slots = _PyFrame_NumSlotsForCodeObject(code);
PyGenObject *gen = PyObject_GC_NewVar(PyGenObject, type, slots);
if (gen == NULL) {
return NULL;
diff --git a/Tools/build/deepfreeze.py b/Tools/build/deepfreeze.py
index 7f4e2428013..e4b422820f7 100644
--- a/Tools/build/deepfreeze.py
+++ b/Tools/build/deepfreeze.py
@@ -262,6 +262,7 @@ class Printer:
self.field(code, "co_argcount")
self.field(code, "co_posonlyargcount")
self.field(code, "co_kwonlyargcount")
+ # The following should remain in sync with _PyFrame_NumSlotsForCodeObject
self.write(f".co_framesize = {code.co_stacksize + len(localsplusnames)} + FRAME_SPECIALS_SIZE,")
self.field(code, "co_stacksize")
self.field(code, "co_firstlineno")