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