cpython/Include/cpython/code.h

/* Definitions for bytecode */

#ifndef Py_LIMITED_API
#ifndef Py_CODE_H
#define Py_CODE_H

#ifdef __cplusplus
extern "C" {
#endif

/* Total tool ids available */
#define _PY_MONITORING_TOOL_IDS
/* Count of all local monitoring events */
#define _PY_MONITORING_LOCAL_EVENTS
/* Count of all "real" monitoring events (not derived from other events) */
#define _PY_MONITORING_UNGROUPED_EVENTS
/* Count of all  monitoring events */
#define _PY_MONITORING_EVENTS

/* Tables of which tools are active for each monitored event. */
_Py_LocalMonitors;

_Py_GlobalMonitors;


_PyCoCached;

/* Ancillary data structure used for instrumentation.
   Line instrumentation creates an array of
   these. One entry per code unit.*/
_PyCoLineInstrumentationData;


_PyExecutorArray;

/* Main data structure used for instrumentation.
 * This is allocated when needed for instrumentation
 */
_PyCoMonitoringData;

#ifdef Py_GIL_DISABLED

/* Each thread specializes a thread-local copy of the bytecode in free-threaded
 * builds. These copies are stored on the code object in a `_PyCodeArray`. The
 * first entry in the array always points to the "main" copy of the bytecode
 * that is stored at the end of the code object.
 */
typedef struct {
    Py_ssize_t size;
    char *entries[1];
} _PyCodeArray;

#define _PyCode_DEF_THREAD_LOCAL_BYTECODE
#else
#define _PyCode_DEF_THREAD_LOCAL_BYTECODE()
#endif

// To avoid repeating ourselves in deepfreeze.py, all PyCodeObject members are
// defined in this macro:
#define _PyCode_DEF(SIZE)

/* Bytecode object */
struct PyCodeObject _PyCode_DEF(1);

/* Masks for co_flags above */
#define CO_OPTIMIZED
#define CO_NEWLOCALS
#define CO_VARARGS
#define CO_VARKEYWORDS
#define CO_NESTED
#define CO_GENERATOR

/* The CO_COROUTINE flag is set for coroutine functions (defined with
   ``async def`` keywords) */
#define CO_COROUTINE
#define CO_ITERABLE_COROUTINE
#define CO_ASYNC_GENERATOR

/* bpo-39562: These constant values are changed in Python 3.9
   to prevent collision with compiler flags. CO_FUTURE_ and PyCF_
   constants must be kept unique. PyCF_ constants can use bits from
   0x0100 to 0x10000. CO_FUTURE_ constants use bits starting at 0x20000. */
#define CO_FUTURE_DIVISION
#define CO_FUTURE_ABSOLUTE_IMPORT
#define CO_FUTURE_WITH_STATEMENT
#define CO_FUTURE_PRINT_FUNCTION
#define CO_FUTURE_UNICODE_LITERALS

#define CO_FUTURE_BARRY_AS_BDFL
#define CO_FUTURE_GENERATOR_STOP
#define CO_FUTURE_ANNOTATIONS

#define CO_NO_MONITORING_EVENTS

/* Whether the code object has a docstring,
   If so, it will be the first item in co_consts
*/
#define CO_HAS_DOCSTRING

/* This should be defined if a future statement modifies the syntax.
   For example, when a keyword is added.
*/
#define PY_PARSER_REQUIRES_FUTURE_KEYWORD

#define CO_MAXBLOCKS

PyAPI_DATA(PyTypeObject) PyCode_Type;

#define PyCode_Check(op)

static inline Py_ssize_t PyCode_GetNumFree(PyCodeObject *op) {}

static inline int PyUnstable_Code_GetFirstFree(PyCodeObject *op) {}

Py_DEPRECATED(3.13) static inline int PyCode_GetFirstFree(PyCodeObject *op) {}

/* Unstable public interface */
PyAPI_FUNC(PyCodeObject *) PyUnstable_Code_New(
        int, int, int, int, int, PyObject *, PyObject *,
        PyObject *, PyObject *, PyObject *, PyObject *,
        PyObject *, PyObject *, PyObject *, int, PyObject *,
        PyObject *);

PyAPI_FUNC(PyCodeObject *) PyUnstable_Code_NewWithPosOnlyArgs(
        int, int, int, int, int, int, PyObject *, PyObject *,
        PyObject *, PyObject *, PyObject *, PyObject *,
        PyObject *, PyObject *, PyObject *, int, PyObject *,
        PyObject *);
        /* same as struct above */
// Old names -- remove when this API changes:
_Py_DEPRECATED_EXTERNALLY() static inline PyCodeObject *
PyCode_New(
        int a, int b, int c, int d, int e, PyObject *f, PyObject *g,
        PyObject *h, PyObject *i, PyObject *j, PyObject *k,
        PyObject *l, PyObject *m, PyObject *n, int o, PyObject *p,
        PyObject *q)
{}
_Py_DEPRECATED_EXTERNALLY() static inline PyCodeObject *
PyCode_NewWithPosOnlyArgs(
        int a, int poac, int b, int c, int d, int e, PyObject *f, PyObject *g,
        PyObject *h, PyObject *i, PyObject *j, PyObject *k,
        PyObject *l, PyObject *m, PyObject *n, int o, PyObject *p,
        PyObject *q)
{}

/* Creates a new empty code object with the specified source location. */
PyAPI_FUNC(PyCodeObject *)
PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno);

