bpo-43693: Revert commits 2c1e2583fd and b2bf2bc1ec (GH-26530)

* Revert "bpo-43693: Compute deref offsets in compiler (gh-25152)"

This reverts commit b2bf2bc1ec.

* Revert "bpo-43693: Add new internal code objects fields: co_fastlocalnames and co_fastlocalkinds. (gh-26388)"

This reverts commit 2c1e2583fd.

These two commits are breaking the refleak buildbots.
This commit is contained in:
Pablo Galindo
2021-06-04 17:51:05 +01:00
committed by GitHub
parent a46c220edc
commit 17c4edc4e0
23 changed files with 5707 additions and 6028 deletions
+46 -32
View File
@@ -1438,7 +1438,7 @@ eval_frame_handle_pending(PyThreadState *tstate)
/* Local variable macros */
#define GETLOCAL(i) (localsplus[i])
#define GETLOCAL(i) (fastlocals[i])
/* The SETLOCAL() macro must not DECREF the local variable in-place and
then store the new value; it must copy the old value to a temporary
@@ -1569,7 +1569,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
const _Py_CODEUNIT *next_instr;
int opcode; /* Current opcode */
int oparg; /* Current opcode argument, if any */
PyObject **localsplus, **specials;
PyObject **fastlocals, **freevars, **specials;
PyObject *retval = NULL; /* Return value */
_Py_atomic_int * const eval_breaker = &tstate->interp->ceval.eval_breaker;
PyCodeObject *co;
@@ -1646,7 +1646,8 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
names = co->co_names;
consts = co->co_consts;
localsplus = f->f_localsptr;
fastlocals = f->f_localsptr;
freevars = f->f_localsptr + co->co_nlocals;
assert(PyBytes_Check(co->co_code));
assert(PyBytes_GET_SIZE(co->co_code) <= INT_MAX);
assert(PyBytes_GET_SIZE(co->co_code) % sizeof(_Py_CODEUNIT) == 0);
@@ -1819,15 +1820,12 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
DISPATCH();
}
/* We keep LOAD_CLOSURE so that the bytecode stays more readable. */
case TARGET(LOAD_CLOSURE):
case TARGET(LOAD_FAST): {
PyObject *value = GETLOCAL(oparg);
if (value == NULL) {
format_exc_check_arg(tstate, PyExc_UnboundLocalError,
UNBOUNDLOCAL_ERROR_MSG,
PyTuple_GetItem(co->co_localsplusnames,
oparg));
PyTuple_GetItem(co->co_varnames, oparg));
goto error;
}
Py_INCREF(value);
@@ -3055,13 +3053,13 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
format_exc_check_arg(
tstate, PyExc_UnboundLocalError,
UNBOUNDLOCAL_ERROR_MSG,
PyTuple_GetItem(co->co_localsplusnames, oparg)
PyTuple_GetItem(co->co_varnames, oparg)
);
goto error;
}
case TARGET(DELETE_DEREF): {
PyObject *cell = GETLOCAL(oparg);
PyObject *cell = freevars[oparg];
PyObject *oldobj = PyCell_GET(cell);
if (oldobj != NULL) {
PyCell_SET(cell, NULL);
@@ -3072,11 +3070,21 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
goto error;
}
case TARGET(LOAD_CLOSURE): {
PyObject *cell = freevars[oparg];
Py_INCREF(cell);
PUSH(cell);
DISPATCH();
}
case TARGET(LOAD_CLASSDEREF): {
PyObject *name, *value, *locals = LOCALS();
Py_ssize_t idx;
assert(locals);
assert(oparg >= 0 && oparg < co->co_nlocalsplus);
name = PyTuple_GET_ITEM(co->co_localsplusnames, oparg);
assert(oparg >= co->co_ncellvars);
idx = oparg - co->co_ncellvars;
assert(idx >= 0 && idx < co->co_nfreevars);
name = PyTuple_GET_ITEM(co->co_freevars, idx);
if (PyDict_CheckExact(locals)) {
value = PyDict_GetItemWithError(locals, name);
if (value != NULL) {
@@ -3096,7 +3104,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
}
}
if (!value) {
PyObject *cell = GETLOCAL(oparg);
PyObject *cell = freevars[oparg];
value = PyCell_GET(cell);
if (value == NULL) {
format_exc_unbound(tstate, co, oparg);
@@ -3109,7 +3117,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
}
case TARGET(LOAD_DEREF): {
PyObject *cell = GETLOCAL(oparg);
PyObject *cell = freevars[oparg];
PyObject *value = PyCell_GET(cell);
if (value == NULL) {
format_exc_unbound(tstate, co, oparg);
@@ -3122,7 +3130,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
case TARGET(STORE_DEREF): {
PyObject *v = POP();
PyObject *cell = GETLOCAL(oparg);
PyObject *cell = freevars[oparg];
PyObject *oldobj = PyCell_GET(cell);
PyCell_SET(cell, v);
Py_XDECREF(oldobj);
@@ -4628,7 +4636,7 @@ format_missing(PyThreadState *tstate, const char *kind,
static void
missing_arguments(PyThreadState *tstate, PyCodeObject *co,
Py_ssize_t missing, Py_ssize_t defcount,
PyObject **localsplus, PyObject *qualname)
PyObject **fastlocals, PyObject *qualname)
{
Py_ssize_t i, j = 0;
Py_ssize_t start, end;
@@ -4650,7 +4658,7 @@ missing_arguments(PyThreadState *tstate, PyCodeObject *co,
}
for (i = start; i < end; i++) {
if (GETLOCAL(i) == NULL) {
PyObject *raw = PyTuple_GET_ITEM(co->co_localsplusnames, i);
PyObject *raw = PyTuple_GET_ITEM(co->co_varnames, i);
PyObject *name = PyObject_Repr(raw);
if (name == NULL) {
Py_DECREF(missing_names);
@@ -4667,7 +4675,7 @@ missing_arguments(PyThreadState *tstate, PyCodeObject *co,
static void
too_many_positional(PyThreadState *tstate, PyCodeObject *co,
Py_ssize_t given, PyObject *defaults,
PyObject **localsplus, PyObject *qualname)
PyObject **fastlocals, PyObject *qualname)
{
int plural;
Py_ssize_t kwonly_given = 0;
@@ -4731,7 +4739,7 @@ positional_only_passed_as_keyword(PyThreadState *tstate, PyCodeObject *co,
PyObject* posonly_names = PyList_New(0);
for(int k=0; k < co->co_posonlyargcount; k++){
PyObject* posonly_name = PyTuple_GET_ITEM(co->co_localsplusnames, k);
PyObject* posonly_name = PyTuple_GET_ITEM(co->co_varnames, k);
for (int k2=0; k2<kwcount; k2++){
/* Compare the pointers first and fallback to PyObject_RichCompareBool*/
@@ -4868,11 +4876,12 @@ get_exception_handler(PyCodeObject *code, int index, int *level, int *handler, i
static int
initialize_locals(PyThreadState *tstate, PyFrameConstructor *con,
PyObject **localsplus, PyObject *const *args,
PyObject **fastlocals, PyObject *const *args,
Py_ssize_t argcount, PyObject *kwnames)
{
PyCodeObject *co = (PyCodeObject*)con->fc_code;
const Py_ssize_t total_args = co->co_argcount + co->co_kwonlyargcount;
PyObject **freevars = fastlocals + co->co_nlocals;
/* Create a dictionary for keyword parameters (**kwags) */
PyObject *kwdict;
@@ -4932,7 +4941,7 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con,
/* Speed hack: do raw pointer compares. As names are
normally interned this should almost always hit. */
co_varnames = ((PyTupleObject *)(co->co_localsplusnames))->ob_item;
co_varnames = ((PyTupleObject *)(co->co_varnames))->ob_item;
for (j = co->co_posonlyargcount; j < total_args; j++) {
PyObject *varname = co_varnames[j];
if (varname == keyword) {
@@ -4988,7 +4997,7 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con,
/* Check the number of positional arguments */
if ((argcount > co->co_argcount) && !(co->co_flags & CO_VARARGS)) {
too_many_positional(tstate, co, argcount, con->fc_defaults, localsplus,
too_many_positional(tstate, co, argcount, con->fc_defaults, fastlocals,
con->fc_qualname);
goto fail;
}
@@ -5004,7 +5013,7 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con,
}
}
if (missing) {
missing_arguments(tstate, co, missing, defcount, localsplus,
missing_arguments(tstate, co, missing, defcount, fastlocals,
con->fc_qualname);
goto fail;
}
@@ -5030,7 +5039,7 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con,
for (i = co->co_argcount; i < total_args; i++) {
if (GETLOCAL(i) != NULL)
continue;
PyObject *varname = PyTuple_GET_ITEM(co->co_localsplusnames, i);
PyObject *varname = PyTuple_GET_ITEM(co->co_varnames, i);
if (con->fc_kwdefaults != NULL) {
PyObject *def = PyDict_GetItemWithError(con->fc_kwdefaults, varname);
if (def) {
@@ -5045,13 +5054,12 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con,
missing++;
}
if (missing) {
missing_arguments(tstate, co, missing, -1, localsplus,
missing_arguments(tstate, co, missing, -1, fastlocals,
con->fc_qualname);
goto fail;
}
}
/* Allocate and initialize storage for cell vars, and copy free
vars into frame. */
for (i = 0; i < co->co_ncellvars; ++i) {
@@ -5076,7 +5084,7 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con,
for (i = 0; i < co->co_nfreevars; ++i) {
PyObject *o = PyTuple_GET_ITEM(con->fc_closure, i);
Py_INCREF(o);
localsplus[co->co_nlocals + co->co_ncellvars + i] = o;
freevars[co->co_ncellvars + i] = o;
}
return 0;
@@ -6409,11 +6417,15 @@ format_exc_unbound(PyThreadState *tstate, PyCodeObject *co, int oparg)
/* Don't stomp existing exception */
if (_PyErr_Occurred(tstate))
return;
name = PyTuple_GET_ITEM(co->co_localsplusnames, oparg);
if (oparg < co->co_ncellvars + co->co_nlocals) {
format_exc_check_arg(tstate, PyExc_UnboundLocalError,
UNBOUNDLOCAL_ERROR_MSG, name);
if (oparg < co->co_ncellvars) {
name = PyTuple_GET_ITEM(co->co_cellvars,
oparg);
format_exc_check_arg(tstate,
PyExc_UnboundLocalError,
UNBOUNDLOCAL_ERROR_MSG,
name);
} else {
name = PyTuple_GET_ITEM(co->co_freevars, oparg - co->co_ncellvars);
format_exc_check_arg(tstate, PyExc_NameError,
UNBOUNDFREE_ERROR_MSG, name);
}
@@ -6455,14 +6467,16 @@ unicode_concatenate(PyThreadState *tstate, PyObject *v, PyObject *w,
switch (opcode) {
case STORE_FAST:
{
PyObject **localsplus = f->f_localsptr;
PyObject **fastlocals = f->f_localsptr;
if (GETLOCAL(oparg) == v)
SETLOCAL(oparg, NULL);
break;
}
case STORE_DEREF:
{
PyObject *c = f->f_localsptr[oparg];
PyObject **freevars = (f->f_localsptr +
f->f_code->co_nlocals);
PyObject *c = freevars[oparg];
if (PyCell_GET(c) == v) {
PyCell_SET(c, NULL);
Py_DECREF(v);
+37 -122
View File
@@ -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;
+4 -3
View File
@@ -5,7 +5,8 @@ const unsigned char _Py_M__hello[] = {
100,1,131,1,1,0,100,2,83,0,41,3,84,122,12,72,
101,108,108,111,32,119,111,114,108,100,33,78,41,2,90,11,
105,110,105,116,105,97,108,105,122,101,100,218,5,112,114,105,
110,116,169,0,122,14,60,102,114,111,122,101,110,32,104,101,
108,108,111,62,218,8,60,109,111,100,117,108,101,62,1,0,
0,0,115,4,0,0,0,4,0,12,1,243,0,0,0,0,
110,116,169,0,114,1,0,0,0,114,1,0,0,0,122,14,
60,102,114,111,122,101,110,32,104,101,108,108,111,62,218,8,
60,109,111,100,117,108,101,62,1,0,0,0,115,4,0,0,
0,4,0,12,1,243,0,0,0,0,
};
+1635 -1597
View File
File diff suppressed because it is too large Load Diff
+2668 -2618
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+22 -30
View File
@@ -518,8 +518,9 @@ w_complex_object(PyObject *v, char flag, WFILE *p)
w_object(co->co_code, p);
w_object(co->co_consts, p);
w_object(co->co_names, p);
w_object(co->co_localsplusnames, p);
w_string(co->co_localspluskinds, co->co_nlocalsplus, p);
w_object(co->co_varnames, p);
w_object(co->co_freevars, p);
w_object(co->co_cellvars, p);
w_object(co->co_filename, p);
w_object(co->co_name, p);
w_long(co->co_firstlineno, p);
@@ -1305,8 +1306,9 @@ r_object(RFILE *p)
PyObject *code = NULL;
PyObject *consts = NULL;
PyObject *names = NULL;
PyObject *localsplusnames = NULL;
_PyLocalsPlusKinds localspluskinds = NULL;
PyObject *varnames = NULL;
PyObject *freevars = NULL;
PyObject *cellvars = NULL;
PyObject *filename = NULL;
PyObject *name = NULL;
int firstlineno;
@@ -1345,22 +1347,16 @@ r_object(RFILE *p)
names = r_object(p);
if (names == NULL)
goto code_error;
localsplusnames = r_object(p);
if (localsplusnames == NULL)
varnames = r_object(p);
if (varnames == NULL)
goto code_error;
Py_ssize_t nlocals = PyTuple_GET_SIZE(varnames);
freevars = r_object(p);
if (freevars == NULL)
goto code_error;
cellvars = r_object(p);
if (cellvars == NULL)
goto code_error;
assert(PyTuple_GET_SIZE(localsplusnames) < INT_MAX);
int nlocalsplus = (int)PyTuple_GET_SIZE(localsplusnames);
if (nlocalsplus) {
if (_PyCode_InitLocalsPlusKinds(nlocalsplus,
&localspluskinds) < 0) {
goto code_error;
}
for (int i = 0; i < nlocalsplus; i++) {
localspluskinds[i] = r_byte(p);
}
}
filename = r_object(p);
if (filename == NULL)
goto code_error;
@@ -1379,8 +1375,7 @@ r_object(RFILE *p)
if (PySys_Audit("code.__new__", "OOOiiiiii",
code, filename, name, argcount, posonlyargcount,
kwonlyargcount, nlocalsplus, stacksize,
flags) < 0) {
kwonlyargcount, nlocals, stacksize, flags) < 0) {
goto code_error;
}
@@ -1396,8 +1391,9 @@ r_object(RFILE *p)
.consts = consts,
.names = names,
.localsplusnames = localsplusnames,
.localspluskinds = localspluskinds,
.varnames = varnames,
.cellvars = cellvars,
.freevars = freevars,
.argcount = argcount,
.posonlyargcount = posonlyargcount,
@@ -1407,26 +1403,22 @@ r_object(RFILE *p)
.exceptiontable = exceptiontable,
};
if (_PyCode_Validate(&con) < 0) {
goto code_error;
}
v = (PyObject *)_PyCode_New(&con);
if (v == NULL) {
goto code_error;
}
localspluskinds = NULL; // This keeps it from getting freed below.
v = r_ref_insert(v, idx, flag, p);
code_error:
Py_XDECREF(code);
Py_XDECREF(consts);
Py_XDECREF(names);
Py_XDECREF(localsplusnames);
_PyCode_ClearLocalsPlusKinds(localspluskinds);
Py_XDECREF(varnames);
Py_XDECREF(freevars);
Py_XDECREF(cellvars);
Py_XDECREF(filename);
Py_XDECREF(name);
Py_XDECREF(linetable);
+2 -7
View File
@@ -3,7 +3,6 @@
#include "pycore_frame.h"
#include "pycore_pyerrors.h"
#include "pycore_code.h" // _PyCode_GetVarnames()
#define MAX_CANDIDATE_ITEMS 750
#define MAX_STRING_SIZE 40
@@ -211,12 +210,8 @@ offer_suggestions_for_name_error(PyNameErrorObject *exc)
PyFrameObject *frame = traceback->tb_frame;
assert(frame != NULL);
PyCodeObject *code = PyFrame_GetCode(frame);
assert(code != NULL && code->co_localsplusnames != NULL);
PyObject *varnames = _PyCode_GetVarnames(code);
if (varnames == NULL) {
return NULL;
}
PyObject *dir = PySequence_List(varnames);
assert(code != NULL && code->co_varnames != NULL);
PyObject *dir = PySequence_List(code->co_varnames);
Py_DECREF(code);
if (dir == NULL) {
return NULL;