diff options
author | Guido van Rossum <guido@python.org> | 2021-06-21 20:53:04 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-21 20:53:04 (GMT) |
commit | 355f5dd36a0f53175517f35798aa874564d1113a (patch) | |
tree | cfc6c7e4f009afc772d4a9e0c909d6e3499cf2e9 /Objects | |
parent | c5d700f0e2e2921c6b54c72ffb0fca3c3d1ef06b (diff) | |
download | cpython-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.c | 43 | ||||
-rw-r--r-- | Objects/frameobject.c | 4 | ||||
-rw-r--r-- | Objects/typeobject.c | 4 |
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__)) { |