cpython/Python/compile.c

/*
 * This file compiles an abstract syntax tree (AST) into Python bytecode.
 *
 * The primary entry point is _PyAST_Compile(), which returns a
 * PyCodeObject.  The compiler makes several passes to build the code
 * object:
 *   1. Checks for future statements.  See future.c
 *   2. Builds a symbol table.  See symtable.c.
 *   3. Generate an instruction sequence. See compiler_mod() in this file, which
 *      calls functions from codegen.c.
 *   4. Generate a control flow graph and run optimizations on it.  See flowgraph.c.
 *   5. Assemble the basic blocks into final code.  See optimize_and_assemble() in
 *      this file, and assembler.c.
 *
 */

#include <stdbool.h>

#include "Python.h"
#include "pycore_ast.h"           // PyAST_Check, _PyAST_GetDocString()
#include "pycore_compile.h"
#include "pycore_flowgraph.h"
#include "pycore_pystate.h"       // _Py_GetConfig()
#include "pycore_setobject.h"     // _PySet_NextEntry()

#include "cpython/code.h"

#undef SUCCESS
#undef ERROR
#define SUCCESS
#define ERROR

#define RETURN_IF_ERROR(X)

location;
jump_target_label;
instr_sequence;
cfg_builder;
fblockinfo;
fblocktype;

/* The following items change on entry and exit of code blocks.
   They must be saved and restored when returning to a block.
*/
struct compiler_unit {};

/* This struct captures the global state of a compilation.

The u pointer points to the current compilation unit, while units
for enclosing blocks are stored in c_stack.     The u and c_stack are
managed by _PyCompile_EnterScope() and _PyCompile_ExitScope().

Note that we don't track recursion levels during compilation - the
task of detecting and rejecting excessive levels of nesting is
handled by the symbol analysis pass.

*/

compiler;

static int
compiler_setup(compiler *c, mod_ty mod, PyObject *filename,
               PyCompilerFlags *flags, int optimize, PyArena *arena)
{}

static void
compiler_free(compiler *c)
{}

static compiler*
new_compiler(mod_ty mod, PyObject *filename, PyCompilerFlags *pflags,
             int optimize, PyArena *arena)
{}

static void
compiler_unit_free(struct compiler_unit *u)
{}

#define CAPSULE_NAME

int
_PyCompile_MaybeAddStaticAttributeToClass(compiler *c, expr_ty e)
{}

static int
compiler_set_qualname(compiler *c)
{}

/* Merge const *o* and return constant key object.
 * If recursive, insert all elements if o is a tuple or frozen set.
 */
static PyObject*
const_cache_insert(PyObject *const_cache, PyObject *o, bool recursive)
{}

static PyObject*
merge_consts_recursive(PyObject *const_cache, PyObject *o)
{}

Py_ssize_t
_PyCompile_DictAddObj(PyObject *dict, PyObject *o)
{}

Py_ssize_t
_PyCompile_AddConst(compiler *c, PyObject *o)
{}

static PyObject *
list2dict(PyObject *list)
{}

/* Return new dict containing names from src that match scope(s).

src is a symbol table dictionary.  If the scope of a name matches
either scope_type or flag is set, insert it into the new dict.  The
values are integers, starting at offset and increasing by one for
each key.
*/

static PyObject *
dictbytype(PyObject *src, int scope_type, int flag, Py_ssize_t offset)
{}

int
_PyCompile_EnterScope(compiler *c, identifier name, int scope_type,
                       void *key, int lineno, PyObject *private,
                      _PyCompile_CodeUnitMetadata *umd)
{}

void
_PyCompile_ExitScope(compiler *c)
{}

/*
 * Frame block handling functions
 */

int
_PyCompile_PushFBlock(compiler *c, location loc,
                     fblocktype t, jump_target_label block_label,
                     jump_target_label exit, void *datum)
{}

void
_PyCompile_PopFBlock(compiler *c, fblocktype t, jump_target_label block_label)
{}

fblockinfo *
_PyCompile_TopFBlock(compiler *c)
{}

PyObject *
_PyCompile_DeferredAnnotations(compiler *c)
{}

static location
start_location(asdl_stmt_seq *stmts)
{}

static int
compiler_codegen(compiler *c, mod_ty mod)
{}

static PyCodeObject *
compiler_mod(compiler *c, mod_ty mod)
{}

int
_PyCompile_GetRefType(compiler *c, PyObject *name)
{}

