blob: d31c89b86e9f1eb5bc795e0532863be4b3b98424 [file] [log] [blame]
Guido van Rossumd8faa362007-04-27 19:54:29 +00001/* Peephole optimizations for bytecode compiler. */
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002
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 ABSOLUTE_JUMP(op) (op==JUMP_ABSOLUTE || op==CONTINUE_LOOP)
17#define GETJUMPTGT(arr, i) (GETARG(arr,i) + (ABSOLUTE_JUMP(arr[i]) ? 0 : i+3))
18#define SETARG(arr, i, val) arr[i+2] = val>>8; arr[i+1] = val & 255
19#define CODESIZE(op) (HAS_ARG(op) ? 3 : 1)
20#define ISBASICBLOCK(blocks, start, bytes) \
21 (blocks[start]==blocks[start+bytes-1])
22
23/* Replace LOAD_CONST c1. LOAD_CONST c2 ... LOAD_CONST cn BUILD_TUPLE n
24 with LOAD_CONST (c1, c2, ... cn).
25 The consts table must still be in list form so that the
26 new constant (c1, c2, ... cn) can be appended.
27 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.
29 Also works for BUILD_LIST when followed by an "in" or "not in" test.
30*/
31static int
Christian Heimescc47b052008-03-25 14:56:36 +000032tuple_of_constants(unsigned char *codestr, Py_ssize_t n, PyObject *consts)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000033{
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;
70}
71
72/* Replace LOAD_CONST c1. LOAD_CONST c2 BINOP
73 with LOAD_CONST binop(c1,c2)
74 The consts table must still be in list form so that the
75 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').
78 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.
81*/
82static int
83fold_binops_on_constants(unsigned char *codestr, PyObject *consts)
84{
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_TRUE_DIVIDE:
106 newconst = PyNumber_TrueDivide(v, w);
107 break;
108 case BINARY_FLOOR_DIVIDE:
109 newconst = PyNumber_FloorDivide(v, w);
110 break;
111 case BINARY_MODULO:
112 newconst = PyNumber_Remainder(v, w);
113 break;
114 case BINARY_ADD:
115 newconst = PyNumber_Add(v, w);
116 break;
117 case BINARY_SUBTRACT:
118 newconst = PyNumber_Subtract(v, w);
119 break;
120 case BINARY_SUBSCR:
121 newconst = PyObject_GetItem(v, w);
122 break;
123 case BINARY_LSHIFT:
124 newconst = PyNumber_Lshift(v, w);
125 break;
126 case BINARY_RSHIFT:
127 newconst = PyNumber_Rshift(v, w);
128 break;
129 case BINARY_AND:
130 newconst = PyNumber_And(v, w);
131 break;
132 case BINARY_XOR:
133 newconst = PyNumber_Xor(v, w);
134 break;
135 case BINARY_OR:
136 newconst = PyNumber_Or(v, w);
137 break;
138 default:
139 /* Called with an unknown opcode */
140 PyErr_Format(PyExc_SystemError,
141 "unexpected binary operation %d on a constant",
142 opcode);
143 return 0;
144 }
145 if (newconst == NULL) {
146 PyErr_Clear();
147 return 0;
148 }
149 size = PyObject_Size(newconst);
150 if (size == -1)
151 PyErr_Clear();
152 else if (size > 20) {
153 Py_DECREF(newconst);
154 return 0;
155 }
156
157 /* Append folded constant into consts table */
158 len_consts = PyList_GET_SIZE(consts);
159 if (PyList_Append(consts, newconst)) {
160 Py_DECREF(newconst);
161 return 0;
162 }
163 Py_DECREF(newconst);
164
165 /* Write NOP NOP NOP NOP LOAD_CONST newconst */
166 memset(codestr, NOP, 4);
167 codestr[4] = LOAD_CONST;
168 SETARG(codestr, 4, len_consts);
169 return 1;
170}
171
172static int
173fold_unaryops_on_constants(unsigned char *codestr, PyObject *consts)
174{
175 PyObject *newconst=NULL, *v;
176 Py_ssize_t len_consts;
177 int opcode;
178
179 /* Pre-conditions */
180 assert(PyList_CheckExact(consts));
181 assert(codestr[0] == LOAD_CONST);
182
183 /* Create new constant */
184 v = PyList_GET_ITEM(consts, GETARG(codestr, 0));
185 opcode = codestr[3];
186 switch (opcode) {
187 case UNARY_NEGATIVE:
188 /* Preserve the sign of -0.0 */
189 if (PyObject_IsTrue(v) == 1)
190 newconst = PyNumber_Negative(v);
191 break;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000192 case UNARY_INVERT:
193 newconst = PyNumber_Invert(v);
194 break;
195 default:
196 /* Called with an unknown opcode */
197 PyErr_Format(PyExc_SystemError,
198 "unexpected unary operation %d on a constant",
199 opcode);
200 return 0;
201 }
202 if (newconst == NULL) {
203 PyErr_Clear();
204 return 0;
205 }
206
207 /* Append folded constant into consts table */
208 len_consts = PyList_GET_SIZE(consts);
209 if (PyList_Append(consts, newconst)) {
210 Py_DECREF(newconst);
211 return 0;
212 }
213 Py_DECREF(newconst);
214
215 /* Write NOP LOAD_CONST newconst */
216 codestr[0] = NOP;
217 codestr[1] = LOAD_CONST;
218 SETARG(codestr, 1, len_consts);
219 return 1;
220}
221
222static unsigned int *
Christian Heimescc47b052008-03-25 14:56:36 +0000223markblocks(unsigned char *code, Py_ssize_t len)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000224{
225 unsigned int *blocks = (unsigned int *)PyMem_Malloc(len*sizeof(int));
226 int i,j, opcode, blockcnt = 0;
227
228 if (blocks == NULL) {
229 PyErr_NoMemory();
230 return NULL;
231 }
232 memset(blocks, 0, len*sizeof(int));
233
234 /* Mark labels in the first pass */
235 for (i=0 ; i<len ; i+=CODESIZE(opcode)) {
236 opcode = code[i];
237 switch (opcode) {
238 case FOR_ITER:
239 case JUMP_FORWARD:
240 case JUMP_IF_FALSE:
241 case JUMP_IF_TRUE:
242 case JUMP_ABSOLUTE:
243 case CONTINUE_LOOP:
244 case SETUP_LOOP:
245 case SETUP_EXCEPT:
246 case SETUP_FINALLY:
247 j = GETJUMPTGT(code, i);
248 blocks[j] = 1;
249 break;
250 }
251 }
252 /* Build block numbers in the second pass */
253 for (i=0 ; i<len ; i++) {
254 blockcnt += blocks[i]; /* increment blockcnt over labels */
255 blocks[i] = blockcnt;
256 }
257 return blocks;
258}
259
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000260/* Helper to replace LOAD_NAME None/True/False with LOAD_CONST
261 Returns: 0 if no change, 1 if change, -1 if error */
262static int
263load_global(unsigned char *codestr, Py_ssize_t i, char *name, PyObject *consts)
264{
265 Py_ssize_t j;
266 PyObject *obj;
267 if (name == NULL)
268 return 0;
269 if (strcmp(name, "None") == 0)
270 obj = Py_None;
271 else if (strcmp(name, "True") == 0)
272 obj = Py_True;
273 else if (strcmp(name, "False") == 0)
274 obj = Py_False;
275 else
276 return 0;
277 for (j = 0; j < PyList_GET_SIZE(consts); j++) {
278 if (PyList_GET_ITEM(consts, j) == obj)
279 break;
280 }
281 if (j == PyList_GET_SIZE(consts)) {
282 if (PyList_Append(consts, obj) < 0)
283 return -1;
284 }
285 assert(PyList_GET_ITEM(consts, j) == obj);
286 codestr[i] = LOAD_CONST;
287 SETARG(codestr, i, j);
288 return 1;
289}
290
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000291/* Perform basic peephole optimizations to components of a code object.
292 The consts object should still be in list form to allow new constants
293 to be appended.
294
Guido van Rossum0240b922007-02-26 21:23:50 +0000295 To keep the optimizer simple, it bails out (does nothing) for code that
296 has a length over 32,700, and does not calculate extended arguments.
297 That allows us to avoid overflow and sign issues. Likewise, it bails when
298 the lineno table has complex encoding for gaps >= 255. EXTENDED_ARG can
299 appear before MAKE_FUNCTION; in this case both opcodes are skipped.
300 EXTENDED_ARG preceding any other opcode causes the optimizer to bail.
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000301
302 Optimizations are restricted to simple transformations occuring within a
303 single basic block. All transformations keep the code size the same or
304 smaller. For those that reduce size, the gaps are initially filled with
305 NOPs. Later those NOPs are removed and the jump addresses retargeted in
306 a single pass. Line numbering is adjusted accordingly. */
307
308PyObject *
309PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
310 PyObject *lineno_obj)
311{
312 Py_ssize_t i, j, codelen;
313 int nops, h, adj;
314 int tgt, tgttgt, opcode;
315 unsigned char *codestr = NULL;
316 unsigned char *lineno;
317 int *addrmap = NULL;
318 int new_line, cum_orig_line, last_line, tabsiz;
319 int cumlc=0, lastlc=0; /* Count runs of consecutive LOAD_CONSTs */
320 unsigned int *blocks = NULL;
321 char *name;
322
323 /* Bail out if an exception is set */
324 if (PyErr_Occurred())
325 goto exitUnchanged;
326
327 /* Bypass optimization when the lineno table is too complex */
Christian Heimes72b710a2008-05-26 13:28:38 +0000328 assert(PyBytes_Check(lineno_obj));
329 lineno = (unsigned char*)PyBytes_AS_STRING(lineno_obj);
330 tabsiz = PyBytes_GET_SIZE(lineno_obj);
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000331 if (memchr(lineno, 255, tabsiz) != NULL)
332 goto exitUnchanged;
333
334 /* Avoid situations where jump retargeting could overflow */
Christian Heimes72b710a2008-05-26 13:28:38 +0000335 assert(PyBytes_Check(code));
336 codelen = PyBytes_GET_SIZE(code);
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000337 if (codelen > 32700)
338 goto exitUnchanged;
339
340 /* Make a modifiable copy of the code string */
341 codestr = (unsigned char *)PyMem_Malloc(codelen);
342 if (codestr == NULL)
343 goto exitUnchanged;
344 codestr = (unsigned char *)memcpy(codestr,
Christian Heimes72b710a2008-05-26 13:28:38 +0000345 PyBytes_AS_STRING(code), codelen);
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000346
347 /* Verify that RETURN_VALUE terminates the codestring. This allows
348 the various transformation patterns to look ahead several
349 instructions without additional checks to make sure they are not
350 looking beyond the end of the code string.
351 */
352 if (codestr[codelen-1] != RETURN_VALUE)
353 goto exitUnchanged;
354
355 /* Mapping to new jump targets after NOPs are removed */
356 addrmap = (int *)PyMem_Malloc(codelen * sizeof(int));
357 if (addrmap == NULL)
358 goto exitUnchanged;
359
360 blocks = markblocks(codestr, codelen);
361 if (blocks == NULL)
362 goto exitUnchanged;
363 assert(PyList_Check(consts));
364
365 for (i=0 ; i<codelen ; i += CODESIZE(codestr[i])) {
366 opcode = codestr[i];
367
368 lastlc = cumlc;
369 cumlc = 0;
370
371 switch (opcode) {
372
373 /* Replace UNARY_NOT JUMP_IF_FALSE POP_TOP with
374 with JUMP_IF_TRUE POP_TOP */
375 case UNARY_NOT:
376 if (codestr[i+1] != JUMP_IF_FALSE ||
377 codestr[i+4] != POP_TOP ||
378 !ISBASICBLOCK(blocks,i,5))
379 continue;
380 tgt = GETJUMPTGT(codestr, (i+1));
381 if (codestr[tgt] != POP_TOP)
382 continue;
383 j = GETARG(codestr, i+1) + 1;
384 codestr[i] = JUMP_IF_TRUE;
385 SETARG(codestr, i, j);
386 codestr[i+3] = POP_TOP;
387 codestr[i+4] = NOP;
388 break;
389
390 /* not a is b --> a is not b
391 not a in b --> a not in b
392 not a is not b --> a is b
393 not a not in b --> a in b
394 */
395 case COMPARE_OP:
396 j = GETARG(codestr, i);
397 if (j < 6 || j > 9 ||
398 codestr[i+3] != UNARY_NOT ||
399 !ISBASICBLOCK(blocks,i,4))
400 continue;
401 SETARG(codestr, i, (j^1));
402 codestr[i+3] = NOP;
403 break;
404
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000405 /* Replace LOAD_GLOBAL/LOAD_NAME None/True/False
406 with LOAD_CONST None/True/False */
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000407 case LOAD_NAME:
408 case LOAD_GLOBAL:
409 j = GETARG(codestr, i);
Marc-André Lemburg4cc0f242008-08-07 18:54:33 +0000410 name = _PyUnicode_AsString(PyTuple_GET_ITEM(names, j));
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000411 h = load_global(codestr, i, name, consts);
412 if (h < 0)
413 goto exitUnchanged;
414 else if (h == 0)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000415 continue;
Guido van Rossumd8faa362007-04-27 19:54:29 +0000416 cumlc = lastlc + 1;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000417 break;
418
419 /* Skip over LOAD_CONST trueconst
420 JUMP_IF_FALSE xx POP_TOP */
421 case LOAD_CONST:
422 cumlc = lastlc + 1;
423 j = GETARG(codestr, i);
424 if (codestr[i+3] != JUMP_IF_FALSE ||
425 codestr[i+6] != POP_TOP ||
426 !ISBASICBLOCK(blocks,i,7) ||
427 !PyObject_IsTrue(PyList_GET_ITEM(consts, j)))
428 continue;
429 memset(codestr+i, NOP, 7);
430 cumlc = 0;
431 break;
432
Raymond Hettingere56131b2008-11-18 00:07:10 +0000433 /* Replace POP_TOP JUMP_FORWARD 1 POP_TOP
434 with NOP NOP NOP NOP POP_TOP. */
435 case POP_TOP:
436 if (UNCONDITIONAL_JUMP(codestr[i+1]) &&
437 GETJUMPTGT(codestr, i+1) == i+5 &&
438 codestr[i+4] == POP_TOP &&
439 ISBASICBLOCK(blocks,i,4))
440 memset(codestr+i, NOP, 4);
441 break;
442
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000443 /* Try to fold tuples of constants (includes a case for lists
444 which are only used for "in" and "not in" tests).
445 Skip over BUILD_SEQN 1 UNPACK_SEQN 1.
446 Replace BUILD_SEQN 2 UNPACK_SEQN 2 with ROT2.
447 Replace BUILD_SEQN 3 UNPACK_SEQN 3 with ROT3 ROT2. */
448 case BUILD_TUPLE:
449 case BUILD_LIST:
450 j = GETARG(codestr, i);
451 h = i - 3 * j;
452 if (h >= 0 &&
453 j <= lastlc &&
454 ((opcode == BUILD_TUPLE &&
455 ISBASICBLOCK(blocks, h, 3*(j+1))) ||
456 (opcode == BUILD_LIST &&
457 codestr[i+3]==COMPARE_OP &&
458 ISBASICBLOCK(blocks, h, 3*(j+2)) &&
459 (GETARG(codestr,i+3)==6 ||
460 GETARG(codestr,i+3)==7))) &&
461 tuple_of_constants(&codestr[h], j, consts)) {
462 assert(codestr[i] == LOAD_CONST);
463 cumlc = 1;
464 break;
465 }
466 if (codestr[i+3] != UNPACK_SEQUENCE ||
467 !ISBASICBLOCK(blocks,i,6) ||
468 j != GETARG(codestr, i+3))
469 continue;
470 if (j == 1) {
471 memset(codestr+i, NOP, 6);
472 } else if (j == 2) {
473 codestr[i] = ROT_TWO;
474 memset(codestr+i+1, NOP, 5);
475 } else if (j == 3) {
476 codestr[i] = ROT_THREE;
477 codestr[i+1] = ROT_TWO;
478 memset(codestr+i+2, NOP, 4);
479 }
480 break;
481
482 /* Fold binary ops on constants.
483 LOAD_CONST c1 LOAD_CONST c2 BINOP --> LOAD_CONST binop(c1,c2) */
484 case BINARY_POWER:
485 case BINARY_MULTIPLY:
486 case BINARY_TRUE_DIVIDE:
487 case BINARY_FLOOR_DIVIDE:
488 case BINARY_MODULO:
489 case BINARY_ADD:
490 case BINARY_SUBTRACT:
491 case BINARY_SUBSCR:
492 case BINARY_LSHIFT:
493 case BINARY_RSHIFT:
494 case BINARY_AND:
495 case BINARY_XOR:
496 case BINARY_OR:
497 if (lastlc >= 2 &&
498 ISBASICBLOCK(blocks, i-6, 7) &&
499 fold_binops_on_constants(&codestr[i-6], consts)) {
500 i -= 2;
501 assert(codestr[i] == LOAD_CONST);
502 cumlc = 1;
503 }
504 break;
505
506 /* Fold unary ops on constants.
507 LOAD_CONST c1 UNARY_OP --> LOAD_CONST unary_op(c) */
508 case UNARY_NEGATIVE:
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000509 case UNARY_INVERT:
510 if (lastlc >= 1 &&
511 ISBASICBLOCK(blocks, i-3, 4) &&
512 fold_unaryops_on_constants(&codestr[i-3], consts)) {
513 i -= 2;
514 assert(codestr[i] == LOAD_CONST);
515 cumlc = 1;
516 }
517 break;
518
519 /* Simplify conditional jump to conditional jump where the
520 result of the first test implies the success of a similar
521 test or the failure of the opposite test.
522 Arises in code like:
523 "if a and b:"
524 "if a or b:"
525 "a and b or c"
526 "(a and b) and c"
527 x:JUMP_IF_FALSE y y:JUMP_IF_FALSE z --> x:JUMP_IF_FALSE z
528 x:JUMP_IF_FALSE y y:JUMP_IF_TRUE z --> x:JUMP_IF_FALSE y+3
529 where y+3 is the instruction following the second test.
530 */
531 case JUMP_IF_FALSE:
532 case JUMP_IF_TRUE:
533 tgt = GETJUMPTGT(codestr, i);
534 j = codestr[tgt];
535 if (j == JUMP_IF_FALSE || j == JUMP_IF_TRUE) {
536 if (j == opcode) {
537 tgttgt = GETJUMPTGT(codestr, tgt) - i - 3;
538 SETARG(codestr, i, tgttgt);
539 } else {
540 tgt -= i;
541 SETARG(codestr, i, tgt);
542 }
543 break;
544 }
545 /* Intentional fallthrough */
546
547 /* Replace jumps to unconditional jumps */
548 case FOR_ITER:
549 case JUMP_FORWARD:
550 case JUMP_ABSOLUTE:
551 case CONTINUE_LOOP:
552 case SETUP_LOOP:
553 case SETUP_EXCEPT:
554 case SETUP_FINALLY:
555 tgt = GETJUMPTGT(codestr, i);
Thomas Wouters89f507f2006-12-13 04:49:30 +0000556 /* Replace JUMP_* to a RETURN into just a RETURN */
557 if (UNCONDITIONAL_JUMP(opcode) &&
558 codestr[tgt] == RETURN_VALUE) {
559 codestr[i] = RETURN_VALUE;
560 memset(codestr+i+1, NOP, 2);
561 continue;
562 }
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000563 if (!UNCONDITIONAL_JUMP(codestr[tgt]))
564 continue;
565 tgttgt = GETJUMPTGT(codestr, tgt);
566 if (opcode == JUMP_FORWARD) /* JMP_ABS can go backwards */
567 opcode = JUMP_ABSOLUTE;
568 if (!ABSOLUTE_JUMP(opcode))
569 tgttgt -= i + 3; /* Calc relative jump addr */
570 if (tgttgt < 0) /* No backward relative jumps */
571 continue;
572 codestr[i] = opcode;
573 SETARG(codestr, i, tgttgt);
574 break;
575
576 case EXTENDED_ARG:
Guido van Rossum0240b922007-02-26 21:23:50 +0000577 if (codestr[i+3] != MAKE_FUNCTION)
578 goto exitUnchanged;
579 /* don't visit MAKE_FUNCTION as GETARG will be wrong */
580 i += 3;
581 break;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000582
583 /* Replace RETURN LOAD_CONST None RETURN with just RETURN */
Thomas Wouters89f507f2006-12-13 04:49:30 +0000584 /* Remove unreachable JUMPs after RETURN */
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000585 case RETURN_VALUE:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000586 if (i+4 >= codelen)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000587 continue;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000588 if (codestr[i+4] == RETURN_VALUE &&
589 ISBASICBLOCK(blocks,i,5))
590 memset(codestr+i+1, NOP, 4);
591 else if (UNCONDITIONAL_JUMP(codestr[i+1]) &&
592 ISBASICBLOCK(blocks,i,4))
593 memset(codestr+i+1, NOP, 3);
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000594 break;
595 }
596 }
597
598 /* Fixup linenotab */
599 for (i=0, nops=0 ; i<codelen ; i += CODESIZE(codestr[i])) {
600 addrmap[i] = i - nops;
601 if (codestr[i] == NOP)
602 nops++;
603 }
604 cum_orig_line = 0;
605 last_line = 0;
606 for (i=0 ; i < tabsiz ; i+=2) {
607 cum_orig_line += lineno[i];
608 new_line = addrmap[cum_orig_line];
609 assert (new_line - last_line < 255);
610 lineno[i] =((unsigned char)(new_line - last_line));
611 last_line = new_line;
612 }
613
614 /* Remove NOPs and fixup jump targets */
615 for (i=0, h=0 ; i<codelen ; ) {
616 opcode = codestr[i];
617 switch (opcode) {
618 case NOP:
619 i++;
620 continue;
621
622 case JUMP_ABSOLUTE:
623 case CONTINUE_LOOP:
624 j = addrmap[GETARG(codestr, i)];
625 SETARG(codestr, i, j);
626 break;
627
628 case FOR_ITER:
629 case JUMP_FORWARD:
630 case JUMP_IF_FALSE:
631 case JUMP_IF_TRUE:
632 case SETUP_LOOP:
633 case SETUP_EXCEPT:
634 case SETUP_FINALLY:
635 j = addrmap[GETARG(codestr, i) + i + 3] - addrmap[i] - 3;
636 SETARG(codestr, i, j);
637 break;
638 }
639 adj = CODESIZE(opcode);
640 while (adj--)
641 codestr[h++] = codestr[i++];
642 }
643 assert(h + nops == codelen);
644
Christian Heimes72b710a2008-05-26 13:28:38 +0000645 code = PyBytes_FromStringAndSize((char *)codestr, h);
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000646 PyMem_Free(addrmap);
647 PyMem_Free(codestr);
648 PyMem_Free(blocks);
649 return code;
650
651 exitUnchanged:
652 if (blocks != NULL)
653 PyMem_Free(blocks);
654 if (addrmap != NULL)
655 PyMem_Free(addrmap);
656 if (codestr != NULL)
657 PyMem_Free(codestr);
658 Py_INCREF(code);
659 return code;
660}