Skip to content

Commit

Permalink
gh-100720: refactor calculation of number of frame slots for a code o…
Browse files Browse the repository at this point in the history
…bject into the new function _PyFrame_NumSlotsForCodeObject (#100722)
  • Loading branch information
iritkatriel authored Jan 4, 2023
1 parent 5fb1c08 commit c31e356
Show file tree
Hide file tree
Showing 5 changed files with 15 additions and 4 deletions.
11 changes: 10 additions & 1 deletion Include/internal/pycore_frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added ``_PyFrame_NumSlotsForCodeObject``, which returns the number of slots needed in a frame for a given code object.
2 changes: 1 addition & 1 deletion Objects/frameobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
4 changes: 2 additions & 2 deletions Objects/genobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions Tools/build/deepfreeze.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ def generate_code(self, name: str, code: types.CodeType) -> str:
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")
Expand Down

0 comments on commit c31e356

Please sign in to comment.