static int
dict_lookup_arg(PyObject *dict, PyObject *name)
{}

int
_PyCompile_LookupCellvar(compiler *c, PyObject *name)
{}

int
_PyCompile_LookupArg(compiler *c, PyCodeObject *co, PyObject *name)
{}

PyObject *
_PyCompile_StaticAttributesAsTuple(compiler *c)
{}

int
_PyCompile_ResolveNameop(compiler *c, PyObject *mangled, int scope,
                          _PyCompile_optype *optype, Py_ssize_t *arg)
{}

int
_PyCompile_TweakInlinedComprehensionScopes(compiler *c, location loc,
                                            PySTEntryObject *entry,
                                            _PyCompile_InlinedComprehensionState *state)
{}

int
_PyCompile_RevertInlinedComprehensionScopes(compiler *c, location loc,
                                             _PyCompile_InlinedComprehensionState *state)
{}

int
_PyCompile_AddDeferredAnnotaion(compiler *c, stmt_ty s)
{}

/* Raises a SyntaxError and returns ERROR.
 * If something goes wrong, a different exception may be raised.
 */
int
_PyCompile_Error(compiler *c, location loc, const char *format, ...)
{}

/* Emits a SyntaxWarning and returns 0 on success.
   If a SyntaxWarning raised as error, replaces it with a SyntaxError
   and returns -1.
*/
int
_PyCompile_Warn(compiler *c, location loc, const char *format, ...)
{}

PyObject *
_PyCompile_Mangle(compiler *c, PyObject *name)
{}

PyObject *
_PyCompile_MaybeMangle(compiler *c, PyObject *name)
{}

instr_sequence *
_PyCompile_InstrSequence(compiler *c)
{}

int
_PyCompile_FutureFeatures(compiler *c)
{}

struct symtable *
_PyCompile_Symtable(compiler *c)
{}

PySTEntryObject *
_PyCompile_SymtableEntry(compiler *c)
{}

int
_PyCompile_OptimizationLevel(compiler *c)
{}

int
_PyCompile_IsInteractiveTopLevel(compiler *c)
{}

int
_PyCompile_ScopeType(compiler *c)
{}

int
_PyCompile_IsInInlinedComp(compiler *c)
{}

PyObject *
_PyCompile_Qualname(compiler *c)
{}

_PyCompile_CodeUnitMetadata *
_PyCompile_Metadata(compiler *c)
{}

// Merge *obj* with constant cache, without recursion.
int
_PyCompile_ConstCacheMergeOne(PyObject *const_cache, PyObject **obj)
{}

static PyObject *
consts_dict_keys_inorder(PyObject *dict)
{}

static int
compute_code_flags(compiler *c)
{}

static PyCodeObject *
optimize_and_assemble_code_unit(struct compiler_unit *u, PyObject *const_cache,
                                int code_flags, PyObject *filename)
{}


PyCodeObject *
_PyCompile_OptimizeAndAssemble(compiler *c, int addNone)
{}

PyCodeObject *
_PyAST_Compile(mod_ty mod, PyObject *filename, PyCompilerFlags *pflags,
               int optimize, PyArena *arena)
{}

int
_PyCompile_AstOptimize(mod_ty mod, PyObject *filename, PyCompilerFlags *cf,
                       int optimize, PyArena *arena)
{}

// C implementation of inspect.cleandoc()
//
// Difference from inspect.cleandoc():
// - Do not remove leading and trailing blank lines to keep lineno.
PyObject *
_PyCompile_CleanDoc(PyObject *doc)
{}

/* Access to compiler optimizations for unit tests.
 *
 * _PyCompile_CodeGen takes an AST, applies code-gen and
 * returns the unoptimized CFG as an instruction list.
 *
 */
PyObject *
_PyCompile_CodeGen(PyObject *ast, PyObject *filename, PyCompilerFlags *pflags,
                   int optimize, int compile_mode)
{}

int _PyCfg_JumpLabelsToTargets(cfg_builder *g);

PyCodeObject *
_PyCompile_Assemble(_PyCompile_CodeUnitMetadata *umd, PyObject *filename,
                    PyObject *seq)
{}

/* Retained for API compatibility.
 * Optimization is now done in _PyCfg_OptimizeCodeUnit */

PyObject *
PyCode_Optimize(PyObject *code, PyObject* Py_UNUSED(consts),
                PyObject *Py_UNUSED(names), PyObject *Py_UNUSED(lnotab_obj))
{}