diff options
Diffstat (limited to 'Python/ceval.c')
-rw-r--r-- | Python/ceval.c | 49 |
1 files changed, 28 insertions, 21 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index 032bc0c..a8abead 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -3076,6 +3076,34 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) goto error; } + case TARGET(MAKE_CELL): { + PyObject *initial = GETLOCAL(oparg); + // Normally initial would be NULL. However, it + // might have been set to an initial value during + // a call to PyFrame_LocalsToFast(). + PyObject *cell = PyCell_New(initial); + if (cell == NULL) { + goto error; + } + /* If it is an arg then copy the arg into the cell. */ + if (initial == NULL && co->co_cell2arg != NULL) { + int argoffset = co->co_cell2arg[oparg - co->co_nlocals]; + if (argoffset != CO_CELL_NOT_AN_ARG) { + PyObject *arg = GETLOCAL(argoffset); + // It will have been set in initialize_locals() but + // may have been deleted PyFrame_LocalsToFast(). + if (arg != NULL) {; + Py_INCREF(arg); + PyCell_SET(cell, arg); + /* Clear the local copy. */ + SETLOCAL(argoffset, NULL); + } + } + } + SETLOCAL(oparg, cell); + DISPATCH(); + } + case TARGET(DELETE_DEREF): { PyObject *cell = GETLOCAL(oparg); PyObject *oldobj = PyCell_GET(cell); @@ -5067,27 +5095,6 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con, } } - - /* Allocate and initialize storage for cell vars, and copy free - vars into frame. */ - for (i = 0; i < co->co_ncellvars; ++i) { - PyObject *c; - Py_ssize_t arg; - /* Possibly account for the cell variable being an argument. */ - if (co->co_cell2arg != NULL && - (arg = co->co_cell2arg[i]) != CO_CELL_NOT_AN_ARG) { - c = PyCell_New(GETLOCAL(arg)); - /* Clear the local copy. */ - SETLOCAL(arg, NULL); - } - else { - c = PyCell_New(NULL); - } - if (c == NULL) - goto fail; - SETLOCAL(co->co_nlocals + i, c); - } - /* Copy closure variables to free variables */ for (i = 0; i < co->co_nfreevars; ++i) { PyObject *o = PyTuple_GET_ITEM(con->fc_closure, i); |