summaryrefslogtreecommitdiffstats
path: root/Python/frame.c
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2021-11-29 12:34:59 (GMT)
committerGitHub <noreply@github.com>2021-11-29 12:34:59 (GMT)
commit60929576e40038ec71d896230f69e4411c82be4b (patch)
tree34dc24d0a73ef0205514202820d66c152260dc22 /Python/frame.c
parent7431448b817d3bf87f71661cf8f3d537807ab2e2 (diff)
downloadcpython-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.c38
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;
}