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

@ -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: