diff options
Diffstat (limited to 'Objects/frameobject.c')
-rw-r--r-- | Objects/frameobject.c | 32 |
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); } |