mirror of https://github.com/python/cpython
gh-100720: refactor calculation of number of frame slots for a code object into the new function _PyFrame_NumSlotsForCodeObject (#100722)
This commit is contained in:
parent
5fb1c08e15
commit
c31e356a10
|
@ -92,7 +92,16 @@ static inline void _PyFrame_StackPush(_PyInterpreterFrame *f, PyObject *value) {
|
||||||
f->stacktop++;
|
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);
|
void _PyFrame_Copy(_PyInterpreterFrame *src, _PyInterpreterFrame *dest);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Added ``_PyFrame_NumSlotsForCodeObject``, which returns the number of slots needed in a frame for a given code object.
|
|
@ -946,7 +946,7 @@ frame_sizeof(PyFrameObject *f, PyObject *Py_UNUSED(ignored))
|
||||||
Py_ssize_t res;
|
Py_ssize_t res;
|
||||||
res = offsetof(PyFrameObject, _f_frame_data) + offsetof(_PyInterpreterFrame, localsplus);
|
res = offsetof(PyFrameObject, _f_frame_data) + offsetof(_PyInterpreterFrame, localsplus);
|
||||||
PyCodeObject *code = f->f_frame->f_code;
|
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);
|
return PyLong_FromSsize_t(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -769,7 +769,7 @@ gen_sizeof(PyGenObject *gen, PyObject *Py_UNUSED(ignored))
|
||||||
Py_ssize_t res;
|
Py_ssize_t res;
|
||||||
res = offsetof(PyGenObject, gi_iframe) + offsetof(_PyInterpreterFrame, localsplus);
|
res = offsetof(PyGenObject, gi_iframe) + offsetof(_PyInterpreterFrame, localsplus);
|
||||||
PyCodeObject *code = gen->gi_code;
|
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);
|
return PyLong_FromSsize_t(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -850,7 +850,7 @@ static PyObject *
|
||||||
make_gen(PyTypeObject *type, PyFunctionObject *func)
|
make_gen(PyTypeObject *type, PyFunctionObject *func)
|
||||||
{
|
{
|
||||||
PyCodeObject *code = (PyCodeObject *)func->func_code;
|
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);
|
PyGenObject *gen = PyObject_GC_NewVar(PyGenObject, type, slots);
|
||||||
if (gen == NULL) {
|
if (gen == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -262,6 +262,7 @@ class Printer:
|
||||||
self.field(code, "co_argcount")
|
self.field(code, "co_argcount")
|
||||||
self.field(code, "co_posonlyargcount")
|
self.field(code, "co_posonlyargcount")
|
||||||
self.field(code, "co_kwonlyargcount")
|
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.write(f".co_framesize = {code.co_stacksize + len(localsplusnames)} + FRAME_SPECIALS_SIZE,")
|
||||||
self.field(code, "co_stacksize")
|
self.field(code, "co_stacksize")
|
||||||
self.field(code, "co_firstlineno")
|
self.field(code, "co_firstlineno")
|
||||||
|
|
Loading…
Reference in New Issue