bpo-43693: Add _PyCode_New(). (gh-26375)

This is an internal-only API that helps us manage the many values used to create a code object.

https://bugs.python.org/issue43693
This commit is contained in:
Eric Snow 2021-05-27 09:54:34 -06:00 committed by GitHub
parent 318adeba78
commit 9f494d4929
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 4736 additions and 4648 deletions

View File

@ -64,7 +64,7 @@ struct PyCodeObject {
/* These fields are set with computed values on new code objects. */
Py_ssize_t *co_cell2arg; /* Maps cell vars which are arguments. */
int *co_cell2arg; /* Maps cell vars which are arguments. */
// These are redundant but offer some performance benefit.
int co_nlocalsplus; /* number of local + cell + free variables */
int co_nlocals; /* number of local variables */

View File

@ -4,6 +4,7 @@
extern "C" {
#endif
typedef struct {
PyObject *ptr; /* Cached pointer (borrowed reference) */
uint64_t globals_ver; /* ma_version of global dict */
@ -24,7 +25,54 @@ struct _PyOpcache {
char optimized;
};
struct _PyCodeConstructor {
/* metadata */
PyObject *filename;
PyObject *name;
int flags;
/* the code */
PyObject *code;
int firstlineno;
PyObject *linetable;
/* used by the code */
PyObject *consts;
PyObject *names;
/* mapping frame offsets to information */
PyObject *varnames;
PyObject *cellvars;
PyObject *freevars;
/* args (within varnames) */
int argcount;
int posonlyargcount;
int kwonlyargcount;
/* needed to create the frame */
int stacksize;
/* used by the eval loop */
PyObject *exceptiontable;
};
// Using an "arguments struct" like this is helpful for maintainability
// in a case such as this with many parameters. It does bear a risk:
// if the struct changes and callers are not updated properly then the
// compiler will not catch problems (like a missing argument). This can
// cause hard-to-debug problems. The risk is mitigated by the use of
// check_code() in codeobject.c. However, we may decide to switch
// back to a regular function signature. Regardless, this approach
// wouldn't be appropriate if this weren't a strictly internal API.
// (See the comments in https://github.com/python/cpython/pull/26258.)
PyAPI_FUNC(int) _PyCode_Validate(struct _PyCodeConstructor *);
PyAPI_FUNC(PyCodeObject *) _PyCode_New(struct _PyCodeConstructor *);
/* Private API */
int _PyCode_InitOpcache(PyCodeObject *co);

View File

@ -80,9 +80,9 @@ class PythonValuesTestCase(unittest.TestCase):
continue
items.append((entry.name.decode("ascii"), entry.size))
expected = [("__hello__", 142),
("__phello__", -142),
("__phello__.spam", 142),
expected = [("__hello__", 138),
("__phello__", -138),
("__phello__.spam", 138),
]
self.assertEqual(items, expected, "PyImport_FrozenModules example "
"in Doc/library/ctypes.rst may be out of date")

View File

@ -354,6 +354,7 @@ _code_type = type(_write_atomic.__code__)
# Python 3.10b1 3439 (Add ROT_N)
# Python 3.11a1 3450 Use exception table for unwinding ("zero cost" exception handling)
# Python 3.11a1 3451 (Add CALL_METHOD_KW)
# Python 3.11a1 3452 (drop nlocals from marshaled code objects)
#
# MAGIC must change whenever the bytecode emitted by the compiler may no
@ -363,7 +364,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 = (3451).to_bytes(2, 'little') + b'\r\n'
MAGIC_NUMBER = (3452).to_bytes(2, 'little') + b'\r\n'
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
_PYCACHE = '__pycache__'

View File

@ -151,7 +151,194 @@ validate_and_copy_tuple(PyObject *tup)
/******************
* the "constructors"
* _PyCode_New()
******************/
int
_PyCode_Validate(struct _PyCodeConstructor *con)
{
/* Check argument types */
if (con->argcount < con->posonlyargcount || con->posonlyargcount < 0 ||
con->kwonlyargcount < 0 ||
con->stacksize < 0 || con->flags < 0 ||
con->code == NULL || !PyBytes_Check(con->code) ||
con->consts == NULL || !PyTuple_Check(con->consts) ||
con->names == NULL || !PyTuple_Check(con->names) ||
con->varnames == NULL || !PyTuple_Check(con->varnames) ||
con->freevars == NULL || !PyTuple_Check(con->freevars) ||
con->cellvars == NULL || !PyTuple_Check(con->cellvars) ||
con->name == NULL || !PyUnicode_Check(con->name) ||
con->filename == NULL || !PyUnicode_Check(con->filename) ||
con->linetable == NULL || !PyBytes_Check(con->linetable) ||
con->exceptiontable == NULL || !PyBytes_Check(con->exceptiontable)
) {
PyErr_BadInternalCall();
return -1;
}
/* Make sure that code is indexable with an int, this is
a long running assumption in ceval.c and many parts of
the interpreter. */
if (PyBytes_GET_SIZE(con->code) > INT_MAX) {
PyErr_SetString(PyExc_OverflowError, "co_code larger than INT_MAX");
return -1;
}
/* Ensure that the co_varnames has enough names to cover the arg counts.
* Note that totalargs = nlocals - nplainlocals. We check nplainlocals
* here to avoid the possibility of overflow (however remote). */
int nplainlocals = (int)PyTuple_GET_SIZE(con->varnames) -
con->argcount -
con->kwonlyargcount -
((con->flags & CO_VARARGS) != 0) -
((con->flags & CO_VARKEYWORDS) != 0);
if (nplainlocals < 0) {
PyErr_SetString(PyExc_ValueError, "code: varnames is too small");
return -1;
}
return 0;
}
static void
init_code(PyCodeObject *co, struct _PyCodeConstructor *con)
{
Py_INCREF(con->filename);
co->co_filename = con->filename;
Py_INCREF(con->name);
co->co_name = con->name;
co->co_flags = con->flags;
Py_INCREF(con->code);
co->co_code = con->code;
co->co_firstlineno = con->firstlineno;
Py_INCREF(con->linetable);
co->co_linetable = con->linetable;
Py_INCREF(con->consts);
co->co_consts = con->consts;
Py_INCREF(con->names);
co->co_names = con->names;
Py_INCREF(con->varnames);
co->co_varnames = con->varnames;
Py_INCREF(con->cellvars);
co->co_cellvars = con->cellvars;
Py_INCREF(con->freevars);
co->co_freevars = con->freevars;
co->co_argcount = con->argcount;
co->co_posonlyargcount = con->posonlyargcount;
co->co_kwonlyargcount = con->kwonlyargcount;
co->co_stacksize = con->stacksize;
Py_INCREF(con->exceptiontable);
co->co_exceptiontable = con->exceptiontable;
/* derived values */
co->co_cell2arg = NULL; // This will be set soon.
co->co_nlocals = (int)PyTuple_GET_SIZE(con->varnames);
co->co_ncellvars = (int)PyTuple_GET_SIZE(con->cellvars);
co->co_nfreevars = (int)PyTuple_GET_SIZE(con->freevars);
co->co_nlocalsplus = co->co_nlocals + co->co_ncellvars + co->co_nfreevars;
/* not set */
co->co_weakreflist = NULL;
co->co_extra = NULL;
co->co_opcache_map = NULL;
co->co_opcache = NULL;
co->co_opcache_flag = 0;
co->co_opcache_size = 0;
}
/* The caller is responsible for ensuring that the given data is valid. */
PyCodeObject *
_PyCode_New(struct _PyCodeConstructor *con)
{
/* Ensure that strings are ready Unicode string */
if (PyUnicode_READY(con->name) < 0) {
return NULL;
}
if (PyUnicode_READY(con->filename) < 0) {
return NULL;
}
if (intern_strings(con->names) < 0) {
return NULL;
}
if (intern_string_constants(con->consts, NULL) < 0) {
return NULL;
}
if (intern_strings(con->varnames) < 0) {
return NULL;
}
if (intern_strings(con->freevars) < 0) {
return NULL;
}
if (intern_strings(con->cellvars) < 0) {
return NULL;
}
/* Check for any inner or outer closure references */
int ncellvars = (int)PyTuple_GET_SIZE(con->cellvars);
if (!ncellvars && !PyTuple_GET_SIZE(con->freevars)) {
con->flags |= CO_NOFREE;
} else {
con->flags &= ~CO_NOFREE;
}
PyCodeObject *co = PyObject_New(PyCodeObject, &PyCode_Type);
if (co == NULL) {
PyErr_NoMemory();
return NULL;
}
init_code(co, con);
/* Create mapping between cells and arguments if needed. */
if (ncellvars) {
int totalargs = co->co_argcount +
co->co_kwonlyargcount +
((co->co_flags & CO_VARARGS) != 0) +
((co->co_flags & CO_VARKEYWORDS) != 0);
assert(totalargs <= co->co_nlocals);
/* Find cells which are also arguments. */
for (int i = 0; i < ncellvars; i++) {
PyObject *cellname = PyTuple_GET_ITEM(co->co_cellvars, i);
for (int j = 0; j < totalargs; j++) {
PyObject *argname = PyTuple_GET_ITEM(co->co_varnames, j);
int cmp = PyUnicode_Compare(cellname, argname);
if (cmp == -1 && PyErr_Occurred()) {
Py_DECREF(co);
return NULL;
}
if (cmp == 0) {
if (co->co_cell2arg == NULL) {
co->co_cell2arg = PyMem_NEW(int, ncellvars);
if (co->co_cell2arg == NULL) {
Py_DECREF(co);
PyErr_NoMemory();
return NULL;
}
for (int k = 0; k < ncellvars; k++) {
co->co_cell2arg[k] = CO_CELL_NOT_AN_ARG;
}
}
co->co_cell2arg[i] = j;
// Go to the next cell name.
break;
}
}
}
}
return co;
}
/******************
* the legacy "constructors"
******************/
PyCodeObject *
@ -162,167 +349,41 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount,
PyObject *filename, PyObject *name, int firstlineno,
PyObject *linetable, PyObject *exceptiontable)
{
PyCodeObject *co;
Py_ssize_t *cell2arg = NULL;
Py_ssize_t i, total_args;
int ncellvars, nfreevars;
struct _PyCodeConstructor con = {
.filename = filename,
.name = name,
.flags = flags,
/* Check argument types */
if (argcount < posonlyargcount || posonlyargcount < 0 ||
kwonlyargcount < 0 || nlocals < 0 ||
stacksize < 0 || flags < 0 ||
code == NULL || !PyBytes_Check(code) ||
consts == NULL || !PyTuple_Check(consts) ||
names == NULL || !PyTuple_Check(names) ||
varnames == NULL || !PyTuple_Check(varnames) ||
freevars == NULL || !PyTuple_Check(freevars) ||
cellvars == NULL || !PyTuple_Check(cellvars) ||
name == NULL || !PyUnicode_Check(name) ||
filename == NULL || !PyUnicode_Check(filename) ||
linetable == NULL || !PyBytes_Check(linetable) ||
exceptiontable == NULL || !PyBytes_Check(exceptiontable)) {
PyErr_BadInternalCall();
return NULL;
}
.code = code,
.firstlineno = firstlineno,
.linetable = linetable,
/* Make sure that code is indexable with an int, this is
a long running assumption in ceval.c and many parts of
the interpreter. */
if (PyBytes_GET_SIZE(code) > INT_MAX) {
PyErr_SetString(PyExc_OverflowError, "co_code larger than INT_MAX");
.consts = consts,
.names = names,
.varnames = varnames,
.cellvars = cellvars,
.freevars = freevars,
.argcount = argcount,
.posonlyargcount = posonlyargcount,
.kwonlyargcount = kwonlyargcount,
.stacksize = stacksize,
.exceptiontable = exceptiontable,
};
if (_PyCode_Validate(&con) < 0) {
return NULL;
}
if (nlocals != PyTuple_GET_SIZE(varnames)) {
PyErr_SetString(PyExc_ValueError, "co_nlocals != len(co_varnames)");
PyErr_SetString(PyExc_ValueError,
"code: co_nlocals != len(co_varnames)");
return NULL;
}
/* Ensure that strings are ready Unicode string */
if (PyUnicode_READY(name) < 0) {
return NULL;
}
if (PyUnicode_READY(filename) < 0) {
return NULL;
}
if (intern_strings(names) < 0) {
return NULL;
}
if (intern_strings(varnames) < 0) {
return NULL;
}
if (intern_strings(freevars) < 0) {
return NULL;
}
if (intern_strings(cellvars) < 0) {
return NULL;
}
if (intern_string_constants(consts, NULL) < 0) {
return NULL;
}
/* Check for any inner or outer closure references */
assert(PyTuple_GET_SIZE(cellvars) < INT_MAX);
ncellvars = (int)PyTuple_GET_SIZE(cellvars);
assert(PyTuple_GET_SIZE(freevars) < INT_MAX);
nfreevars = (int)PyTuple_GET_SIZE(freevars);
if (!ncellvars && !nfreevars) {
flags |= CO_NOFREE;
} else {
flags &= ~CO_NOFREE;
}
if (argcount <= nlocals && kwonlyargcount <= nlocals) {
/* Never overflows. */
total_args = (Py_ssize_t)argcount + (Py_ssize_t)kwonlyargcount +
((flags & CO_VARARGS) != 0) + ((flags & CO_VARKEYWORDS) != 0);
}
else {
total_args = nlocals + 1;
}
if (total_args > nlocals) {
PyErr_SetString(PyExc_ValueError, "code: varnames is too small");
return NULL;
}
/* Create mapping between cells and arguments if needed. */
if (ncellvars) {
bool used_cell2arg = false;
cell2arg = PyMem_NEW(Py_ssize_t, ncellvars);
if (cell2arg == NULL) {
PyErr_NoMemory();
return NULL;
}
/* Find cells which are also arguments. */
for (i = 0; i < ncellvars; i++) {
Py_ssize_t j;
PyObject *cell = PyTuple_GET_ITEM(cellvars, i);
cell2arg[i] = CO_CELL_NOT_AN_ARG;
for (j = 0; j < total_args; j++) {
PyObject *arg = PyTuple_GET_ITEM(varnames, j);
int cmp = PyUnicode_Compare(cell, arg);
if (cmp == -1 && PyErr_Occurred()) {
PyMem_Free(cell2arg);
return NULL;
}
if (cmp == 0) {
cell2arg[i] = j;
used_cell2arg = true;
break;
}
}
}
if (!used_cell2arg) {
PyMem_Free(cell2arg);
cell2arg = NULL;
}
}
co = PyObject_New(PyCodeObject, &PyCode_Type);
if (co == NULL) {
if (cell2arg)
PyMem_Free(cell2arg);
return NULL;
}
co->co_argcount = argcount;
co->co_posonlyargcount = posonlyargcount;
co->co_kwonlyargcount = kwonlyargcount;
co->co_nlocalsplus = nlocals + ncellvars + nfreevars;
co->co_nlocals = nlocals;
co->co_ncellvars = ncellvars;
co->co_nfreevars = nfreevars;
co->co_stacksize = stacksize;
co->co_flags = flags;
Py_INCREF(code);
co->co_code = code;
Py_INCREF(consts);
co->co_consts = consts;
Py_INCREF(names);
co->co_names = names;
Py_INCREF(varnames);
co->co_varnames = varnames;
Py_INCREF(freevars);
co->co_freevars = freevars;
Py_INCREF(cellvars);
co->co_cellvars = cellvars;
co->co_cell2arg = cell2arg;
Py_INCREF(filename);
co->co_filename = filename;
Py_INCREF(name);
co->co_name = name;
co->co_firstlineno = firstlineno;
Py_INCREF(linetable);
co->co_linetable = linetable;
Py_INCREF(exceptiontable);
co->co_exceptiontable = exceptiontable;
co->co_weakreflist = NULL;
co->co_extra = NULL;
co->co_opcache_map = NULL;
co->co_opcache = NULL;
co->co_opcache_flag = 0;
co->co_opcache_size = 0;
return co;
return _PyCode_New(&con);
}
PyCodeObject *
@ -342,49 +403,47 @@ PyCode_New(int argcount, int kwonlyargcount,
PyCodeObject *
PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
{
static PyObject *emptystring = NULL;
static PyObject *nulltuple = NULL;
PyObject *emptystring = NULL;
PyObject *nulltuple = NULL;
PyObject *filename_ob = NULL;
PyObject *funcname_ob = NULL;
PyCodeObject *result = NULL;
if (emptystring == NULL) {
emptystring = PyBytes_FromString("");
if (emptystring == NULL)
if (emptystring == NULL) {
goto failed;
}
if (nulltuple == NULL) {
nulltuple = PyTuple_New(0);
if (nulltuple == NULL)
if (nulltuple == NULL) {
goto failed;
}
funcname_ob = PyUnicode_FromString(funcname);
if (funcname_ob == NULL)
if (funcname_ob == NULL) {
goto failed;
}
filename_ob = PyUnicode_DecodeFSDefault(filename);
if (filename_ob == NULL)
if (filename_ob == NULL) {
goto failed;
}
result = PyCode_NewWithPosOnlyArgs(
0, /* argcount */
0, /* posonlyargcount */
0, /* kwonlyargcount */
0, /* nlocals */
0, /* stacksize */
0, /* flags */
emptystring, /* code */
nulltuple, /* consts */
nulltuple, /* names */
nulltuple, /* varnames */
nulltuple, /* freevars */
nulltuple, /* cellvars */
filename_ob, /* filename */
funcname_ob, /* name */
firstlineno, /* firstlineno */
emptystring, /* linetable */
emptystring /* exception table */
);
struct _PyCodeConstructor con = {
.filename = filename_ob,
.name = funcname_ob,
.code = emptystring,
.firstlineno = firstlineno,
.linetable = emptystring,
.consts = nulltuple,
.names = nulltuple,
.varnames = nulltuple,
.cellvars = nulltuple,
.freevars = nulltuple,
.exceptiontable = emptystring,
};
result = _PyCode_New(&con);
failed:
Py_XDECREF(emptystring);
Py_XDECREF(nulltuple);
Py_XDECREF(funcname_ob);
Py_XDECREF(filename_ob);
return result;

View File

@ -1,28 +1,28 @@
// Auto-generated by Programs/freeze_test_frozenmain.py
unsigned char M_test_frozenmain[] = {
227,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,7,0,0,0,64,0,0,0,115,86,0,0,0,100,0,
100,1,108,0,90,0,100,0,100,1,108,1,90,1,101,2,
100,2,131,1,1,0,101,2,100,3,101,0,106,3,131,2,
1,0,101,1,160,4,161,0,100,4,25,0,90,5,100,5,
68,0,93,14,90,6,101,2,100,6,101,6,155,0,100,7,
101,5,101,6,25,0,155,0,157,4,131,1,1,0,113,26,
100,1,83,0,41,8,233,0,0,0,0,78,122,18,70,114,
111,122,101,110,32,72,101,108,108,111,32,87,111,114,108,100,
122,8,115,121,115,46,97,114,103,118,218,6,99,111,110,102,
105,103,41,5,90,12,112,114,111,103,114,97,109,95,110,97,
109,101,218,10,101,120,101,99,117,116,97,98,108,101,90,15,
117,115,101,95,101,110,118,105,114,111,110,109,101,110,116,90,
17,99,111,110,102,105,103,117,114,101,95,99,95,115,116,100,
105,111,90,14,98,117,102,102,101,114,101,100,95,115,116,100,
105,111,122,7,99,111,110,102,105,103,32,122,2,58,32,41,
7,218,3,115,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,114,
8,0,0,0,114,8,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,
243,0,0,0,0,
227,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,
0,64,0,0,0,115,86,0,0,0,100,0,100,1,108,0,
90,0,100,0,100,1,108,1,90,1,101,2,100,2,131,1,
1,0,101,2,100,3,101,0,106,3,131,2,1,0,101,1,
160,4,161,0,100,4,25,0,90,5,100,5,68,0,93,14,
90,6,101,2,100,6,101,6,155,0,100,7,101,5,101,6,
25,0,155,0,157,4,131,1,1,0,113,26,100,1,83,0,
41,8,233,0,0,0,0,78,122,18,70,114,111,122,101,110,
32,72,101,108,108,111,32,87,111,114,108,100,122,8,115,121,
115,46,97,114,103,118,218,6,99,111,110,102,105,103,41,5,
90,12,112,114,111,103,114,97,109,95,110,97,109,101,218,10,
101,120,101,99,117,116,97,98,108,101,90,15,117,115,101,95,
101,110,118,105,114,111,110,109,101,110,116,90,17,99,111,110,
102,105,103,117,114,101,95,99,95,115,116,100,105,111,90,14,
98,117,102,102,101,114,101,100,95,115,116,100,105,111,122,7,
99,111,110,102,105,103,32,122,2,58,32,41,7,218,3,115,
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,114,8,0,0,0,
114,8,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,243,0,0,0,
0,
};

View File

@ -24,6 +24,7 @@
#include "Python.h"
#include "pycore_ast.h" // _PyAST_GetDocString()
#include "pycore_compile.h" // _PyFuture_FromAST()
#include "pycore_code.h" // _PyCode_New()
#include "pycore_pymem.h" // _PyMem_IsPtrFreed()
#include "pycore_long.h" // _PyLong_GetZero()
#include "pycore_symtable.h" // PySTEntryObject
@ -7166,16 +7167,16 @@ merge_const_one(struct compiler *c, PyObject **obj)
}
static PyCodeObject *
makecode(struct compiler *c, struct assembler *a, PyObject *consts, int maxdepth)
makecode(struct compiler *c, struct assembler *a, PyObject *constslist,
int maxdepth)
{
PyCodeObject *co = NULL;
PyObject *names = NULL;
PyObject *consts = NULL;
PyObject *varnames = NULL;
PyObject *name = NULL;
PyObject *freevars = NULL;
PyObject *cellvars = NULL;
Py_ssize_t nlocals;
int nlocals_int;
int flags;
int posorkeywordargcount, posonlyargcount, kwonlyargcount;
@ -7199,34 +7200,53 @@ makecode(struct compiler *c, struct assembler *a, PyObject *consts, int maxdepth
goto error;
}
nlocals = PyDict_GET_SIZE(c->u->u_varnames);
assert(nlocals < INT_MAX);
nlocals_int = Py_SAFE_DOWNCAST(nlocals, Py_ssize_t, int);
flags = compute_code_flags(c);
if (flags < 0)
goto error;
consts = PyList_AsTuple(consts); /* PyCode_New requires a tuple */
consts = PyList_AsTuple(constslist); /* PyCode_New requires a tuple */
if (consts == NULL) {
goto error;
}
if (!merge_const_one(c, &consts)) {
Py_DECREF(consts);
goto error;
}
posonlyargcount = Py_SAFE_DOWNCAST(c->u->u_posonlyargcount, Py_ssize_t, int);
posorkeywordargcount = Py_SAFE_DOWNCAST(c->u->u_argcount, Py_ssize_t, int);
kwonlyargcount = Py_SAFE_DOWNCAST(c->u->u_kwonlyargcount, Py_ssize_t, int);
co = PyCode_NewWithPosOnlyArgs(posonlyargcount+posorkeywordargcount,
posonlyargcount, kwonlyargcount, nlocals_int,
maxdepth, flags, a->a_bytecode, consts, names,
varnames, freevars, cellvars, c->c_filename,
c->u->u_name, c->u->u_firstlineno, a->a_lnotab, a->a_except_table);
Py_DECREF(consts);
struct _PyCodeConstructor con = {
.filename = c->c_filename,
.name = c->u->u_name,
.flags = flags,
.code = a->a_bytecode,
.firstlineno = c->u->u_firstlineno,
.linetable = a->a_lnotab,
.consts = consts,
.names = names,
.varnames = varnames,
.cellvars = cellvars,
.freevars = freevars,
.argcount = posonlyargcount + posorkeywordargcount,
.posonlyargcount = posonlyargcount,
.kwonlyargcount = kwonlyargcount,
.stacksize = maxdepth,
.exceptiontable = a->a_except_table,
};
if (_PyCode_Validate(&con) < 0) {
goto error;
}
co = _PyCode_New(&con);
error:
Py_XDECREF(names);
Py_XDECREF(consts);
Py_XDECREF(varnames);
Py_XDECREF(name);
Py_XDECREF(freevars);

View File

@ -1,12 +1,12 @@
/* Auto-generated by Programs/_freeze_importlib.c */
const unsigned char _Py_M__hello[] = {
99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2,0,0,0,64,0,0,0,115,16,0,0,0,100,0,
90,0,101,1,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,114,1,0,0,0,114,1,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,243,0,0,0,0,
99,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,
0,64,0,0,0,115,16,0,0,0,100,0,90,0,101,1,
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,114,1,0,0,0,114,1,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,243,0,0,0,0,
};

2944
Python/importlib.h generated

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

View File

@ -13,6 +13,7 @@
#include "code.h"
#include "marshal.h"
#include "pycore_hashtable.h"
#include "pycore_code.h" // _PyCode_New()
/*[clinic input]
module marshal
@ -512,7 +513,6 @@ w_complex_object(PyObject *v, char flag, WFILE *p)
w_long(co->co_argcount, p);
w_long(co->co_posonlyargcount, p);
w_long(co->co_kwonlyargcount, p);
w_long(co->co_nlocals, p);
w_long(co->co_stacksize, p);
w_long(co->co_flags, p);
w_object(co->co_code, p);
@ -1301,7 +1301,6 @@ r_object(RFILE *p)
int argcount;
int posonlyargcount;
int kwonlyargcount;
int nlocals;
int stacksize;
int flags;
PyObject *code = NULL;
@ -1331,9 +1330,6 @@ r_object(RFILE *p)
goto code_error;
}
kwonlyargcount = (int)r_long(p);
if (PyErr_Occurred())
goto code_error;
nlocals = (int)r_long(p);
if (PyErr_Occurred())
goto code_error;
stacksize = (int)r_long(p);
@ -1354,6 +1350,7 @@ r_object(RFILE *p)
varnames = r_object(p);
if (varnames == NULL)
goto code_error;
Py_ssize_t nlocals = PyTuple_GET_SIZE(varnames);
freevars = r_object(p);
if (freevars == NULL)
goto code_error;
@ -1376,19 +1373,43 @@ r_object(RFILE *p)
if (exceptiontable == NULL)
goto code_error;
if (PySys_Audit("code.__new__", "OOOiiiiii",
code, filename, name, argcount, posonlyargcount,
kwonlyargcount, nlocals, stacksize, flags) < 0) {
goto code_error;
}
v = (PyObject *) PyCode_NewWithPosOnlyArgs(
argcount, posonlyargcount, kwonlyargcount,
nlocals, stacksize, flags,
code, consts, names, varnames,
freevars, cellvars, filename, name,
firstlineno, linetable, exceptiontable);
struct _PyCodeConstructor con = {
.filename = filename,
.name = name,
.flags = flags,
.code = code,
.firstlineno = firstlineno,
.linetable = linetable,
.consts = consts,
.names = names,
.varnames = varnames,
.cellvars = cellvars,
.freevars = freevars,
.argcount = argcount,
.posonlyargcount = posonlyargcount,
.kwonlyargcount = kwonlyargcount,
.stacksize = stacksize,
.exceptiontable = exceptiontable,
};
if (_PyCode_Validate(&con) < 0) {
goto code_error;
}
v = (PyObject *)_PyCode_New(&con);
if (v == NULL) {
goto code_error;
}
v = r_ref_insert(v, idx, flag, p);
code_error: