summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2021-06-21 20:53:04 (GMT)
committerGitHub <noreply@github.com>2021-06-21 20:53:04 (GMT)
commit355f5dd36a0f53175517f35798aa874564d1113a (patch)
treecfc6c7e4f009afc772d4a9e0c909d6e3499cf2e9 /Objects
parentc5d700f0e2e2921c6b54c72ffb0fca3c3d1ef06b (diff)
downloadcpython-355f5dd36a0f53175517f35798aa874564d1113a.zip
cpython-355f5dd36a0f53175517f35798aa874564d1113a.tar.gz
cpython-355f5dd36a0f53175517f35798aa874564d1113a.tar.bz2
bpo-43693: Turn localspluskinds into an object (GH-26749)
Managing it as a bare pointer to malloc'ed bytes is just too awkward in a few places.
Diffstat (limited to 'Objects')
-rw-r--r--Objects/codeobject.c43
-rw-r--r--Objects/frameobject.c4
-rw-r--r--Objects/typeobject.c4
3 files changed, 28 insertions, 23 deletions
diff --git a/Objects/codeobject.c b/Objects/codeobject.c
index 11a83d4..99199cc 100644
--- a/Objects/codeobject.c
+++ b/Objects/codeobject.c
@@ -156,16 +156,16 @@ validate_and_copy_tuple(PyObject *tup)
// This is also used in compile.c.
void
-_Py_set_localsplus_info(int offset, PyObject *name, _PyLocalsPlusKind kind,
- PyObject *names, _PyLocalsPlusKinds kinds)
+_Py_set_localsplus_info(int offset, PyObject *name, _PyLocals_Kind kind,
+ PyObject *names, PyObject *kinds)
{
Py_INCREF(name);
PyTuple_SET_ITEM(names, offset, name);
- kinds[offset] = kind;
+ _PyLocals_SetKind(kinds, offset, kind);
}
static void
-get_localsplus_counts(PyObject *names, _PyLocalsPlusKinds kinds,
+get_localsplus_counts(PyObject *names, PyObject *kinds,
int *pnlocals, int *pnplaincellvars, int *pncellvars,
int *pnfreevars)
{
@@ -175,17 +175,18 @@ get_localsplus_counts(PyObject *names, _PyLocalsPlusKinds kinds,
int nfreevars = 0;
Py_ssize_t nlocalsplus = PyTuple_GET_SIZE(names);
for (int i = 0; i < nlocalsplus; i++) {
- if (kinds[i] & CO_FAST_LOCAL) {
+ _PyLocals_Kind kind = _PyLocals_GetKind(kinds, i);
+ if (kind & CO_FAST_LOCAL) {
nlocals += 1;
- if (kinds[i] & CO_FAST_CELL) {
+ if (kind & CO_FAST_CELL) {
ncellvars += 1;
}
}
- else if (kinds[i] & CO_FAST_CELL) {
+ else if (kind & CO_FAST_CELL) {
ncellvars += 1;
nplaincellvars += 1;
}
- else if (kinds[i] & CO_FAST_FREE) {
+ else if (kind & CO_FAST_FREE) {
nfreevars += 1;
}
}
@@ -204,7 +205,7 @@ get_localsplus_counts(PyObject *names, _PyLocalsPlusKinds kinds,
}
static PyObject *
-get_localsplus_names(PyCodeObject *co, _PyLocalsPlusKind kind, int num)
+get_localsplus_names(PyCodeObject *co, _PyLocals_Kind kind, int num)
{
PyObject *names = PyTuple_New(num);
if (names == NULL) {
@@ -212,7 +213,8 @@ get_localsplus_names(PyCodeObject *co, _PyLocalsPlusKind kind, int num)
}
int index = 0;
for (int offset = 0; offset < co->co_nlocalsplus; offset++) {
- if ((co->co_localspluskinds[offset] & kind) == 0) {
+ _PyLocals_Kind k = _PyLocals_GetKind(co->co_localspluskinds, offset);
+ if ((k & kind) == 0) {
continue;
}
assert(index < num);
@@ -236,8 +238,9 @@ _PyCode_Validate(struct _PyCodeConstructor *con)
con->consts == NULL || !PyTuple_Check(con->consts) ||
con->names == NULL || !PyTuple_Check(con->names) ||
con->localsplusnames == NULL || !PyTuple_Check(con->localsplusnames) ||
- (PyTuple_GET_SIZE(con->localsplusnames) && con->localspluskinds == NULL) ||
- (!PyTuple_GET_SIZE(con->localsplusnames) && con->localspluskinds != NULL) ||
+ con->localspluskinds == NULL || !PyBytes_Check(con->localspluskinds) ||
+ PyTuple_GET_SIZE(con->localsplusnames)
+ != PyBytes_GET_SIZE(con->localspluskinds) ||
con->name == NULL || !PyUnicode_Check(con->name) ||
con->filename == NULL || !PyUnicode_Check(con->filename) ||
con->linetable == NULL || !PyBytes_Check(con->linetable) ||
@@ -309,7 +312,7 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con)
Py_INCREF(con->localsplusnames);
co->co_localsplusnames = con->localsplusnames;
- // We take ownership of the kinds array.
+ Py_INCREF(con->localspluskinds);
co->co_localspluskinds = con->localspluskinds;
co->co_argcount = con->argcount;
@@ -394,7 +397,7 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount,
{
PyCodeObject *co = NULL;
PyObject *localsplusnames = NULL;
- _PyLocalsPlusKinds localspluskinds = NULL;
+ PyObject *localspluskinds = NULL;
if (varnames == NULL || !PyTuple_Check(varnames) ||
cellvars == NULL || !PyTuple_Check(cellvars) ||
@@ -413,7 +416,8 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount,
if (localsplusnames == NULL) {
goto error;
}
- if (_PyCode_InitLocalsPlusKinds(nlocalsplus, &localspluskinds) < 0) {
+ localspluskinds = PyBytes_FromStringAndSize(NULL, nlocalsplus);
+ if (localspluskinds == NULL) {
goto error;
}
int offset = 0;
@@ -438,7 +442,8 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount,
// Merge the localsplus indices.
nlocalsplus -= 1;
offset -= 1;
- localspluskinds[argoffset] |= CO_FAST_CELL;
+ _PyLocals_Kind kind = _PyLocals_GetKind(localspluskinds, argoffset);
+ _PyLocals_SetKind(localspluskinds, argoffset, kind | CO_FAST_CELL);
continue;
}
_Py_set_localsplus_info(offset, name, CO_FAST_CELL,
@@ -495,7 +500,6 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount,
goto error;
}
- localspluskinds = NULL; // This keeps it from getting freed below.
Py_INCREF(varnames);
co->co_varnames = varnames;
Py_INCREF(cellvars);
@@ -505,7 +509,7 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount,
error:
Py_XDECREF(localsplusnames);
- _PyCode_ClearLocalsPlusKinds(localspluskinds);
+ Py_XDECREF(localspluskinds);
return co;
}
@@ -558,6 +562,7 @@ PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
.consts = nulltuple,
.names = nulltuple,
.localsplusnames = nulltuple,
+ .localspluskinds = emptystring,
.exceptiontable = emptystring,
};
result = _PyCode_New(&con);
@@ -1142,7 +1147,7 @@ code_dealloc(PyCodeObject *co)
Py_XDECREF(co->co_consts);
Py_XDECREF(co->co_names);
Py_XDECREF(co->co_localsplusnames);
- _PyCode_ClearLocalsPlusKinds(co->co_localspluskinds);
+ Py_XDECREF(co->co_localspluskinds);
Py_XDECREF(co->co_varnames);
Py_XDECREF(co->co_freevars);
Py_XDECREF(co->co_cellvars);
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index f9090d8..813ec56 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -958,7 +958,7 @@ PyFrame_FastToLocalsWithError(PyFrameObject *f)
co = _PyFrame_GetCode(f);
fast = f->f_localsptr;
for (int i = 0; i < co->co_nlocalsplus; i++) {
- _PyLocalsPlusKind kind = co->co_localspluskinds[i];
+ _PyLocals_Kind kind = _PyLocals_GetKind(co->co_localspluskinds, i);
/* If the namespace is unoptimized, then one of the
following cases applies:
@@ -1052,7 +1052,7 @@ PyFrame_LocalsToFast(PyFrameObject *f, int clear)
PyErr_Fetch(&error_type, &error_value, &error_traceback);
for (int i = 0; i < co->co_nlocalsplus; i++) {
- _PyLocalsPlusKind kind = co->co_localspluskinds[i];
+ _PyLocals_Kind kind = _PyLocals_GetKind(co->co_localspluskinds, i);
/* Same test as in PyFrame_FastToLocals() above. */
if (kind & CO_FAST_FREE && !(co->co_flags & CO_OPTIMIZED)) {
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index fbe3d16..3c766e9 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -8864,7 +8864,7 @@ super_init_without_args(PyFrameObject *f, PyCodeObject *co,
PyObject *firstarg = f->f_localsptr[0];
// The first argument might be a cell.
- if (firstarg != NULL && (co->co_localspluskinds[0] & CO_FAST_CELL)) {
+ if (firstarg != NULL && (_PyLocals_GetKind(co->co_localspluskinds, 0) & CO_FAST_CELL)) {
// "firstarg" is a cell here unless (very unlikely) super()
// was called from the C-API before the first MAKE_CELL op.
if (f->f_lasti >= 0) {
@@ -8883,7 +8883,7 @@ super_init_without_args(PyFrameObject *f, PyCodeObject *co,
PyTypeObject *type = NULL;
int i = co->co_nlocals + co->co_nplaincellvars;
for (; i < co->co_nlocalsplus; i++) {
- assert((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);
assert(PyUnicode_Check(name));
if (_PyUnicode_EqualToASCIIId(name, &PyId___class__)) {