8000 GH-100719: Remove the `co_nplaincellvars` field from code objects. (G… · python/cpython@15aecf8 · GitHub
[go: up one dir, main page]

Skip to content

Commit 15aecf8

Browse files
authored
GH-100719: Remove the co_nplaincellvars field from code objects. (GH-100721)
1 parent c31e356 commit 15aecf8

File tree

10 files changed

+19
-23
lines changed

10 files changed

+19
-23
lines changed

Include/cpython/code.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ typedef struct {
8787
int co_nlocalsplus; /* number of local + cell + free variables */ \
8888
int co_framesize; /* Size of frame in words */ \
8989
int co_nlocals; /* number of local variables */ \
90-
int co_nplaincellvars; /* number of non-arg cell variables */ \
9190
int co_ncellvars; /* total number of cell variables */ \
9291
int co_nfreevars; /* number of free variables */ \
9392
uint32_t co_version; /* version number */ \
@@ -157,6 +156,11 @@ static inline Py_ssize_t PyCode_GetNumFree(PyCodeObject *op) {
157156
return op->co_nfreevars;
158157
}
159158

159+
static inline int PyCode_GetFirstFree(PyCodeObject *op) {
160+
assert(PyCode_Check(op));
161+
return op->co_nlocalsplus - op->co_nfreevars;
162+
}
163+
160164
#define _PyCode_CODE(CO) _Py_RVALUE((_Py_CODEUNIT *)(CO)->co_code_adaptive)
161165
#define _PyCode_NBYTES(CO) (Py_SIZE(CO) * (Py_ssize_t)sizeof(_Py_CODEUNIT))
162166

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Removed the co_nplaincellvars field from the code object, as it is
2+
redundant.

Objects/codeobject.c

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -247,11 +247,10 @@ _Py_set_localsplus_info(int offset, PyObject *name, _PyLocals_Kind kind,
247247

248248
static void
249249
get_localsplus_counts(PyObject *names, PyObject *kinds,
250-
int *pnlocals, int *pnplaincellvars, int *pncellvars,
250+
int *pnlocals, int *pncellvars,
251251
int *pnfreevars)
252252
{
253253
int nlocals = 0;
254-
int nplaincellvars = 0;
255254
int ncellvars = 0;
256255
int nfreevars = 0;
257256
Py_ssize_t nlocalsplus = PyTuple_GET_SIZE(names);
@@ -265,7 +264,6 @@ get_localsplus_counts(PyObject *names, PyObject *kinds,
265264
}
266265
else if (kind & CO_FAST_CELL) {
267266
ncellvars += 1;
268-
nplaincellvars += 1;
269267
}
270268
else if (kind & CO_FAST_FREE) {
271269
nfreevars += 1;
@@ -274,9 +272,6 @@ get_localsplus_counts(PyObject *names, PyObject *kinds,
274272
if (pnlocals != NULL) {
275273
*pnlocals = nlocals;
276274
}
277-
if (pnplaincellvars != NULL) {
278-
*pnplaincellvars = nplaincellvars;
279-
}
280275
if (pncellvars != NULL) {
281276
*pncellvars = ncellvars;
282277
}
@@ -351,7 +346,7 @@ _PyCode_Validate(struct _PyCodeConstructor *con)
351346
* here to avoid the possibility of overflow (however remote). */
352347
int nlocals;
353348
get_localsplus_counts(con->localsplusnames, con->localspluskinds,
354-
&nlocals, NULL, NULL, NULL);
349+
&nlocals, NULL, NULL);
355350
int nplainlocals = nlocals -
356351
con->argcount -
357352
con->kwonlyargcount -
@@ -371,9 +366,9 @@ static void
371366
init_code(PyCodeObject *co, struct _PyCodeConstructor *con)
372367
{
373368
int nlocalsplus = (int)PyTuple_GET_SIZE(con->localsplusnames);
374-
int nlocals, nplaincellvars, ncellvars, nfreevars;
369+
int nlocals, ncellvars, nfreevars;
375370
get_localsplus_counts(con->localsplusnames, con->localspluskinds,
376-
&nlocals, &nplaincellvars, &ncellvars, &nfreevars);
371+
&nlocals, &ncellvars, &nfreevars);
377372

378373
co->co_filename = Py_NewRef(con->filename);
379374
co->co_name = Py_NewRef(con->name);
@@ -401,7 +396,6 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con)
401396
co->co_nlocalsplus = nlocalsplus;
402397
co->co_nlocals = nlocals;
403398
co->co_framesize = nlocalsplus + con->stacksize + FRAME_SPECIALS_SIZE;
404-
co->co_nplaincellvars = nplaincellvars;
405399
co->co_ncellvars = ncellvars;
406400
co->co_nfreevars = nfreevars;
407401
co->co_version = _Py_next_func_version;

Objects/frameobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1119,7 +1119,7 @@ frame_init_get_vars(_PyInterpreterFrame *frame)
11191119

11201120
/* Free vars have not been initialized -- Do that */
11211121
PyObject *closure = ((PyFunctionObject *)frame->f_funcobj)->func_closure;
1122-
int offset = co->co_nlocals + co->co_nplaincellvars;
1122+
int offset = PyCode_GetFirstFree(co);
11231123
for (int i = 0; i < co->co_nfreevars; ++i) {
11241124
PyObject *o = PyTuple_GET_ITEM(closure, i);
11251125
frame->localsplus[offset + i] = Py_NewRef(o);

Objects/typeobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9514,7 +9514,7 @@ super_init_without_args(_PyInterpreterFrame *cframe, PyCodeObject *co,
95149514

95159515
// Look for __class__ in the free vars.
95169516
PyTypeObject *type = NULL;
9517-
int i = co->co_nlocals + co->co_nplaincellvars;
9517+
int i = PyCode_GetFirstFree(co);
95189518
for (; i < co->co_nlocalsplus; i++) {
95199519
assert((_PyLocals_GetKind(co->co_localspluskinds, i) & CO_FAST_FREE) != 0);
95209520
PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, i);

Python/bytecodes.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1357,8 +1357,8 @@ dummy_func(
13571357
PyCodeObject *co = frame->f_code;
13581358
assert(PyFunction_Check(frame->f_funcobj));
13591359
PyObject *closure = ((PyFunctionObject *)frame->f_funcobj)->func_closure;
1360-
int offset = co->co_nlocals + co->co_nplaincellvars;
13611360
assert(oparg == co->co_nfreevars);
1361+
int offset = co->co_nlocalsplus - oparg;
13621362
for (int i = 0; i < oparg; ++i) {
13631363
PyObject *o = PyTuple_GET_ITEM(closure, i);
13641364
frame->localsplus[offset + i] = Py_NewRef(o);

Python/ceval.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3417,7 +3417,7 @@ format_exc_unbound(PyThreadState *tstate, PyCodeObject *co, int oparg)
34173417
if (_PyErr_Occurred(tstate))
34183418
return;
34193419
name = PyTuple_GET_ITEM(co->co_localsplusnames, oparg);
3420-
if (oparg < co->co_nplaincellvars + co->co_nlocals) {
3420+
if (oparg < PyCode_GetFirstFree(co)) {
34213421
format_exc_check_arg(tstate, PyExc_UnboundLocalError,
34223422
UNBOUNDLOCAL_ERROR_MSG, name);
34233423
} else {

Python/compile.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2260,7 +2260,7 @@ compiler_make_closure(struct compiler *c, location loc,
22602260
qualname = co->co_name;
22612261

22622262
if (co->co_nfreevars) {
2263-
int i = co->co_nlocals + co->co_nplaincellvars;
2263+
int i = PyCode_GetFirstFree(co);
22642264
for (; i < co->co_nlocalsplus; ++i) {
22652265
/* Bypass com_addop_varname because it will generate
22662266
LOAD_DEREF but LOAD_CLOSURE is needed.

Python/generated_cases.c.h

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Tools/build/deepfreeze.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ def get_localsplus_counts(code: types.CodeType,
6161
names: Tuple[str, ...],
6262
kinds: bytes) -> Tuple[int, int, int, int]:
6363
nlocals = 0
64-
nplaincellvars = 0
6564
ncellvars = 0
6665
nfreevars = 0
6766
assert len(names) == len(kinds)
@@ -72,15 +71,13 @@ def get_localsplus_counts(code: types.CodeType,
7271
ncellvars += 1
7372
elif kind & CO_FAST_CELL:
7473
ncellvars += 1
75-
nplaincellvars += 1
7674
elif kind & CO_FAST_FREE:
7775
nfreevars += 1
7876
assert nlocals == len(code.co_varnames) == code.co_nlocals, \
7977
(nlocals, len(code.co_varnames), code.co_nlocals)
8078
assert ncellvars == len(code.co_cellvars)
8179
assert nfreevars == len(code.co_freevars)
82-
assert len(names) == nlocals + nplaincellvars + nfreevars
83-
return nlocals, nplaincellvars, ncellvars, nfreevars
80+
return nlocals, ncellvars, nfreevars
8481

8582

8683
PyUnicode_1BYTE_KIND = 1
@@ -243,7 +240,7 @@ def generate_code(self, name: str, code: types.CodeType) -> str:
243240
co_localsplusnames = self.generate(name + "_localsplusnames", localsplusnames)
244241
co_localspluskinds = self.generate(name + "_localspluskinds", localspluskinds)
245242
# Derived values
246-
nlocals, nplaincellvars, ncellvars, nfreevars = \
243+
nlocals, ncellvars, nfreevars = \
247244
get_localsplus_counts(code, localsplusnames, localspluskinds)
248245
co_code_adaptive = make_string_literal(code.co_code)
249246
self.write("static")
@@ -268,7 +265,6 @@ def generate_code(self, name: str, code: types.CodeType) -> str:
268265
self.field(code, "co_firstlineno")
269266
self.write(f".co_nlocalsplus = {len(localsplusnames)},")
270267
self.field(code, "co_nlocals")
271-
self.write(f".co_nplaincellvars = {nplaincellvars},")
272268
self.write(f".co_ncellvars = {ncellvars},")
273269
self.write(f".co_nfreevars = {nfreevars},")
274270
self.write(f".co_version = {next_code_version},")

0 commit comments

Comments
 (0)
0