summaryrefslogtreecommitdiffstats
path: root/Objects/frameobject.c
diff options
context:
space:
mode:
Diffstat (limited to 'Objects/frameobject.c')
-rw-r--r--Objects/frameobject.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index 09857c7..2a283b3 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -5,6 +5,7 @@
#include "pycore_moduleobject.h" // _PyModule_GetDict()
#include "pycore_object.h" // _PyObject_GC_UNTRACK()
#include "pycore_code.h" // CO_FAST_LOCAL, etc.
+#include "pycore_function.h" // _PyFunction_FromConstructor()
#include "frameobject.h" // PyFrameObject
#include "pycore_frame.h"
@@ -626,8 +627,7 @@ frame_dealloc(PyFrameObject *f)
/* Don't clear code object until the end */
co = frame->f_code;
frame->f_code = NULL;
- Py_CLEAR(frame->f_globals);
- Py_CLEAR(frame->f_builtins);
+ Py_CLEAR(frame->f_func);
Py_CLEAR(frame->f_locals);
PyObject **locals = _PyFrame_GetLocalsArray(frame);
for (int i = 0; i < frame->stacktop; i++) {
@@ -782,16 +782,16 @@ PyTypeObject PyFrame_Type = {
_Py_IDENTIFIER(__builtins__);
static InterpreterFrame *
-allocate_heap_frame(PyFrameConstructor *con, PyObject *locals)
+allocate_heap_frame(PyFunctionObject *func, PyObject *locals)
{
- PyCodeObject *code = (PyCodeObject *)con->fc_code;
+ PyCodeObject *code = (PyCodeObject *)func->func_code;
int size = code->co_nlocalsplus+code->co_stacksize + FRAME_SPECIALS_SIZE;
InterpreterFrame *frame = (InterpreterFrame *)PyMem_Malloc(sizeof(PyObject *)*size);
if (frame == NULL) {
PyErr_NoMemory();
return NULL;
}
- _PyFrame_InitializeSpecials(frame, con, locals, code->co_nlocalsplus);
+ _PyFrame_InitializeSpecials(frame, func, locals, code->co_nlocalsplus);
for (Py_ssize_t i = 0; i < code->co_nlocalsplus; i++) {
frame->localsplus[i] = NULL;
}
@@ -872,7 +872,12 @@ PyFrame_New(PyThreadState *tstate, PyCodeObject *code,
.fc_kwdefaults = NULL,
.fc_closure = NULL
};
- InterpreterFrame *frame = allocate_heap_frame(&desc, locals);
+ PyFunctionObject *func = _PyFunction_FromConstructor(&desc);
+ if (func == NULL) {
+ return NULL;
+ }
+ InterpreterFrame *frame = allocate_heap_frame(func, locals);
+ Py_DECREF(func);
if (frame == NULL) {
return NULL;
}
@@ -910,6 +915,18 @@ _PyFrame_FastToLocalsWithError(InterpreterFrame *frame) {
}
co = frame->f_code;
fast = _PyFrame_GetLocalsArray(frame);
+ if (frame->f_lasti < 0 && _Py_OPCODE(co->co_firstinstr[0]) == COPY_FREE_VARS) {
+ /* Free vars have not been initialized -- Do that */
+ PyCodeObject *co = frame->f_code;
+ PyObject *closure = frame->f_func->func_closure;
+ int offset = co->co_nlocals + co->co_nplaincellvars;
+ for (int i = 0; i < co->co_nfreevars; ++i) {
+ PyObject *o = PyTuple_GET_ITEM(closure, i);
+ Py_INCREF(o);
+ frame->localsplus[offset + i] = o;
+ }
+ frame->f_lasti = 0;
+ }
for (int i = 0; i < co->co_nlocalsplus; i++) {
_PyLocals_Kind kind = _PyLocals_GetKind(co->co_localspluskinds, i);
@@ -929,8 +946,7 @@ _PyFrame_FastToLocalsWithError(InterpreterFrame *frame) {
PyObject *value = fast[i];
if (frame->f_state != FRAME_CLEARED) {
if (kind & CO_FAST_FREE) {
- // The cell was set when the frame was created from
- // the function's closure.
+ // The cell was set by COPY_FREE_VARS.
assert(value != NULL && PyCell_Check(value));
value = PyCell_GET(value);
}