120e1199fbe8493796a12d1c20ee1c857527fe396Raymond Hettinger/* Peephole optimizations for bytecode compiler. */
2644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton
3644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton#include "Python.h"
4644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton
5644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton#include "Python-ast.h"
6644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton#include "node.h"
7644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton#include "pyarena.h"
8644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton#include "ast.h"
9644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton#include "code.h"
10644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton#include "compile.h"
11644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton#include "symtable.h"
12644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton#include "opcode.h"
13644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton
14644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton#define GETARG(arr, i) ((int)((arr[i+2]<<8) + arr[i+1]))
15c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define UNCONDITIONAL_JUMP(op)  (op==JUMP_ABSOLUTE || op==JUMP_FORWARD)
1668d68520061a5a4aa3437f8c74ba383b2da50280Jeffrey Yasskin#define CONDITIONAL_JUMP(op) (op==POP_JUMP_IF_FALSE || op==POP_JUMP_IF_TRUE \
17c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    || op==JUMP_IF_FALSE_OR_POP || op==JUMP_IF_TRUE_OR_POP)
1868d68520061a5a4aa3437f8c74ba383b2da50280Jeffrey Yasskin#define ABSOLUTE_JUMP(op) (op==JUMP_ABSOLUTE || op==CONTINUE_LOOP \
19c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    || op==POP_JUMP_IF_FALSE || op==POP_JUMP_IF_TRUE \
20c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    || op==JUMP_IF_FALSE_OR_POP || op==JUMP_IF_TRUE_OR_POP)
2168d68520061a5a4aa3437f8c74ba383b2da50280Jeffrey Yasskin#define JUMPS_ON_TRUE(op) (op==POP_JUMP_IF_TRUE || op==JUMP_IF_TRUE_OR_POP)
22644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton#define GETJUMPTGT(arr, i) (GETARG(arr,i) + (ABSOLUTE_JUMP(arr[i]) ? 0 : i+3))
23644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton#define SETARG(arr, i, val) arr[i+2] = val>>8; arr[i+1] = val & 255
24644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton#define CODESIZE(op)  (HAS_ARG(op) ? 3 : 1)
25644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton#define ISBASICBLOCK(blocks, start, bytes) \
26c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    (blocks[start]==blocks[start+bytes-1])
27644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton
28644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton/* Replace LOAD_CONST c1. LOAD_CONST c2 ... LOAD_CONST cn BUILD_TUPLE n
29c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou   with    LOAD_CONST (c1, c2, ... cn).
30644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton   The consts table must still be in list form so that the
31644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton   new constant (c1, c2, ... cn) can be appended.
32644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton   Called with codestr pointing to the first LOAD_CONST.
33c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou   Bails out with no change if one or more of the LOAD_CONSTs is missing.
34644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton   Also works for BUILD_LIST when followed by an "in" or "not in" test.
35644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton*/
36644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hyltonstatic int
374677fbf7de591d0cea0d1aeaa9639ee46faa48f5Neal Norwitztuple_of_constants(unsigned char *codestr, Py_ssize_t n, PyObject *consts)
38644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton{
39c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *newconst, *constant;
40c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_ssize_t i, arg, len_consts;
41c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
42c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Pre-conditions */
43c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(PyList_CheckExact(consts));
44c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(codestr[n*3] == BUILD_TUPLE || codestr[n*3] == BUILD_LIST);
45c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(GETARG(codestr, (n*3)) == n);
46c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    for (i=0 ; i<n ; i++)
47c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        assert(codestr[i*3] == LOAD_CONST);
48c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
49c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Buildup new tuple of constants */
50c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    newconst = PyTuple_New(n);
51c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (newconst == NULL)
52c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return 0;
53c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    len_consts = PyList_GET_SIZE(consts);
54c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    for (i=0 ; i<n ; i++) {
55c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        arg = GETARG(codestr, (i*3));
56c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        assert(arg < len_consts);
57c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        constant = PyList_GET_ITEM(consts, arg);
58c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_INCREF(constant);
59c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyTuple_SET_ITEM(newconst, i, constant);
60c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
61c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
62c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Append folded constant onto consts */
63c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyList_Append(consts, newconst)) {
64c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_DECREF(newconst);
65c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return 0;
66c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
67c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(newconst);
68c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
69c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Write NOPs over old LOAD_CONSTS and
70c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou       add a new LOAD_CONST newconst on top of the BUILD_TUPLE n */
71c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    memset(codestr, NOP, n*3);
72c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    codestr[n*3] = LOAD_CONST;
73c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    SETARG(codestr, (n*3), len_consts);
74c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return 1;
75644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton}
76644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton
77644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton/* Replace LOAD_CONST c1. LOAD_CONST c2 BINOP
78c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou   with    LOAD_CONST binop(c1,c2)
79644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton   The consts table must still be in list form so that the
80644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton   new constant can be appended.
81c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou   Called with codestr pointing to the first LOAD_CONST.
82c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou   Abandons the transformation if the folding fails (i.e.  1+'a').
83644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton   If the new constant is a sequence, only folds when the size
84c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou   is below a threshold value.  That keeps pyc files from
85c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou   becoming large in the presence of code like:  (None,)*1000.
86644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton*/
87644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hyltonstatic int
88644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hyltonfold_binops_on_constants(unsigned char *codestr, PyObject *consts)
89644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton{
90c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *newconst, *v, *w;
91c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_ssize_t len_consts, size;
92c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int opcode;
93c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
94c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Pre-conditions */
95c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(PyList_CheckExact(consts));
96c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(codestr[0] == LOAD_CONST);
97c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(codestr[3] == LOAD_CONST);
98c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
99c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Create new constant */
100c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    v = PyList_GET_ITEM(consts, GETARG(codestr, 0));
101c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    w = PyList_GET_ITEM(consts, GETARG(codestr, 3));
102c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    opcode = codestr[6];
103c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    switch (opcode) {
104c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        case BINARY_POWER:
105c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            newconst = PyNumber_Power(v, w, Py_None);
106c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            break;
107c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        case BINARY_MULTIPLY:
108c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            newconst = PyNumber_Multiply(v, w);
109c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            break;
110c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        case BINARY_DIVIDE:
111c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            /* Cannot fold this operation statically since
112c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou               the result can depend on the run-time presence
113c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou               of the -Qnew flag */
114c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return 0;
115c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        case BINARY_TRUE_DIVIDE:
116c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            newconst = PyNumber_TrueDivide(v, w);
117c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            break;
118c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        case BINARY_FLOOR_DIVIDE:
119c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            newconst = PyNumber_FloorDivide(v, w);
120c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            break;
121c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        case BINARY_MODULO:
122c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            newconst = PyNumber_Remainder(v, w);
123c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            break;
124c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        case BINARY_ADD:
125c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            newconst = PyNumber_Add(v, w);
126c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            break;
127c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        case BINARY_SUBTRACT:
128c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            newconst = PyNumber_Subtract(v, w);
129c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            break;
130c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        case BINARY_SUBSCR:
131c283a85e1214594c50fc07fe42f4ecc2cc3681b4Ezio Melotti            /* #5057: if v is unicode, there might be differences between
132c18cc0edff5269d715f9aa06ca31a4f19ff87b30Ezio Melotti               wide and narrow builds in cases like '\U00012345'[0] or
133c18cc0edff5269d715f9aa06ca31a4f19ff87b30Ezio Melotti               '\U00012345abcdef'[3], so it's better to skip the optimization
134c18cc0edff5269d715f9aa06ca31a4f19ff87b30Ezio Melotti               in order to produce compatible pycs.
135c18cc0edff5269d715f9aa06ca31a4f19ff87b30Ezio Melotti            */
136c18cc0edff5269d715f9aa06ca31a4f19ff87b30Ezio Melotti            if (PyUnicode_Check(v))
137c18cc0edff5269d715f9aa06ca31a4f19ff87b30Ezio Melotti                return 0;
138c18cc0edff5269d715f9aa06ca31a4f19ff87b30Ezio Melotti            newconst = PyObject_GetItem(v, w);
139c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            break;
140c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        case BINARY_LSHIFT:
141c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            newconst = PyNumber_Lshift(v, w);
142c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            break;
143c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        case BINARY_RSHIFT:
144c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            newconst = PyNumber_Rshift(v, w);
145c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            break;
146c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        case BINARY_AND:
147c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            newconst = PyNumber_And(v, w);
148c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            break;
149c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        case BINARY_XOR:
150c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            newconst = PyNumber_Xor(v, w);
151c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            break;
152c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        case BINARY_OR:
153c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            newconst = PyNumber_Or(v, w);
154c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            break;
155c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        default:
156c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            /* Called with an unknown opcode */
157c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            PyErr_Format(PyExc_SystemError,
158c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                 "unexpected binary operation %d on a constant",
159c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                     opcode);
160c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return 0;
161c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
162c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (newconst == NULL) {
163c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyErr_Clear();
164c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return 0;
165c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
166c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    size = PyObject_Size(newconst);
167c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (size == -1)
168c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyErr_Clear();
169c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    else if (size > 20) {
170c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_DECREF(newconst);
171c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return 0;
172c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
173c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
174c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Append folded constant into consts table */
175c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    len_consts = PyList_GET_SIZE(consts);
176c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyList_Append(consts, newconst)) {
177c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_DECREF(newconst);
178c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return 0;
179c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
180c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(newconst);
181c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
182c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Write NOP NOP NOP NOP LOAD_CONST newconst */
183c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    memset(codestr, NOP, 4);
184c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    codestr[4] = LOAD_CONST;
185c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    SETARG(codestr, 4, len_consts);
186c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return 1;
187644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton}
188644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton
189644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hyltonstatic int
190644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hyltonfold_unaryops_on_constants(unsigned char *codestr, PyObject *consts)
191644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton{
192c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *newconst=NULL, *v;
193c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_ssize_t len_consts;
194c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int opcode;
195c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
196c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Pre-conditions */
197c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(PyList_CheckExact(consts));
198c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(codestr[0] == LOAD_CONST);
199c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
200c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Create new constant */
201c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    v = PyList_GET_ITEM(consts, GETARG(codestr, 0));
202c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    opcode = codestr[3];
203c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    switch (opcode) {
204c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        case UNARY_NEGATIVE:
205c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            /* Preserve the sign of -0.0 */
206c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            if (PyObject_IsTrue(v) == 1)
207c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                newconst = PyNumber_Negative(v);
208c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            break;
209c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        case UNARY_CONVERT:
210c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            newconst = PyObject_Repr(v);
211c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            break;
212c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        case UNARY_INVERT:
213c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            newconst = PyNumber_Invert(v);
214c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            break;
215c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        default:
216c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            /* Called with an unknown opcode */
217c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            PyErr_Format(PyExc_SystemError,
218c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                 "unexpected unary operation %d on a constant",
219c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                     opcode);
220c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return 0;
221c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
222c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (newconst == NULL) {
223c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyErr_Clear();
224c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return 0;
225c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
226c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
227c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Append folded constant into consts table */
228c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    len_consts = PyList_GET_SIZE(consts);
229c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyList_Append(consts, newconst)) {
230c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_DECREF(newconst);
231c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return 0;
232c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
233c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(newconst);
234c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
235c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Write NOP LOAD_CONST newconst */
236c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    codestr[0] = NOP;
237c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    codestr[1] = LOAD_CONST;
238c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    SETARG(codestr, 1, len_consts);
239c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return 1;
240644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton}
241644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton
242644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hyltonstatic unsigned int *
2434677fbf7de591d0cea0d1aeaa9639ee46faa48f5Neal Norwitzmarkblocks(unsigned char *code, Py_ssize_t len)
244644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton{
245a2269d074b02440b7a9c22115454ad7e33aeb3f4Serhiy Storchaka    unsigned int *blocks = PyMem_New(unsigned int, len);
246c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int i,j, opcode, blockcnt = 0;
247c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
248c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (blocks == NULL) {
249c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyErr_NoMemory();
250c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
251c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
252c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    memset(blocks, 0, len*sizeof(int));
253c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
254c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Mark labels in the first pass */
255c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    for (i=0 ; i<len ; i+=CODESIZE(opcode)) {
256c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        opcode = code[i];
257c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        switch (opcode) {
258c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case FOR_ITER:
259c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case JUMP_FORWARD:
260c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case JUMP_IF_FALSE_OR_POP:
261c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case JUMP_IF_TRUE_OR_POP:
262c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case POP_JUMP_IF_FALSE:
263c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case POP_JUMP_IF_TRUE:
264c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case JUMP_ABSOLUTE:
265c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case CONTINUE_LOOP:
266c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case SETUP_LOOP:
267c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case SETUP_EXCEPT:
268c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case SETUP_FINALLY:
269c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case SETUP_WITH:
270c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                j = GETJUMPTGT(code, i);
271c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                blocks[j] = 1;
272c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                break;
273c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
274c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
275c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Build block numbers in the second pass */
276c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    for (i=0 ; i<len ; i++) {
277c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        blockcnt += blocks[i];          /* increment blockcnt over labels */
278c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        blocks[i] = blockcnt;
279c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
280c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return blocks;
281644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton}
282644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton
283644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton/* Perform basic peephole optimizations to components of a code object.
284c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou   The consts object should still be in list form to allow new constants
285644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton   to be appended.
286644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton
287644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton   To keep the optimizer simple, it bails out (does nothing) for code
288c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou   containing extended arguments or that has a length over 32,700.  That
289c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou   allows us to avoid overflow and sign issues.  Likewise, it bails when
290644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton   the lineno table has complex encoding for gaps >= 255.
291644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton
292b1d867f14965e2369d31a3fcdab5bca34b4d81b4Martin Panter   Optimizations are restricted to simple transformations occurring within a
293c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou   single basic block.  All transformations keep the code size the same or
294c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou   smaller.  For those that reduce size, the gaps are initially filled with
295c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou   NOPs.  Later those NOPs are removed and the jump addresses retargeted in
296644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton   a single pass.  Line numbering is adjusted accordingly. */
297644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton
298644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy HyltonPyObject *
299644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy HyltonPyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
300644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton                PyObject *lineno_obj)
301644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton{
302c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_ssize_t i, j, codelen;
303c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int nops, h, adj;
304c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int tgt, tgttgt, opcode;
305c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    unsigned char *codestr = NULL;
306c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    unsigned char *lineno;
307c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int *addrmap = NULL;
308c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int new_line, cum_orig_line, last_line, tabsiz;
309c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int cumlc=0, lastlc=0;      /* Count runs of consecutive LOAD_CONSTs */
310c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    unsigned int *blocks = NULL;
311c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    char *name;
312c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
313c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Bail out if an exception is set */
314c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyErr_Occurred())
315c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto exitError;
316c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
317c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Bypass optimization when the lineno table is too complex */
318c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(PyString_Check(lineno_obj));
319c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    lineno = (unsigned char*)PyString_AS_STRING(lineno_obj);
320c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    tabsiz = PyString_GET_SIZE(lineno_obj);
321c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (memchr(lineno, 255, tabsiz) != NULL)
322c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto exitUnchanged;
323c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
324c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Avoid situations where jump retargeting could overflow */
325c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(PyString_Check(code));
326c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    codelen = PyString_GET_SIZE(code);
327c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (codelen > 32700)
328c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto exitUnchanged;
329c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
330c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Make a modifiable copy of the code string */
331c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    codestr = (unsigned char *)PyMem_Malloc(codelen);
332c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (codestr == NULL)
333c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto exitError;
334c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    codestr = (unsigned char *)memcpy(codestr,
335c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                      PyString_AS_STRING(code), codelen);
336c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
337dee8af225b04c28b2ed7e9dfcef6d93b7ae1c827Raymond Hettinger    /* Verify that RETURN_VALUE terminates the codestring. This allows
338c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou       the various transformation patterns to look ahead several
339c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou       instructions without additional checks to make sure they are not
340c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou       looking beyond the end of the code string.
341c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    */
342c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (codestr[codelen-1] != RETURN_VALUE)
343c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto exitUnchanged;
344c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
345c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Mapping to new jump targets after NOPs are removed */
346a2269d074b02440b7a9c22115454ad7e33aeb3f4Serhiy Storchaka    addrmap = PyMem_New(int, codelen);
347a2269d074b02440b7a9c22115454ad7e33aeb3f4Serhiy Storchaka    if (addrmap == NULL) {
348a2269d074b02440b7a9c22115454ad7e33aeb3f4Serhiy Storchaka        PyErr_NoMemory();
349c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto exitError;
350a2269d074b02440b7a9c22115454ad7e33aeb3f4Serhiy Storchaka    }
351c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
352c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    blocks = markblocks(codestr, codelen);
353c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (blocks == NULL)
354c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto exitError;
355c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(PyList_Check(consts));
356c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
357c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    for (i=0 ; i<codelen ; i += CODESIZE(codestr[i])) {
358c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou      reoptimize_current:
359c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        opcode = codestr[i];
360c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
361c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        lastlc = cumlc;
362c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        cumlc = 0;
363c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
364c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        switch (opcode) {
365c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            /* Replace UNARY_NOT POP_JUMP_IF_FALSE
366c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou               with    POP_JUMP_IF_TRUE */
367c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case UNARY_NOT:
368c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                if (codestr[i+1] != POP_JUMP_IF_FALSE
369c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    || !ISBASICBLOCK(blocks,i,4))
370c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    continue;
371c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                j = GETARG(codestr, i+1);
372c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                codestr[i] = POP_JUMP_IF_TRUE;
373c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                SETARG(codestr, i, j);
374c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                codestr[i+3] = NOP;
375c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                goto reoptimize_current;
376c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
377c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                /* not a is b -->  a is not b
378c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                   not a in b -->  a not in b
379c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                   not a is not b -->  a is b
380c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                   not a not in b -->  a in b
381c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                */
382c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case COMPARE_OP:
383c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                j = GETARG(codestr, i);
384c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                if (j < 6  ||  j > 9  ||
385c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    codestr[i+3] != UNARY_NOT  ||
386c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    !ISBASICBLOCK(blocks,i,4))
387c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    continue;
388c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                SETARG(codestr, i, (j^1));
389c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                codestr[i+3] = NOP;
390c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                break;
391c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
392c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                /* Replace LOAD_GLOBAL/LOAD_NAME None
393c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                   with LOAD_CONST None */
394c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case LOAD_NAME:
395c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case LOAD_GLOBAL:
396c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                j = GETARG(codestr, i);
397c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                name = PyString_AsString(PyTuple_GET_ITEM(names, j));
398c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                if (name == NULL  ||  strcmp(name, "None") != 0)
399c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    continue;
400c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                for (j=0 ; j < PyList_GET_SIZE(consts) ; j++) {
401c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    if (PyList_GET_ITEM(consts, j) == Py_None)
402c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        break;
403c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                }
404c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                if (j == PyList_GET_SIZE(consts)) {
405c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    if (PyList_Append(consts, Py_None) == -1)
406c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        goto exitError;
407c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                }
408c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                assert(PyList_GET_ITEM(consts, j) == Py_None);
409c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                codestr[i] = LOAD_CONST;
410c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                SETARG(codestr, i, j);
411c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                cumlc = lastlc + 1;
412c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                break;
413c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
414c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                /* Skip over LOAD_CONST trueconst
415c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                   POP_JUMP_IF_FALSE xx. This improves
416c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                   "while 1" performance. */
417c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case LOAD_CONST:
418c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                cumlc = lastlc + 1;
419c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                j = GETARG(codestr, i);
420c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                if (codestr[i+3] != POP_JUMP_IF_FALSE  ||
421c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    !ISBASICBLOCK(blocks,i,6)  ||
422c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    !PyObject_IsTrue(PyList_GET_ITEM(consts, j)))
423c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    continue;
424c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                memset(codestr+i, NOP, 6);
425c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                cumlc = 0;
426c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                break;
427c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
428c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                /* Try to fold tuples of constants (includes a case for lists
429c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                   which are only used for "in" and "not in" tests).
430c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                   Skip over BUILD_SEQN 1 UNPACK_SEQN 1.
431c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                   Replace BUILD_SEQN 2 UNPACK_SEQN 2 with ROT2.
432c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                   Replace BUILD_SEQN 3 UNPACK_SEQN 3 with ROT3 ROT2. */
433c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case BUILD_TUPLE:
434c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case BUILD_LIST:
435c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                j = GETARG(codestr, i);
436c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                h = i - 3 * j;
437dee8af225b04c28b2ed7e9dfcef6d93b7ae1c827Raymond Hettinger                if (h >= 0 &&
438dee8af225b04c28b2ed7e9dfcef6d93b7ae1c827Raymond Hettinger                    j <= lastlc &&
439c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    ((opcode == BUILD_TUPLE &&
440c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      ISBASICBLOCK(blocks, h, 3*(j+1))) ||
441c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                     (opcode == BUILD_LIST &&
442c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      codestr[i+3]==COMPARE_OP &&
443c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      ISBASICBLOCK(blocks, h, 3*(j+2)) &&
444c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      (GETARG(codestr,i+3)==6 ||
445c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                       GETARG(codestr,i+3)==7))) &&
446c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    tuple_of_constants(&codestr[h], j, consts)) {
447c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    assert(codestr[i] == LOAD_CONST);
448c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    cumlc = 1;
449c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    break;
450c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                }
451c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                if (codestr[i+3] != UNPACK_SEQUENCE  ||
452c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    !ISBASICBLOCK(blocks,i,6) ||
453c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    j != GETARG(codestr, i+3))
454c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    continue;
455c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                if (j == 1) {
456c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    memset(codestr+i, NOP, 6);
457c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                } else if (j == 2) {
458c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    codestr[i] = ROT_TWO;
459c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    memset(codestr+i+1, NOP, 5);
460c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                } else if (j == 3) {
461c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    codestr[i] = ROT_THREE;
462c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    codestr[i+1] = ROT_TWO;
463c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    memset(codestr+i+2, NOP, 4);
464c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                }
465c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                break;
466c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
467c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                /* Fold binary ops on constants.
468c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                   LOAD_CONST c1 LOAD_CONST c2 BINOP -->  LOAD_CONST binop(c1,c2) */
469c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case BINARY_POWER:
470c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case BINARY_MULTIPLY:
471c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case BINARY_TRUE_DIVIDE:
472c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case BINARY_FLOOR_DIVIDE:
473c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case BINARY_MODULO:
474c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case BINARY_ADD:
475c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case BINARY_SUBTRACT:
476c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case BINARY_SUBSCR:
477c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case BINARY_LSHIFT:
478c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case BINARY_RSHIFT:
479c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case BINARY_AND:
480c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case BINARY_XOR:
481c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case BINARY_OR:
482dee8af225b04c28b2ed7e9dfcef6d93b7ae1c827Raymond Hettinger                if (lastlc >= 2 &&
483dee8af225b04c28b2ed7e9dfcef6d93b7ae1c827Raymond Hettinger                    ISBASICBLOCK(blocks, i-6, 7) &&
484c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    fold_binops_on_constants(&codestr[i-6], consts)) {
485c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    i -= 2;
486c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    assert(codestr[i] == LOAD_CONST);
487c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    cumlc = 1;
488c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                }
489c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                break;
490c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
491c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                /* Fold unary ops on constants.
492dee8af225b04c28b2ed7e9dfcef6d93b7ae1c827Raymond Hettinger                   LOAD_CONST c1  UNARY_OP --> LOAD_CONST unary_op(c) */
493c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case UNARY_NEGATIVE:
494c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case UNARY_CONVERT:
495c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case UNARY_INVERT:
496dee8af225b04c28b2ed7e9dfcef6d93b7ae1c827Raymond Hettinger                if (lastlc >= 1 &&
497dee8af225b04c28b2ed7e9dfcef6d93b7ae1c827Raymond Hettinger                    ISBASICBLOCK(blocks, i-3, 4) &&
498dee8af225b04c28b2ed7e9dfcef6d93b7ae1c827Raymond Hettinger                    fold_unaryops_on_constants(&codestr[i-3], consts)) {
499c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    i -= 2;
500c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    assert(codestr[i] == LOAD_CONST);
501c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    cumlc = 1;
502c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                }
503c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                break;
504c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
505c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                /* Simplify conditional jump to conditional jump where the
506c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                   result of the first test implies the success of a similar
507c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                   test or the failure of the opposite test.
508c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                   Arises in code like:
509c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                   "if a and b:"
510c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                   "if a or b:"
511c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                   "a and b or c"
512c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                   "(a and b) and c"
513c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                   x:JUMP_IF_FALSE_OR_POP y   y:JUMP_IF_FALSE_OR_POP z
514c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      -->  x:JUMP_IF_FALSE_OR_POP z
515c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                   x:JUMP_IF_FALSE_OR_POP y   y:JUMP_IF_TRUE_OR_POP z
516c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      -->  x:POP_JUMP_IF_FALSE y+3
517c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                   where y+3 is the instruction following the second test.
518c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                */
519c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case JUMP_IF_FALSE_OR_POP:
520c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case JUMP_IF_TRUE_OR_POP:
521c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                tgt = GETJUMPTGT(codestr, i);
522c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                j = codestr[tgt];
523c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                if (CONDITIONAL_JUMP(j)) {
524dee8af225b04c28b2ed7e9dfcef6d93b7ae1c827Raymond Hettinger                    /* NOTE: all possible jumps here are absolute! */
525c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    if (JUMPS_ON_TRUE(j) == JUMPS_ON_TRUE(opcode)) {
526c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        /* The second jump will be
527c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                           taken iff the first is. */
528c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        tgttgt = GETJUMPTGT(codestr, tgt);
529c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        /* The current opcode inherits
530c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                           its target's stack behaviour */
531c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        codestr[i] = j;
532c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        SETARG(codestr, i, tgttgt);
533c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        goto reoptimize_current;
534c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    } else {
535dee8af225b04c28b2ed7e9dfcef6d93b7ae1c827Raymond Hettinger                        /* The second jump is not taken if the first is (so
536dee8af225b04c28b2ed7e9dfcef6d93b7ae1c827Raymond Hettinger                           jump past it), and all conditional jumps pop their
537dee8af225b04c28b2ed7e9dfcef6d93b7ae1c827Raymond Hettinger                           argument when they're not taken (so change the
538dee8af225b04c28b2ed7e9dfcef6d93b7ae1c827Raymond Hettinger                           first jump to pop its argument when it's taken). */
539c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        if (JUMPS_ON_TRUE(opcode))
540c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                            codestr[i] = POP_JUMP_IF_TRUE;
541c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        else
542c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                            codestr[i] = POP_JUMP_IF_FALSE;
543c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        SETARG(codestr, i, (tgt + 3));
544c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        goto reoptimize_current;
545c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    }
546c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                }
547c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                /* Intentional fallthrough */
548c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
549c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                /* Replace jumps to unconditional jumps */
550c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case POP_JUMP_IF_FALSE:
551c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case POP_JUMP_IF_TRUE:
552c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case FOR_ITER:
553c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case JUMP_FORWARD:
554c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case JUMP_ABSOLUTE:
555c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case CONTINUE_LOOP:
556c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case SETUP_LOOP:
557c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case SETUP_EXCEPT:
558c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case SETUP_FINALLY:
559c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case SETUP_WITH:
560c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                tgt = GETJUMPTGT(codestr, i);
561c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                /* Replace JUMP_* to a RETURN into just a RETURN */
562c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                if (UNCONDITIONAL_JUMP(opcode) &&
563c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    codestr[tgt] == RETURN_VALUE) {
564c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    codestr[i] = RETURN_VALUE;
565c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    memset(codestr+i+1, NOP, 2);
566c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    continue;
567c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                }
568c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                if (!UNCONDITIONAL_JUMP(codestr[tgt]))
569c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    continue;
570c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                tgttgt = GETJUMPTGT(codestr, tgt);
571c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                if (opcode == JUMP_FORWARD) /* JMP_ABS can go backwards */
572c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    opcode = JUMP_ABSOLUTE;
573c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                if (!ABSOLUTE_JUMP(opcode))
574dee8af225b04c28b2ed7e9dfcef6d93b7ae1c827Raymond Hettinger                    tgttgt -= i + 3;        /* Calc relative jump addr */
575dee8af225b04c28b2ed7e9dfcef6d93b7ae1c827Raymond Hettinger                if (tgttgt < 0)             /* No backward relative jumps */
576c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    continue;
577c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                codestr[i] = opcode;
578c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                SETARG(codestr, i, tgttgt);
579c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                break;
580c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
581c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case EXTENDED_ARG:
582c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                goto exitUnchanged;
583c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
584c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                /* Replace RETURN LOAD_CONST None RETURN with just RETURN */
585c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                /* Remove unreachable JUMPs after RETURN */
586c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case RETURN_VALUE:
587c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                if (i+4 >= codelen)
588c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    continue;
589c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                if (codestr[i+4] == RETURN_VALUE &&
590c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    ISBASICBLOCK(blocks,i,5))
591c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    memset(codestr+i+1, NOP, 4);
592c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                else if (UNCONDITIONAL_JUMP(codestr[i+1]) &&
593c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                         ISBASICBLOCK(blocks,i,4))
594c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    memset(codestr+i+1, NOP, 3);
595c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                break;
596c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
597c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
598c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
599c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Fixup linenotab */
600c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    for (i=0, nops=0 ; i<codelen ; i += CODESIZE(codestr[i])) {
601c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        addrmap[i] = i - nops;
602c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (codestr[i] == NOP)
603c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            nops++;
604c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
605c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    cum_orig_line = 0;
606c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    last_line = 0;
607c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    for (i=0 ; i < tabsiz ; i+=2) {
608c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        cum_orig_line += lineno[i];
609c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        new_line = addrmap[cum_orig_line];
610c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        assert (new_line - last_line < 255);
611c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        lineno[i] =((unsigned char)(new_line - last_line));
612c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        last_line = new_line;
613c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
614c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
615c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Remove NOPs and fixup jump targets */
616c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    for (i=0, h=0 ; i<codelen ; ) {
617c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        opcode = codestr[i];
618c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        switch (opcode) {
619c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case NOP:
620c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                i++;
621c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                continue;
622c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
623c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case JUMP_ABSOLUTE:
624c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case CONTINUE_LOOP:
625c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case POP_JUMP_IF_FALSE:
626c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case POP_JUMP_IF_TRUE:
627c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case JUMP_IF_FALSE_OR_POP:
628c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case JUMP_IF_TRUE_OR_POP:
629c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                j = addrmap[GETARG(codestr, i)];
630c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                SETARG(codestr, i, j);
631c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                break;
632c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
633c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case FOR_ITER:
634c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case JUMP_FORWARD:
635c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case SETUP_LOOP:
636c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case SETUP_EXCEPT:
637c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case SETUP_FINALLY:
638c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            case SETUP_WITH:
639c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                j = addrmap[GETARG(codestr, i) + i + 3] - addrmap[i] - 3;
640c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                SETARG(codestr, i, j);
641c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                break;
642c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
643c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        adj = CODESIZE(opcode);
644c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        while (adj--)
645c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            codestr[h++] = codestr[i++];
646c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
647c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(h + nops == codelen);
648c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
649c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    code = PyString_FromStringAndSize((char *)codestr, h);
650c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyMem_Free(addrmap);
651c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyMem_Free(codestr);
652c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyMem_Free(blocks);
653c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return code;
654644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton
655e323e0e91a27df127f53d24f2d741c2172e11233Georg Brandl exitError:
656c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    code = NULL;
657e323e0e91a27df127f53d24f2d741c2172e11233Georg Brandl
658644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton exitUnchanged:
659c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (blocks != NULL)
660c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyMem_Free(blocks);
661c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (addrmap != NULL)
662c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyMem_Free(addrmap);
663c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (codestr != NULL)
664c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyMem_Free(codestr);
665c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_XINCREF(code);
666c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return code;
667644dddcc3f0ae886fe92f23cdce3e24c5e032566Jeremy Hylton}
668