mirror of https://github.com/python/cpython
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.
This commit is contained in:
parent
c5d700f0e2
commit
355f5dd36a
|
@ -26,9 +26,6 @@ typedef uint16_t _Py_CODEUNIT;
|
|||
typedef struct _PyOpcache _PyOpcache;
|
||||
|
||||
|
||||
typedef unsigned char _PyLocalsPlusKind;
|
||||
typedef _PyLocalsPlusKind *_PyLocalsPlusKinds;
|
||||
|
||||
/* Bytecode object */
|
||||
struct PyCodeObject {
|
||||
PyObject_HEAD
|
||||
|
@ -75,7 +72,7 @@ struct PyCodeObject {
|
|||
int co_firstlineno; /* first source line number */
|
||||
PyObject *co_code; /* instruction opcodes */
|
||||
PyObject *co_localsplusnames; /* tuple mapping offsets to names */
|
||||
_PyLocalsPlusKinds co_localspluskinds; /* array mapping to local kinds */
|
||||
PyObject *co_localspluskinds; /* Bytes mapping to local kinds (one byte per variable) */
|
||||
PyObject *co_filename; /* unicode (where it was loaded from) */
|
||||
PyObject *co_name; /* unicode (name, for reference) */
|
||||
PyObject *co_linetable; /* string (encoding addr<->lineno mapping) See
|
||||
|
@ -222,4 +219,3 @@ void PyLineTable_InitAddressRange(const char *linetable, Py_ssize_t length, int
|
|||
int PyLineTable_NextAddressRange(PyCodeAddressRange *range);
|
||||
int PyLineTable_PreviousAddressRange(PyCodeAddressRange *range);
|
||||
|
||||
|
||||
|
|
|
@ -180,39 +180,34 @@ extern Py_ssize_t _Py_QuickenedCount;
|
|||
* "free" kind is mutually exclusive with both.
|
||||
*/
|
||||
|
||||
// For now _PyLocalsPlusKind and _PyLocalsPlusKinds are defined
|
||||
// in Include/cpython/code.h.
|
||||
/* Note that these all fit within _PyLocalsPlusKind, as do combinations. */
|
||||
// Note that these all fit within a byte, as do combinations.
|
||||
// Later, we will use the smaller numbers to differentiate the different
|
||||
// kinds of locals (e.g. pos-only arg, varkwargs, local-only).
|
||||
#define CO_FAST_LOCAL 0x20
|
||||
#define CO_FAST_CELL 0x40
|
||||
#define CO_FAST_FREE 0x80
|
||||
|
||||
static inline int
|
||||
_PyCode_InitLocalsPlusKinds(int num, _PyLocalsPlusKinds *pkinds)
|
||||
typedef unsigned char _PyLocals_Kind;
|
||||
|
||||
static inline _PyLocals_Kind
|
||||
_PyLocals_GetKind(PyObject *kinds, int i)
|
||||
{
|
||||
if (num == 0) {
|
||||
*pkinds = NULL;
|
||||
return 0;
|
||||
}
|
||||
_PyLocalsPlusKinds kinds = PyMem_NEW(_PyLocalsPlusKind, num);
|
||||
if (kinds == NULL) {
|
||||
PyErr_NoMemory();
|
||||
return -1;
|
||||
}
|
||||
*pkinds = kinds;
|
||||
return 0;
|
||||
assert(PyBytes_Check(kinds));
|
||||
assert(0 <= i && i < PyBytes_GET_SIZE(kinds));
|
||||
char *ptr = PyBytes_AS_STRING(kinds);
|
||||
return (_PyLocals_Kind)(ptr[i]);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_PyCode_ClearLocalsPlusKinds(_PyLocalsPlusKinds kinds)
|
||||
_PyLocals_SetKind(PyObject *kinds, int i, _PyLocals_Kind kind)
|
||||
{
|
||||
if (kinds != NULL) {
|
||||
PyMem_Free(kinds);
|
||||
}
|
||||
assert(PyBytes_Check(kinds));
|
||||
assert(0 <= i && i < PyBytes_GET_SIZE(kinds));
|
||||
char *ptr = PyBytes_AS_STRING(kinds);
|
||||
ptr[i] = (char) kind;
|
||||
}
|
||||
|
||||
|
||||
struct _PyCodeConstructor {
|
||||
/* metadata */
|
||||
PyObject *filename;
|
||||
|
@ -229,8 +224,8 @@ struct _PyCodeConstructor {
|
|||
PyObject *names;
|
||||
|
||||
/* mapping frame offsets to information */
|
||||
PyObject *localsplusnames;
|
||||
_PyLocalsPlusKinds localspluskinds;
|
||||
PyObject *localsplusnames; // Tuple of strings
|
||||
PyObject *localspluskinds; // Bytes object, one byte per variable
|
||||
|
||||
/* args (within varnames) */
|
||||
int argcount;
|
||||
|
|
|
@ -80,9 +80,9 @@ class PythonValuesTestCase(unittest.TestCase):
|
|||
continue
|
||||
items.append((entry.name.decode("ascii"), entry.size))
|
||||
|
||||
expected = [("__hello__", 128),
|
||||
("__phello__", -128),
|
||||
("__phello__.spam", 128),
|
||||
expected = [("__hello__", 133),
|
||||
("__phello__", -133),
|
||||
("__phello__.spam", 133),
|
||||
]
|
||||
self.assertEqual(items, expected, "PyImport_FrozenModules example "
|
||||
"in Doc/library/ctypes.rst may be out of date")
|
||||
|
|
|
@ -359,6 +359,7 @@ _code_type = type(_write_atomic.__code__)
|
|||
# Python 3.11a1 3454 (compute cell offsets relative to locals bpo-43693)
|
||||
# Python 3.11a1 3455 (add MAKE_CELL bpo-43693)
|
||||
# Python 3.11a1 3456 (interleave cell args bpo-43693)
|
||||
# Python 3.11a1 3457 (Change localsplus to a bytes object bpo-43693)
|
||||
|
||||
#
|
||||
# MAGIC must change whenever the bytecode emitted by the compiler may no
|
||||
|
@ -368,7 +369,7 @@ _code_type = type(_write_atomic.__code__)
|
|||
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
|
||||
# in PC/launcher.c must also be updated.
|
||||
|
||||
MAGIC_NUMBER = (3456).to_bytes(2, 'little') + b'\r\n'
|
||||
MAGIC_NUMBER = (3457).to_bytes(2, 'little') + b'\r\n'
|
||||
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
|
||||
|
||||
_PYCACHE = '__pycache__'
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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__)) {
|
||||
|
|
|
@ -19,9 +19,9 @@ unsigned char M_test_frozenmain[] = {
|
|||
121,115,90,17,95,116,101,115,116,105,110,116,101,114,110,97,
|
||||
108,99,97,112,105,218,5,112,114,105,110,116,218,4,97,114,
|
||||
103,118,90,11,103,101,116,95,99,111,110,102,105,103,115,114,
|
||||
2,0,0,0,218,3,107,101,121,169,0,250,18,116,101,115,
|
||||
116,95,102,114,111,122,101,110,109,97,105,110,46,112,121,218,
|
||||
8,60,109,111,100,117,108,101,62,1,0,0,0,115,16,0,
|
||||
0,0,8,3,8,1,8,2,12,1,12,1,8,1,26,7,
|
||||
4,249,243,0,0,0,0,
|
||||
2,0,0,0,218,3,107,101,121,169,0,243,0,0,0,0,
|
||||
250,18,116,101,115,116,95,102,114,111,122,101,110,109,97,105,
|
||||
110,46,112,121,218,8,60,109,111,100,117,108,101,62,1,0,
|
||||
0,0,115,16,0,0,0,8,3,8,1,8,2,12,1,12,
|
||||
1,8,1,26,7,4,249,114,9,0,0,0,
|
||||
};
|
||||
|
|
|
@ -7187,15 +7187,13 @@ merge_const_one(struct compiler *c, PyObject **obj)
|
|||
}
|
||||
|
||||
// This is in codeobject.c.
|
||||
extern void _Py_set_localsplus_info(int, PyObject *, _PyLocalsPlusKind,
|
||||
PyObject *, _PyLocalsPlusKinds);
|
||||
extern void _Py_set_localsplus_info(int, PyObject *, unsigned char,
|
||||
PyObject *, PyObject *);
|
||||
|
||||
static void
|
||||
compute_localsplus_info(struct compiler *c, int nlocalsplus,
|
||||
PyObject *names, _PyLocalsPlusKinds kinds)
|
||||
PyObject *names, PyObject *kinds)
|
||||
{
|
||||
assert(PyTuple_GET_SIZE(names) == nlocalsplus);
|
||||
|
||||
PyObject *k, *v;
|
||||
Py_ssize_t pos = 0;
|
||||
while (PyDict_Next(c->u->u_varnames, &pos, &k, &v)) {
|
||||
|
@ -7203,7 +7201,7 @@ compute_localsplus_info(struct compiler *c, int nlocalsplus,
|
|||
assert(offset >= 0);
|
||||
assert(offset < nlocalsplus);
|
||||
// For now we do not distinguish arg kinds.
|
||||
_PyLocalsPlusKind kind = CO_FAST_LOCAL;
|
||||
_PyLocals_Kind kind = CO_FAST_LOCAL;
|
||||
if (PyDict_GetItem(c->u->u_cellvars, k) != NULL) {
|
||||
kind |= CO_FAST_CELL;
|
||||
}
|
||||
|
@ -7245,7 +7243,7 @@ makecode(struct compiler *c, struct assembler *a, PyObject *constslist,
|
|||
PyObject *names = NULL;
|
||||
PyObject *consts = NULL;
|
||||
PyObject *localsplusnames = NULL;
|
||||
_PyLocalsPlusKinds localspluskinds = NULL;
|
||||
PyObject *localspluskinds = NULL;
|
||||
PyObject *name = NULL;
|
||||
|
||||
names = dict_keys_inorder(c->u->u_names, 0);
|
||||
|
@ -7281,7 +7279,8 @@ makecode(struct compiler *c, struct assembler *a, PyObject *constslist,
|
|||
if (localsplusnames == NULL) {
|
||||
goto error;
|
||||
}
|
||||
if (_PyCode_InitLocalsPlusKinds(nlocalsplus, &localspluskinds) < 0) {
|
||||
localspluskinds = PyBytes_FromStringAndSize(NULL, nlocalsplus);
|
||||
if (localspluskinds == NULL) {
|
||||
goto error;
|
||||
}
|
||||
compute_localsplus_info(c, nlocalsplus, localsplusnames, localspluskinds);
|
||||
|
@ -7315,7 +7314,6 @@ makecode(struct compiler *c, struct assembler *a, PyObject *constslist,
|
|||
}
|
||||
|
||||
if (!merge_const_one(c, &localsplusnames)) {
|
||||
_PyCode_ClearLocalsPlusKinds(con.localspluskinds);
|
||||
goto error;
|
||||
}
|
||||
con.localsplusnames = localsplusnames;
|
||||
|
@ -7325,13 +7323,11 @@ makecode(struct compiler *c, struct assembler *a, PyObject *constslist,
|
|||
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(localspluskinds);
|
||||
Py_XDECREF(name);
|
||||
return co;
|
||||
}
|
||||
|
|
|
@ -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,243,0,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,
|
||||
114,2,0,0,0,
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -519,7 +519,7 @@ w_complex_object(PyObject *v, char flag, WFILE *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_localspluskinds, p);
|
||||
w_object(co->co_filename, p);
|
||||
w_object(co->co_name, p);
|
||||
w_long(co->co_firstlineno, p);
|
||||
|
@ -1306,7 +1306,7 @@ r_object(RFILE *p)
|
|||
PyObject *consts = NULL;
|
||||
PyObject *names = NULL;
|
||||
PyObject *localsplusnames = NULL;
|
||||
_PyLocalsPlusKinds localspluskinds = NULL;
|
||||
PyObject *localspluskinds = NULL;
|
||||
PyObject *filename = NULL;
|
||||
PyObject *name = NULL;
|
||||
int firstlineno;
|
||||
|
@ -1348,19 +1348,9 @@ r_object(RFILE *p)
|
|||
localsplusnames = r_object(p);
|
||||
if (localsplusnames == 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) {
|
||||
localspluskinds = r_object(p);
|
||||
if (localspluskinds == NULL)
|
||||
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;
|
||||
|
@ -1377,6 +1367,7 @@ r_object(RFILE *p)
|
|||
if (exceptiontable == NULL)
|
||||
goto code_error;
|
||||
|
||||
Py_ssize_t nlocalsplus = PyTuple_GET_SIZE(localsplusnames);
|
||||
if (PySys_Audit("code.__new__", "OOOiiiiii",
|
||||
code, filename, name, argcount, posonlyargcount,
|
||||
kwonlyargcount, nlocalsplus, stacksize,
|
||||
|
@ -1417,8 +1408,6 @@ r_object(RFILE *p)
|
|||
goto code_error;
|
||||
}
|
||||
|
||||
localspluskinds = NULL; // This keeps it from getting freed below.
|
||||
|
||||
v = r_ref_insert(v, idx, flag, p);
|
||||
|
||||
code_error:
|
||||
|
@ -1426,7 +1415,7 @@ r_object(RFILE *p)
|
|||
Py_XDECREF(consts);
|
||||
Py_XDECREF(names);
|
||||
Py_XDECREF(localsplusnames);
|
||||
_PyCode_ClearLocalsPlusKinds(localspluskinds);
|
||||
Py_XDECREF(localspluskinds);
|
||||
Py_XDECREF(filename);
|
||||
Py_XDECREF(name);
|
||||
Py_XDECREF(linetable);
|
||||
|
|
Loading…
Reference in New Issue