1c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* 2c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel * This file compiles an abstract syntax tree (AST) into Python bytecode. 3c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel * 4c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel * The primary entry point is PyAST_Compile(), which returns a 5c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel * PyCodeObject. The compiler makes several passes to build the code 6c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel * object: 7c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel * 1. Checks for future statements. See future.c 8c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel * 2. Builds a symbol table. See symtable.c. 9c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel * 3. Generate code for basic blocks. See compiler_mod() in this file. 10c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel * 4. Assemble the basic blocks into final code. See assemble() in 11c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel * this file. 12c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel * 5. Optimize the byte code (peephole optimizations). See peephole.c 13c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel * 14c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel * Note that compiler_mod() suggests module, but the module ast type 15c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel * (mod_ty) has cases for expressions and interactive statements. 16c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel * 17c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel * CAUTION: The VISIT_* macros abort the current function when they 18c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel * encounter a problem. So don't invoke them when there is memory 19c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel * which needs to be released. Code blocks are OK, as the compiler 20c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel * structure takes care of releasing those. Use the arena to manage 21c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel * objects. 22c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel */ 23c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 24c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#include "Python.h" 25c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 26c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#include "Python-ast.h" 27c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#include "node.h" 28c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#include "pyarena.h" 29c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#include "ast.h" 30c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#include "code.h" 31c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#include "compile.h" 32c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#include "symtable.h" 33c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#include "opcode.h" 34c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 35c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielint Py_OptimizeFlag = 0; 36c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 37c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#define DEFAULT_BLOCK_SIZE 16 38c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#define DEFAULT_BLOCKS 8 39c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#define DEFAULT_CODE_SIZE 128 40c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#define DEFAULT_LNOTAB_SIZE 16 41c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 42c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#define COMP_GENEXP 0 43c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#define COMP_SETCOMP 1 44c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#define COMP_DICTCOMP 2 45c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 46c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstruct instr { 47c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel unsigned i_jabs : 1; 48c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel unsigned i_jrel : 1; 49c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel unsigned i_hasarg : 1; 50c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel unsigned char i_opcode; 51c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int i_oparg; 52c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel struct basicblock_ *i_target; /* target block (if jump instruction) */ 53c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int i_lineno; 54c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel}; 55c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 56c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanieltypedef struct basicblock_ { 57c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Each basicblock in a compilation unit is linked via b_list in the 58c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel reverse order that the block are allocated. b_list points to the next 59c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel block, not to be confused with b_next, which is next by control flow. */ 60c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel struct basicblock_ *b_list; 61c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* number of instructions used */ 62c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int b_iused; 63c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* length of instruction array (b_instr) */ 64c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int b_ialloc; 65c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* pointer to an array of instructions, initially NULL */ 66c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel struct instr *b_instr; 67c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* If b_next is non-NULL, it is a pointer to the next 68c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel block reached by normal control flow. */ 69c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel struct basicblock_ *b_next; 70c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* b_seen is used to perform a DFS of basicblocks. */ 71c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel unsigned b_seen : 1; 72c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* b_return is true if a RETURN_VALUE opcode is inserted. */ 73c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel unsigned b_return : 1; 74c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* depth of stack upon entry of block, computed by stackdepth() */ 75c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int b_startdepth; 76c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* instruction offset for block, computed by assemble_jump_offsets() */ 77c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int b_offset; 78c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} basicblock; 79c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 80c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* fblockinfo tracks the current frame block. 81c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 82c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielA frame block is used to handle loops, try/except, and try/finally. 83c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielIt's called a frame block to distinguish it from a basic block in the 84c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler IR. 85c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel*/ 86c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 87c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielenum fblocktype { LOOP, EXCEPT, FINALLY_TRY, FINALLY_END }; 88c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 89c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstruct fblockinfo { 90c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel enum fblocktype fb_type; 91c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel basicblock *fb_block; 92c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel}; 93c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 94c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* The following items change on entry and exit of code blocks. 95c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel They must be saved and restored when returning to a block. 96c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel*/ 97c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstruct compiler_unit { 98c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PySTEntryObject *u_ste; 99c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 100c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *u_name; 101c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* The following fields are dicts that map objects to 102c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel the index of them in co_XXX. The index is used as 103c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel the argument for opcodes that refer to those collections. 104c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel */ 105c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *u_consts; /* all constants */ 106c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *u_names; /* all names */ 107c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *u_varnames; /* local variables */ 108c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *u_cellvars; /* cell variables */ 109c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *u_freevars; /* free variables */ 110c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 111c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *u_private; /* for private name mangling */ 112c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 113c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int u_argcount; /* number of arguments for block */ 114c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Pointer to the most recently allocated block. By following b_list 115c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel members, you can reach all early allocated blocks. */ 116c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel basicblock *u_blocks; 117c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel basicblock *u_curblock; /* pointer to current block */ 118c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 119c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int u_nfblocks; 120c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel struct fblockinfo u_fblock[CO_MAXBLOCKS]; 121c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 122c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int u_firstlineno; /* the first lineno of the block */ 123c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int u_lineno; /* the lineno for the current stmt */ 124c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel bool u_lineno_set; /* boolean to indicate whether instr 125c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel has been generated with current lineno */ 126c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel}; 127c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 128c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* This struct captures the global state of a compilation. 129c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 130c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielThe u pointer points to the current compilation unit, while units 131c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielfor enclosing blocks are stored in c_stack. The u and c_stack are 132c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielmanaged by compiler_enter_scope() and compiler_exit_scope(). 133c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel*/ 134c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 135c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstruct compiler { 136c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel const char *c_filename; 137c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel struct symtable *c_st; 138c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyFutureFeatures *c_future; /* pointer to module's __future__ */ 139c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyCompilerFlags *c_flags; 140c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 141c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int c_interactive; /* true if in interactive mode */ 142c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int c_nestlevel; 143c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 144c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel struct compiler_unit *u; /* compiler state for current block */ 145c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *c_stack; /* Python list holding compiler_unit ptrs */ 146c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyArena *c_arena; /* pointer to memory allocation arena */ 147c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel}; 148c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 149c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int compiler_enter_scope(struct compiler *, identifier, void *, int); 150c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic void compiler_free(struct compiler *); 151c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic basicblock *compiler_new_block(struct compiler *); 152c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int compiler_next_instr(struct compiler *, basicblock *); 153c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int compiler_addop(struct compiler *, int); 154c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int compiler_addop_o(struct compiler *, int, PyObject *, PyObject *); 155c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int compiler_addop_i(struct compiler *, int, int); 156c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int compiler_addop_j(struct compiler *, int, basicblock *, int); 157c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic basicblock *compiler_use_new_block(struct compiler *); 158c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int compiler_error(struct compiler *, const char *); 159c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int compiler_nameop(struct compiler *, identifier, expr_context_ty); 160c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 161c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic PyCodeObject *compiler_mod(struct compiler *, mod_ty); 162c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int compiler_visit_stmt(struct compiler *, stmt_ty); 163c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int compiler_visit_keyword(struct compiler *, keyword_ty); 164c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int compiler_visit_expr(struct compiler *, expr_ty); 165c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int compiler_augassign(struct compiler *, stmt_ty); 166c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int compiler_visit_slice(struct compiler *, slice_ty, 167c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel expr_context_ty); 168c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 169c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int compiler_push_fblock(struct compiler *, enum fblocktype, 170c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel basicblock *); 171c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic void compiler_pop_fblock(struct compiler *, enum fblocktype, 172c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel basicblock *); 173c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* Returns true if there is a loop on the fblock stack. */ 174c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int compiler_in_loop(struct compiler *); 175c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 176c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int inplace_binop(struct compiler *, operator_ty); 177c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int expr_constant(expr_ty e); 178c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 179c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int compiler_with(struct compiler *, stmt_ty); 180c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 181c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic PyCodeObject *assemble(struct compiler *, int addNone); 182c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic PyObject *__doc__; 183c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 184c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#define COMPILER_CAPSULE_NAME_COMPILER_UNIT "compile.c compiler unit" 185c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 186c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielPyObject * 187c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel_Py_Mangle(PyObject *privateobj, PyObject *ident) 188c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 189c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Name mangling: __private becomes _classname__private. 190c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel This is independent from how the name is used. */ 191c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel const char *p, *name = PyString_AsString(ident); 192c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel char *buffer; 193c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel size_t nlen, plen; 194c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (privateobj == NULL || !PyString_Check(privateobj) || 195c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel name == NULL || name[0] != '_' || name[1] != '_') { 196c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_INCREF(ident); 197c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return ident; 198c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 199c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel p = PyString_AsString(privateobj); 200c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel nlen = strlen(name); 201c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Don't mangle __id__ or names with dots. 202c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 203c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel The only time a name with a dot can occur is when 204c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel we are compiling an import statement that has a 205c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel package name. 206c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 207c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel TODO(jhylton): Decide whether we want to support 208c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel mangling of the module name, e.g. __M.X. 209c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel */ 210c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if ((name[nlen-1] == '_' && name[nlen-2] == '_') 211c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel || strchr(name, '.')) { 212c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_INCREF(ident); 213c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return ident; /* Don't mangle __whatever__ */ 214c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 215c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Strip leading underscores from class name */ 216c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel while (*p == '_') 217c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel p++; 218c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (*p == '\0') { 219c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_INCREF(ident); 220c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return ident; /* Don't mangle if class is just underscores */ 221c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 222c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel plen = strlen(p); 223c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 224c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (plen + nlen >= PY_SSIZE_T_MAX - 1) { 225c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_SetString(PyExc_OverflowError, 226c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "private identifier too large to be mangled"); 227c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 228c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 229c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 230c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ident = PyString_FromStringAndSize(NULL, 1 + nlen + plen); 231c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!ident) 232c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 233c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* ident = "_" + p[:plen] + name # i.e. 1+plen+nlen bytes */ 234c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel buffer = PyString_AS_STRING(ident); 235c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel buffer[0] = '_'; 236c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel strncpy(buffer+1, p, plen); 237c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel strcpy(buffer+1+plen, name); 238c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return ident; 239c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 240c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 241c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 242c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_init(struct compiler *c) 243c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 244c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel memset(c, 0, sizeof(struct compiler)); 245c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 246c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c->c_stack = PyList_New(0); 247c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!c->c_stack) 248c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 249c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 250c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 251c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 252c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 253c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielPyCodeObject * 254c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielPyAST_Compile(mod_ty mod, const char *filename, PyCompilerFlags *flags, 255c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyArena *arena) 256c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 257c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel struct compiler c; 258c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyCodeObject *co = NULL; 259c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyCompilerFlags local_flags; 260c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int merged; 261c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 262c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!__doc__) { 263c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel __doc__ = PyString_InternFromString("__doc__"); 264c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!__doc__) 265c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 266c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 267c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 268c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_init(&c)) 269c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 270c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c.c_filename = filename; 271c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c.c_arena = arena; 272c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c.c_future = PyFuture_FromAST(mod, filename); 273c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (c.c_future == NULL) 274c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto finally; 275c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!flags) { 276c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel local_flags.cf_flags = 0; 277c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel flags = &local_flags; 278c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 279c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel merged = c.c_future->ff_features | flags->cf_flags; 280c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c.c_future->ff_features = merged; 281c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel flags->cf_flags = merged; 282c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c.c_flags = flags; 283c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c.c_nestlevel = 0; 284c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 285c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c.c_st = PySymtable_Build(mod, filename, c.c_future); 286c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (c.c_st == NULL) { 287c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!PyErr_Occurred()) 288c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_SetString(PyExc_SystemError, "no symtable"); 289c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto finally; 290c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 291c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 292c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel co = compiler_mod(&c, mod); 293c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 294c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel finally: 295c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_free(&c); 296c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(co || PyErr_Occurred()); 297c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return co; 298c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 299c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 300c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielPyCodeObject * 301c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielPyNode_Compile(struct _node *n, const char *filename) 302c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 303c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyCodeObject *co = NULL; 304c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel mod_ty mod; 305c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyArena *arena = PyArena_New(); 306c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!arena) 307c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 308c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel mod = PyAST_FromNode(n, NULL, filename, arena); 309c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (mod) 310c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel co = PyAST_Compile(mod, filename, NULL, arena); 311c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyArena_Free(arena); 312c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return co; 313c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 314c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 315c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic void 316c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_free(struct compiler *c) 317c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 318c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (c->c_st) 319c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PySymtable_Free(c->c_st); 320c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (c->c_future) 321c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject_Free(c->c_future); 322c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(c->c_stack); 323c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 324c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 325c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic PyObject * 326c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniellist2dict(PyObject *list) 327c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 328c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_ssize_t i, n; 329c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *v, *k; 330c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *dict = PyDict_New(); 331c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!dict) return NULL; 332c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 333c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel n = PyList_Size(list); 334c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (i = 0; i < n; i++) { 335c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel v = PyInt_FromLong(i); 336c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!v) { 337c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(dict); 338c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 339c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 340c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel k = PyList_GET_ITEM(list, i); 341c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel k = PyTuple_Pack(2, k, k->ob_type); 342c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (k == NULL || PyDict_SetItem(dict, k, v) < 0) { 343c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_XDECREF(k); 344c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(v); 345c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(dict); 346c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 347c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 348c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(k); 349c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(v); 350c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 351c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return dict; 352c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 353c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 354c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* Return new dict containing names from src that match scope(s). 355c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 356c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielsrc is a symbol table dictionary. If the scope of a name matches 357c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanieleither scope_type or flag is set, insert it into the new dict. The 358c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielvalues are integers, starting at offset and increasing by one for 359c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanieleach key. 360c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel*/ 361c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 362c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic PyObject * 363c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanieldictbytype(PyObject *src, int scope_type, int flag, int offset) 364c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 365c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_ssize_t i = offset, scope, num_keys, key_i; 366c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *k, *v, *dest = PyDict_New(); 367c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *sorted_keys; 368c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 369c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(offset >= 0); 370c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (dest == NULL) 371c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 372c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 373c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Sort the keys so that we have a deterministic order on the indexes 374c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel saved in the returned dictionary. These indexes are used as indexes 375c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel into the free and cell var storage. Therefore if they aren't 376c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel deterministic, then the generated bytecode is not deterministic. 377c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel */ 378c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel sorted_keys = PyDict_Keys(src); 379c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (sorted_keys == NULL) 380c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 381c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (PyList_Sort(sorted_keys) != 0) { 382c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(sorted_keys); 383c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 384c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 385c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel num_keys = PyList_GET_SIZE(sorted_keys); 386c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 387c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (key_i = 0; key_i < num_keys; key_i++) { 388c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel k = PyList_GET_ITEM(sorted_keys, key_i); 389c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel v = PyDict_GetItem(src, k); 390c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* XXX this should probably be a macro in symtable.h */ 391c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(PyInt_Check(v)); 392c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel scope = (PyInt_AS_LONG(v) >> SCOPE_OFF) & SCOPE_MASK; 393c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 394c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (scope == scope_type || PyInt_AS_LONG(v) & flag) { 395c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *tuple, *item = PyInt_FromLong(i); 396c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (item == NULL) { 397c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(sorted_keys); 398c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(dest); 399c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 400c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 401c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel i++; 402c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel tuple = PyTuple_Pack(2, k, k->ob_type); 403c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!tuple || PyDict_SetItem(dest, tuple, item) < 0) { 404c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(sorted_keys); 405c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(item); 406c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(dest); 407c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_XDECREF(tuple); 408c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 409c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 410c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(item); 411c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(tuple); 412c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 413c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 414c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(sorted_keys); 415c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return dest; 416c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 417c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 418c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic void 419c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_unit_check(struct compiler_unit *u) 420c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 421c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel basicblock *block; 422c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (block = u->u_blocks; block != NULL; block = block->b_list) { 423c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert((void *)block != (void *)0xcbcbcbcb); 424c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert((void *)block != (void *)0xfbfbfbfb); 425c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert((void *)block != (void *)0xdbdbdbdb); 426c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (block->b_instr != NULL) { 427c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(block->b_ialloc > 0); 428c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(block->b_iused > 0); 429c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(block->b_ialloc >= block->b_iused); 430c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 431c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else { 432c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert (block->b_iused == 0); 433c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert (block->b_ialloc == 0); 434c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 435c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 436c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 437c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 438c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic void 439c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_unit_free(struct compiler_unit *u) 440c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 441c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel basicblock *b, *next; 442c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 443c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_unit_check(u); 444c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel b = u->u_blocks; 445c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel while (b != NULL) { 446c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (b->b_instr) 447c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject_Free((void *)b->b_instr); 448c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel next = b->b_list; 449c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject_Free((void *)b); 450c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel b = next; 451c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 452c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_CLEAR(u->u_ste); 453c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_CLEAR(u->u_name); 454c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_CLEAR(u->u_consts); 455c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_CLEAR(u->u_names); 456c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_CLEAR(u->u_varnames); 457c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_CLEAR(u->u_freevars); 458c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_CLEAR(u->u_cellvars); 459c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_CLEAR(u->u_private); 460c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject_Free(u); 461c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 462c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 463c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 464c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_enter_scope(struct compiler *c, identifier name, void *key, 465c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int lineno) 466c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 467c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel struct compiler_unit *u; 468c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 469c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel u = (struct compiler_unit *)PyObject_Malloc(sizeof( 470c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel struct compiler_unit)); 471c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!u) { 472c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_NoMemory(); 473c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 474c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 475c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel memset(u, 0, sizeof(struct compiler_unit)); 476c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel u->u_argcount = 0; 477c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel u->u_ste = PySymtable_Lookup(c->c_st, key); 478c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!u->u_ste) { 479c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_unit_free(u); 480c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 481c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 482c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_INCREF(name); 483c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel u->u_name = name; 484c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel u->u_varnames = list2dict(u->u_ste->ste_varnames); 485c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel u->u_cellvars = dictbytype(u->u_ste->ste_symbols, CELL, 0, 0); 486c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!u->u_varnames || !u->u_cellvars) { 487c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_unit_free(u); 488c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 489c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 490c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 491c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel u->u_freevars = dictbytype(u->u_ste->ste_symbols, FREE, DEF_FREE_CLASS, 492c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyDict_Size(u->u_cellvars)); 493c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!u->u_freevars) { 494c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_unit_free(u); 495c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 496c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 497c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 498c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel u->u_blocks = NULL; 499c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel u->u_nfblocks = 0; 500c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel u->u_firstlineno = lineno; 501c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel u->u_lineno = 0; 502c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel u->u_lineno_set = false; 503c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel u->u_consts = PyDict_New(); 504c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!u->u_consts) { 505c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_unit_free(u); 506c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 507c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 508c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel u->u_names = PyDict_New(); 509c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!u->u_names) { 510c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_unit_free(u); 511c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 512c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 513c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 514c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel u->u_private = NULL; 515c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 516c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Push the old compiler_unit on the stack. */ 517c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (c->u) { 518c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *capsule = PyCapsule_New(c->u, COMPILER_CAPSULE_NAME_COMPILER_UNIT, NULL); 519c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!capsule || PyList_Append(c->c_stack, capsule) < 0) { 520c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_XDECREF(capsule); 521c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_unit_free(u); 522c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 523c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 524c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(capsule); 525c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel u->u_private = c->u->u_private; 526c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_XINCREF(u->u_private); 527c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 528c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c->u = u; 529c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 530c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c->c_nestlevel++; 531c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (compiler_use_new_block(c) == NULL) 532c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 533c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 534c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 535c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 536c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 537c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic void 538c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_exit_scope(struct compiler *c) 539c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 540c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int n; 541c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *capsule; 542c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 543c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c->c_nestlevel--; 544c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_unit_free(c->u); 545c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Restore c->u to the parent unit. */ 546c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel n = PyList_GET_SIZE(c->c_stack) - 1; 547c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (n >= 0) { 548c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel capsule = PyList_GET_ITEM(c->c_stack, n); 549c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c->u = (struct compiler_unit *)PyCapsule_GetPointer(capsule, COMPILER_CAPSULE_NAME_COMPILER_UNIT); 550c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(c->u); 551c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* we are deleting from a list so this really shouldn't fail */ 552c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (PySequence_DelItem(c->c_stack, n) < 0) 553c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_FatalError("compiler_exit_scope()"); 554c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_unit_check(c->u); 555c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 556c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else 557c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c->u = NULL; 558c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 559c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 560c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 561c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* Allocate a new block and return a pointer to it. 562c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Returns NULL on error. 563c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel*/ 564c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 565c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic basicblock * 566c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_new_block(struct compiler *c) 567c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 568c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel basicblock *b; 569c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel struct compiler_unit *u; 570c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 571c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel u = c->u; 572c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel b = (basicblock *)PyObject_Malloc(sizeof(basicblock)); 573c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (b == NULL) { 574c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_NoMemory(); 575c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 576c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 577c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel memset((void *)b, 0, sizeof(basicblock)); 578c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Extend the singly linked list of blocks with new block. */ 579c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel b->b_list = u->u_blocks; 580c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel u->u_blocks = b; 581c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return b; 582c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 583c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 584c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic basicblock * 585c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_use_new_block(struct compiler *c) 586c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 587c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel basicblock *block = compiler_new_block(c); 588c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (block == NULL) 589c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 590c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c->u->u_curblock = block; 591c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return block; 592c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 593c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 594c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic basicblock * 595c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_next_block(struct compiler *c) 596c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 597c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel basicblock *block = compiler_new_block(c); 598c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (block == NULL) 599c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 600c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c->u->u_curblock->b_next = block; 601c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c->u->u_curblock = block; 602c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return block; 603c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 604c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 605c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic basicblock * 606c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_use_next_block(struct compiler *c, basicblock *block) 607c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 608c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(block != NULL); 609c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c->u->u_curblock->b_next = block; 610c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c->u->u_curblock = block; 611c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return block; 612c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 613c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 614c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* Returns the offset of the next instruction in the current block's 615c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel b_instr array. Resizes the b_instr as necessary. 616c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Returns -1 on failure. 617c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel*/ 618c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 619c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 620c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_next_instr(struct compiler *c, basicblock *b) 621c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 622c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(b != NULL); 623c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (b->b_instr == NULL) { 624c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel b->b_instr = (struct instr *)PyObject_Malloc( 625c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel sizeof(struct instr) * DEFAULT_BLOCK_SIZE); 626c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (b->b_instr == NULL) { 627c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_NoMemory(); 628c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 629c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 630c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel b->b_ialloc = DEFAULT_BLOCK_SIZE; 631c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel memset((char *)b->b_instr, 0, 632c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel sizeof(struct instr) * DEFAULT_BLOCK_SIZE); 633c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 634c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else if (b->b_iused == b->b_ialloc) { 635c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel struct instr *tmp; 636c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel size_t oldsize, newsize; 637c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel oldsize = b->b_ialloc * sizeof(struct instr); 638c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel newsize = oldsize << 1; 639c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 640c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (oldsize > (PY_SIZE_MAX >> 1)) { 641c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_NoMemory(); 642c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 643c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 644c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 645c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (newsize == 0) { 646c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_NoMemory(); 647c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 648c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 649c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel b->b_ialloc <<= 1; 650c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel tmp = (struct instr *)PyObject_Realloc( 651c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel (void *)b->b_instr, newsize); 652c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (tmp == NULL) { 653c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_NoMemory(); 654c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 655c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 656c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel b->b_instr = tmp; 657c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel memset((char *)b->b_instr + oldsize, 0, newsize - oldsize); 658c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 659c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return b->b_iused++; 660c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 661c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 662c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* Set the i_lineno member of the instruction at offset off if the 663c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel line number for the current expression/statement has not 664c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel already been set. If it has been set, the call has no effect. 665c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 666c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel The line number is reset in the following cases: 667c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel - when entering a new scope 668c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel - on each statement 669c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel - on each expression that start a new line 670c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel - before the "except" clause 671c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel - before the "for" and "while" expressions 672c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel*/ 673c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 674c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic void 675c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_set_lineno(struct compiler *c, int off) 676c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 677c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel basicblock *b; 678c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (c->u->u_lineno_set) 679c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return; 680c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c->u->u_lineno_set = true; 681c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel b = c->u->u_curblock; 682c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel b->b_instr[off].i_lineno = c->u->u_lineno; 683c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 684c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 685c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 686c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielopcode_stack_effect(int opcode, int oparg) 687c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 688c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel switch (opcode) { 689c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case POP_TOP: 690c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 691c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case ROT_TWO: 692c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case ROT_THREE: 693c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 694c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case DUP_TOP: 695c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 696c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case ROT_FOUR: 697c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 698c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 699c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case UNARY_POSITIVE: 700c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case UNARY_NEGATIVE: 701c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case UNARY_NOT: 702c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case UNARY_CONVERT: 703c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case UNARY_INVERT: 704c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 705c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 706c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case SET_ADD: 707c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case LIST_APPEND: 708c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 709c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 710c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case MAP_ADD: 711c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -2; 712c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 713c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case BINARY_POWER: 714c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case BINARY_MULTIPLY: 715c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case BINARY_DIVIDE: 716c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case BINARY_MODULO: 717c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case BINARY_ADD: 718c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case BINARY_SUBTRACT: 719c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case BINARY_SUBSCR: 720c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case BINARY_FLOOR_DIVIDE: 721c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case BINARY_TRUE_DIVIDE: 722c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 723c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case INPLACE_FLOOR_DIVIDE: 724c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case INPLACE_TRUE_DIVIDE: 725c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 726c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 727c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case SLICE+0: 728c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 729c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case SLICE+1: 730c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 731c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case SLICE+2: 732c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 733c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case SLICE+3: 734c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -2; 735c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 736c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case STORE_SLICE+0: 737c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -2; 738c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case STORE_SLICE+1: 739c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -3; 740c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case STORE_SLICE+2: 741c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -3; 742c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case STORE_SLICE+3: 743c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -4; 744c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 745c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case DELETE_SLICE+0: 746c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 747c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case DELETE_SLICE+1: 748c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -2; 749c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case DELETE_SLICE+2: 750c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -2; 751c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case DELETE_SLICE+3: 752c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -3; 753c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 754c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case INPLACE_ADD: 755c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case INPLACE_SUBTRACT: 756c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case INPLACE_MULTIPLY: 757c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case INPLACE_DIVIDE: 758c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case INPLACE_MODULO: 759c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 760c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case STORE_SUBSCR: 761c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -3; 762c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case STORE_MAP: 763c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -2; 764c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case DELETE_SUBSCR: 765c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -2; 766c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 767c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case BINARY_LSHIFT: 768c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case BINARY_RSHIFT: 769c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case BINARY_AND: 770c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case BINARY_XOR: 771c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case BINARY_OR: 772c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 773c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case INPLACE_POWER: 774c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 775c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case GET_ITER: 776c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 777c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 778c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case PRINT_EXPR: 779c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 780c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case PRINT_ITEM: 781c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 782c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case PRINT_NEWLINE: 783c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 784c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case PRINT_ITEM_TO: 785c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -2; 786c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case PRINT_NEWLINE_TO: 787c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 788c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case INPLACE_LSHIFT: 789c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case INPLACE_RSHIFT: 790c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case INPLACE_AND: 791c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case INPLACE_XOR: 792c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case INPLACE_OR: 793c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 794c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case BREAK_LOOP: 795c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 796c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case SETUP_WITH: 797c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 4; 798c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case WITH_CLEANUP: 799c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; /* XXX Sometimes more */ 800c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case LOAD_LOCALS: 801c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 802c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case RETURN_VALUE: 803c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 804c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case IMPORT_STAR: 805c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 806c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case EXEC_STMT: 807c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -3; 808c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case YIELD_VALUE: 809c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 810c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 811c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case POP_BLOCK: 812c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 813c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case END_FINALLY: 814c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -3; /* or -1 or -2 if no exception occurred or 815c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return/break/continue */ 816c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case BUILD_CLASS: 817c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -2; 818c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 819c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case STORE_NAME: 820c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 821c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case DELETE_NAME: 822c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 823c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case UNPACK_SEQUENCE: 824c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return oparg-1; 825c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case FOR_ITER: 826c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; /* or -1, at end of iterator */ 827c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 828c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case STORE_ATTR: 829c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -2; 830c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case DELETE_ATTR: 831c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 832c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case STORE_GLOBAL: 833c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 834c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case DELETE_GLOBAL: 835c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 836c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case DUP_TOPX: 837c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return oparg; 838c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case LOAD_CONST: 839c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 840c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case LOAD_NAME: 841c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 842c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case BUILD_TUPLE: 843c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case BUILD_LIST: 844c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case BUILD_SET: 845c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1-oparg; 846c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case BUILD_MAP: 847c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 848c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case LOAD_ATTR: 849c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 850c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case COMPARE_OP: 851c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 852c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case IMPORT_NAME: 853c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 854c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case IMPORT_FROM: 855c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 856c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 857c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case JUMP_FORWARD: 858c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case JUMP_IF_TRUE_OR_POP: /* -1 if jump not taken */ 859c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case JUMP_IF_FALSE_OR_POP: /* "" */ 860c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case JUMP_ABSOLUTE: 861c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 862c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 863c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case POP_JUMP_IF_FALSE: 864c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case POP_JUMP_IF_TRUE: 865c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 866c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 867c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case LOAD_GLOBAL: 868c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 869c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 870c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case CONTINUE_LOOP: 871c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 872c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case SETUP_LOOP: 873c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case SETUP_EXCEPT: 874c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case SETUP_FINALLY: 875c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 876c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 877c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case LOAD_FAST: 878c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 879c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case STORE_FAST: 880c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 881c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case DELETE_FAST: 882c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 883c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 884c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case RAISE_VARARGS: 885c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -oparg; 886c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#define NARGS(o) (((o) % 256) + 2*((o) / 256)) 887c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case CALL_FUNCTION: 888c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -NARGS(oparg); 889c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case CALL_FUNCTION_VAR: 890c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case CALL_FUNCTION_KW: 891c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -NARGS(oparg)-1; 892c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case CALL_FUNCTION_VAR_KW: 893c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -NARGS(oparg)-2; 894c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#undef NARGS 895c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case MAKE_FUNCTION: 896c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -oparg; 897c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case BUILD_SLICE: 898c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (oparg == 3) 899c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -2; 900c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else 901c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 902c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 903c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case MAKE_CLOSURE: 904c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -oparg-1; 905c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case LOAD_CLOSURE: 906c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 907c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case LOAD_DEREF: 908c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 909c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case STORE_DEREF: 910c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 911c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel default: 912c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel fprintf(stderr, "opcode = %d\n", opcode); 913c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_FatalError("opcode_stack_effect()"); 914c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 915c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 916c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; /* not reachable */ 917c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 918c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 919c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* Add an opcode with no argument. 920c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Returns 0 on failure, 1 on success. 921c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel*/ 922c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 923c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 924c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_addop(struct compiler *c, int opcode) 925c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 926c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel basicblock *b; 927c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel struct instr *i; 928c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int off; 929c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel off = compiler_next_instr(c, c->u->u_curblock); 930c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (off < 0) 931c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 932c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel b = c->u->u_curblock; 933c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel i = &b->b_instr[off]; 934c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel i->i_opcode = opcode; 935c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel i->i_hasarg = 0; 936c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (opcode == RETURN_VALUE) 937c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel b->b_return = 1; 938c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_set_lineno(c, off); 939c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 940c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 941c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 942c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 943c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_add_o(struct compiler *c, PyObject *dict, PyObject *o) 944c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 945c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *t, *v; 946c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_ssize_t arg; 947c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel double d; 948c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 949c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* necessary to make sure types aren't coerced (e.g., int and long) */ 950c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* _and_ to distinguish 0.0 from -0.0 e.g. on IEEE platforms */ 951c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (PyFloat_Check(o)) { 952c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel d = PyFloat_AS_DOUBLE(o); 953c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* all we need is to make the tuple different in either the 0.0 954c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel * or -0.0 case from all others, just to avoid the "coercion". 955c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel */ 956c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (d == 0.0 && copysign(1.0, d) < 0.0) 957c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel t = PyTuple_Pack(3, o, o->ob_type, Py_None); 958c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else 959c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel t = PyTuple_Pack(2, o, o->ob_type); 960c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 961c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#ifndef WITHOUT_COMPLEX 962c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else if (PyComplex_Check(o)) { 963c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_complex z; 964c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int real_negzero, imag_negzero; 965c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* For the complex case we must make complex(x, 0.) 966c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel different from complex(x, -0.) and complex(0., y) 967c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel different from complex(-0., y), for any x and y. 968c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel All four complex zeros must be distinguished.*/ 969c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel z = PyComplex_AsCComplex(o); 970c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel real_negzero = z.real == 0.0 && copysign(1.0, z.real) < 0.0; 971c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel imag_negzero = z.imag == 0.0 && copysign(1.0, z.imag) < 0.0; 972c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (real_negzero && imag_negzero) { 973c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel t = PyTuple_Pack(5, o, o->ob_type, 974c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_None, Py_None, Py_None); 975c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 976c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else if (imag_negzero) { 977c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel t = PyTuple_Pack(4, o, o->ob_type, Py_None, Py_None); 978c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 979c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else if (real_negzero) { 980c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel t = PyTuple_Pack(3, o, o->ob_type, Py_None); 981c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 982c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else { 983c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel t = PyTuple_Pack(2, o, o->ob_type); 984c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 985c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 986c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#endif /* WITHOUT_COMPLEX */ 987c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else { 988c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel t = PyTuple_Pack(2, o, o->ob_type); 989c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 990c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (t == NULL) 991c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 992c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 993c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel v = PyDict_GetItem(dict, t); 994c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!v) { 995c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel arg = PyDict_Size(dict); 996c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel v = PyInt_FromLong(arg); 997c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!v) { 998c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(t); 999c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 1000c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1001c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (PyDict_SetItem(dict, t, v) < 0) { 1002c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(t); 1003c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(v); 1004c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 1005c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1006c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(v); 1007c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1008c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else 1009c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel arg = PyInt_AsLong(v); 1010c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(t); 1011c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return arg; 1012c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1013c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1014c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 1015c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_addop_o(struct compiler *c, int opcode, PyObject *dict, 1016c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *o) 1017c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 1018c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int arg = compiler_add_o(c, dict, o); 1019c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (arg < 0) 1020c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1021c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_addop_i(c, opcode, arg); 1022c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1023c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1024c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 1025c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_addop_name(struct compiler *c, int opcode, PyObject *dict, 1026c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *o) 1027c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 1028c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int arg; 1029c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *mangled = _Py_Mangle(c->u->u_private, o); 1030c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!mangled) 1031c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1032c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel arg = compiler_add_o(c, dict, mangled); 1033c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(mangled); 1034c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (arg < 0) 1035c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1036c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_addop_i(c, opcode, arg); 1037c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1038c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1039c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* Add an opcode with an integer argument. 1040c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Returns 0 on failure, 1 on success. 1041c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel*/ 1042c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1043c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 1044c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_addop_i(struct compiler *c, int opcode, int oparg) 1045c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 1046c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel struct instr *i; 1047c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int off; 1048c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel off = compiler_next_instr(c, c->u->u_curblock); 1049c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (off < 0) 1050c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1051c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel i = &c->u->u_curblock->b_instr[off]; 1052c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel i->i_opcode = opcode; 1053c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel i->i_oparg = oparg; 1054c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel i->i_hasarg = 1; 1055c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_set_lineno(c, off); 1056c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 1057c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1058c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1059c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 1060c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute) 1061c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 1062c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel struct instr *i; 1063c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int off; 1064c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1065c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(b != NULL); 1066c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel off = compiler_next_instr(c, c->u->u_curblock); 1067c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (off < 0) 1068c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1069c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel i = &c->u->u_curblock->b_instr[off]; 1070c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel i->i_opcode = opcode; 1071c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel i->i_target = b; 1072c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel i->i_hasarg = 1; 1073c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (absolute) 1074c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel i->i_jabs = 1; 1075c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else 1076c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel i->i_jrel = 1; 1077c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_set_lineno(c, off); 1078c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 1079c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1080c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1081c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* The distinction between NEW_BLOCK and NEXT_BLOCK is subtle. (I'd 1082c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel like to find better names.) NEW_BLOCK() creates a new block and sets 1083c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel it as the current block. NEXT_BLOCK() also creates an implicit jump 1084c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel from the current block to the new block. 1085c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel*/ 1086c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1087c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* The returns inside these macros make it impossible to decref objects 1088c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel created in the local function. Local objects should use the arena. 1089c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel*/ 1090c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1091c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1092c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#define NEW_BLOCK(C) { \ 1093c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (compiler_use_new_block((C)) == NULL) \ 1094c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; \ 1095c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1096c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1097c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#define NEXT_BLOCK(C) { \ 1098c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (compiler_next_block((C)) == NULL) \ 1099c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; \ 1100c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1101c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1102c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#define ADDOP(C, OP) { \ 1103c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_addop((C), (OP))) \ 1104c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; \ 1105c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1106c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1107c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#define ADDOP_IN_SCOPE(C, OP) { \ 1108c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_addop((C), (OP))) { \ 1109c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_exit_scope(c); \ 1110c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; \ 1111c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } \ 1112c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1113c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1114c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#define ADDOP_O(C, OP, O, TYPE) { \ 1115c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_addop_o((C), (OP), (C)->u->u_ ## TYPE, (O))) \ 1116c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; \ 1117c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1118c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1119c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#define ADDOP_NAME(C, OP, O, TYPE) { \ 1120c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_addop_name((C), (OP), (C)->u->u_ ## TYPE, (O))) \ 1121c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; \ 1122c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1123c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1124c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#define ADDOP_I(C, OP, O) { \ 1125c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_addop_i((C), (OP), (O))) \ 1126c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; \ 1127c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1128c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1129c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#define ADDOP_JABS(C, OP, O) { \ 1130c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_addop_j((C), (OP), (O), 1)) \ 1131c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; \ 1132c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1133c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1134c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#define ADDOP_JREL(C, OP, O) { \ 1135c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_addop_j((C), (OP), (O), 0)) \ 1136c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; \ 1137c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1138c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1139c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* VISIT and VISIT_SEQ takes an ASDL type as their second argument. They use 1140c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel the ASDL name to synthesize the name of the C type and the visit function. 1141c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel*/ 1142c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1143c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#define VISIT(C, TYPE, V) {\ 1144c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_visit_ ## TYPE((C), (V))) \ 1145c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; \ 1146c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1147c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1148c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#define VISIT_IN_SCOPE(C, TYPE, V) {\ 1149c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_visit_ ## TYPE((C), (V))) { \ 1150c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_exit_scope(c); \ 1151c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; \ 1152c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } \ 1153c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1154c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1155c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#define VISIT_SLICE(C, V, CTX) {\ 1156c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_visit_slice((C), (V), (CTX))) \ 1157c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; \ 1158c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1159c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1160c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#define VISIT_SEQ(C, TYPE, SEQ) { \ 1161c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int _i; \ 1162c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel asdl_seq *seq = (SEQ); /* avoid variable capture */ \ 1163c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (_i = 0; _i < asdl_seq_LEN(seq); _i++) { \ 1164c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i); \ 1165c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_visit_ ## TYPE((C), elt)) \ 1166c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; \ 1167c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } \ 1168c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1169c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1170c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#define VISIT_SEQ_IN_SCOPE(C, TYPE, SEQ) { \ 1171c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int _i; \ 1172c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel asdl_seq *seq = (SEQ); /* avoid variable capture */ \ 1173c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (_i = 0; _i < asdl_seq_LEN(seq); _i++) { \ 1174c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i); \ 1175c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_visit_ ## TYPE((C), elt)) { \ 1176c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_exit_scope(c); \ 1177c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; \ 1178c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } \ 1179c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } \ 1180c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1181c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1182c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 1183c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_isdocstring(stmt_ty s) 1184c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 1185c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (s->kind != Expr_kind) 1186c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1187c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return s->v.Expr.value->kind == Str_kind; 1188c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1189c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1190c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* Compile a sequence of statements, checking for a docstring. */ 1191c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1192c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 1193c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_body(struct compiler *c, asdl_seq *stmts) 1194c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 1195c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int i = 0; 1196c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel stmt_ty st; 1197c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1198c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!asdl_seq_LEN(stmts)) 1199c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 1200c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel st = (stmt_ty)asdl_seq_GET(stmts, 0); 1201c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (compiler_isdocstring(st) && Py_OptimizeFlag < 2) { 1202c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* don't generate docstrings if -OO */ 1203c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel i = 1; 1204c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, st->v.Expr.value); 1205c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_nameop(c, __doc__, Store)) 1206c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1207c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1208c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (; i < asdl_seq_LEN(stmts); i++) 1209c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, stmt, (stmt_ty)asdl_seq_GET(stmts, i)); 1210c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 1211c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1212c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1213c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic PyCodeObject * 1214c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_mod(struct compiler *c, mod_ty mod) 1215c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 1216c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyCodeObject *co; 1217c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int addNone = 1; 1218c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel static PyObject *module; 1219c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!module) { 1220c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel module = PyString_InternFromString("<module>"); 1221c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!module) 1222c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 1223c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1224c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Use 0 for firstlineno initially, will fixup in assemble(). */ 1225c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_enter_scope(c, module, mod, 0)) 1226c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 1227c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel switch (mod->kind) { 1228c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Module_kind: 1229c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_body(c, mod->v.Module.body)) { 1230c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_exit_scope(c); 1231c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1232c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1233c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 1234c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Interactive_kind: 1235c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c->c_interactive = 1; 1236c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT_SEQ_IN_SCOPE(c, stmt, 1237c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel mod->v.Interactive.body); 1238c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 1239c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Expression_kind: 1240c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT_IN_SCOPE(c, expr, mod->v.Expression.body); 1241c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel addNone = 0; 1242c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 1243c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Suite_kind: 1244c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_SetString(PyExc_SystemError, 1245c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "suite should not be possible"); 1246c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1247c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel default: 1248c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_Format(PyExc_SystemError, 1249c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "module kind %d should not be possible", 1250c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel mod->kind); 1251c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1252c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1253c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel co = assemble(c, addNone); 1254c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_exit_scope(c); 1255c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return co; 1256c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1257c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1258c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* The test for LOCAL must come before the test for FREE in order to 1259c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel handle classes where name is both local and free. The local var is 1260c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel a method and the free var is a free var referenced within a method. 1261c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel*/ 1262c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1263c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 1264c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielget_ref_type(struct compiler *c, PyObject *name) 1265c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 1266c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int scope = PyST_GetScope(c->u->u_ste, name); 1267c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (scope == 0) { 1268c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel char buf[350]; 1269c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyOS_snprintf(buf, sizeof(buf), 1270c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "unknown scope for %.100s in %.100s(%s) in %s\n" 1271c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "symbols: %s\nlocals: %s\nglobals: %s", 1272c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyString_AS_STRING(name), 1273c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyString_AS_STRING(c->u->u_name), 1274c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyString_AS_STRING(PyObject_Repr(c->u->u_ste->ste_id)), 1275c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c->c_filename, 1276c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyString_AS_STRING(PyObject_Repr(c->u->u_ste->ste_symbols)), 1277c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyString_AS_STRING(PyObject_Repr(c->u->u_varnames)), 1278c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyString_AS_STRING(PyObject_Repr(c->u->u_names)) 1279c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ); 1280c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_FatalError(buf); 1281c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1282c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1283c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return scope; 1284c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1285c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1286c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 1287c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_lookup_arg(PyObject *dict, PyObject *name) 1288c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 1289c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *k, *v; 1290c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel k = PyTuple_Pack(2, name, name->ob_type); 1291c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (k == NULL) 1292c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 1293c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel v = PyDict_GetItem(dict, k); 1294c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(k); 1295c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (v == NULL) 1296c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 1297c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return PyInt_AS_LONG(v); 1298c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1299c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1300c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 1301c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_make_closure(struct compiler *c, PyCodeObject *co, int args) 1302c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 1303c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int i, free = PyCode_GetNumFree(co); 1304c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (free == 0) { 1305c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_O(c, LOAD_CONST, (PyObject*)co, consts); 1306c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_I(c, MAKE_FUNCTION, args); 1307c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 1308c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1309c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (i = 0; i < free; ++i) { 1310c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Bypass com_addop_varname because it will generate 1311c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel LOAD_DEREF but LOAD_CLOSURE is needed. 1312c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel */ 1313c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *name = PyTuple_GET_ITEM(co->co_freevars, i); 1314c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int arg, reftype; 1315c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1316c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Special case: If a class contains a method with a 1317c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel free variable that has the same name as a method, 1318c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel the name will be considered free *and* local in the 1319c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel class. It should be handled by the closure, as 1320c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel well as by the normal name loookup logic. 1321c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel */ 1322c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel reftype = get_ref_type(c, name); 1323c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (reftype == CELL) 1324c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel arg = compiler_lookup_arg(c->u->u_cellvars, name); 1325c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else /* (reftype == FREE) */ 1326c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel arg = compiler_lookup_arg(c->u->u_freevars, name); 1327c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (arg == -1) { 1328c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel printf("lookup %s in %s %d %d\n" 1329c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "freevars of %s: %s\n", 1330c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyString_AS_STRING(PyObject_Repr(name)), 1331c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyString_AS_STRING(c->u->u_name), 1332c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel reftype, arg, 1333c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyString_AS_STRING(co->co_name), 1334c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyString_AS_STRING(PyObject_Repr(co->co_freevars))); 1335c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_FatalError("compiler_make_closure()"); 1336c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1337c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_I(c, LOAD_CLOSURE, arg); 1338c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1339c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_I(c, BUILD_TUPLE, free); 1340c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_O(c, LOAD_CONST, (PyObject*)co, consts); 1341c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_I(c, MAKE_CLOSURE, args); 1342c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 1343c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1344c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1345c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 1346c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_decorators(struct compiler *c, asdl_seq* decos) 1347c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 1348c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int i; 1349c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1350c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!decos) 1351c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 1352c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1353c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (i = 0; i < asdl_seq_LEN(decos); i++) { 1354c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, (expr_ty)asdl_seq_GET(decos, i)); 1355c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1356c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 1357c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1358c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1359c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 1360c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_arguments(struct compiler *c, arguments_ty args) 1361c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 1362c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int i; 1363c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int n = asdl_seq_LEN(args->args); 1364c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Correctly handle nested argument lists */ 1365c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (i = 0; i < n; i++) { 1366c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel expr_ty arg = (expr_ty)asdl_seq_GET(args->args, i); 1367c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (arg->kind == Tuple_kind) { 1368c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *id = PyString_FromFormat(".%d", i); 1369c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (id == NULL) { 1370c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1371c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1372c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_nameop(c, id, Load)) { 1373c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(id); 1374c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1375c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1376c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(id); 1377c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, arg); 1378c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1379c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1380c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 1381c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1382c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1383c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 1384c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_function(struct compiler *c, stmt_ty s) 1385c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 1386c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyCodeObject *co; 1387c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *first_const = Py_None; 1388c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel arguments_ty args = s->v.FunctionDef.args; 1389c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel asdl_seq* decos = s->v.FunctionDef.decorator_list; 1390c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel stmt_ty st; 1391c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int i, n, docstring; 1392c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1393c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(s->kind == FunctionDef_kind); 1394c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1395c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_decorators(c, decos)) 1396c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1397c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (args->defaults) 1398c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT_SEQ(c, expr, args->defaults); 1399c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_enter_scope(c, s->v.FunctionDef.name, (void *)s, 1400c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel s->lineno)) 1401c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1402c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1403c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel st = (stmt_ty)asdl_seq_GET(s->v.FunctionDef.body, 0); 1404c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel docstring = compiler_isdocstring(st); 1405c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (docstring && Py_OptimizeFlag < 2) 1406c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel first_const = st->v.Expr.value->v.Str.s; 1407c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (compiler_add_o(c, c->u->u_consts, first_const) < 0) { 1408c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_exit_scope(c); 1409c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1410c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1411c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1412c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* unpack nested arguments */ 1413c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_arguments(c, args); 1414c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1415c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c->u->u_argcount = asdl_seq_LEN(args->args); 1416c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel n = asdl_seq_LEN(s->v.FunctionDef.body); 1417c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* if there was a docstring, we need to skip the first statement */ 1418c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (i = docstring; i < n; i++) { 1419c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel st = (stmt_ty)asdl_seq_GET(s->v.FunctionDef.body, i); 1420c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT_IN_SCOPE(c, stmt, st); 1421c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1422c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel co = assemble(c, 1); 1423c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_exit_scope(c); 1424c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (co == NULL) 1425c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1426c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1427c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_make_closure(c, co, asdl_seq_LEN(args->defaults)); 1428c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(co); 1429c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1430c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (i = 0; i < asdl_seq_LEN(decos); i++) { 1431c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_I(c, CALL_FUNCTION, 1); 1432c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1433c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1434c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_nameop(c, s->v.FunctionDef.name, Store); 1435c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1436c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1437c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 1438c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_class(struct compiler *c, stmt_ty s) 1439c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 1440c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int n, i; 1441c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyCodeObject *co; 1442c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *str; 1443c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel asdl_seq* decos = s->v.ClassDef.decorator_list; 1444c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1445c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_decorators(c, decos)) 1446c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1447c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1448c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* push class name on stack, needed by BUILD_CLASS */ 1449c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_O(c, LOAD_CONST, s->v.ClassDef.name, consts); 1450c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* push the tuple of base classes on the stack */ 1451c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel n = asdl_seq_LEN(s->v.ClassDef.bases); 1452c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (n > 0) 1453c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT_SEQ(c, expr, s->v.ClassDef.bases); 1454c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_I(c, BUILD_TUPLE, n); 1455c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_enter_scope(c, s->v.ClassDef.name, (void *)s, 1456c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel s->lineno)) 1457c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1458c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_XDECREF(c->u->u_private); 1459c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c->u->u_private = s->v.ClassDef.name; 1460c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_INCREF(c->u->u_private); 1461c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel str = PyString_InternFromString("__name__"); 1462c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!str || !compiler_nameop(c, str, Load)) { 1463c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_XDECREF(str); 1464c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_exit_scope(c); 1465c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1466c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1467c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1468c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(str); 1469c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel str = PyString_InternFromString("__module__"); 1470c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!str || !compiler_nameop(c, str, Store)) { 1471c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_XDECREF(str); 1472c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_exit_scope(c); 1473c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1474c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1475c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(str); 1476c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1477c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_body(c, s->v.ClassDef.body)) { 1478c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_exit_scope(c); 1479c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1480c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1481c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1482c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_IN_SCOPE(c, LOAD_LOCALS); 1483c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_IN_SCOPE(c, RETURN_VALUE); 1484c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel co = assemble(c, 1); 1485c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_exit_scope(c); 1486c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (co == NULL) 1487c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1488c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1489c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_make_closure(c, co, 0); 1490c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(co); 1491c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1492c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_I(c, CALL_FUNCTION, 0); 1493c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, BUILD_CLASS); 1494c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* apply decorators */ 1495c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (i = 0; i < asdl_seq_LEN(decos); i++) { 1496c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_I(c, CALL_FUNCTION, 1); 1497c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1498c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_nameop(c, s->v.ClassDef.name, Store)) 1499c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1500c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 1501c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1502c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1503c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 1504c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_ifexp(struct compiler *c, expr_ty e) 1505c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 1506c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel basicblock *end, *next; 1507c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1508c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(e->kind == IfExp_kind); 1509c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel end = compiler_new_block(c); 1510c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (end == NULL) 1511c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1512c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel next = compiler_new_block(c); 1513c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (next == NULL) 1514c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1515c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, e->v.IfExp.test); 1516c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_JABS(c, POP_JUMP_IF_FALSE, next); 1517c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, e->v.IfExp.body); 1518c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_JREL(c, JUMP_FORWARD, end); 1519c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_use_next_block(c, next); 1520c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, e->v.IfExp.orelse); 1521c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_use_next_block(c, end); 1522c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 1523c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1524c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1525c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 1526c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_lambda(struct compiler *c, expr_ty e) 1527c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 1528c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyCodeObject *co; 1529c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel static identifier name; 1530c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel arguments_ty args = e->v.Lambda.args; 1531c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(e->kind == Lambda_kind); 1532c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1533c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!name) { 1534c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel name = PyString_InternFromString("<lambda>"); 1535c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!name) 1536c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1537c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1538c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1539c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (args->defaults) 1540c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT_SEQ(c, expr, args->defaults); 1541c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_enter_scope(c, name, (void *)e, e->lineno)) 1542c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1543c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1544c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* unpack nested arguments */ 1545c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_arguments(c, args); 1546c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1547c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Make None the first constant, so the lambda can't have a 1548c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel docstring. */ 1549c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (compiler_add_o(c, c->u->u_consts, Py_None) < 0) 1550c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1551c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1552c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c->u->u_argcount = asdl_seq_LEN(args->args); 1553c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT_IN_SCOPE(c, expr, e->v.Lambda.body); 1554c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (c->u->u_ste->ste_generator) { 1555c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_IN_SCOPE(c, POP_TOP); 1556c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1557c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else { 1558c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_IN_SCOPE(c, RETURN_VALUE); 1559c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1560c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel co = assemble(c, 1); 1561c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_exit_scope(c); 1562c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (co == NULL) 1563c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1564c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1565c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_make_closure(c, co, asdl_seq_LEN(args->defaults)); 1566c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(co); 1567c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1568c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 1569c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1570c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1571c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 1572c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_print(struct compiler *c, stmt_ty s) 1573c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 1574c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int i, n; 1575c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel bool dest; 1576c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1577c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(s->kind == Print_kind); 1578c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel n = asdl_seq_LEN(s->v.Print.values); 1579c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel dest = false; 1580c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (s->v.Print.dest) { 1581c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, s->v.Print.dest); 1582c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel dest = true; 1583c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1584c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (i = 0; i < n; i++) { 1585c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel expr_ty e = (expr_ty)asdl_seq_GET(s->v.Print.values, i); 1586c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (dest) { 1587c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, DUP_TOP); 1588c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, e); 1589c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, ROT_TWO); 1590c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, PRINT_ITEM_TO); 1591c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1592c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else { 1593c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, e); 1594c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, PRINT_ITEM); 1595c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1596c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1597c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (s->v.Print.nl) { 1598c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (dest) 1599c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, PRINT_NEWLINE_TO) 1600c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else 1601c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, PRINT_NEWLINE) 1602c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1603c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else if (dest) 1604c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, POP_TOP); 1605c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 1606c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1607c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1608c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 1609c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_if(struct compiler *c, stmt_ty s) 1610c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 1611c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel basicblock *end, *next; 1612c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int constant; 1613c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(s->kind == If_kind); 1614c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel end = compiler_new_block(c); 1615c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (end == NULL) 1616c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1617c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1618c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel constant = expr_constant(s->v.If.test); 1619c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* constant = 0: "if 0" 1620c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel * constant = 1: "if 1", "if 2", ... 1621c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel * constant = -1: rest */ 1622c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (constant == 0) { 1623c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (s->v.If.orelse) 1624c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT_SEQ(c, stmt, s->v.If.orelse); 1625c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } else if (constant == 1) { 1626c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT_SEQ(c, stmt, s->v.If.body); 1627c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } else { 1628c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (s->v.If.orelse) { 1629c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel next = compiler_new_block(c); 1630c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (next == NULL) 1631c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1632c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1633c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else 1634c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel next = end; 1635c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, s->v.If.test); 1636c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_JABS(c, POP_JUMP_IF_FALSE, next); 1637c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT_SEQ(c, stmt, s->v.If.body); 1638c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_JREL(c, JUMP_FORWARD, end); 1639c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (s->v.If.orelse) { 1640c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_use_next_block(c, next); 1641c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT_SEQ(c, stmt, s->v.If.orelse); 1642c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1643c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1644c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_use_next_block(c, end); 1645c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 1646c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1647c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1648c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 1649c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_for(struct compiler *c, stmt_ty s) 1650c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 1651c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel basicblock *start, *cleanup, *end; 1652c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1653c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel start = compiler_new_block(c); 1654c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel cleanup = compiler_new_block(c); 1655c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel end = compiler_new_block(c); 1656c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (start == NULL || end == NULL || cleanup == NULL) 1657c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1658c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_JREL(c, SETUP_LOOP, end); 1659c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_push_fblock(c, LOOP, start)) 1660c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1661c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, s->v.For.iter); 1662c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, GET_ITER); 1663c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_use_next_block(c, start); 1664c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_JREL(c, FOR_ITER, cleanup); 1665c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, s->v.For.target); 1666c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT_SEQ(c, stmt, s->v.For.body); 1667c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_JABS(c, JUMP_ABSOLUTE, start); 1668c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_use_next_block(c, cleanup); 1669c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, POP_BLOCK); 1670c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_pop_fblock(c, LOOP, start); 1671c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT_SEQ(c, stmt, s->v.For.orelse); 1672c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_use_next_block(c, end); 1673c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 1674c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1675c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1676c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 1677c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_while(struct compiler *c, stmt_ty s) 1678c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 1679c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel basicblock *loop, *orelse, *end, *anchor = NULL; 1680c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int constant = expr_constant(s->v.While.test); 1681c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1682c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (constant == 0) { 1683c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (s->v.While.orelse) 1684c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT_SEQ(c, stmt, s->v.While.orelse); 1685c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 1686c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1687c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel loop = compiler_new_block(c); 1688c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel end = compiler_new_block(c); 1689c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (constant == -1) { 1690c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel anchor = compiler_new_block(c); 1691c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (anchor == NULL) 1692c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1693c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1694c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (loop == NULL || end == NULL) 1695c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1696c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (s->v.While.orelse) { 1697c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel orelse = compiler_new_block(c); 1698c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (orelse == NULL) 1699c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1700c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1701c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else 1702c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel orelse = NULL; 1703c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1704c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_JREL(c, SETUP_LOOP, end); 1705c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_use_next_block(c, loop); 1706c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_push_fblock(c, LOOP, loop)) 1707c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1708c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (constant == -1) { 1709c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, s->v.While.test); 1710c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_JABS(c, POP_JUMP_IF_FALSE, anchor); 1711c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1712c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT_SEQ(c, stmt, s->v.While.body); 1713c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_JABS(c, JUMP_ABSOLUTE, loop); 1714c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1715c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* XXX should the two POP instructions be in a separate block 1716c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if there is no else clause ? 1717c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel */ 1718c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1719c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (constant == -1) 1720c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_use_next_block(c, anchor); 1721c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, POP_BLOCK); 1722c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_pop_fblock(c, LOOP, loop); 1723c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (orelse != NULL) /* what if orelse is just pass? */ 1724c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT_SEQ(c, stmt, s->v.While.orelse); 1725c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_use_next_block(c, end); 1726c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1727c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 1728c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1729c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1730c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 1731c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_continue(struct compiler *c) 1732c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 1733c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel static const char LOOP_ERROR_MSG[] = "'continue' not properly in loop"; 1734c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel static const char IN_FINALLY_ERROR_MSG[] = 1735c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "'continue' not supported inside 'finally' clause"; 1736c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int i; 1737c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1738c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!c->u->u_nfblocks) 1739c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_error(c, LOOP_ERROR_MSG); 1740c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel i = c->u->u_nfblocks - 1; 1741c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel switch (c->u->u_fblock[i].fb_type) { 1742c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case LOOP: 1743c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_JABS(c, JUMP_ABSOLUTE, c->u->u_fblock[i].fb_block); 1744c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 1745c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case EXCEPT: 1746c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case FINALLY_TRY: 1747c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel while (--i >= 0 && c->u->u_fblock[i].fb_type != LOOP) { 1748c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Prevent continue anywhere under a finally 1749c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel even if hidden in a sub-try or except. */ 1750c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (c->u->u_fblock[i].fb_type == FINALLY_END) 1751c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_error(c, IN_FINALLY_ERROR_MSG); 1752c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1753c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (i == -1) 1754c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_error(c, LOOP_ERROR_MSG); 1755c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_JABS(c, CONTINUE_LOOP, c->u->u_fblock[i].fb_block); 1756c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 1757c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case FINALLY_END: 1758c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_error(c, IN_FINALLY_ERROR_MSG); 1759c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1760c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1761c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 1762c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1763c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1764c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* Code generated for "try: <body> finally: <finalbody>" is as follows: 1765c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1766c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel SETUP_FINALLY L 1767c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel <code for body> 1768c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel POP_BLOCK 1769c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel LOAD_CONST <None> 1770c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel L: <code for finalbody> 1771c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel END_FINALLY 1772c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1773c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel The special instructions use the block stack. Each block 1774c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel stack entry contains the instruction that created it (here 1775c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel SETUP_FINALLY), the level of the value stack at the time the 1776c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel block stack entry was created, and a label (here L). 1777c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1778c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel SETUP_FINALLY: 1779c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Pushes the current value stack level and the label 1780c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel onto the block stack. 1781c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel POP_BLOCK: 1782c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Pops en entry from the block stack, and pops the value 1783c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel stack until its level is the same as indicated on the 1784c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel block stack. (The label is ignored.) 1785c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel END_FINALLY: 1786c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Pops a variable number of entries from the *value* stack 1787c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel and re-raises the exception they specify. The number of 1788c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel entries popped depends on the (pseudo) exception type. 1789c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1790c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel The block stack is unwound when an exception is raised: 1791c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel when a SETUP_FINALLY entry is found, the exception is pushed 1792c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel onto the value stack (and the exception condition is cleared), 1793c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel and the interpreter jumps to the label gotten from the block 1794c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel stack. 1795c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel*/ 1796c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1797c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 1798c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_try_finally(struct compiler *c, stmt_ty s) 1799c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 1800c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel basicblock *body, *end; 1801c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel body = compiler_new_block(c); 1802c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel end = compiler_new_block(c); 1803c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (body == NULL || end == NULL) 1804c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1805c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1806c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_JREL(c, SETUP_FINALLY, end); 1807c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_use_next_block(c, body); 1808c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_push_fblock(c, FINALLY_TRY, body)) 1809c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1810c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT_SEQ(c, stmt, s->v.TryFinally.body); 1811c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, POP_BLOCK); 1812c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_pop_fblock(c, FINALLY_TRY, body); 1813c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1814c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_O(c, LOAD_CONST, Py_None, consts); 1815c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_use_next_block(c, end); 1816c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_push_fblock(c, FINALLY_END, end)) 1817c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1818c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT_SEQ(c, stmt, s->v.TryFinally.finalbody); 1819c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, END_FINALLY); 1820c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_pop_fblock(c, FINALLY_END, end); 1821c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1822c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 1823c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1824c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1825c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* 1826c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Code generated for "try: S except E1, V1: S1 except E2, V2: S2 ...": 1827c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel (The contents of the value stack is shown in [], with the top 1828c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel at the right; 'tb' is trace-back info, 'val' the exception's 1829c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel associated value, and 'exc' the exception.) 1830c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1831c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Value stack Label Instruction Argument 1832c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel [] SETUP_EXCEPT L1 1833c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel [] <code for S> 1834c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel [] POP_BLOCK 1835c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel [] JUMP_FORWARD L0 1836c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1837c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel [tb, val, exc] L1: DUP ) 1838c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel [tb, val, exc, exc] <evaluate E1> ) 1839c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel [tb, val, exc, exc, E1] COMPARE_OP EXC_MATCH ) only if E1 1840c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel [tb, val, exc, 1-or-0] POP_JUMP_IF_FALSE L2 ) 1841c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel [tb, val, exc] POP 1842c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel [tb, val] <assign to V1> (or POP if no V1) 1843c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel [tb] POP 1844c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel [] <code for S1> 1845c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel JUMP_FORWARD L0 1846c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1847c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel [tb, val, exc] L2: DUP 1848c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel .............................etc....................... 1849c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1850c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel [tb, val, exc] Ln+1: END_FINALLY # re-raise exception 1851c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1852c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel [] L0: <next statement> 1853c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1854c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Of course, parts are not generated if Vi or Ei is not present. 1855c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel*/ 1856c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 1857c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_try_except(struct compiler *c, stmt_ty s) 1858c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 1859c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel basicblock *body, *orelse, *except, *end; 1860c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int i, n; 1861c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1862c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel body = compiler_new_block(c); 1863c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel except = compiler_new_block(c); 1864c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel orelse = compiler_new_block(c); 1865c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel end = compiler_new_block(c); 1866c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (body == NULL || except == NULL || orelse == NULL || end == NULL) 1867c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1868c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_JREL(c, SETUP_EXCEPT, except); 1869c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_use_next_block(c, body); 1870c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_push_fblock(c, EXCEPT, body)) 1871c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1872c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT_SEQ(c, stmt, s->v.TryExcept.body); 1873c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, POP_BLOCK); 1874c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_pop_fblock(c, EXCEPT, body); 1875c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_JREL(c, JUMP_FORWARD, orelse); 1876c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel n = asdl_seq_LEN(s->v.TryExcept.handlers); 1877c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_use_next_block(c, except); 1878c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (i = 0; i < n; i++) { 1879c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET( 1880c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel s->v.TryExcept.handlers, i); 1881c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!handler->v.ExceptHandler.type && i < n-1) 1882c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_error(c, "default 'except:' must be last"); 1883c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c->u->u_lineno_set = false; 1884c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c->u->u_lineno = handler->lineno; 1885c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel except = compiler_new_block(c); 1886c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (except == NULL) 1887c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1888c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (handler->v.ExceptHandler.type) { 1889c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, DUP_TOP); 1890c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, handler->v.ExceptHandler.type); 1891c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_I(c, COMPARE_OP, PyCmp_EXC_MATCH); 1892c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_JABS(c, POP_JUMP_IF_FALSE, except); 1893c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1894c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, POP_TOP); 1895c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (handler->v.ExceptHandler.name) { 1896c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, handler->v.ExceptHandler.name); 1897c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1898c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else { 1899c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, POP_TOP); 1900c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1901c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, POP_TOP); 1902c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body); 1903c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_JREL(c, JUMP_FORWARD, end); 1904c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_use_next_block(c, except); 1905c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1906c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, END_FINALLY); 1907c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_use_next_block(c, orelse); 1908c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT_SEQ(c, stmt, s->v.TryExcept.orelse); 1909c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_use_next_block(c, end); 1910c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 1911c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1912c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1913c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 1914c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_import_as(struct compiler *c, identifier name, identifier asname) 1915c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 1916c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* The IMPORT_NAME opcode was already generated. This function 1917c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel merely needs to bind the result to a name. 1918c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1919c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel If there is a dot in name, we need to split it and emit a 1920c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel LOAD_ATTR for each name. 1921c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel */ 1922c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel const char *src = PyString_AS_STRING(name); 1923c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel const char *dot = strchr(src, '.'); 1924c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (dot) { 1925c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Consume the base module name to get the first attribute */ 1926c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel src = dot + 1; 1927c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel while (dot) { 1928c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* NB src is only defined when dot != NULL */ 1929c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *attr; 1930c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel dot = strchr(src, '.'); 1931c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel attr = PyString_FromStringAndSize(src, 1932c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel dot ? dot - src : strlen(src)); 1933c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!attr) 1934c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 1935c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_O(c, LOAD_ATTR, attr, names); 1936c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(attr); 1937c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel src = dot + 1; 1938c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1939c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1940c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_nameop(c, asname, Store); 1941c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1942c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1943c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 1944c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_import(struct compiler *c, stmt_ty s) 1945c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 1946c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* The Import node stores a module name like a.b.c as a single 1947c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel string. This is convenient for all cases except 1948c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel import a.b.c as d 1949c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel where we need to parse that string to extract the individual 1950c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel module names. 1951c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel XXX Perhaps change the representation to make this case simpler? 1952c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel */ 1953c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int i, n = asdl_seq_LEN(s->v.Import.names); 1954c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1955c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (i = 0; i < n; i++) { 1956c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel alias_ty alias = (alias_ty)asdl_seq_GET(s->v.Import.names, i); 1957c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int r; 1958c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *level; 1959c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1960c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (c->c_flags && (c->c_flags->cf_flags & CO_FUTURE_ABSOLUTE_IMPORT)) 1961c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel level = PyInt_FromLong(0); 1962c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else 1963c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel level = PyInt_FromLong(-1); 1964c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1965c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (level == NULL) 1966c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 1967c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1968c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_O(c, LOAD_CONST, level, consts); 1969c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(level); 1970c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_O(c, LOAD_CONST, Py_None, consts); 1971c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_NAME(c, IMPORT_NAME, alias->name, names); 1972c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1973c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (alias->asname) { 1974c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel r = compiler_import_as(c, alias->name, alias->asname); 1975c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!r) 1976c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return r; 1977c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1978c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else { 1979c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel identifier tmp = alias->name; 1980c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel const char *base = PyString_AS_STRING(alias->name); 1981c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel char *dot = strchr(base, '.'); 1982c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (dot) 1983c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel tmp = PyString_FromStringAndSize(base, 1984c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel dot - base); 1985c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel r = compiler_nameop(c, tmp, Store); 1986c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (dot) { 1987c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(tmp); 1988c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1989c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!r) 1990c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return r; 1991c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1992c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 1993c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 1994c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 1995c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 1996c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 1997c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_from_import(struct compiler *c, stmt_ty s) 1998c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 1999c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int i, n = asdl_seq_LEN(s->v.ImportFrom.names); 2000c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2001c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *names = PyTuple_New(n); 2002c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *level; 2003c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel static PyObject *empty_string; 2004c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2005c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!empty_string) { 2006c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel empty_string = PyString_FromString(""); 2007c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!empty_string) 2008c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 2009c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2010c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2011c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!names) 2012c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 2013c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2014c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (s->v.ImportFrom.level == 0 && c->c_flags && 2015c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel !(c->c_flags->cf_flags & CO_FUTURE_ABSOLUTE_IMPORT)) 2016c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel level = PyInt_FromLong(-1); 2017c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else 2018c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel level = PyInt_FromLong(s->v.ImportFrom.level); 2019c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2020c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!level) { 2021c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(names); 2022c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 2023c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2024c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2025c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* build up the names */ 2026c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (i = 0; i < n; i++) { 2027c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i); 2028c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_INCREF(alias->name); 2029c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyTuple_SET_ITEM(names, i, alias->name); 2030c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2031c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2032c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (s->lineno > c->c_future->ff_lineno && s->v.ImportFrom.module && 2033c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel !strcmp(PyString_AS_STRING(s->v.ImportFrom.module), "__future__")) { 2034c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(level); 2035c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(names); 2036c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_error(c, "from __future__ imports must occur " 2037c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "at the beginning of the file"); 2038c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2039c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2040c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_O(c, LOAD_CONST, level, consts); 2041c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(level); 2042c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_O(c, LOAD_CONST, names, consts); 2043c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(names); 2044c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (s->v.ImportFrom.module) { 2045c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_NAME(c, IMPORT_NAME, s->v.ImportFrom.module, names); 2046c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2047c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else { 2048c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_NAME(c, IMPORT_NAME, empty_string, names); 2049c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2050c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (i = 0; i < n; i++) { 2051c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i); 2052c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel identifier store_name; 2053c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2054c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (i == 0 && *PyString_AS_STRING(alias->name) == '*') { 2055c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(n == 1); 2056c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, IMPORT_STAR); 2057c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 2058c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2059c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2060c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_NAME(c, IMPORT_FROM, alias->name, names); 2061c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel store_name = alias->name; 2062c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (alias->asname) 2063c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel store_name = alias->asname; 2064c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2065c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_nameop(c, store_name, Store)) { 2066c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(names); 2067c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 2068c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2069c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2070c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* remove imported module */ 2071c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, POP_TOP); 2072c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 2073c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 2074c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2075c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 2076c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_assert(struct compiler *c, stmt_ty s) 2077c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 2078c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel static PyObject *assertion_error = NULL; 2079c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel basicblock *end; 2080c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2081c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (Py_OptimizeFlag) 2082c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 2083c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (assertion_error == NULL) { 2084c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assertion_error = PyString_InternFromString("AssertionError"); 2085c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (assertion_error == NULL) 2086c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 2087c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2088c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (s->v.Assert.test->kind == Tuple_kind && 2089c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel asdl_seq_LEN(s->v.Assert.test->v.Tuple.elts) > 0) { 2090c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel const char* msg = 2091c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "assertion is always true, perhaps remove parentheses?"; 2092c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (PyErr_WarnExplicit(PyExc_SyntaxWarning, msg, c->c_filename, 2093c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c->u->u_lineno, NULL, NULL) == -1) 2094c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 2095c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2096c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, s->v.Assert.test); 2097c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel end = compiler_new_block(c); 2098c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (end == NULL) 2099c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 2100c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_JABS(c, POP_JUMP_IF_TRUE, end); 2101c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_O(c, LOAD_GLOBAL, assertion_error, names); 2102c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (s->v.Assert.msg) { 2103c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, s->v.Assert.msg); 2104c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_I(c, CALL_FUNCTION, 1); 2105c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2106c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_I(c, RAISE_VARARGS, 1); 2107c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_use_next_block(c, end); 2108c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 2109c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 2110c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2111c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 2112c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_visit_stmt(struct compiler *c, stmt_ty s) 2113c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 2114c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int i, n; 2115c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2116c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Always assign a lineno to the next instruction for a stmt. */ 2117c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c->u->u_lineno = s->lineno; 2118c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c->u->u_lineno_set = false; 2119c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2120c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel switch (s->kind) { 2121c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case FunctionDef_kind: 2122c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_function(c, s); 2123c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case ClassDef_kind: 2124c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_class(c, s); 2125c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Return_kind: 2126c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (c->u->u_ste->ste_type != FunctionBlock) 2127c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_error(c, "'return' outside function"); 2128c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (s->v.Return.value) { 2129c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, s->v.Return.value); 2130c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2131c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else 2132c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_O(c, LOAD_CONST, Py_None, consts); 2133c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, RETURN_VALUE); 2134c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 2135c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Delete_kind: 2136c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT_SEQ(c, expr, s->v.Delete.targets) 2137c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 2138c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Assign_kind: 2139c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel n = asdl_seq_LEN(s->v.Assign.targets); 2140c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, s->v.Assign.value); 2141c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (i = 0; i < n; i++) { 2142c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (i < n - 1) 2143c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, DUP_TOP); 2144c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, 2145c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel (expr_ty)asdl_seq_GET(s->v.Assign.targets, i)); 2146c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2147c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 2148c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case AugAssign_kind: 2149c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_augassign(c, s); 2150c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Print_kind: 2151c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_print(c, s); 2152c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case For_kind: 2153c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_for(c, s); 2154c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case While_kind: 2155c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_while(c, s); 2156c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case If_kind: 2157c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_if(c, s); 2158c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Raise_kind: 2159c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel n = 0; 2160c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (s->v.Raise.type) { 2161c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, s->v.Raise.type); 2162c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel n++; 2163c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (s->v.Raise.inst) { 2164c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, s->v.Raise.inst); 2165c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel n++; 2166c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (s->v.Raise.tback) { 2167c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, s->v.Raise.tback); 2168c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel n++; 2169c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2170c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2171c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2172c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_I(c, RAISE_VARARGS, n); 2173c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 2174c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case TryExcept_kind: 2175c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_try_except(c, s); 2176c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case TryFinally_kind: 2177c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_try_finally(c, s); 2178c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Assert_kind: 2179c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_assert(c, s); 2180c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Import_kind: 2181c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_import(c, s); 2182c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case ImportFrom_kind: 2183c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_from_import(c, s); 2184c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Exec_kind: 2185c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, s->v.Exec.body); 2186c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (s->v.Exec.globals) { 2187c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, s->v.Exec.globals); 2188c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (s->v.Exec.locals) { 2189c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, s->v.Exec.locals); 2190c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } else { 2191c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, DUP_TOP); 2192c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2193c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } else { 2194c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_O(c, LOAD_CONST, Py_None, consts); 2195c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, DUP_TOP); 2196c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2197c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, EXEC_STMT); 2198c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 2199c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Global_kind: 2200c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 2201c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Expr_kind: 2202c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (c->c_interactive && c->c_nestlevel <= 1) { 2203c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, s->v.Expr.value); 2204c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, PRINT_EXPR); 2205c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2206c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else if (s->v.Expr.value->kind != Str_kind && 2207c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel s->v.Expr.value->kind != Num_kind) { 2208c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, s->v.Expr.value); 2209c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, POP_TOP); 2210c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2211c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 2212c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Pass_kind: 2213c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 2214c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Break_kind: 2215c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_in_loop(c)) 2216c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_error(c, "'break' outside loop"); 2217c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, BREAK_LOOP); 2218c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 2219c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Continue_kind: 2220c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_continue(c); 2221c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case With_kind: 2222c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_with(c, s); 2223c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2224c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 2225c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 2226c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2227c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 2228c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielunaryop(unaryop_ty op) 2229c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 2230c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel switch (op) { 2231c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Invert: 2232c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return UNARY_INVERT; 2233c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Not: 2234c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return UNARY_NOT; 2235c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case UAdd: 2236c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return UNARY_POSITIVE; 2237c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case USub: 2238c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return UNARY_NEGATIVE; 2239c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel default: 2240c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_Format(PyExc_SystemError, 2241c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "unary op %d should not be possible", op); 2242c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 2243c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2244c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 2245c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2246c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 2247c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielbinop(struct compiler *c, operator_ty op) 2248c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 2249c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel switch (op) { 2250c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Add: 2251c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return BINARY_ADD; 2252c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Sub: 2253c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return BINARY_SUBTRACT; 2254c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Mult: 2255c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return BINARY_MULTIPLY; 2256c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Div: 2257c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (c->c_flags && c->c_flags->cf_flags & CO_FUTURE_DIVISION) 2258c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return BINARY_TRUE_DIVIDE; 2259c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else 2260c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return BINARY_DIVIDE; 2261c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Mod: 2262c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return BINARY_MODULO; 2263c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Pow: 2264c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return BINARY_POWER; 2265c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case LShift: 2266c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return BINARY_LSHIFT; 2267c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case RShift: 2268c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return BINARY_RSHIFT; 2269c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case BitOr: 2270c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return BINARY_OR; 2271c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case BitXor: 2272c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return BINARY_XOR; 2273c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case BitAnd: 2274c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return BINARY_AND; 2275c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case FloorDiv: 2276c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return BINARY_FLOOR_DIVIDE; 2277c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel default: 2278c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_Format(PyExc_SystemError, 2279c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "binary op %d should not be possible", op); 2280c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 2281c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2282c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 2283c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2284c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 2285c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcmpop(cmpop_ty op) 2286c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 2287c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel switch (op) { 2288c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Eq: 2289c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return PyCmp_EQ; 2290c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case NotEq: 2291c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return PyCmp_NE; 2292c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Lt: 2293c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return PyCmp_LT; 2294c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case LtE: 2295c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return PyCmp_LE; 2296c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Gt: 2297c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return PyCmp_GT; 2298c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case GtE: 2299c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return PyCmp_GE; 2300c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Is: 2301c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return PyCmp_IS; 2302c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case IsNot: 2303c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return PyCmp_IS_NOT; 2304c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case In: 2305c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return PyCmp_IN; 2306c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case NotIn: 2307c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return PyCmp_NOT_IN; 2308c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel default: 2309c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return PyCmp_BAD; 2310c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2311c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 2312c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2313c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 2314c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielinplace_binop(struct compiler *c, operator_ty op) 2315c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 2316c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel switch (op) { 2317c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Add: 2318c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return INPLACE_ADD; 2319c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Sub: 2320c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return INPLACE_SUBTRACT; 2321c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Mult: 2322c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return INPLACE_MULTIPLY; 2323c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Div: 2324c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (c->c_flags && c->c_flags->cf_flags & CO_FUTURE_DIVISION) 2325c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return INPLACE_TRUE_DIVIDE; 2326c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else 2327c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return INPLACE_DIVIDE; 2328c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Mod: 2329c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return INPLACE_MODULO; 2330c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Pow: 2331c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return INPLACE_POWER; 2332c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case LShift: 2333c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return INPLACE_LSHIFT; 2334c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case RShift: 2335c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return INPLACE_RSHIFT; 2336c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case BitOr: 2337c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return INPLACE_OR; 2338c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case BitXor: 2339c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return INPLACE_XOR; 2340c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case BitAnd: 2341c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return INPLACE_AND; 2342c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case FloorDiv: 2343c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return INPLACE_FLOOR_DIVIDE; 2344c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel default: 2345c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_Format(PyExc_SystemError, 2346c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "inplace binary op %d should not be possible", op); 2347c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 2348c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2349c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 2350c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2351c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 2352c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) 2353c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 2354c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int op, scope, arg; 2355c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel enum { OP_FAST, OP_GLOBAL, OP_DEREF, OP_NAME } optype; 2356c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2357c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *dict = c->u->u_names; 2358c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *mangled; 2359c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* XXX AugStore isn't used anywhere! */ 2360c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2361c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel mangled = _Py_Mangle(c->u->u_private, name); 2362c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!mangled) 2363c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 2364c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2365c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel op = 0; 2366c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel optype = OP_NAME; 2367c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel scope = PyST_GetScope(c->u->u_ste, mangled); 2368c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel switch (scope) { 2369c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case FREE: 2370c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel dict = c->u->u_freevars; 2371c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel optype = OP_DEREF; 2372c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 2373c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case CELL: 2374c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel dict = c->u->u_cellvars; 2375c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel optype = OP_DEREF; 2376c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 2377c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case LOCAL: 2378c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (c->u->u_ste->ste_type == FunctionBlock) 2379c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel optype = OP_FAST; 2380c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 2381c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case GLOBAL_IMPLICIT: 2382c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (c->u->u_ste->ste_type == FunctionBlock && 2383c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel !c->u->u_ste->ste_unoptimized) 2384c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel optype = OP_GLOBAL; 2385c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 2386c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case GLOBAL_EXPLICIT: 2387c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel optype = OP_GLOBAL; 2388c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 2389c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel default: 2390c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* scope can be 0 */ 2391c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 2392c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2393c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2394c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* XXX Leave assert here, but handle __doc__ and the like better */ 2395c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(scope || PyString_AS_STRING(name)[0] == '_'); 2396c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2397c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel switch (optype) { 2398c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case OP_DEREF: 2399c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel switch (ctx) { 2400c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Load: op = LOAD_DEREF; break; 2401c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Store: op = STORE_DEREF; break; 2402c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case AugLoad: 2403c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case AugStore: 2404c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 2405c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Del: 2406c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_Format(PyExc_SyntaxError, 2407c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "can not delete variable '%s' referenced " 2408c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "in nested scope", 2409c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyString_AS_STRING(name)); 2410c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(mangled); 2411c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 2412c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Param: 2413c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel default: 2414c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_SetString(PyExc_SystemError, 2415c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "param invalid for deref variable"); 2416c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 2417c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2418c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 2419c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case OP_FAST: 2420c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel switch (ctx) { 2421c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Load: op = LOAD_FAST; break; 2422c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Store: op = STORE_FAST; break; 2423c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Del: op = DELETE_FAST; break; 2424c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case AugLoad: 2425c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case AugStore: 2426c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 2427c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Param: 2428c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel default: 2429c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_SetString(PyExc_SystemError, 2430c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "param invalid for local variable"); 2431c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 2432c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2433c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_O(c, op, mangled, varnames); 2434c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(mangled); 2435c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 2436c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case OP_GLOBAL: 2437c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel switch (ctx) { 2438c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Load: op = LOAD_GLOBAL; break; 2439c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Store: op = STORE_GLOBAL; break; 2440c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Del: op = DELETE_GLOBAL; break; 2441c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case AugLoad: 2442c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case AugStore: 2443c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 2444c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Param: 2445c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel default: 2446c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_SetString(PyExc_SystemError, 2447c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "param invalid for global variable"); 2448c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 2449c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2450c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 2451c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case OP_NAME: 2452c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel switch (ctx) { 2453c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Load: op = LOAD_NAME; break; 2454c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Store: op = STORE_NAME; break; 2455c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Del: op = DELETE_NAME; break; 2456c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case AugLoad: 2457c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case AugStore: 2458c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 2459c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Param: 2460c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel default: 2461c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_SetString(PyExc_SystemError, 2462c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "param invalid for name variable"); 2463c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 2464c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2465c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 2466c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2467c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2468c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(op); 2469c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel arg = compiler_add_o(c, dict, mangled); 2470c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(mangled); 2471c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (arg < 0) 2472c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 2473c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_addop_i(c, op, arg); 2474c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 2475c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2476c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 2477c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_boolop(struct compiler *c, expr_ty e) 2478c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 2479c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel basicblock *end; 2480c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int jumpi, i, n; 2481c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel asdl_seq *s; 2482c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2483c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(e->kind == BoolOp_kind); 2484c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (e->v.BoolOp.op == And) 2485c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel jumpi = JUMP_IF_FALSE_OR_POP; 2486c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else 2487c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel jumpi = JUMP_IF_TRUE_OR_POP; 2488c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel end = compiler_new_block(c); 2489c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (end == NULL) 2490c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 2491c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel s = e->v.BoolOp.values; 2492c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel n = asdl_seq_LEN(s) - 1; 2493c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(n >= 0); 2494c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (i = 0; i < n; ++i) { 2495c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, (expr_ty)asdl_seq_GET(s, i)); 2496c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_JABS(c, jumpi, end); 2497c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2498c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, (expr_ty)asdl_seq_GET(s, n)); 2499c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_use_next_block(c, end); 2500c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 2501c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 2502c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2503c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 2504c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_list(struct compiler *c, expr_ty e) 2505c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 2506c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int n = asdl_seq_LEN(e->v.List.elts); 2507c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (e->v.List.ctx == Store) { 2508c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_I(c, UNPACK_SEQUENCE, n); 2509c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2510c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT_SEQ(c, expr, e->v.List.elts); 2511c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (e->v.List.ctx == Load) { 2512c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_I(c, BUILD_LIST, n); 2513c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2514c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 2515c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 2516c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2517c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 2518c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_tuple(struct compiler *c, expr_ty e) 2519c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 2520c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int n = asdl_seq_LEN(e->v.Tuple.elts); 2521c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (e->v.Tuple.ctx == Store) { 2522c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_I(c, UNPACK_SEQUENCE, n); 2523c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2524c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT_SEQ(c, expr, e->v.Tuple.elts); 2525c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (e->v.Tuple.ctx == Load) { 2526c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_I(c, BUILD_TUPLE, n); 2527c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2528c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 2529c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 2530c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2531c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 2532c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_compare(struct compiler *c, expr_ty e) 2533c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 2534c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int i, n; 2535c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel basicblock *cleanup = NULL; 2536c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2537c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* XXX the logic can be cleaned up for 1 or multiple comparisons */ 2538c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, e->v.Compare.left); 2539c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel n = asdl_seq_LEN(e->v.Compare.ops); 2540c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(n > 0); 2541c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (n > 1) { 2542c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel cleanup = compiler_new_block(c); 2543c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (cleanup == NULL) 2544c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 2545c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, 2546c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel (expr_ty)asdl_seq_GET(e->v.Compare.comparators, 0)); 2547c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2548c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (i = 1; i < n; i++) { 2549c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, DUP_TOP); 2550c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, ROT_THREE); 2551c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_I(c, COMPARE_OP, 2552c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel cmpop((cmpop_ty)(asdl_seq_GET( 2553c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel e->v.Compare.ops, i - 1)))); 2554c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_JABS(c, JUMP_IF_FALSE_OR_POP, cleanup); 2555c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel NEXT_BLOCK(c); 2556c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (i < (n - 1)) 2557c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, 2558c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i)); 2559c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2560c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n - 1)); 2561c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_I(c, COMPARE_OP, 2562c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel cmpop((cmpop_ty)(asdl_seq_GET(e->v.Compare.ops, n - 1)))); 2563c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (n > 1) { 2564c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel basicblock *end = compiler_new_block(c); 2565c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (end == NULL) 2566c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 2567c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_JREL(c, JUMP_FORWARD, end); 2568c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_use_next_block(c, cleanup); 2569c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, ROT_TWO); 2570c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, POP_TOP); 2571c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_use_next_block(c, end); 2572c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2573c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 2574c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 2575c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2576c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 2577c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_call(struct compiler *c, expr_ty e) 2578c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 2579c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int n, code = 0; 2580c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2581c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, e->v.Call.func); 2582c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel n = asdl_seq_LEN(e->v.Call.args); 2583c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT_SEQ(c, expr, e->v.Call.args); 2584c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (e->v.Call.keywords) { 2585c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT_SEQ(c, keyword, e->v.Call.keywords); 2586c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel n |= asdl_seq_LEN(e->v.Call.keywords) << 8; 2587c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2588c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (e->v.Call.starargs) { 2589c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, e->v.Call.starargs); 2590c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel code |= 1; 2591c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2592c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (e->v.Call.kwargs) { 2593c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, e->v.Call.kwargs); 2594c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel code |= 2; 2595c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2596c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel switch (code) { 2597c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case 0: 2598c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_I(c, CALL_FUNCTION, n); 2599c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 2600c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case 1: 2601c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_I(c, CALL_FUNCTION_VAR, n); 2602c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 2603c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case 2: 2604c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_I(c, CALL_FUNCTION_KW, n); 2605c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 2606c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case 3: 2607c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_I(c, CALL_FUNCTION_VAR_KW, n); 2608c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 2609c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2610c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 2611c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 2612c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2613c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 2614c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_listcomp_generator(struct compiler *c, asdl_seq *generators, 2615c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int gen_index, expr_ty elt) 2616c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 2617c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* generate code for the iterator, then each of the ifs, 2618c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel and then write to the element */ 2619c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2620c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel comprehension_ty l; 2621c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel basicblock *start, *anchor, *skip, *if_cleanup; 2622c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int i, n; 2623c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2624c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel start = compiler_new_block(c); 2625c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel skip = compiler_new_block(c); 2626c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if_cleanup = compiler_new_block(c); 2627c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel anchor = compiler_new_block(c); 2628c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2629c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (start == NULL || skip == NULL || if_cleanup == NULL || 2630c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel anchor == NULL) 2631c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 2632c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2633c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel l = (comprehension_ty)asdl_seq_GET(generators, gen_index); 2634c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, l->iter); 2635c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, GET_ITER); 2636c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_use_next_block(c, start); 2637c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_JREL(c, FOR_ITER, anchor); 2638c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel NEXT_BLOCK(c); 2639c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, l->target); 2640c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2641c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* XXX this needs to be cleaned up...a lot! */ 2642c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel n = asdl_seq_LEN(l->ifs); 2643c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (i = 0; i < n; i++) { 2644c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel expr_ty e = (expr_ty)asdl_seq_GET(l->ifs, i); 2645c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, e); 2646c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_JABS(c, POP_JUMP_IF_FALSE, if_cleanup); 2647c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel NEXT_BLOCK(c); 2648c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2649c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2650c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (++gen_index < asdl_seq_LEN(generators)) 2651c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_listcomp_generator(c, generators, gen_index, elt)) 2652c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 2653c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2654c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* only append after the last for generator */ 2655c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (gen_index >= asdl_seq_LEN(generators)) { 2656c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, elt); 2657c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_I(c, LIST_APPEND, gen_index+1); 2658c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2659c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_use_next_block(c, skip); 2660c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2661c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_use_next_block(c, if_cleanup); 2662c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_JABS(c, JUMP_ABSOLUTE, start); 2663c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_use_next_block(c, anchor); 2664c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2665c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 2666c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 2667c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2668c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 2669c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_listcomp(struct compiler *c, expr_ty e) 2670c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 2671c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(e->kind == ListComp_kind); 2672c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_I(c, BUILD_LIST, 0); 2673c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_listcomp_generator(c, e->v.ListComp.generators, 0, 2674c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel e->v.ListComp.elt); 2675c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 2676c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2677c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* Dict and set comprehensions and generator expressions work by creating a 2678c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel nested function to perform the actual iteration. This means that the 2679c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel iteration variables don't leak into the current scope. 2680c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel The defined function is called immediately following its definition, with the 2681c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel result of that call being the result of the expression. 2682c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel The LC/SC version returns the populated container, while the GE version is 2683c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel flagged in symtable.c as a generator, so it returns the generator object 2684c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel when the function is called. 2685c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel This code *knows* that the loop cannot contain break, continue, or return, 2686c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel so it cheats and skips the SETUP_LOOP/POP_BLOCK steps used in normal loops. 2687c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2688c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Possible cleanups: 2689c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel - iterate over the generator sequence instead of using recursion 2690c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel*/ 2691c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2692c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 2693c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_comprehension_generator(struct compiler *c, 2694c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel asdl_seq *generators, int gen_index, 2695c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel expr_ty elt, expr_ty val, int type) 2696c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 2697c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* generate code for the iterator, then each of the ifs, 2698c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel and then write to the element */ 2699c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2700c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel comprehension_ty gen; 2701c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel basicblock *start, *anchor, *skip, *if_cleanup; 2702c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int i, n; 2703c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2704c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel start = compiler_new_block(c); 2705c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel skip = compiler_new_block(c); 2706c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if_cleanup = compiler_new_block(c); 2707c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel anchor = compiler_new_block(c); 2708c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2709c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (start == NULL || skip == NULL || if_cleanup == NULL || 2710c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel anchor == NULL) 2711c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 2712c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2713c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel gen = (comprehension_ty)asdl_seq_GET(generators, gen_index); 2714c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2715c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (gen_index == 0) { 2716c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Receive outermost iter as an implicit argument */ 2717c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c->u->u_argcount = 1; 2718c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_I(c, LOAD_FAST, 0); 2719c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2720c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else { 2721c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Sub-iter - calculate on the fly */ 2722c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, gen->iter); 2723c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, GET_ITER); 2724c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2725c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_use_next_block(c, start); 2726c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_JREL(c, FOR_ITER, anchor); 2727c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel NEXT_BLOCK(c); 2728c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, gen->target); 2729c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2730c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* XXX this needs to be cleaned up...a lot! */ 2731c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel n = asdl_seq_LEN(gen->ifs); 2732c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (i = 0; i < n; i++) { 2733c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel expr_ty e = (expr_ty)asdl_seq_GET(gen->ifs, i); 2734c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, e); 2735c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_JABS(c, POP_JUMP_IF_FALSE, if_cleanup); 2736c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel NEXT_BLOCK(c); 2737c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2738c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2739c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (++gen_index < asdl_seq_LEN(generators)) 2740c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_comprehension_generator(c, 2741c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel generators, gen_index, 2742c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel elt, val, type)) 2743c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 2744c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2745c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* only append after the last for generator */ 2746c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (gen_index >= asdl_seq_LEN(generators)) { 2747c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* comprehension specific code */ 2748c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel switch (type) { 2749c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case COMP_GENEXP: 2750c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, elt); 2751c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, YIELD_VALUE); 2752c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, POP_TOP); 2753c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 2754c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case COMP_SETCOMP: 2755c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, elt); 2756c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_I(c, SET_ADD, gen_index + 1); 2757c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 2758c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case COMP_DICTCOMP: 2759c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* With 'd[k] = v', v is evaluated before k, so we do 2760c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel the same. */ 2761c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, val); 2762c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, elt); 2763c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_I(c, MAP_ADD, gen_index + 1); 2764c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 2765c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel default: 2766c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 2767c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2768c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2769c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_use_next_block(c, skip); 2770c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2771c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_use_next_block(c, if_cleanup); 2772c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_JABS(c, JUMP_ABSOLUTE, start); 2773c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_use_next_block(c, anchor); 2774c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2775c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 2776c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 2777c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2778c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 2779c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_comprehension(struct compiler *c, expr_ty e, int type, identifier name, 2780c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel asdl_seq *generators, expr_ty elt, expr_ty val) 2781c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 2782c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyCodeObject *co = NULL; 2783c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel expr_ty outermost_iter; 2784c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2785c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel outermost_iter = ((comprehension_ty) 2786c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel asdl_seq_GET(generators, 0))->iter; 2787c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2788c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_enter_scope(c, name, (void *)e, e->lineno)) 2789c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto error; 2790c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2791c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (type != COMP_GENEXP) { 2792c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int op; 2793c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel switch (type) { 2794c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case COMP_SETCOMP: 2795c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel op = BUILD_SET; 2796c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 2797c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case COMP_DICTCOMP: 2798c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel op = BUILD_MAP; 2799c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 2800c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel default: 2801c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_Format(PyExc_SystemError, 2802c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "unknown comprehension type %d", type); 2803c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto error_in_scope; 2804c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2805c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2806c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_I(c, op, 0); 2807c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2808c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2809c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_comprehension_generator(c, generators, 0, elt, 2810c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel val, type)) 2811c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto error_in_scope; 2812c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2813c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (type != COMP_GENEXP) { 2814c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, RETURN_VALUE); 2815c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2816c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2817c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel co = assemble(c, 1); 2818c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_exit_scope(c); 2819c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (co == NULL) 2820c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto error; 2821c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2822c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_make_closure(c, co, 0)) 2823c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto error; 2824c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(co); 2825c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2826c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, outermost_iter); 2827c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, GET_ITER); 2828c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_I(c, CALL_FUNCTION, 1); 2829c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 2830c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielerror_in_scope: 2831c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_exit_scope(c); 2832c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielerror: 2833c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_XDECREF(co); 2834c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 2835c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 2836c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2837c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 2838c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_genexp(struct compiler *c, expr_ty e) 2839c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 2840c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel static identifier name; 2841c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!name) { 2842c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel name = PyString_FromString("<genexpr>"); 2843c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!name) 2844c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 2845c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2846c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(e->kind == GeneratorExp_kind); 2847c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_comprehension(c, e, COMP_GENEXP, name, 2848c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel e->v.GeneratorExp.generators, 2849c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel e->v.GeneratorExp.elt, NULL); 2850c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 2851c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2852c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 2853c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_setcomp(struct compiler *c, expr_ty e) 2854c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 2855c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel static identifier name; 2856c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!name) { 2857c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel name = PyString_FromString("<setcomp>"); 2858c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!name) 2859c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 2860c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2861c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(e->kind == SetComp_kind); 2862c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_comprehension(c, e, COMP_SETCOMP, name, 2863c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel e->v.SetComp.generators, 2864c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel e->v.SetComp.elt, NULL); 2865c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 2866c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2867c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 2868c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_dictcomp(struct compiler *c, expr_ty e) 2869c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 2870c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel static identifier name; 2871c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!name) { 2872c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel name = PyString_FromString("<dictcomp>"); 2873c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!name) 2874c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 2875c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2876c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(e->kind == DictComp_kind); 2877c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_comprehension(c, e, COMP_DICTCOMP, name, 2878c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel e->v.DictComp.generators, 2879c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel e->v.DictComp.key, e->v.DictComp.value); 2880c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 2881c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2882c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 2883c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_visit_keyword(struct compiler *c, keyword_ty k) 2884c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 2885c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_O(c, LOAD_CONST, k->arg, consts); 2886c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, k->value); 2887c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 2888c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 2889c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2890c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* Test whether expression is constant. For constants, report 2891c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel whether they are true or false. 2892c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2893c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Return values: 1 for true, 0 for false, -1 for non-constant. 2894c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel */ 2895c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2896c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 2897c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielexpr_constant(expr_ty e) 2898c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 2899c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel switch (e->kind) { 2900c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Num_kind: 2901c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return PyObject_IsTrue(e->v.Num.n); 2902c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Str_kind: 2903c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return PyObject_IsTrue(e->v.Str.s); 2904c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Name_kind: 2905c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* __debug__ is not assignable, so we can optimize 2906c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel * it away in if and while statements */ 2907c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (strcmp(PyString_AS_STRING(e->v.Name.id), 2908c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "__debug__") == 0) 2909c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return ! Py_OptimizeFlag; 2910c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* fall through */ 2911c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel default: 2912c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 2913c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2914c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 2915c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2916c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* 2917c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Implements the with statement from PEP 343. 2918c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2919c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel The semantics outlined in that PEP are as follows: 2920c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2921c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel with EXPR as VAR: 2922c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel BLOCK 2923c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2924c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel It is implemented roughly as: 2925c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2926c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel context = EXPR 2927c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel exit = context.__exit__ # not calling it 2928c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel value = context.__enter__() 2929c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel try: 2930c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VAR = value # if VAR present in the syntax 2931c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel BLOCK 2932c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel finally: 2933c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if an exception was raised: 2934c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel exc = copy of (exception, instance, traceback) 2935c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else: 2936c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel exc = (None, None, None) 2937c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel exit(*exc) 2938c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel */ 2939c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 2940c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_with(struct compiler *c, stmt_ty s) 2941c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 2942c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel basicblock *block, *finally; 2943c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2944c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(s->kind == With_kind); 2945c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2946c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel block = compiler_new_block(c); 2947c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel finally = compiler_new_block(c); 2948c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!block || !finally) 2949c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 2950c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2951c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Evaluate EXPR */ 2952c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, s->v.With.context_expr); 2953c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_JREL(c, SETUP_WITH, finally); 2954c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2955c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* SETUP_WITH pushes a finally block. */ 2956c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_use_next_block(c, block); 2957c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Note that the block is actually called SETUP_WITH in ceval.c, but 2958c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel functions the same as SETUP_FINALLY except that exceptions are 2959c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel normalized. */ 2960c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_push_fblock(c, FINALLY_TRY, block)) { 2961c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 2962c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2963c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2964c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (s->v.With.optional_vars) { 2965c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, s->v.With.optional_vars); 2966c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2967c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else { 2968c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Discard result from context.__enter__() */ 2969c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, POP_TOP); 2970c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 2971c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2972c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* BLOCK code */ 2973c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT_SEQ(c, stmt, s->v.With.body); 2974c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2975c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* End of try block; start the finally block */ 2976c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, POP_BLOCK); 2977c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_pop_fblock(c, FINALLY_TRY, block); 2978c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2979c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_O(c, LOAD_CONST, Py_None, consts); 2980c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_use_next_block(c, finally); 2981c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_push_fblock(c, FINALLY_END, finally)) 2982c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 2983c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2984c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Finally block starts; context.__exit__ is on the stack under 2985c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel the exception or return information. Just issue our magic 2986c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel opcode. */ 2987c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, WITH_CLEANUP); 2988c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2989c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Finally block ends. */ 2990c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, END_FINALLY); 2991c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel compiler_pop_fblock(c, FINALLY_END, finally); 2992c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 2993c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 2994c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 2995c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 2996c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_visit_expr(struct compiler *c, expr_ty e) 2997c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 2998c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int i, n; 2999c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3000c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* If expr e has a different line number than the last expr/stmt, 3001c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel set a new line number for the next instruction. 3002c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel */ 3003c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (e->lineno > c->u->u_lineno) { 3004c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c->u->u_lineno = e->lineno; 3005c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c->u->u_lineno_set = false; 3006c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3007c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel switch (e->kind) { 3008c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case BoolOp_kind: 3009c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_boolop(c, e); 3010c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case BinOp_kind: 3011c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, e->v.BinOp.left); 3012c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, e->v.BinOp.right); 3013c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, binop(c, e->v.BinOp.op)); 3014c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 3015c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case UnaryOp_kind: 3016c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, e->v.UnaryOp.operand); 3017c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, unaryop(e->v.UnaryOp.op)); 3018c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 3019c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Lambda_kind: 3020c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_lambda(c, e); 3021c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case IfExp_kind: 3022c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_ifexp(c, e); 3023c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Dict_kind: 3024c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel n = asdl_seq_LEN(e->v.Dict.values); 3025c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_I(c, BUILD_MAP, (n>0xFFFF ? 0xFFFF : n)); 3026c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (i = 0; i < n; i++) { 3027c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, 3028c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel (expr_ty)asdl_seq_GET(e->v.Dict.values, i)); 3029c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, 3030c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel (expr_ty)asdl_seq_GET(e->v.Dict.keys, i)); 3031c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, STORE_MAP); 3032c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3033c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 3034c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Set_kind: 3035c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel n = asdl_seq_LEN(e->v.Set.elts); 3036c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT_SEQ(c, expr, e->v.Set.elts); 3037c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_I(c, BUILD_SET, n); 3038c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 3039c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case ListComp_kind: 3040c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_listcomp(c, e); 3041c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case SetComp_kind: 3042c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_setcomp(c, e); 3043c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case DictComp_kind: 3044c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_dictcomp(c, e); 3045c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case GeneratorExp_kind: 3046c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_genexp(c, e); 3047c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Yield_kind: 3048c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (c->u->u_ste->ste_type != FunctionBlock) 3049c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_error(c, "'yield' outside function"); 3050c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (e->v.Yield.value) { 3051c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, e->v.Yield.value); 3052c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3053c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else { 3054c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_O(c, LOAD_CONST, Py_None, consts); 3055c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3056c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, YIELD_VALUE); 3057c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 3058c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Compare_kind: 3059c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_compare(c, e); 3060c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Call_kind: 3061c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_call(c, e); 3062c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Repr_kind: 3063c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, e->v.Repr.value); 3064c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, UNARY_CONVERT); 3065c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 3066c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Num_kind: 3067c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_O(c, LOAD_CONST, e->v.Num.n, consts); 3068c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 3069c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Str_kind: 3070c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_O(c, LOAD_CONST, e->v.Str.s, consts); 3071c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 3072c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* The following exprs can be assignment targets. */ 3073c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Attribute_kind: 3074c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (e->v.Attribute.ctx != AugStore) 3075c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, e->v.Attribute.value); 3076c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel switch (e->v.Attribute.ctx) { 3077c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case AugLoad: 3078c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, DUP_TOP); 3079c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Fall through to load */ 3080c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Load: 3081c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_NAME(c, LOAD_ATTR, e->v.Attribute.attr, names); 3082c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 3083c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case AugStore: 3084c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, ROT_TWO); 3085c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Fall through to save */ 3086c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Store: 3087c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_NAME(c, STORE_ATTR, e->v.Attribute.attr, names); 3088c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 3089c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Del: 3090c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_NAME(c, DELETE_ATTR, e->v.Attribute.attr, names); 3091c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 3092c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Param: 3093c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel default: 3094c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_SetString(PyExc_SystemError, 3095c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "param invalid in attribute expression"); 3096c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 3097c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3098c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 3099c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Subscript_kind: 3100c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel switch (e->v.Subscript.ctx) { 3101c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case AugLoad: 3102c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, e->v.Subscript.value); 3103c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT_SLICE(c, e->v.Subscript.slice, AugLoad); 3104c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 3105c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Load: 3106c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, e->v.Subscript.value); 3107c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT_SLICE(c, e->v.Subscript.slice, Load); 3108c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 3109c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case AugStore: 3110c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT_SLICE(c, e->v.Subscript.slice, AugStore); 3111c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 3112c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Store: 3113c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, e->v.Subscript.value); 3114c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT_SLICE(c, e->v.Subscript.slice, Store); 3115c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 3116c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Del: 3117c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, e->v.Subscript.value); 3118c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT_SLICE(c, e->v.Subscript.slice, Del); 3119c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 3120c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Param: 3121c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel default: 3122c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_SetString(PyExc_SystemError, 3123c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "param invalid in subscript expression"); 3124c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 3125c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3126c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 3127c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Name_kind: 3128c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_nameop(c, e->v.Name.id, e->v.Name.ctx); 3129c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* child nodes of List and Tuple will have expr_context set */ 3130c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case List_kind: 3131c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_list(c, e); 3132c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Tuple_kind: 3133c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_tuple(c, e); 3134c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3135c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 3136c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 3137c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3138c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 3139c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_augassign(struct compiler *c, stmt_ty s) 3140c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 3141c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel expr_ty e = s->v.AugAssign.target; 3142c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel expr_ty auge; 3143c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3144c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(s->kind == AugAssign_kind); 3145c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3146c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel switch (e->kind) { 3147c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Attribute_kind: 3148c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel auge = Attribute(e->v.Attribute.value, e->v.Attribute.attr, 3149c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel AugLoad, e->lineno, e->col_offset, c->c_arena); 3150c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (auge == NULL) 3151c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 3152c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, auge); 3153c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, s->v.AugAssign.value); 3154c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, inplace_binop(c, s->v.AugAssign.op)); 3155c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel auge->v.Attribute.ctx = AugStore; 3156c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, auge); 3157c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 3158c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Subscript_kind: 3159c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel auge = Subscript(e->v.Subscript.value, e->v.Subscript.slice, 3160c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel AugLoad, e->lineno, e->col_offset, c->c_arena); 3161c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (auge == NULL) 3162c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 3163c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, auge); 3164c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, s->v.AugAssign.value); 3165c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, inplace_binop(c, s->v.AugAssign.op)); 3166c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel auge->v.Subscript.ctx = AugStore; 3167c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, auge); 3168c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 3169c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Name_kind: 3170c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_nameop(c, e->v.Name.id, Load)) 3171c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 3172c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, s->v.AugAssign.value); 3173c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, inplace_binop(c, s->v.AugAssign.op)); 3174c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_nameop(c, e->v.Name.id, Store); 3175c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel default: 3176c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_Format(PyExc_SystemError, 3177c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "invalid node type (%d) for augmented assignment", 3178c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel e->kind); 3179c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 3180c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3181c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 3182c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 3183c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3184c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 3185c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_push_fblock(struct compiler *c, enum fblocktype t, basicblock *b) 3186c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 3187c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel struct fblockinfo *f; 3188c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (c->u->u_nfblocks >= CO_MAXBLOCKS) { 3189c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_SetString(PyExc_SystemError, 3190c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "too many statically nested blocks"); 3191c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 3192c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3193c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel f = &c->u->u_fblock[c->u->u_nfblocks++]; 3194c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel f->fb_type = t; 3195c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel f->fb_block = b; 3196c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 3197c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 3198c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3199c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic void 3200c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_pop_fblock(struct compiler *c, enum fblocktype t, basicblock *b) 3201c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 3202c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel struct compiler_unit *u = c->u; 3203c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(u->u_nfblocks > 0); 3204c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel u->u_nfblocks--; 3205c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(u->u_fblock[u->u_nfblocks].fb_type == t); 3206c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(u->u_fblock[u->u_nfblocks].fb_block == b); 3207c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 3208c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3209c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 3210c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_in_loop(struct compiler *c) { 3211c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int i; 3212c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel struct compiler_unit *u = c->u; 3213c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (i = 0; i < u->u_nfblocks; ++i) { 3214c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (u->u_fblock[i].fb_type == LOOP) 3215c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 3216c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3217c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 3218c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 3219c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* Raises a SyntaxError and returns 0. 3220c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel If something goes wrong, a different exception may be raised. 3221c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel*/ 3222c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3223c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 3224c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_error(struct compiler *c, const char *errstr) 3225c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 3226c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *loc; 3227c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *u = NULL, *v = NULL; 3228c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3229c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel loc = PyErr_ProgramText(c->c_filename, c->u->u_lineno); 3230c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!loc) { 3231c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_INCREF(Py_None); 3232c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel loc = Py_None; 3233c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3234c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel u = Py_BuildValue("(ziOO)", c->c_filename, c->u->u_lineno, 3235c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_None, loc); 3236c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!u) 3237c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto exit; 3238c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel v = Py_BuildValue("(zO)", errstr, u); 3239c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!v) 3240c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto exit; 3241c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_SetObject(PyExc_SyntaxError, v); 3242c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel exit: 3243c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(loc); 3244c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_XDECREF(u); 3245c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_XDECREF(v); 3246c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 3247c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 3248c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3249c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 3250c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_handle_subscr(struct compiler *c, const char *kind, 3251c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel expr_context_ty ctx) 3252c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 3253c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int op = 0; 3254c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3255c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* XXX this code is duplicated */ 3256c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel switch (ctx) { 3257c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case AugLoad: /* fall through to Load */ 3258c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Load: op = BINARY_SUBSCR; break; 3259c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case AugStore:/* fall through to Store */ 3260c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Store: op = STORE_SUBSCR; break; 3261c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Del: op = DELETE_SUBSCR; break; 3262c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Param: 3263c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_Format(PyExc_SystemError, 3264c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "invalid %s kind %d in subscript\n", 3265c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel kind, ctx); 3266c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 3267c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3268c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (ctx == AugLoad) { 3269c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_I(c, DUP_TOPX, 2); 3270c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3271c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else if (ctx == AugStore) { 3272c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, ROT_THREE); 3273c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3274c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, op); 3275c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 3276c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 3277c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3278c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 3279c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_slice(struct compiler *c, slice_ty s, expr_context_ty ctx) 3280c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 3281c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int n = 2; 3282c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(s->kind == Slice_kind); 3283c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3284c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* only handles the cases where BUILD_SLICE is emitted */ 3285c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (s->v.Slice.lower) { 3286c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, s->v.Slice.lower); 3287c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3288c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else { 3289c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_O(c, LOAD_CONST, Py_None, consts); 3290c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3291c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3292c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (s->v.Slice.upper) { 3293c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, s->v.Slice.upper); 3294c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3295c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else { 3296c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_O(c, LOAD_CONST, Py_None, consts); 3297c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3298c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3299c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (s->v.Slice.step) { 3300c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel n++; 3301c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, s->v.Slice.step); 3302c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3303c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_I(c, BUILD_SLICE, n); 3304c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 3305c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 3306c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3307c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 3308c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_simple_slice(struct compiler *c, slice_ty s, expr_context_ty ctx) 3309c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 3310c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int op = 0, slice_offset = 0, stack_count = 0; 3311c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3312c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(s->v.Slice.step == NULL); 3313c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (s->v.Slice.lower) { 3314c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel slice_offset++; 3315c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel stack_count++; 3316c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (ctx != AugStore) 3317c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, s->v.Slice.lower); 3318c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3319c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (s->v.Slice.upper) { 3320c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel slice_offset += 2; 3321c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel stack_count++; 3322c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (ctx != AugStore) 3323c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, s->v.Slice.upper); 3324c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3325c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3326c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (ctx == AugLoad) { 3327c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel switch (stack_count) { 3328c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case 0: ADDOP(c, DUP_TOP); break; 3329c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case 1: ADDOP_I(c, DUP_TOPX, 2); break; 3330c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case 2: ADDOP_I(c, DUP_TOPX, 3); break; 3331c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3332c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3333c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else if (ctx == AugStore) { 3334c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel switch (stack_count) { 3335c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case 0: ADDOP(c, ROT_TWO); break; 3336c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case 1: ADDOP(c, ROT_THREE); break; 3337c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case 2: ADDOP(c, ROT_FOUR); break; 3338c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3339c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3340c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3341c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel switch (ctx) { 3342c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case AugLoad: /* fall through to Load */ 3343c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Load: op = SLICE; break; 3344c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case AugStore:/* fall through to Store */ 3345c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Store: op = STORE_SLICE; break; 3346c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Del: op = DELETE_SLICE; break; 3347c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Param: 3348c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel default: 3349c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_SetString(PyExc_SystemError, 3350c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "param invalid in simple slice"); 3351c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 3352c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3353c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3354c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, op + slice_offset); 3355c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 3356c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 3357c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3358c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 3359c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_visit_nested_slice(struct compiler *c, slice_ty s, 3360c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel expr_context_ty ctx) 3361c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 3362c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel switch (s->kind) { 3363c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Ellipsis_kind: 3364c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_O(c, LOAD_CONST, Py_Ellipsis, consts); 3365c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 3366c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Slice_kind: 3367c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_slice(c, s, ctx); 3368c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Index_kind: 3369c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, s->v.Index.value); 3370c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 3371c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case ExtSlice_kind: 3372c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel default: 3373c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_SetString(PyExc_SystemError, 3374c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "extended slice invalid in nested slice"); 3375c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 3376c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3377c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 3378c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 3379c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3380c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 3381c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompiler_visit_slice(struct compiler *c, slice_ty s, expr_context_ty ctx) 3382c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 3383c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel char * kindname = NULL; 3384c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel switch (s->kind) { 3385c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Index_kind: 3386c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel kindname = "index"; 3387c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (ctx != AugStore) { 3388c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel VISIT(c, expr, s->v.Index.value); 3389c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3390c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 3391c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Ellipsis_kind: 3392c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel kindname = "ellipsis"; 3393c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (ctx != AugStore) { 3394c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_O(c, LOAD_CONST, Py_Ellipsis, consts); 3395c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3396c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 3397c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case Slice_kind: 3398c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel kindname = "slice"; 3399c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!s->v.Slice.step) 3400c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_simple_slice(c, s, ctx); 3401c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (ctx != AugStore) { 3402c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_slice(c, s, ctx)) 3403c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 3404c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3405c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 3406c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel case ExtSlice_kind: 3407c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel kindname = "extended slice"; 3408c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (ctx != AugStore) { 3409c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int i, n = asdl_seq_LEN(s->v.ExtSlice.dims); 3410c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (i = 0; i < n; i++) { 3411c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel slice_ty sub = (slice_ty)asdl_seq_GET( 3412c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel s->v.ExtSlice.dims, i); 3413c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!compiler_visit_nested_slice(c, sub, ctx)) 3414c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 3415c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3416c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_I(c, BUILD_TUPLE, n); 3417c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3418c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 3419c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel default: 3420c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_Format(PyExc_SystemError, 3421c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "invalid subscript kind %d", s->kind); 3422c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 3423c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3424c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return compiler_handle_subscr(c, kindname, ctx); 3425c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 3426c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3427c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3428c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* End of the compiler section, beginning of the assembler section */ 3429c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3430c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* do depth-first search of basic block graph, starting with block. 3431c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel post records the block indices in post-order. 3432c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3433c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel XXX must handle implicit jumps from one block to next 3434c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel*/ 3435c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3436c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstruct assembler { 3437c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *a_bytecode; /* string containing bytecode */ 3438c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int a_offset; /* offset into bytecode */ 3439c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int a_nblocks; /* number of reachable blocks */ 3440c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel basicblock **a_postorder; /* list of blocks in dfs postorder */ 3441c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *a_lnotab; /* string containing lnotab */ 3442c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int a_lnotab_off; /* offset into lnotab */ 3443c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int a_lineno; /* last lineno of emitted instruction */ 3444c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int a_lineno_off; /* bytecode offset of last lineno */ 3445c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel}; 3446c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3447c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic void 3448c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanieldfs(struct compiler *c, basicblock *b, struct assembler *a) 3449c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 3450c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int i; 3451c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel struct instr *instr = NULL; 3452c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3453c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (b->b_seen) 3454c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return; 3455c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel b->b_seen = 1; 3456c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (b->b_next != NULL) 3457c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel dfs(c, b->b_next, a); 3458c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (i = 0; i < b->b_iused; i++) { 3459c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel instr = &b->b_instr[i]; 3460c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (instr->i_jrel || instr->i_jabs) 3461c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel dfs(c, instr->i_target, a); 3462c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3463c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel a->a_postorder[a->a_nblocks++] = b; 3464c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 3465c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3466c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 3467c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstackdepth_walk(struct compiler *c, basicblock *b, int depth, int maxdepth) 3468c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 3469c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int i, target_depth; 3470c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel struct instr *instr; 3471c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (b->b_seen || b->b_startdepth >= depth) 3472c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return maxdepth; 3473c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel b->b_seen = 1; 3474c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel b->b_startdepth = depth; 3475c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (i = 0; i < b->b_iused; i++) { 3476c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel instr = &b->b_instr[i]; 3477c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel depth += opcode_stack_effect(instr->i_opcode, instr->i_oparg); 3478c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (depth > maxdepth) 3479c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel maxdepth = depth; 3480c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(depth >= 0); /* invalid code or bug in stackdepth() */ 3481c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (instr->i_jrel || instr->i_jabs) { 3482c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel target_depth = depth; 3483c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (instr->i_opcode == FOR_ITER) { 3484c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel target_depth = depth-2; 3485c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3486c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else if (instr->i_opcode == SETUP_FINALLY || 3487c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel instr->i_opcode == SETUP_EXCEPT) { 3488c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel target_depth = depth+3; 3489c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (target_depth > maxdepth) 3490c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel maxdepth = target_depth; 3491c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3492c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else if (instr->i_opcode == JUMP_IF_TRUE_OR_POP || 3493c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel instr->i_opcode == JUMP_IF_FALSE_OR_POP) 3494c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel depth = depth - 1; 3495c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel maxdepth = stackdepth_walk(c, instr->i_target, 3496c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel target_depth, maxdepth); 3497c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (instr->i_opcode == JUMP_ABSOLUTE || 3498c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel instr->i_opcode == JUMP_FORWARD) { 3499c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto out; /* remaining code is dead */ 3500c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3501c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3502c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3503c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (b->b_next) 3504c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel maxdepth = stackdepth_walk(c, b->b_next, depth, maxdepth); 3505c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielout: 3506c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel b->b_seen = 0; 3507c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return maxdepth; 3508c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 3509c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3510c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* Find the flow path that needs the largest stack. We assume that 3511c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel * cycles in the flow graph have no net effect on the stack depth. 3512c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel */ 3513c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 3514c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstackdepth(struct compiler *c) 3515c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 3516c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel basicblock *b, *entryblock; 3517c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel entryblock = NULL; 3518c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (b = c->u->u_blocks; b != NULL; b = b->b_list) { 3519c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel b->b_seen = 0; 3520c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel b->b_startdepth = INT_MIN; 3521c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel entryblock = b; 3522c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3523c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!entryblock) 3524c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 3525c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return stackdepth_walk(c, entryblock, 0, 0); 3526c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 3527c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3528c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 3529c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielassemble_init(struct assembler *a, int nblocks, int firstlineno) 3530c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 3531c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel memset(a, 0, sizeof(struct assembler)); 3532c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel a->a_lineno = firstlineno; 3533c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel a->a_bytecode = PyString_FromStringAndSize(NULL, DEFAULT_CODE_SIZE); 3534c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!a->a_bytecode) 3535c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 3536c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel a->a_lnotab = PyString_FromStringAndSize(NULL, DEFAULT_LNOTAB_SIZE); 3537c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!a->a_lnotab) 3538c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 3539c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (nblocks > PY_SIZE_MAX / sizeof(basicblock *)) { 3540c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_NoMemory(); 3541c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 3542c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3543c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel a->a_postorder = (basicblock **)PyObject_Malloc( 3544c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel sizeof(basicblock *) * nblocks); 3545c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!a->a_postorder) { 3546c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_NoMemory(); 3547c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 3548c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3549c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 3550c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 3551c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3552c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic void 3553c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielassemble_free(struct assembler *a) 3554c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 3555c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_XDECREF(a->a_bytecode); 3556c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_XDECREF(a->a_lnotab); 3557c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (a->a_postorder) 3558c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject_Free(a->a_postorder); 3559c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 3560c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3561c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* Return the size of a basic block in bytes. */ 3562c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3563c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 3564c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielinstrsize(struct instr *instr) 3565c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 3566c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!instr->i_hasarg) 3567c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; /* 1 byte for the opcode*/ 3568c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (instr->i_oparg > 0xffff) 3569c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 6; /* 1 (opcode) + 1 (EXTENDED_ARG opcode) + 2 (oparg) + 2(oparg extended) */ 3570c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 3; /* 1 (opcode) + 2 (oparg) */ 3571c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 3572c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3573c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 3574c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielblocksize(basicblock *b) 3575c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 3576c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int i; 3577c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int size = 0; 3578c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3579c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (i = 0; i < b->b_iused; i++) 3580c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel size += instrsize(&b->b_instr[i]); 3581c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return size; 3582c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 3583c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3584c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* Appends a pair to the end of the line number table, a_lnotab, representing 3585c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel the instruction's bytecode offset and line number. See 3586c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Objects/lnotab_notes.txt for the description of the line number table. */ 3587c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3588c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 3589c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielassemble_lnotab(struct assembler *a, struct instr *i) 3590c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 3591c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int d_bytecode, d_lineno; 3592c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int len; 3593c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel unsigned char *lnotab; 3594c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3595c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel d_bytecode = a->a_offset - a->a_lineno_off; 3596c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel d_lineno = i->i_lineno - a->a_lineno; 3597c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3598c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(d_bytecode >= 0); 3599c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(d_lineno >= 0); 3600c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3601c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if(d_bytecode == 0 && d_lineno == 0) 3602c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 3603c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3604c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (d_bytecode > 255) { 3605c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int j, nbytes, ncodes = d_bytecode / 255; 3606c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel nbytes = a->a_lnotab_off + 2 * ncodes; 3607c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel len = PyString_GET_SIZE(a->a_lnotab); 3608c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (nbytes >= len) { 3609c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if ((len <= INT_MAX / 2) && (len * 2 < nbytes)) 3610c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel len = nbytes; 3611c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else if (len <= INT_MAX / 2) 3612c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel len *= 2; 3613c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else { 3614c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_NoMemory(); 3615c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 3616c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3617c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (_PyString_Resize(&a->a_lnotab, len) < 0) 3618c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 3619c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3620c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel lnotab = (unsigned char *) 3621c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyString_AS_STRING(a->a_lnotab) + a->a_lnotab_off; 3622c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (j = 0; j < ncodes; j++) { 3623c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *lnotab++ = 255; 3624c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *lnotab++ = 0; 3625c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3626c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel d_bytecode -= ncodes * 255; 3627c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel a->a_lnotab_off += ncodes * 2; 3628c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3629c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(d_bytecode <= 255); 3630c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (d_lineno > 255) { 3631c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int j, nbytes, ncodes = d_lineno / 255; 3632c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel nbytes = a->a_lnotab_off + 2 * ncodes; 3633c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel len = PyString_GET_SIZE(a->a_lnotab); 3634c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (nbytes >= len) { 3635c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if ((len <= INT_MAX / 2) && len * 2 < nbytes) 3636c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel len = nbytes; 3637c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else if (len <= INT_MAX / 2) 3638c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel len *= 2; 3639c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else { 3640c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_NoMemory(); 3641c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 3642c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3643c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (_PyString_Resize(&a->a_lnotab, len) < 0) 3644c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 3645c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3646c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel lnotab = (unsigned char *) 3647c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyString_AS_STRING(a->a_lnotab) + a->a_lnotab_off; 3648c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *lnotab++ = d_bytecode; 3649c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *lnotab++ = 255; 3650c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel d_bytecode = 0; 3651c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (j = 1; j < ncodes; j++) { 3652c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *lnotab++ = 0; 3653c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *lnotab++ = 255; 3654c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3655c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel d_lineno -= ncodes * 255; 3656c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel a->a_lnotab_off += ncodes * 2; 3657c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3658c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3659c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel len = PyString_GET_SIZE(a->a_lnotab); 3660c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (a->a_lnotab_off + 2 >= len) { 3661c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (_PyString_Resize(&a->a_lnotab, len * 2) < 0) 3662c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 3663c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3664c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel lnotab = (unsigned char *) 3665c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyString_AS_STRING(a->a_lnotab) + a->a_lnotab_off; 3666c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3667c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel a->a_lnotab_off += 2; 3668c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (d_bytecode) { 3669c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *lnotab++ = d_bytecode; 3670c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *lnotab++ = d_lineno; 3671c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3672c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else { /* First line of a block; def stmt, etc. */ 3673c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *lnotab++ = 0; 3674c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *lnotab++ = d_lineno; 3675c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3676c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel a->a_lineno = i->i_lineno; 3677c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel a->a_lineno_off = a->a_offset; 3678c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 3679c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 3680c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3681c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* assemble_emit() 3682c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Extend the bytecode with a new instruction. 3683c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Update lnotab if necessary. 3684c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel*/ 3685c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3686c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 3687c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielassemble_emit(struct assembler *a, struct instr *i) 3688c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 3689c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int size, arg = 0, ext = 0; 3690c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_ssize_t len = PyString_GET_SIZE(a->a_bytecode); 3691c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel char *code; 3692c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3693c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel size = instrsize(i); 3694c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (i->i_hasarg) { 3695c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel arg = i->i_oparg; 3696c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ext = arg >> 16; 3697c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3698c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (i->i_lineno && !assemble_lnotab(a, i)) 3699c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 3700c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (a->a_offset + size >= len) { 3701c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (len > PY_SSIZE_T_MAX / 2) 3702c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 3703c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (_PyString_Resize(&a->a_bytecode, len * 2) < 0) 3704c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 3705c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3706c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel code = PyString_AS_STRING(a->a_bytecode) + a->a_offset; 3707c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel a->a_offset += size; 3708c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (size == 6) { 3709c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(i->i_hasarg); 3710c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *code++ = (char)EXTENDED_ARG; 3711c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *code++ = ext & 0xff; 3712c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *code++ = ext >> 8; 3713c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel arg &= 0xffff; 3714c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3715c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *code++ = i->i_opcode; 3716c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (i->i_hasarg) { 3717c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert(size == 3 || size == 6); 3718c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *code++ = arg & 0xff; 3719c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *code++ = arg >> 8; 3720c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3721c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 1; 3722c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 3723c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3724c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic void 3725c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielassemble_jump_offsets(struct assembler *a, struct compiler *c) 3726c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 3727c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel basicblock *b; 3728c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int bsize, totsize, extended_arg_count = 0, last_extended_arg_count; 3729c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int i; 3730c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3731c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Compute the size of each block and fixup jump args. 3732c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Replace block pointer with position in bytecode. */ 3733c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel do { 3734c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel totsize = 0; 3735c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (i = a->a_nblocks - 1; i >= 0; i--) { 3736c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel b = a->a_postorder[i]; 3737c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel bsize = blocksize(b); 3738c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel b->b_offset = totsize; 3739c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel totsize += bsize; 3740c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3741c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel last_extended_arg_count = extended_arg_count; 3742c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel extended_arg_count = 0; 3743c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (b = c->u->u_blocks; b != NULL; b = b->b_list) { 3744c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel bsize = b->b_offset; 3745c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (i = 0; i < b->b_iused; i++) { 3746c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel struct instr *instr = &b->b_instr[i]; 3747c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Relative jumps are computed relative to 3748c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel the instruction pointer after fetching 3749c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel the jump instruction. 3750c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel */ 3751c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel bsize += instrsize(instr); 3752c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (instr->i_jabs) 3753c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel instr->i_oparg = instr->i_target->b_offset; 3754c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else if (instr->i_jrel) { 3755c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int delta = instr->i_target->b_offset - bsize; 3756c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel instr->i_oparg = delta; 3757c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3758c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else 3759c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel continue; 3760c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (instr->i_oparg > 0xffff) 3761c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel extended_arg_count++; 3762c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3763c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3764c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3765c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* XXX: This is an awful hack that could hurt performance, but 3766c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel on the bright side it should work until we come up 3767c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel with a better solution. 3768c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3769c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel The issue is that in the first loop blocksize() is called 3770c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel which calls instrsize() which requires i_oparg be set 3771c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel appropriately. There is a bootstrap problem because 3772c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel i_oparg is calculated in the second loop above. 3773c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3774c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel So we loop until we stop seeing new EXTENDED_ARGs. 3775c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel The only EXTENDED_ARGs that could be popping up are 3776c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ones in jump instructions. So this should converge 3777c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel fairly quickly. 3778c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel */ 3779c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } while (last_extended_arg_count != extended_arg_count); 3780c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 3781c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3782c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic PyObject * 3783c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanieldict_keys_inorder(PyObject *dict, int offset) 3784c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 3785c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *tuple, *k, *v; 3786c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_ssize_t i, pos = 0, size = PyDict_Size(dict); 3787c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3788c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel tuple = PyTuple_New(size); 3789c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (tuple == NULL) 3790c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 3791c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel while (PyDict_Next(dict, &pos, &k, &v)) { 3792c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel i = PyInt_AS_LONG(v); 3793c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* The keys of the dictionary are tuples. (see compiler_add_o) 3794c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel The object we want is always first, though. */ 3795c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel k = PyTuple_GET_ITEM(k, 0); 3796c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_INCREF(k); 3797c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert((i - offset) < size); 3798c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assert((i - offset) >= 0); 3799c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyTuple_SET_ITEM(tuple, i - offset, k); 3800c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3801c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return tuple; 3802c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 3803c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3804c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int 3805c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielcompute_code_flags(struct compiler *c) 3806c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 3807c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PySTEntryObject *ste = c->u->u_ste; 3808c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int flags = 0, n; 3809c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (ste->ste_type != ModuleBlock) 3810c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel flags |= CO_NEWLOCALS; 3811c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (ste->ste_type == FunctionBlock) { 3812c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!ste->ste_unoptimized) 3813c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel flags |= CO_OPTIMIZED; 3814c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (ste->ste_nested) 3815c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel flags |= CO_NESTED; 3816c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (ste->ste_generator) 3817c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel flags |= CO_GENERATOR; 3818c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (ste->ste_varargs) 3819c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel flags |= CO_VARARGS; 3820c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (ste->ste_varkeywords) 3821c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel flags |= CO_VARKEYWORDS; 3822c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3823c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3824c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* (Only) inherit compilerflags in PyCF_MASK */ 3825c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel flags |= (c->c_flags->cf_flags & PyCF_MASK); 3826c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3827c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel n = PyDict_Size(c->u->u_freevars); 3828c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (n < 0) 3829c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 3830c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (n == 0) { 3831c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel n = PyDict_Size(c->u->u_cellvars); 3832c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (n < 0) 3833c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 3834c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (n == 0) { 3835c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel flags |= CO_NOFREE; 3836c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3837c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3838c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3839c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return flags; 3840c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 3841c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3842c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic PyCodeObject * 3843c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielmakecode(struct compiler *c, struct assembler *a) 3844c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 3845c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *tmp; 3846c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyCodeObject *co = NULL; 3847c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *consts = NULL; 3848c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *names = NULL; 3849c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *varnames = NULL; 3850c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *filename = NULL; 3851c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *name = NULL; 3852c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *freevars = NULL; 3853c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *cellvars = NULL; 3854c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *bytecode = NULL; 3855c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int nlocals, flags; 3856c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3857c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel tmp = dict_keys_inorder(c->u->u_consts, 0); 3858c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!tmp) 3859c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto error; 3860c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel consts = PySequence_List(tmp); /* optimize_code requires a list */ 3861c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(tmp); 3862c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3863c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel names = dict_keys_inorder(c->u->u_names, 0); 3864c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel varnames = dict_keys_inorder(c->u->u_varnames, 0); 3865c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!consts || !names || !varnames) 3866c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto error; 3867c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3868c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel cellvars = dict_keys_inorder(c->u->u_cellvars, 0); 3869c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!cellvars) 3870c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto error; 3871c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel freevars = dict_keys_inorder(c->u->u_freevars, PyTuple_Size(cellvars)); 3872c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!freevars) 3873c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto error; 3874c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel filename = PyString_FromString(c->c_filename); 3875c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!filename) 3876c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto error; 3877c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3878c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel nlocals = PyDict_Size(c->u->u_varnames); 3879c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel flags = compute_code_flags(c); 3880c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (flags < 0) 3881c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto error; 3882c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3883c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel bytecode = PyCode_Optimize(a->a_bytecode, consts, names, a->a_lnotab); 3884c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!bytecode) 3885c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto error; 3886c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3887c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel tmp = PyList_AsTuple(consts); /* PyCode_New requires a tuple */ 3888c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!tmp) 3889c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto error; 3890c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(consts); 3891c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel consts = tmp; 3892c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3893c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel co = PyCode_New(c->u->u_argcount, nlocals, stackdepth(c), flags, 3894c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel bytecode, consts, names, varnames, 3895c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel freevars, cellvars, 3896c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel filename, c->u->u_name, 3897c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c->u->u_firstlineno, 3898c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel a->a_lnotab); 3899c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel error: 3900c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_XDECREF(consts); 3901c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_XDECREF(names); 3902c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_XDECREF(varnames); 3903c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_XDECREF(filename); 3904c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_XDECREF(name); 3905c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_XDECREF(freevars); 3906c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_XDECREF(cellvars); 3907c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_XDECREF(bytecode); 3908c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return co; 3909c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 3910c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3911c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3912c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* For debugging purposes only */ 3913c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#if 0 3914c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic void 3915c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanieldump_instr(const struct instr *i) 3916c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 3917c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel const char *jrel = i->i_jrel ? "jrel " : ""; 3918c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel const char *jabs = i->i_jabs ? "jabs " : ""; 3919c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel char arg[128]; 3920c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3921c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *arg = '\0'; 3922c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (i->i_hasarg) 3923c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel sprintf(arg, "arg: %d ", i->i_oparg); 3924c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3925c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel fprintf(stderr, "line: %d, opcode: %d %s%s%s\n", 3926c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel i->i_lineno, i->i_opcode, arg, jabs, jrel); 3927c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 3928c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3929c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic void 3930c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanieldump_basicblock(const basicblock *b) 3931c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 3932c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel const char *seen = b->b_seen ? "seen " : ""; 3933c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel const char *b_return = b->b_return ? "return " : ""; 3934c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel fprintf(stderr, "used: %d, depth: %d, offset: %d %s%s\n", 3935c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel b->b_iused, b->b_startdepth, b->b_offset, seen, b_return); 3936c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (b->b_instr) { 3937c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int i; 3938c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (i = 0; i < b->b_iused; i++) { 3939c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel fprintf(stderr, " [%02d] ", i); 3940c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel dump_instr(b->b_instr + i); 3941c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3942c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3943c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 3944c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#endif 3945c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3946c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic PyCodeObject * 3947c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielassemble(struct compiler *c, int addNone) 3948c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 3949c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel basicblock *b, *entryblock; 3950c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel struct assembler a; 3951c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int i, j, nblocks; 3952c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyCodeObject *co = NULL; 3953c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3954c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Make sure every block that falls off the end returns None. 3955c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel XXX NEXT_BLOCK() isn't quite right, because if the last 3956c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel block ends with a jump or return b_next shouldn't set. 3957c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel */ 3958c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!c->u->u_curblock->b_return) { 3959c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel NEXT_BLOCK(c); 3960c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (addNone) 3961c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP_O(c, LOAD_CONST, Py_None, consts); 3962c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ADDOP(c, RETURN_VALUE); 3963c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3964c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3965c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel nblocks = 0; 3966c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel entryblock = NULL; 3967c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (b = c->u->u_blocks; b != NULL; b = b->b_list) { 3968c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel nblocks++; 3969c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel entryblock = b; 3970c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3971c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3972c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Set firstlineno if it wasn't explicitly set. */ 3973c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!c->u->u_firstlineno) { 3974c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (entryblock && entryblock->b_instr) 3975c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c->u->u_firstlineno = entryblock->b_instr->i_lineno; 3976c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else 3977c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel c->u->u_firstlineno = 1; 3978c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3979c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!assemble_init(&a, nblocks, c->u->u_firstlineno)) 3980c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto error; 3981c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel dfs(c, entryblock, &a); 3982c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3983c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Can't modify the bytecode after computing jump offsets. */ 3984c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assemble_jump_offsets(&a, c); 3985c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3986c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Emit code in reverse postorder from dfs. */ 3987c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (i = a.a_nblocks - 1; i >= 0; i--) { 3988c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel b = a.a_postorder[i]; 3989c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (j = 0; j < b->b_iused; j++) 3990c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!assemble_emit(&a, &b->b_instr[j])) 3991c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto error; 3992c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 3993c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3994c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (_PyString_Resize(&a.a_lnotab, a.a_lnotab_off) < 0) 3995c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto error; 3996c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (_PyString_Resize(&a.a_bytecode, a.a_offset) < 0) 3997c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto error; 3998c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3999c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel co = makecode(c, &a); 4000c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel error: 4001c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel assemble_free(&a); 4002c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return co; 4003c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 4004