mirror of
https://github.com/python/cpython.git
synced 2025-08-27 04:05:34 +00:00
bpo-45786: Allocate space for frame in frame object. (GH-29729)
This commit is contained in:
parent
7431448b81
commit
60929576e4
12 changed files with 76 additions and 181 deletions
|
@ -5694,7 +5694,8 @@ make_coro_frame(PyThreadState *tstate,
|
|||
}
|
||||
assert(frame->frame_obj == NULL);
|
||||
if (initialize_locals(tstate, func, frame->localsplus, args, argcount, kwnames)) {
|
||||
_PyFrame_Clear(frame, 1);
|
||||
_PyFrame_Clear(frame);
|
||||
PyMem_Free(frame);
|
||||
return NULL;
|
||||
}
|
||||
return frame;
|
||||
|
@ -5750,7 +5751,7 @@ _PyEvalFramePushAndInit(PyThreadState *tstate, PyFunctionObject *func,
|
|||
localsarray[i] = NULL;
|
||||
}
|
||||
if (initialize_locals(tstate, func, localsarray, args, argcount, kwnames)) {
|
||||
_PyFrame_Clear(frame, 0);
|
||||
_PyFrame_Clear(frame);
|
||||
return NULL;
|
||||
}
|
||||
return frame;
|
||||
|
@ -5773,11 +5774,8 @@ static int
|
|||
_PyEvalFrameClearAndPop(PyThreadState *tstate, InterpreterFrame * frame)
|
||||
{
|
||||
--tstate->recursion_remaining;
|
||||
assert(frame->frame_obj == NULL || frame->frame_obj->f_own_locals_memory == 0);
|
||||
if (_PyFrame_Clear(frame, 0)) {
|
||||
++tstate->recursion_remaining;
|
||||
return -1;
|
||||
}
|
||||
assert(frame->frame_obj == NULL || frame->frame_obj->f_owns_frame == 0);
|
||||
_PyFrame_Clear(frame);
|
||||
++tstate->recursion_remaining;
|
||||
_PyThreadState_PopFrame(tstate, frame);
|
||||
return 0;
|
||||
|
|
|
@ -27,22 +27,24 @@ _PyFrame_MakeAndSetFrameObject(InterpreterFrame *frame)
|
|||
assert(frame->frame_obj == NULL);
|
||||
PyObject *error_type, *error_value, *error_traceback;
|
||||
PyErr_Fetch(&error_type, &error_value, &error_traceback);
|
||||
PyFrameObject *f = _PyFrame_New_NoTrack(frame, 0);
|
||||
|
||||
PyFrameObject *f = _PyFrame_New_NoTrack(frame->f_code);
|
||||
if (f == NULL) {
|
||||
Py_XDECREF(error_type);
|
||||
Py_XDECREF(error_value);
|
||||
Py_XDECREF(error_traceback);
|
||||
}
|
||||
else {
|
||||
f->f_owns_frame = 0;
|
||||
f->f_frame = frame;
|
||||
frame->frame_obj = f;
|
||||
PyErr_Restore(error_type, error_value, error_traceback);
|
||||
}
|
||||
frame->frame_obj = f;
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
static InterpreterFrame *
|
||||
copy_frame_to_heap(InterpreterFrame *frame)
|
||||
InterpreterFrame *
|
||||
_PyFrame_Copy(InterpreterFrame *frame)
|
||||
{
|
||||
assert(frame->stacktop >= frame->f_code->co_nlocalsplus);
|
||||
Py_ssize_t size = ((char*)&frame->localsplus[frame->stacktop]) - (char *)frame;
|
||||
|
@ -68,10 +70,11 @@ clear_specials(InterpreterFrame *frame)
|
|||
static void
|
||||
take_ownership(PyFrameObject *f, InterpreterFrame *frame)
|
||||
{
|
||||
assert(f->f_own_locals_memory == 0);
|
||||
assert(frame->frame_obj == NULL);
|
||||
|
||||
f->f_own_locals_memory = 1;
|
||||
assert(f->f_owns_frame == 0);
|
||||
Py_ssize_t size = ((char*)&frame->localsplus[frame->stacktop]) - (char *)frame;
|
||||
memcpy((InterpreterFrame *)f->_f_frame_data, frame, size);
|
||||
frame = (InterpreterFrame *)f->_f_frame_data;
|
||||
f->f_owns_frame = 1;
|
||||
f->f_frame = frame;
|
||||
assert(f->f_back == NULL);
|
||||
if (frame->previous != NULL) {
|
||||
|
@ -82,7 +85,6 @@ take_ownership(PyFrameObject *f, InterpreterFrame *frame)
|
|||
assert(PyErr_ExceptionMatches(PyExc_MemoryError));
|
||||
/* Nothing we can do about it */
|
||||
PyErr_Clear();
|
||||
_PyErr_WriteUnraisableMsg("Out of memory lazily allocating frame->f_back", NULL);
|
||||
}
|
||||
else {
|
||||
f->f_back = (PyFrameObject *)Py_NewRef(back);
|
||||
|
@ -94,8 +96,8 @@ take_ownership(PyFrameObject *f, InterpreterFrame *frame)
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
_PyFrame_Clear(InterpreterFrame * frame, int take)
|
||||
void
|
||||
_PyFrame_Clear(InterpreterFrame * frame)
|
||||
{
|
||||
/* It is the responsibility of the owning generator/coroutine
|
||||
* to have cleared the generator pointer */
|
||||
|
@ -104,15 +106,9 @@ _PyFrame_Clear(InterpreterFrame * frame, int take)
|
|||
PyFrameObject *f = frame->frame_obj;
|
||||
frame->frame_obj = NULL;
|
||||
if (Py_REFCNT(f) > 1) {
|
||||
if (!take) {
|
||||
frame = copy_frame_to_heap(frame);
|
||||
if (frame == NULL) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
take_ownership(f, frame);
|
||||
Py_DECREF(f);
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
Py_DECREF(f);
|
||||
}
|
||||
|
@ -121,8 +117,4 @@ _PyFrame_Clear(InterpreterFrame * frame, int take)
|
|||
Py_XDECREF(frame->localsplus[i]);
|
||||
}
|
||||
clear_specials(frame);
|
||||
if (take) {
|
||||
PyMem_Free(frame);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue