Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpo-43693: Add _PyCode_New(). #26375

Merged
@@ -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 */
@@ -3,7 +3,8 @@
#ifdef __cplusplus
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);


@@ -80,9 +80,9 @@ class struct_frozen(Structure):
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")
@@ -354,6 +354,7 @@ def _write_atomic(path, data, mode=0o666):
# 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 @@ def _write_atomic(path, data, mode=0o666):
# 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__'
ProTip! Use n and p to navigate between commits in a pull request.