mirror of
https://github.com/python/cpython.git
synced 2025-10-09 16:34:44 +00:00
GH-100719: Remove the co_nplaincellvars
field from code objects. (GH-100721)
This commit is contained in:
parent
c31e356a10
commit
15aecf8dd7
10 changed files with 19 additions and 23 deletions
|
@ -87,7 +87,6 @@ typedef struct {
|
||||||
int co_nlocalsplus; /* number of local + cell + free variables */ \
|
int co_nlocalsplus; /* number of local + cell + free variables */ \
|
||||||
int co_framesize; /* Size of frame in words */ \
|
int co_framesize; /* Size of frame in words */ \
|
||||||
int co_nlocals; /* number of local variables */ \
|
int co_nlocals; /* number of local variables */ \
|
||||||
int co_nplaincellvars; /* number of non-arg cell variables */ \
|
|
||||||
int co_ncellvars; /* total number of cell variables */ \
|
int co_ncellvars; /* total number of cell variables */ \
|
||||||
int co_nfreevars; /* number of free variables */ \
|
int co_nfreevars; /* number of free variables */ \
|
||||||
uint32_t co_version; /* version number */ \
|
uint32_t co_version; /* version number */ \
|
||||||
|
@ -157,6 +156,11 @@ static inline Py_ssize_t PyCode_GetNumFree(PyCodeObject *op) {
|
||||||
return op->co_nfreevars;
|
return op->co_nfreevars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int PyCode_GetFirstFree(PyCodeObject *op) {
|
||||||
|
assert(PyCode_Check(op));
|
||||||
|
return op->co_nlocalsplus - op->co_nfreevars;
|
||||||
|
}
|
||||||
|
|
||||||
#define _PyCode_CODE(CO) _Py_RVALUE((_Py_CODEUNIT *)(CO)->co_code_adaptive)
|
#define _PyCode_CODE(CO) _Py_RVALUE((_Py_CODEUNIT *)(CO)->co_code_adaptive)
|
||||||
#define _PyCode_NBYTES(CO) (Py_SIZE(CO) * (Py_ssize_t)sizeof(_Py_CODEUNIT))
|
#define _PyCode_NBYTES(CO) (Py_SIZE(CO) * (Py_ssize_t)sizeof(_Py_CODEUNIT))
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Removed the co_nplaincellvars field from the code object, as it is
|
||||||
|
redundant.
|
|
@ -247,11 +247,10 @@ _Py_set_localsplus_info(int offset, PyObject *name, _PyLocals_Kind kind,
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_localsplus_counts(PyObject *names, PyObject *kinds,
|
get_localsplus_counts(PyObject *names, PyObject *kinds,
|
||||||
int *pnlocals, int *pnplaincellvars, int *pncellvars,
|
int *pnlocals, int *pncellvars,
|
||||||
int *pnfreevars)
|
int *pnfreevars)
|
||||||
{
|
{
|
||||||
int nlocals = 0;
|
int nlocals = 0;
|
||||||
int nplaincellvars = 0;
|
|
||||||
int ncellvars = 0;
|
int ncellvars = 0;
|
||||||
int nfreevars = 0;
|
int nfreevars = 0;
|
||||||
Py_ssize_t nlocalsplus = PyTuple_GET_SIZE(names);
|
Py_ssize_t nlocalsplus = PyTuple_GET_SIZE(names);
|
||||||
|
@ -265,7 +264,6 @@ get_localsplus_counts(PyObject *names, PyObject *kinds,
|
||||||
}
|
}
|
||||||
else if (kind & CO_FAST_CELL) {
|
else if (kind & CO_FAST_CELL) {
|
||||||
ncellvars += 1;
|
ncellvars += 1;
|
||||||
nplaincellvars += 1;
|
|
||||||
}
|
}
|
||||||
else if (kind & CO_FAST_FREE) {
|
else if (kind & CO_FAST_FREE) {
|
||||||
nfreevars += 1;
|
nfreevars += 1;
|
||||||
|
@ -274,9 +272,6 @@ get_localsplus_counts(PyObject *names, PyObject *kinds,
|
||||||
if (pnlocals != NULL) {
|
if (pnlocals != NULL) {
|
||||||
*pnlocals = nlocals;
|
*pnlocals = nlocals;
|
||||||
}
|
}
|
||||||
if (pnplaincellvars != NULL) {
|
|
||||||
*pnplaincellvars = nplaincellvars;
|
|
||||||
}
|
|
||||||
if (pncellvars != NULL) {
|
if (pncellvars != NULL) {
|
||||||
*pncellvars = ncellvars;
|
*pncellvars = ncellvars;
|
||||||
}
|
}
|
||||||
|
@ -351,7 +346,7 @@ _PyCode_Validate(struct _PyCodeConstructor *con)
|
||||||
* here to avoid the possibility of overflow (however remote). */
|
* here to avoid the possibility of overflow (however remote). */
|
||||||
int nlocals;
|
int nlocals;
|
||||||
get_localsplus_counts(con->localsplusnames, con->localspluskinds,
|
get_localsplus_counts(con->localsplusnames, con->localspluskinds,
|
||||||
&nlocals, NULL, NULL, NULL);
|
&nlocals, NULL, NULL);
|
||||||
int nplainlocals = nlocals -
|
int nplainlocals = nlocals -
|
||||||
con->argcount -
|
con->argcount -
|
||||||
con->kwonlyargcount -
|
con->kwonlyargcount -
|
||||||
|
@ -371,9 +366,9 @@ static void
|
||||||
init_code(PyCodeObject *co, struct _PyCodeConstructor *con)
|
init_code(PyCodeObject *co, struct _PyCodeConstructor *con)
|
||||||
{
|
{
|
||||||
int nlocalsplus = (int)PyTuple_GET_SIZE(con->localsplusnames);
|
int nlocalsplus = (int)PyTuple_GET_SIZE(con->localsplusnames);
|
||||||
int nlocals, nplaincellvars, ncellvars, nfreevars;
|
int nlocals, ncellvars, nfreevars;
|
||||||
get_localsplus_counts(con->localsplusnames, con->localspluskinds,
|
get_localsplus_counts(con->localsplusnames, con->localspluskinds,
|
||||||
&nlocals, &nplaincellvars, &ncellvars, &nfreevars);
|
&nlocals, &ncellvars, &nfreevars);
|
||||||
|
|
||||||
co->co_filename = Py_NewRef(con->filename);
|
co->co_filename = Py_NewRef(con->filename);
|
||||||
co->co_name = Py_NewRef(con->name);
|
co->co_name = Py_NewRef(con->name);
|
||||||
|
@ -401,7 +396,6 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con)
|
||||||
co->co_nlocalsplus = nlocalsplus;
|
co->co_nlocalsplus = nlocalsplus;
|
||||||
co->co_nlocals = nlocals;
|
co->co_nlocals = nlocals;
|
||||||
co->co_framesize = nlocalsplus + con->stacksize + FRAME_SPECIALS_SIZE;
|
co->co_framesize = nlocalsplus + con->stacksize + FRAME_SPECIALS_SIZE;
|
||||||
co->co_nplaincellvars = nplaincellvars;
|
|
||||||
co->co_ncellvars = ncellvars;
|
co->co_ncellvars = ncellvars;
|
||||||
co->co_nfreevars = nfreevars;
|
co->co_nfreevars = nfreevars;
|
||||||
co->co_version = _Py_next_func_version;
|
co->co_version = _Py_next_func_version;
|
||||||
|
|
|
@ -1119,7 +1119,7 @@ frame_init_get_vars(_PyInterpreterFrame *frame)
|
||||||
|
|
||||||
/* Free vars have not been initialized -- Do that */
|
/* Free vars have not been initialized -- Do that */
|
||||||
PyObject *closure = ((PyFunctionObject *)frame->f_funcobj)->func_closure;
|
PyObject *closure = ((PyFunctionObject *)frame->f_funcobj)->func_closure;
|
||||||
int offset = co->co_nlocals + co->co_nplaincellvars;
|
int offset = PyCode_GetFirstFree(co);
|
||||||
for (int i = 0; i < co->co_nfreevars; ++i) {
|
for (int i = 0; i < co->co_nfreevars; ++i) {
|
||||||
PyObject *o = PyTuple_GET_ITEM(closure, i);
|
PyObject *o = PyTuple_GET_ITEM(closure, i);
|
||||||
frame->localsplus[offset + i] = Py_NewRef(o);
|
frame->localsplus[offset + i] = Py_NewRef(o);
|
||||||
|
|
|
@ -9514,7 +9514,7 @@ super_init_without_args(_PyInterpreterFrame *cframe, PyCodeObject *co,
|
||||||
|
|
||||||
// Look for __class__ in the free vars.
|
// Look for __class__ in the free vars.
|
||||||
PyTypeObject *type = NULL;
|
PyTypeObject *type = NULL;
|
||||||
int i = co->co_nlocals + co->co_nplaincellvars;
|
int i = PyCode_GetFirstFree(co);
|
||||||
for (; i < co->co_nlocalsplus; i++) {
|
for (; i < co->co_nlocalsplus; i++) {
|
||||||
assert((_PyLocals_GetKind(co->co_localspluskinds, i) & CO_FAST_FREE) != 0);
|
assert((_PyLocals_GetKind(co->co_localspluskinds, i) & CO_FAST_FREE) != 0);
|
||||||
PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, i);
|
PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, i);
|
||||||
|
|
|
@ -1357,8 +1357,8 @@ dummy_func(
|
||||||
PyCodeObject *co = frame->f_code;
|
PyCodeObject *co = frame->f_code;
|
||||||
assert(PyFunction_Check(frame->f_funcobj));
|
assert(PyFunction_Check(frame->f_funcobj));
|
||||||
PyObject *closure = ((PyFunctionObject *)frame->f_funcobj)->func_closure;
|
PyObject *closure = ((PyFunctionObject *)frame->f_funcobj)->func_closure;
|
||||||
int offset = co->co_nlocals + co->co_nplaincellvars;
|
|
||||||
assert(oparg == co->co_nfreevars);
|
assert(oparg == co->co_nfreevars);
|
||||||
|
int offset = co->co_nlocalsplus - oparg;
|
||||||
for (int i = 0; i < oparg; ++i) {
|
for (int i = 0; i < oparg; ++i) {
|
||||||
PyObject *o = PyTuple_GET_ITEM(closure, i);
|
PyObject *o = PyTuple_GET_ITEM(closure, i);
|
||||||
frame->localsplus[offset + i] = Py_NewRef(o);
|
frame->localsplus[offset + i] = Py_NewRef(o);
|
||||||
|
|
|
@ -3417,7 +3417,7 @@ format_exc_unbound(PyThreadState *tstate, PyCodeObject *co, int oparg)
|
||||||
if (_PyErr_Occurred(tstate))
|
if (_PyErr_Occurred(tstate))
|
||||||
return;
|
return;
|
||||||
name = PyTuple_GET_ITEM(co->co_localsplusnames, oparg);
|
name = PyTuple_GET_ITEM(co->co_localsplusnames, oparg);
|
||||||
if (oparg < co->co_nplaincellvars + co->co_nlocals) {
|
if (oparg < PyCode_GetFirstFree(co)) {
|
||||||
format_exc_check_arg(tstate, PyExc_UnboundLocalError,
|
format_exc_check_arg(tstate, PyExc_UnboundLocalError,
|
||||||
UNBOUNDLOCAL_ERROR_MSG, name);
|
UNBOUNDLOCAL_ERROR_MSG, name);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -2260,7 +2260,7 @@ compiler_make_closure(struct compiler *c, location loc,
|
||||||
qualname = co->co_name;
|
qualname = co->co_name;
|
||||||
|
|
||||||
if (co->co_nfreevars) {
|
if (co->co_nfreevars) {
|
||||||
int i = co->co_nlocals + co->co_nplaincellvars;
|
int i = PyCode_GetFirstFree(co);
|
||||||
for (; i < co->co_nlocalsplus; ++i) {
|
for (; i < co->co_nlocalsplus; ++i) {
|
||||||
/* Bypass com_addop_varname because it will generate
|
/* Bypass com_addop_varname because it will generate
|
||||||
LOAD_DEREF but LOAD_CLOSURE is needed.
|
LOAD_DEREF but LOAD_CLOSURE is needed.
|
||||||
|
|
2
Python/generated_cases.c.h
generated
2
Python/generated_cases.c.h
generated
|
@ -1575,8 +1575,8 @@
|
||||||
PyCodeObject *co = frame->f_code;
|
PyCodeObject *co = frame->f_code;
|
||||||
assert(PyFunction_Check(frame->f_funcobj));
|
assert(PyFunction_Check(frame->f_funcobj));
|
||||||
PyObject *closure = ((PyFunctionObject *)frame->f_funcobj)->func_closure;
|
PyObject *closure = ((PyFunctionObject *)frame->f_funcobj)->func_closure;
|
||||||
int offset = co->co_nlocals + co->co_nplaincellvars;
|
|
||||||
assert(oparg == co->co_nfreevars);
|
assert(oparg == co->co_nfreevars);
|
||||||
|
int offset = co->co_nlocalsplus - oparg;
|
||||||
for (int i = 0; i < oparg; ++i) {
|
for (int i = 0; i < oparg; ++i) {
|
||||||
PyObject *o = PyTuple_GET_ITEM(closure, i);
|
PyObject *o = PyTuple_GET_ITEM(closure, i);
|
||||||
frame->localsplus[offset + i] = Py_NewRef(o);
|
frame->localsplus[offset + i] = Py_NewRef(o);
|
||||||
|
|
|
@ -61,7 +61,6 @@ def get_localsplus_counts(code: types.CodeType,
|
||||||
names: Tuple[str, ...],
|
names: Tuple[str, ...],
|
||||||
kinds: bytes) -> Tuple[int, int, int, int]:
|
kinds: bytes) -> Tuple[int, int, int, int]:
|
||||||
nlocals = 0
|
nlocals = 0
|
||||||
nplaincellvars = 0
|
|
||||||
ncellvars = 0
|
ncellvars = 0
|
||||||
nfreevars = 0
|
nfreevars = 0
|
||||||
assert len(names) == len(kinds)
|
assert len(names) == len(kinds)
|
||||||
|
@ -72,15 +71,13 @@ def get_localsplus_counts(code: types.CodeType,
|
||||||
ncellvars += 1
|
ncellvars += 1
|
||||||
elif kind & CO_FAST_CELL:
|
elif kind & CO_FAST_CELL:
|
||||||
ncellvars += 1
|
ncellvars += 1
|
||||||
nplaincellvars += 1
|
|
||||||
elif kind & CO_FAST_FREE:
|
elif kind & CO_FAST_FREE:
|
||||||
nfreevars += 1
|
nfreevars += 1
|
||||||
assert nlocals == len(code.co_varnames) == code.co_nlocals, \
|
assert nlocals == len(code.co_varnames) == code.co_nlocals, \
|
||||||
(nlocals, len(code.co_varnames), code.co_nlocals)
|
(nlocals, len(code.co_varnames), code.co_nlocals)
|
||||||
assert ncellvars == len(code.co_cellvars)
|
assert ncellvars == len(code.co_cellvars)
|
||||||
assert nfreevars == len(code.co_freevars)
|
assert nfreevars == len(code.co_freevars)
|
||||||
assert len(names) == nlocals + nplaincellvars + nfreevars
|
return nlocals, ncellvars, nfreevars
|
||||||
return nlocals, nplaincellvars, ncellvars, nfreevars
|
|
||||||
|
|
||||||
|
|
||||||
PyUnicode_1BYTE_KIND = 1
|
PyUnicode_1BYTE_KIND = 1
|
||||||
|
@ -243,7 +240,7 @@ class Printer:
|
||||||
co_localsplusnames = self.generate(name + "_localsplusnames", localsplusnames)
|
co_localsplusnames = self.generate(name + "_localsplusnames", localsplusnames)
|
||||||
co_localspluskinds = self.generate(name + "_localspluskinds", localspluskinds)
|
co_localspluskinds = self.generate(name + "_localspluskinds", localspluskinds)
|
||||||
# Derived values
|
# Derived values
|
||||||
nlocals, nplaincellvars, ncellvars, nfreevars = \
|
nlocals, ncellvars, nfreevars = \
|
||||||
get_localsplus_counts(code, localsplusnames, localspluskinds)
|
get_localsplus_counts(code, localsplusnames, localspluskinds)
|
||||||
co_code_adaptive = make_string_literal(code.co_code)
|
co_code_adaptive = make_string_literal(code.co_code)
|
||||||
self.write("static")
|
self.write("static")
|
||||||
|
@ -268,7 +265,6 @@ class Printer:
|
||||||
self.field(code, "co_firstlineno")
|
self.field(code, "co_firstlineno")
|
||||||
self.write(f".co_nlocalsplus = {len(localsplusnames)},")
|
self.write(f".co_nlocalsplus = {len(localsplusnames)},")
|
||||||
self.field(code, "co_nlocals")
|
self.field(code, "co_nlocals")
|
||||||
self.write(f".co_nplaincellvars = {nplaincellvars},")
|
|
||||||
self.write(f".co_ncellvars = {ncellvars},")
|
self.write(f".co_ncellvars = {ncellvars},")
|
||||||
self.write(f".co_nfreevars = {nfreevars},")
|
self.write(f".co_nfreevars = {nfreevars},")
|
||||||
self.write(f".co_version = {next_code_version},")
|
self.write(f".co_version = {next_code_version},")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue