diff options
author | Mark Shannon <mark@hotpy.org> | 2021-11-29 12:34:59 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-29 12:34:59 (GMT) |
commit | 60929576e40038ec71d896230f69e4411c82be4b (patch) | |
tree | 34dc24d0a73ef0205514202820d66c152260dc22 /Python/frame.c | |
parent | 7431448b817d3bf87f71661cf8f3d537807ab2e2 (diff) | |
download | cpython-60929576e40038ec71d896230f69e4411c82be4b.zip cpython-60929576e40038ec71d896230f69e4411c82be4b.tar.gz cpython-60929576e40038ec71d896230f69e4411c82be4b.tar.bz2 |
bpo-45786: Allocate space for frame in frame object. (GH-29729)
Diffstat (limited to 'Python/frame.c')
-rw-r--r-- | Python/frame.c | 38 |
1 files changed, 15 insertions, 23 deletions
diff --git a/Python/frame.c b/Python/frame.c index 79b0f77..21f2ced 100644 --- a/Python/frame.c +++ b/Python/frame.c @@ -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; } |