Python-2.7.3/Python/peephole.c

No issues found

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