diff options
Diffstat (limited to 'Python/compile.c')
-rw-r--r-- | Python/compile.c | 159 |
1 files changed, 37 insertions, 122 deletions
diff --git a/Python/compile.c b/Python/compile.c index 1104250..03d522b 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -2047,16 +2047,16 @@ static int compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t flags, PyObject *qualname) { + Py_ssize_t i, free = PyCode_GetNumFree(co); if (qualname == NULL) qualname = co->co_name; - if (co->co_nfreevars) { - int i = co->co_nlocals + co->co_ncellvars; - for (; i < co->co_nlocalsplus; ++i) { + if (free) { + for (i = 0; i < free; ++i) { /* Bypass com_addop_varname because it will generate LOAD_DEREF but LOAD_CLOSURE is needed. */ - PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, i); + PyObject *name = PyTuple_GET_ITEM(co->co_freevars, i); /* Special case: If a class contains a method with a free variable that has the same name as a method, @@ -2076,10 +2076,6 @@ compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t flags, arg = compiler_lookup_arg(c->u->u_freevars, name); } if (arg == -1) { - PyObject *freevars = _PyCode_GetFreevars(co); - if (freevars == NULL) { - PyErr_Clear(); - } PyErr_Format(PyExc_SystemError, "compiler_lookup_arg(name=%R) with reftype=%d failed in %S; " "freevars of code %S: %R", @@ -2087,13 +2083,13 @@ compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t flags, reftype, c->u->u_name, co->co_name, - freevars); + co->co_freevars); return 0; } ADDOP_I(c, LOAD_CLOSURE, arg); } flags |= 0x08; - ADDOP_I(c, BUILD_TUPLE, co->co_nfreevars); + ADDOP_I(c, BUILD_TUPLE, free); } ADDOP_LOAD_CONST(c, (PyObject*)co); ADDOP_LOAD_CONST(c, qualname); @@ -7180,46 +7176,6 @@ merge_const_one(struct compiler *c, PyObject **obj) return 1; } -// This is in codeobject.c. -extern void _Py_set_localsplus_info(int, PyObject *, _PyLocalsPlusKind, - PyObject *, _PyLocalsPlusKinds); - -static void -compute_localsplus_info(struct compiler *c, - PyObject *names, _PyLocalsPlusKinds kinds) -{ - int nlocalsplus = (int)PyTuple_GET_SIZE(names); - - PyObject *k, *v; - Py_ssize_t pos = 0; - while (PyDict_Next(c->u->u_varnames, &pos, &k, &v)) { - int offset = (int)PyLong_AS_LONG(v); - assert(offset >= 0); - assert(offset < nlocalsplus); - // For now we do not distinguish arg kinds. - _Py_set_localsplus_info(offset, k, CO_FAST_LOCAL, names, kinds); - } - int nlocals = (int)PyDict_GET_SIZE(c->u->u_varnames); - - pos = 0; - while (PyDict_Next(c->u->u_cellvars, &pos, &k, &v)) { - int offset = (int)PyLong_AS_LONG(v); - assert(offset >= 0); - offset += nlocals; - assert(offset < nlocalsplus); - _Py_set_localsplus_info(offset, k, CO_FAST_CELL, names, kinds); - } - - pos = 0; - while (PyDict_Next(c->u->u_freevars, &pos, &k, &v)) { - int offset = (int)PyLong_AS_LONG(v); - assert(offset >= 0); - offset += nlocals; - assert(offset < nlocalsplus); - _Py_set_localsplus_info(offset, k, CO_FAST_FREE, names, kinds); - } -} - static PyCodeObject * makecode(struct compiler *c, struct assembler *a, PyObject *constslist, int maxdepth) @@ -7227,23 +7183,37 @@ makecode(struct compiler *c, struct assembler *a, PyObject *constslist, PyCodeObject *co = NULL; PyObject *names = NULL; PyObject *consts = NULL; - PyObject *localsplusnames = NULL; - _PyLocalsPlusKinds localspluskinds = NULL; + PyObject *varnames = NULL; PyObject *name = NULL; + PyObject *freevars = NULL; + PyObject *cellvars = NULL; + int flags; + int posorkeywordargcount, posonlyargcount, kwonlyargcount; names = dict_keys_inorder(c->u->u_names, 0); - if (!names) { + varnames = dict_keys_inorder(c->u->u_varnames, 0); + if (!names || !varnames) { goto error; } - if (!merge_const_one(c, &names)) { + cellvars = dict_keys_inorder(c->u->u_cellvars, 0); + if (!cellvars) + goto error; + freevars = dict_keys_inorder(c->u->u_freevars, PyTuple_GET_SIZE(cellvars)); + if (!freevars) goto error; - } - int flags = compute_code_flags(c); - if (flags < 0) { + if (!merge_const_one(c, &names) || + !merge_const_one(c, &varnames) || + !merge_const_one(c, &cellvars) || + !merge_const_one(c, &freevars)) + { goto error; } + flags = compute_code_flags(c); + if (flags < 0) + goto error; + consts = PyList_AsTuple(constslist); /* PyCode_New requires a tuple */ if (consts == NULL) { goto error; @@ -7252,32 +7222,9 @@ makecode(struct compiler *c, struct assembler *a, PyObject *constslist, goto error; } - assert(c->u->u_posonlyargcount < INT_MAX); - assert(c->u->u_argcount < INT_MAX); - assert(c->u->u_kwonlyargcount < INT_MAX); - int posonlyargcount = (int)c->u->u_posonlyargcount; - int posorkwargcount = (int)c->u->u_argcount; - assert(INT_MAX - posonlyargcount - posorkwargcount > 0); - int kwonlyargcount = (int)c->u->u_kwonlyargcount; - - Py_ssize_t nlocals = PyDict_GET_SIZE(c->u->u_varnames); - Py_ssize_t ncellvars = PyDict_GET_SIZE(c->u->u_cellvars); - Py_ssize_t nfreevars = PyDict_GET_SIZE(c->u->u_freevars); - assert(nlocals < INT_MAX); - assert(ncellvars < INT_MAX); - assert(nfreevars < INT_MAX); - assert(INT_MAX - nlocals - ncellvars - nfreevars > 0); - int nlocalsplus = (int)nlocals + (int)ncellvars + (int)nfreevars; - - localsplusnames = PyTuple_New(nlocalsplus); - if (localsplusnames == NULL) { - goto error; - } - if (_PyCode_InitLocalsPlusKinds(nlocalsplus, &localspluskinds) < 0) { - goto error; - } - compute_localsplus_info(c, localsplusnames, localspluskinds); - + posonlyargcount = Py_SAFE_DOWNCAST(c->u->u_posonlyargcount, Py_ssize_t, int); + posorkeywordargcount = Py_SAFE_DOWNCAST(c->u->u_argcount, Py_ssize_t, int); + kwonlyargcount = Py_SAFE_DOWNCAST(c->u->u_kwonlyargcount, Py_ssize_t, int); struct _PyCodeConstructor con = { .filename = c->c_filename, .name = c->u->u_name, @@ -7290,10 +7237,11 @@ makecode(struct compiler *c, struct assembler *a, PyObject *constslist, .consts = consts, .names = names, - .localsplusnames = localsplusnames, - .localspluskinds = localspluskinds, + .varnames = varnames, + .cellvars = cellvars, + .freevars = freevars, - .argcount = posonlyargcount + posorkwargcount, + .argcount = posonlyargcount + posorkeywordargcount, .posonlyargcount = posonlyargcount, .kwonlyargcount = kwonlyargcount, @@ -7301,30 +7249,18 @@ makecode(struct compiler *c, struct assembler *a, PyObject *constslist, .exceptiontable = a->a_except_table, }; - if (_PyCode_Validate(&con) < 0) { goto error; } - - if (!merge_const_one(c, &localsplusnames)) { - _PyCode_ClearLocalsPlusKinds(con.localspluskinds); - goto error; - } - con.localsplusnames = localsplusnames; - co = _PyCode_New(&con); - if (co == NULL) { - goto error; - } - - localspluskinds = NULL; // This keeps it from getting freed below. error: Py_XDECREF(names); Py_XDECREF(consts); - Py_XDECREF(localsplusnames); - _PyCode_ClearLocalsPlusKinds(localspluskinds); + Py_XDECREF(varnames); Py_XDECREF(name); + Py_XDECREF(freevars); + Py_XDECREF(cellvars); return co; } @@ -7435,24 +7371,6 @@ guarantee_lineno_for_exits(struct assembler *a, int firstlineno) { } } -static void -offset_derefs(basicblock *entryblock, int nlocals) -{ - for (basicblock *b = entryblock; b != NULL; b = b->b_next) { - for (int i = 0; i < b->b_iused; i++) { - struct instr *inst = &b->b_instr[i]; - switch(inst->i_opcode) { - case LOAD_CLOSURE: - case LOAD_DEREF: - case STORE_DEREF: - case DELETE_DEREF: - case LOAD_CLASSDEREF: - inst->i_oparg += nlocals; - } - } - } -} - static PyCodeObject * assemble(struct compiler *c, int addNone) { @@ -7508,9 +7426,6 @@ assemble(struct compiler *c, int addNone) a.a_entry = entryblock; a.a_nblocks = nblocks; - assert(PyDict_GET_SIZE(c->u->u_varnames) < INT_MAX); - offset_derefs(entryblock, (int)PyDict_GET_SIZE(c->u->u_varnames)); - consts = consts_dict_keys_inorder(c->u->u_consts); if (consts == NULL) { goto error; |