Ignore:
Timestamp:
Mar 19, 2014, 11:11:30 AM (11 years ago)
Author:
dmik
Message:

python: Update vendor to 2.7.6.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • python/vendor/current/Python/peephole.c

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