/* Return the line number associated with the specified bytecode index
   in this code object.  If you just need the line number of a frame,
   use PyFrame_GetLineNumber() instead. */
PyAPI_FUNC(int) PyCode_Addr2Line(PyCodeObject *, int);

PyAPI_FUNC(int) PyCode_Addr2Location(PyCodeObject *, int, int *, int *, int *, int *);

#define PY_FOREACH_CODE_EVENT(V)

PyCodeEvent;


/*
 * A callback that is invoked for different events in a code object's lifecycle.
 *
 * The callback is invoked with a borrowed reference to co, after it is
 * created and before it is destroyed.
 *
 * If the callback sets an exception, it must return -1. Otherwise
 * it should return 0.
 */
PyCode_WatchCallback;

/*
 * Register a per-interpreter callback that will be invoked for code object
 * lifecycle events.
 *
 * Returns a handle that may be passed to PyCode_ClearWatcher on success,
 * or -1 and sets an error if no more handles are available.
 */
PyAPI_FUNC(int) PyCode_AddWatcher(PyCode_WatchCallback callback);

/*
 * Clear the watcher associated with the watcher_id handle.
 *
 * Returns 0 on success or -1 if no watcher exists for the provided id.
 */
PyAPI_FUNC(int) PyCode_ClearWatcher(int watcher_id);

/* for internal use only */
struct _opaque {};

PyCodeAddressRange;

/* Update *bounds to describe the first and one-past-the-last instructions in the
   same line as lasti.  Return the number of that line.
*/
PyAPI_FUNC(int) _PyCode_CheckLineNumber(int lasti, PyCodeAddressRange *bounds);

/* Create a comparable key used to compare constants taking in account the
 * object type. It is used to make sure types are not coerced (e.g., float and
 * complex) _and_ to distinguish 0.0 from -0.0 e.g. on IEEE platforms
 *
 * Return (type(obj), obj, ...): a tuple with variable size (at least 2 items)
 * depending on the type and the value. The type is the first item to not
 * compare bytes and str which can raise a BytesWarning exception. */
PyAPI_FUNC(PyObject*) _PyCode_ConstantKey(PyObject *obj);

PyAPI_FUNC(PyObject*) PyCode_Optimize(PyObject *code, PyObject* consts,
                                      PyObject *names, PyObject *lnotab);

PyAPI_FUNC(int) PyUnstable_Code_GetExtra(
    PyObject *code, Py_ssize_t index, void **extra);
PyAPI_FUNC(int) PyUnstable_Code_SetExtra(
    PyObject *code, Py_ssize_t index, void *extra);
// Old names -- remove when this API changes:
_Py_DEPRECATED_EXTERNALLY() static inline int
_PyCode_GetExtra(PyObject *code, Py_ssize_t index, void **extra)
{}
_Py_DEPRECATED_EXTERNALLY() static inline int
_PyCode_SetExtra(PyObject *code, Py_ssize_t index, void *extra)
{}

/* Equivalent to getattr(code, 'co_code') in Python.
   Returns a strong reference to a bytes object. */
PyAPI_FUNC(PyObject *) PyCode_GetCode(PyCodeObject *code);
/* Equivalent to getattr(code, 'co_varnames') in Python. */
PyAPI_FUNC(PyObject *) PyCode_GetVarnames(PyCodeObject *code);
/* Equivalent to getattr(code, 'co_cellvars') in Python. */
PyAPI_FUNC(PyObject *) PyCode_GetCellvars(PyCodeObject *code);
/* Equivalent to getattr(code, 'co_freevars') in Python. */
PyAPI_FUNC(PyObject *) PyCode_GetFreevars(PyCodeObject *code);

_PyCodeLocationInfoKind;

#ifdef __cplusplus
}
#endif
#endif  // !Py_CODE_H
#endif  // !Py_LIMITED_API