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 struct _PyOpcache _PyOpcache;
|
||||||
|
|
||||||
|
|
||||||
typedef unsigned char _PyLocalsPlusKind;
|
|
||||||
typedef _PyLocalsPlusKind *_PyLocalsPlusKinds;
|
|
||||||
|
|
||||||
/* Bytecode object */
|
/* Bytecode object */
|
||||||
struct PyCodeObject {
|
struct PyCodeObject {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
|
@ -75,7 +72,7 @@ struct PyCodeObject {
|
||||||
int co_firstlineno; /* first source line number */
|
int co_firstlineno; /* first source line number */
|
||||||
PyObject *co_code; /* instruction opcodes */
|
PyObject *co_code; /* instruction opcodes */
|
||||||
PyObject *co_localsplusnames; /* tuple mapping offsets to names */
|
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_filename; /* unicode (where it was loaded from) */
|
||||||
PyObject *co_name; /* unicode (name, for reference) */
|
PyObject *co_name; /* unicode (name, for reference) */
|
||||||
PyObject *co_linetable; /* string (encoding addr<->lineno mapping) See
|
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_NextAddressRange(PyCodeAddressRange *range);
|
||||||
int PyLineTable_PreviousAddressRange(PyCodeAddressRange *range);
|
int PyLineTable_PreviousAddressRange(PyCodeAddressRange *range);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -180,39 +180,34 @@ extern Py_ssize_t _Py_QuickenedCount;
|
||||||
* "free" kind is mutually exclusive with both.
|
* "free" kind is mutually exclusive with both.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// For now _PyLocalsPlusKind and _PyLocalsPlusKinds are defined
|
// Note that these all fit within a byte, as do combinations.
|
||||||
// in Include/cpython/code.h.
|
|
||||||
/* Note that these all fit within _PyLocalsPlusKind, as do combinations. */
|
|
||||||
// Later, we will use the smaller numbers to differentiate the different
|
// Later, we will use the smaller numbers to differentiate the different
|
||||||
// kinds of locals (e.g. pos-only arg, varkwargs, local-only).
|
// kinds of locals (e.g. pos-only arg, varkwargs, local-only).
|
||||||
#define CO_FAST_LOCAL 0x20
|
#define CO_FAST_LOCAL 0x20
|
||||||
#define CO_FAST_CELL 0x40
|
#define CO_FAST_CELL 0x40
|
||||||
#define CO_FAST_FREE 0x80
|
#define CO_FAST_FREE 0x80
|
||||||
|
|
||||||
static inline int
|
typedef unsigned char _PyLocals_Kind;
|
||||||
_PyCode_InitLocalsPlusKinds(int num, _PyLocalsPlusKinds *pkinds)
|
|
||||||
|
static inline _PyLocals_Kind
|
||||||
|
_PyLocals_GetKind(PyObject *kinds, int i)
|
||||||
{
|
{
|
||||||
if (num == 0) {
|
assert(PyBytes_Check(kinds));
|
||||||
*pkinds = NULL;
|
assert(0 <= i && i < PyBytes_GET_SIZE(kinds));
|
||||||
return 0;
|
char *ptr = PyBytes_AS_STRING(kinds);
|
||||||
}
|
return (_PyLocals_Kind)(ptr[i]);
|
||||||
_PyLocalsPlusKinds kinds = PyMem_NEW(_PyLocalsPlusKind, num);
|
|
||||||
if (kinds == NULL) {
|
|
||||||
PyErr_NoMemory();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
*pkinds = kinds;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
_PyCode_ClearLocalsPlusKinds(_PyLocalsPlusKinds kinds)
|
_PyLocals_SetKind(PyObject *kinds, int i, _PyLocals_Kind kind)
|
||||||
{
|
{
|
||||||
if (kinds != NULL) {
|
assert(PyBytes_Check(kinds));
|
||||||
PyMem_Free(kinds);
|
assert(0 <= i && i < PyBytes_GET_SIZE(kinds));
|
||||||
}
|
char *ptr = PyBytes_AS_STRING(kinds);
|
||||||
|
ptr[i] = (char) kind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct _PyCodeConstructor {
|
struct _PyCodeConstructor {
|
||||||
/* metadata */
|
/* metadata */
|
||||||
PyObject *filename;
|
PyObject *filename;
|
||||||
|
@ -229,8 +224,8 @@ struct _PyCodeConstructor {
|
||||||
PyObject *names;
|
PyObject *names;
|
||||||
|
|
||||||
/* mapping frame offsets to information */
|
/* mapping frame offsets to information */
|
||||||
PyObject *localsplusnames;
|
PyObject *localsplusnames; // Tuple of strings
|
||||||
_PyLocalsPlusKinds localspluskinds;
|
PyObject *localspluskinds; // Bytes object, one byte per variable
|
||||||
|
|
||||||
/* args (within varnames) */
|
/* args (within varnames) */
|
||||||
int argcount;
|
int argcount;
|
||||||
|
|
|
@ -80,9 +80,9 @@ class PythonValuesTestCase(unittest.TestCase):
|
||||||
continue
|
continue
|
||||||
items.append((entry.name.decode("ascii"), entry.size))
|
items.append((entry.name.decode("ascii"), entry.size))
|
||||||
|
|
||||||
expected = [("__hello__", 128),
|
expected = [("__hello__", 133),
|
||||||
("__phello__", -128),
|
("__phello__", -133),
|
||||||
("__phello__.spam", 128),
|
("__phello__.spam", 133),
|
||||||
]
|
]
|
||||||
self.assertEqual(items, expected, "PyImport_FrozenModules example "
|
self.assertEqual(items, expected, "PyImport_FrozenModules example "
|
||||||
"in Doc/library/ctypes.rst may be out of date")
|
"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 3454 (compute cell offsets relative to locals bpo-43693)
|
||||||
# Python 3.11a1 3455 (add MAKE_CELL bpo-43693)
|
# Python 3.11a1 3455 (add MAKE_CELL bpo-43693)
|
||||||
# Python 3.11a1 3456 (interleave cell args 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
|
# 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
|
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
|
||||||
# in PC/launcher.c must also be updated.
|
# 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
|
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
|
||||||
|
|
||||||
_PYCACHE = '__pycache__'
|
_PYCACHE = '__pycache__'
|
||||||
|
|
|
@ -156,16 +156,16 @@ validate_and_copy_tuple(PyObject *tup)
|
||||||
|
|
||||||
// This is also used in compile.c.
|
// This is also used in compile.c.
|
||||||
void
|
void
|
||||||
_Py_set_localsplus_info(int offset, PyObject *name, _PyLocalsPlusKind kind,
|
_Py_set_localsplus_info(int offset, PyObject *name, _PyLocals_Kind kind,
|
||||||
PyObject *names, _PyLocalsPlusKinds kinds)
|
PyObject *names, PyObject *kinds)
|
||||||
{
|
{
|
||||||
Py_INCREF(name);
|
Py_INCREF(name);
|
||||||
PyTuple_SET_ITEM(names, offset, name);
|
PyTuple_SET_ITEM(names, offset, name);
|
||||||
kinds[offset] = kind;
|
_PyLocals_SetKind(kinds, offset, kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_localsplus_counts(PyObject *names, _PyLocalsPlusKinds kinds,
|
get_localsplus_counts(PyObject *names, PyObject *kinds,
|
||||||
int *pnlocals, int *pnplaincellvars, int *pncellvars,
|
int *pnlocals, int *pnplaincellvars, int *pncellvars,
|
||||||
int *pnfreevars)
|
int *pnfreevars)
|
||||||
{
|
{
|
||||||
|
@ -175,17 +175,18 @@ get_localsplus_counts(PyObject *names, _PyLocalsPlusKinds kinds,
|
||||||
int nfreevars = 0;
|
int nfreevars = 0;
|
||||||
Py_ssize_t nlocalsplus = PyTuple_GET_SIZE(names);
|
Py_ssize_t nlocalsplus = PyTuple_GET_SIZE(names);
|
||||||
for (int i = 0; i < nlocalsplus; i++) {
|
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;
|
nlocals += 1;
|
||||||
if (kinds[i] & CO_FAST_CELL) {
|
if (kind & CO_FAST_CELL) {
|
||||||
ncellvars += 1;
|
ncellvars += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (kinds[i] & CO_FAST_CELL) {
|
else if (kind & CO_FAST_CELL) {
|
||||||
ncellvars += 1;
|
ncellvars += 1;
|
||||||
nplaincellvars += 1;
|
nplaincellvars += 1;
|
||||||
}
|
}
|
||||||
else if (kinds[i] & CO_FAST_FREE) {
|
else if (kind & CO_FAST_FREE) {
|
||||||
nfreevars += 1;
|
nfreevars += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -204,7 +205,7 @@ get_localsplus_counts(PyObject *names, _PyLocalsPlusKinds kinds,
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
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);
|
PyObject *names = PyTuple_New(num);
|
||||||
if (names == NULL) {
|
if (names == NULL) {
|
||||||
|
@ -212,7 +213,8 @@ get_localsplus_names(PyCodeObject *co, _PyLocalsPlusKind kind, int num)
|
||||||
}
|
}
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int offset = 0; offset < co->co_nlocalsplus; offset++) {
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
assert(index < num);
|
assert(index < num);
|
||||||
|
@ -236,8 +238,9 @@ _PyCode_Validate(struct _PyCodeConstructor *con)
|
||||||
con->consts == NULL || !PyTuple_Check(con->consts) ||
|
con->consts == NULL || !PyTuple_Check(con->consts) ||
|
||||||
con->names == NULL || !PyTuple_Check(con->names) ||
|
con->names == NULL || !PyTuple_Check(con->names) ||
|
||||||
con->localsplusnames == NULL || !PyTuple_Check(con->localsplusnames) ||
|
con->localsplusnames == NULL || !PyTuple_Check(con->localsplusnames) ||
|
||||||
(PyTuple_GET_SIZE(con->localsplusnames) && con->localspluskinds == NULL) ||
|
con->localspluskinds == NULL || !PyBytes_Check(con->localspluskinds) ||
|
||||||
(!PyTuple_GET_SIZE(con->localsplusnames) && con->localspluskinds != NULL) ||
|
PyTuple_GET_SIZE(con->localsplusnames)
|
||||||
|
!= PyBytes_GET_SIZE(con->localspluskinds) ||
|
||||||
con->name == NULL || !PyUnicode_Check(con->name) ||
|
con->name == NULL || !PyUnicode_Check(con->name) ||
|
||||||
con->filename == NULL || !PyUnicode_Check(con->filename) ||
|
con->filename == NULL || !PyUnicode_Check(con->filename) ||
|
||||||
con->linetable == NULL || !PyBytes_Check(con->linetable) ||
|
con->linetable == NULL || !PyBytes_Check(con->linetable) ||
|
||||||
|
@ -309,7 +312,7 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con)
|
||||||
|
|
||||||
Py_INCREF(con->localsplusnames);
|
Py_INCREF(con->localsplusnames);
|
||||||
co->co_localsplusnames = 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_localspluskinds = con->localspluskinds;
|
||||||
|
|
||||||
co->co_argcount = con->argcount;
|
co->co_argcount = con->argcount;
|
||||||
|
@ -394,7 +397,7 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount,
|
||||||
{
|
{
|
||||||
PyCodeObject *co = NULL;
|
PyCodeObject *co = NULL;
|
||||||
PyObject *localsplusnames = NULL;
|
PyObject *localsplusnames = NULL;
|
||||||
_PyLocalsPlusKinds localspluskinds = NULL;
|
PyObject *localspluskinds = NULL;
|
||||||
|
|
||||||
if (varnames == NULL || !PyTuple_Check(varnames) ||
|
if (varnames == NULL || !PyTuple_Check(varnames) ||
|
||||||
cellvars == NULL || !PyTuple_Check(cellvars) ||
|
cellvars == NULL || !PyTuple_Check(cellvars) ||
|
||||||
|
@ -413,7 +416,8 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount,
|
||||||
if (localsplusnames == NULL) {
|
if (localsplusnames == NULL) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (_PyCode_InitLocalsPlusKinds(nlocalsplus, &localspluskinds) < 0) {
|
localspluskinds = PyBytes_FromStringAndSize(NULL, nlocalsplus);
|
||||||
|
if (localspluskinds == NULL) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
@ -438,7 +442,8 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount,
|
||||||
// Merge the localsplus indices.
|
// Merge the localsplus indices.
|
||||||
nlocalsplus -= 1;
|
nlocalsplus -= 1;
|
||||||
offset -= 1;
|
offset -= 1;
|
||||||
localspluskinds[argoffset] |= CO_FAST_CELL;
|
_PyLocals_Kind kind = _PyLocals_GetKind(localspluskinds, argoffset);
|
||||||
|
_PyLocals_SetKind(localspluskinds, argoffset, kind | CO_FAST_CELL);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
_Py_set_localsplus_info(offset, name, CO_FAST_CELL,
|
_Py_set_localsplus_info(offset, name, CO_FAST_CELL,
|
||||||
|
@ -495,7 +500,6 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
localspluskinds = NULL; // This keeps it from getting freed below.
|
|
||||||
Py_INCREF(varnames);
|
Py_INCREF(varnames);
|
||||||
co->co_varnames = varnames;
|
co->co_varnames = varnames;
|
||||||
Py_INCREF(cellvars);
|
Py_INCREF(cellvars);
|
||||||
|
@ -505,7 +509,7 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount,
|
||||||
|
|
||||||
error:
|
error:
|
||||||
Py_XDECREF(localsplusnames);
|
Py_XDECREF(localsplusnames);
|
||||||
_PyCode_ClearLocalsPlusKinds(localspluskinds);
|
Py_XDECREF(localspluskinds);
|
||||||
return co;
|
return co;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -558,6 +562,7 @@ PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
|
||||||
.consts = nulltuple,
|
.consts = nulltuple,
|
||||||
.names = nulltuple,
|
.names = nulltuple,
|
||||||
.localsplusnames = nulltuple,
|
.localsplusnames = nulltuple,
|
||||||
|
.localspluskinds = emptystring,
|
||||||
.exceptiontable = emptystring,
|
.exceptiontable = emptystring,
|
||||||
};
|
};
|
||||||
result = _PyCode_New(&con);
|
result = _PyCode_New(&con);
|
||||||
|
@ -1142,7 +1147,7 @@ code_dealloc(PyCodeObject *co)
|
||||||
Py_XDECREF(co->co_consts);
|
Py_XDECREF(co->co_consts);
|
||||||
Py_XDECREF(co->co_names);
|
Py_XDECREF(co->co_names);
|
||||||
Py_XDECREF(co->co_localsplusnames);
|
Py_XDECREF(co->co_localsplusnames);
|
||||||
_PyCode_ClearLocalsPlusKinds(co->co_localspluskinds);
|
Py_XDECREF(co->co_localspluskinds);
|
||||||
Py_XDECREF(co->co_varnames);
|
Py_XDECREF(co->co_varnames);
|
||||||
Py_XDECREF(co->co_freevars);
|
Py_XDECREF(co->co_freevars);
|
||||||
Py_XDECREF(co->co_cellvars);
|
Py_XDECREF(co->co_cellvars);
|
||||||
|
|
|
@ -958,7 +958,7 @@ PyFrame_FastToLocalsWithError(PyFrameObject *f)
|
||||||
co = _PyFrame_GetCode(f);
|
co = _PyFrame_GetCode(f);
|
||||||
fast = f->f_localsptr;
|
fast = f->f_localsptr;
|
||||||
for (int i = 0; i < co->co_nlocalsplus; i++) {
|
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
|
/* If the namespace is unoptimized, then one of the
|
||||||
following cases applies:
|
following cases applies:
|
||||||
|
@ -1052,7 +1052,7 @@ PyFrame_LocalsToFast(PyFrameObject *f, int clear)
|
||||||
|
|
||||||
PyErr_Fetch(&error_type, &error_value, &error_traceback);
|
PyErr_Fetch(&error_type, &error_value, &error_traceback);
|
||||||
for (int i = 0; i < co->co_nlocalsplus; i++) {
|
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. */
|
/* Same test as in PyFrame_FastToLocals() above. */
|
||||||
if (kind & CO_FAST_FREE && !(co->co_flags & CO_OPTIMIZED)) {
|
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];
|
PyObject *firstarg = f->f_localsptr[0];
|
||||||
// The first argument might be a cell.
|
// 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()
|
// "firstarg" is a cell here unless (very unlikely) super()
|
||||||
// was called from the C-API before the first MAKE_CELL op.
|
// was called from the C-API before the first MAKE_CELL op.
|
||||||
if (f->f_lasti >= 0) {
|
if (f->f_lasti >= 0) {
|
||||||
|
@ -8883,7 +8883,7 @@ super_init_without_args(PyFrameObject *f, PyCodeObject *co,
|
||||||
PyTypeObject *type = NULL;
|
PyTypeObject *type = NULL;
|
||||||
int i = co->co_nlocals + co->co_nplaincellvars;
|
int i = co->co_nlocals + co->co_nplaincellvars;
|
||||||
for (; i < co->co_nlocalsplus; i++) {
|
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);
|
PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, i);
|
||||||
assert(PyUnicode_Check(name));
|
assert(PyUnicode_Check(name));
|
||||||
if (_PyUnicode_EqualToASCIIId(name, &PyId___class__)) {
|
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,
|
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,
|
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,
|
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,
|
2,0,0,0,218,3,107,101,121,169,0,243,0,0,0,0,
|
||||||
116,95,102,114,111,122,101,110,109,97,105,110,46,112,121,218,
|
250,18,116,101,115,116,95,102,114,111,122,101,110,109,97,105,
|
||||||
8,60,109,111,100,117,108,101,62,1,0,0,0,115,16,0,
|
110,46,112,121,218,8,60,109,111,100,117,108,101,62,1,0,
|
||||||
0,0,8,3,8,1,8,2,12,1,12,1,8,1,26,7,
|
0,0,115,16,0,0,0,8,3,8,1,8,2,12,1,12,
|
||||||
4,249,243,0,0,0,0,
|
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.
|
// This is in codeobject.c.
|
||||||
extern void _Py_set_localsplus_info(int, PyObject *, _PyLocalsPlusKind,
|
extern void _Py_set_localsplus_info(int, PyObject *, unsigned char,
|
||||||
PyObject *, _PyLocalsPlusKinds);
|
PyObject *, PyObject *);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
compute_localsplus_info(struct compiler *c, int nlocalsplus,
|
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;
|
PyObject *k, *v;
|
||||||
Py_ssize_t pos = 0;
|
Py_ssize_t pos = 0;
|
||||||
while (PyDict_Next(c->u->u_varnames, &pos, &k, &v)) {
|
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 >= 0);
|
||||||
assert(offset < nlocalsplus);
|
assert(offset < nlocalsplus);
|
||||||
// For now we do not distinguish arg kinds.
|
// 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) {
|
if (PyDict_GetItem(c->u->u_cellvars, k) != NULL) {
|
||||||
kind |= CO_FAST_CELL;
|
kind |= CO_FAST_CELL;
|
||||||
}
|
}
|
||||||
|
@ -7245,7 +7243,7 @@ makecode(struct compiler *c, struct assembler *a, PyObject *constslist,
|
||||||
PyObject *names = NULL;
|
PyObject *names = NULL;
|
||||||
PyObject *consts = NULL;
|
PyObject *consts = NULL;
|
||||||
PyObject *localsplusnames = NULL;
|
PyObject *localsplusnames = NULL;
|
||||||
_PyLocalsPlusKinds localspluskinds = NULL;
|
PyObject *localspluskinds = NULL;
|
||||||
PyObject *name = NULL;
|
PyObject *name = NULL;
|
||||||
|
|
||||||
names = dict_keys_inorder(c->u->u_names, 0);
|
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) {
|
if (localsplusnames == NULL) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (_PyCode_InitLocalsPlusKinds(nlocalsplus, &localspluskinds) < 0) {
|
localspluskinds = PyBytes_FromStringAndSize(NULL, nlocalsplus);
|
||||||
|
if (localspluskinds == NULL) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
compute_localsplus_info(c, nlocalsplus, localsplusnames, localspluskinds);
|
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)) {
|
if (!merge_const_one(c, &localsplusnames)) {
|
||||||
_PyCode_ClearLocalsPlusKinds(con.localspluskinds);
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
con.localsplusnames = localsplusnames;
|
con.localsplusnames = localsplusnames;
|
||||||
|
@ -7325,13 +7323,11 @@ makecode(struct compiler *c, struct assembler *a, PyObject *constslist,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
localspluskinds = NULL; // This keeps it from getting freed below.
|
|
||||||
|
|
||||||
error:
|
error:
|
||||||
Py_XDECREF(names);
|
Py_XDECREF(names);
|
||||||
Py_XDECREF(consts);
|
Py_XDECREF(consts);
|
||||||
Py_XDECREF(localsplusnames);
|
Py_XDECREF(localsplusnames);
|
||||||
_PyCode_ClearLocalsPlusKinds(localspluskinds);
|
Py_XDECREF(localspluskinds);
|
||||||
Py_XDECREF(name);
|
Py_XDECREF(name);
|
||||||
return co;
|
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,
|
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,
|
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,
|
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,
|
110,116,169,0,243,0,0,0,0,122,14,60,102,114,111,122,
|
||||||
108,108,111,62,218,8,60,109,111,100,117,108,101,62,1,0,
|
101,110,32,104,101,108,108,111,62,218,8,60,109,111,100,117,
|
||||||
0,0,115,4,0,0,0,4,0,12,1,243,0,0,0,0,
|
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_consts, p);
|
||||||
w_object(co->co_names, p);
|
w_object(co->co_names, p);
|
||||||
w_object(co->co_localsplusnames, 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_filename, p);
|
||||||
w_object(co->co_name, p);
|
w_object(co->co_name, p);
|
||||||
w_long(co->co_firstlineno, p);
|
w_long(co->co_firstlineno, p);
|
||||||
|
@ -1306,7 +1306,7 @@ r_object(RFILE *p)
|
||||||
PyObject *consts = NULL;
|
PyObject *consts = NULL;
|
||||||
PyObject *names = NULL;
|
PyObject *names = NULL;
|
||||||
PyObject *localsplusnames = NULL;
|
PyObject *localsplusnames = NULL;
|
||||||
_PyLocalsPlusKinds localspluskinds = NULL;
|
PyObject *localspluskinds = NULL;
|
||||||
PyObject *filename = NULL;
|
PyObject *filename = NULL;
|
||||||
PyObject *name = NULL;
|
PyObject *name = NULL;
|
||||||
int firstlineno;
|
int firstlineno;
|
||||||
|
@ -1348,19 +1348,9 @@ r_object(RFILE *p)
|
||||||
localsplusnames = r_object(p);
|
localsplusnames = r_object(p);
|
||||||
if (localsplusnames == NULL)
|
if (localsplusnames == NULL)
|
||||||
goto code_error;
|
goto code_error;
|
||||||
|
localspluskinds = r_object(p);
|
||||||
assert(PyTuple_GET_SIZE(localsplusnames) < INT_MAX);
|
if (localspluskinds == NULL)
|
||||||
int nlocalsplus = (int)PyTuple_GET_SIZE(localsplusnames);
|
goto code_error;
|
||||||
if (nlocalsplus) {
|
|
||||||
if (_PyCode_InitLocalsPlusKinds(nlocalsplus,
|
|
||||||
&localspluskinds) < 0) {
|
|
||||||
goto code_error;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < nlocalsplus; i++) {
|
|
||||||
localspluskinds[i] = r_byte(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
filename = r_object(p);
|
filename = r_object(p);
|
||||||
if (filename == NULL)
|
if (filename == NULL)
|
||||||
goto code_error;
|
goto code_error;
|
||||||
|
@ -1377,6 +1367,7 @@ r_object(RFILE *p)
|
||||||
if (exceptiontable == NULL)
|
if (exceptiontable == NULL)
|
||||||
goto code_error;
|
goto code_error;
|
||||||
|
|
||||||
|
Py_ssize_t nlocalsplus = PyTuple_GET_SIZE(localsplusnames);
|
||||||
if (PySys_Audit("code.__new__", "OOOiiiiii",
|
if (PySys_Audit("code.__new__", "OOOiiiiii",
|
||||||
code, filename, name, argcount, posonlyargcount,
|
code, filename, name, argcount, posonlyargcount,
|
||||||
kwonlyargcount, nlocalsplus, stacksize,
|
kwonlyargcount, nlocalsplus, stacksize,
|
||||||
|
@ -1417,8 +1408,6 @@ r_object(RFILE *p)
|
||||||
goto code_error;
|
goto code_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
localspluskinds = NULL; // This keeps it from getting freed below.
|
|
||||||
|
|
||||||
v = r_ref_insert(v, idx, flag, p);
|
v = r_ref_insert(v, idx, flag, p);
|
||||||
|
|
||||||
code_error:
|
code_error:
|
||||||
|
@ -1426,7 +1415,7 @@ r_object(RFILE *p)
|
||||||
Py_XDECREF(consts);
|
Py_XDECREF(consts);
|
||||||
Py_XDECREF(names);
|
Py_XDECREF(names);
|
||||||
Py_XDECREF(localsplusnames);
|
Py_XDECREF(localsplusnames);
|
||||||
_PyCode_ClearLocalsPlusKinds(localspluskinds);
|
Py_XDECREF(localspluskinds);
|
||||||
Py_XDECREF(filename);
|
Py_XDECREF(filename);
|
||||||
Py_XDECREF(name);
|
Py_XDECREF(name);
|
||||||
Py_XDECREF(linetable);
|
Py_XDECREF(linetable);
|
||||||
|
|
Loading…
Reference in New Issue