mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
bpo-43693: Revert commits 2c1e2583fd
and b2bf2bc1ec
(GH-26530)
* Revert "bpo-43693: Compute deref offsets in compiler (gh-25152)" This reverts commitb2bf2bc1ec
. * Revert "bpo-43693: Add new internal code objects fields: co_fastlocalnames and co_fastlocalkinds. (gh-26388)" This reverts commit2c1e2583fd
. These two commits are breaking the refleak buildbots.
This commit is contained in:
parent
a46c220edc
commit
17c4edc4e0
23 changed files with 5707 additions and 6028 deletions
159
Python/compile.c
159
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,22 +7183,36 @@ 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;
|
||||
|
||||
if (!merge_const_one(c, &names) ||
|
||||
!merge_const_one(c, &varnames) ||
|
||||
!merge_const_one(c, &cellvars) ||
|
||||
!merge_const_one(c, &freevars))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
int flags = compute_code_flags(c);
|
||||
if (flags < 0) {
|
||||
flags = compute_code_flags(c);
|
||||
if (flags < 0)
|
||||
goto error;
|
||||
}
|
||||
|
||||
consts = PyList_AsTuple(constslist); /* PyCode_New requires a tuple */
|
||||
if (consts == NULL) {
|
||||
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue