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