[3.11] GH-97779: Ensure that *all* frame objects are backed by "complete" frames (GH-97886)

(cherry picked from commit 0ff8fd6583)

Co-authored-by: Brandt Bucher <brandtbucher@microsoft.com>
This commit is contained in:
Miss Islington (bot) 2022-10-04 22:46:34 -07:00 committed by GitHub
parent 8c517d88fb
commit 015b49ac05
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 75 additions and 4 deletions

View file

@ -590,6 +590,7 @@ first_line_not_before(int *lines, int len, int line)
static PyFrameState
_PyFrame_GetState(PyFrameObject *frame)
{
assert(!_PyFrame_IsIncomplete(frame->f_frame));
if (frame->f_frame->stacktop == 0) {
return FRAME_CLEARED;
}
@ -1063,6 +1064,9 @@ PyFrame_New(PyThreadState *tstate, PyCodeObject *code,
init_frame((_PyInterpreterFrame *)f->_f_frame_data, func, locals);
f->f_frame = (_PyInterpreterFrame *)f->_f_frame_data;
f->f_frame->owner = FRAME_OWNED_BY_FRAME_OBJECT;
// This frame needs to be "complete", so pretend that the first RESUME ran:
f->f_frame->prev_instr = _PyCode_CODE(code) + code->_co_firsttraceable;
assert(!_PyFrame_IsIncomplete(f->f_frame));
Py_DECREF(func);
_PyObject_GC_TRACK(f);
return f;
@ -1189,6 +1193,7 @@ _PyFrame_FastToLocalsWithError(_PyInterpreterFrame *frame) {
int
PyFrame_FastToLocalsWithError(PyFrameObject *f)
{
assert(!_PyFrame_IsIncomplete(f->f_frame));
if (f == NULL) {
PyErr_BadInternalCall();
return -1;
@ -1204,7 +1209,7 @@ void
PyFrame_FastToLocals(PyFrameObject *f)
{
int res;
assert(!_PyFrame_IsIncomplete(f->f_frame));
assert(!PyErr_Occurred());
res = PyFrame_FastToLocalsWithError(f);
@ -1282,6 +1287,7 @@ _PyFrame_LocalsToFast(_PyInterpreterFrame *frame, int clear)
void
PyFrame_LocalsToFast(PyFrameObject *f, int clear)
{
assert(!_PyFrame_IsIncomplete(f->f_frame));
if (f && f->f_fast_as_locals && _PyFrame_GetState(f) != FRAME_CLEARED) {
_PyFrame_LocalsToFast(f->f_frame, clear);
f->f_fast_as_locals = 0;
@ -1292,6 +1298,7 @@ PyFrame_LocalsToFast(PyFrameObject *f, int clear)
int _PyFrame_IsEntryFrame(PyFrameObject *frame)
{
assert(frame != NULL);
assert(!_PyFrame_IsIncomplete(frame->f_frame));
return frame->f_frame->is_entry;
}
@ -1300,6 +1307,7 @@ PyCodeObject *
PyFrame_GetCode(PyFrameObject *frame)
{
assert(frame != NULL);
assert(!_PyFrame_IsIncomplete(frame->f_frame));
PyCodeObject *code = frame->f_frame->f_code;
assert(code != NULL);
Py_INCREF(code);
@ -1311,6 +1319,7 @@ PyFrameObject*
PyFrame_GetBack(PyFrameObject *frame)
{
assert(frame != NULL);
assert(!_PyFrame_IsIncomplete(frame->f_frame));
PyFrameObject *back = frame->f_back;
if (back == NULL) {
_PyInterpreterFrame *prev = frame->f_frame->previous;
@ -1328,24 +1337,28 @@ PyFrame_GetBack(PyFrameObject *frame)
PyObject*
PyFrame_GetLocals(PyFrameObject *frame)
{
assert(!_PyFrame_IsIncomplete(frame->f_frame));
return frame_getlocals(frame, NULL);
}
PyObject*
PyFrame_GetGlobals(PyFrameObject *frame)
{
assert(!_PyFrame_IsIncomplete(frame->f_frame));
return frame_getglobals(frame, NULL);
}
PyObject*
PyFrame_GetBuiltins(PyFrameObject *frame)
{
assert(!_PyFrame_IsIncomplete(frame->f_frame));
return frame_getbuiltins(frame, NULL);
}
int
PyFrame_GetLasti(PyFrameObject *frame)
{
assert(!_PyFrame_IsIncomplete(frame->f_frame));
int lasti = _PyInterpreterFrame_LASTI(frame->f_frame);
if (lasti < 0) {
return -1;
@ -1356,6 +1369,7 @@ PyFrame_GetLasti(PyFrameObject *frame)
PyObject *
PyFrame_GetGenerator(PyFrameObject *frame)
{
assert(!_PyFrame_IsIncomplete(frame->f_frame));
if (frame->f_frame->owner != FRAME_OWNED_BY_GENERATOR) {
return NULL;
}