diff options
author | Neal Norwitz <nnorwitz@gmail.com> | 2005-10-23 23:00:41 (GMT) |
---|---|---|
committer | Neal Norwitz <nnorwitz@gmail.com> | 2005-10-23 23:00:41 (GMT) |
commit | f1d50684c691bb310244e5f7b1f309c097c2b48e (patch) | |
tree | cd335974c05010f072a18ad085f33e94360aa6c1 | |
parent | 7d37f2ff40c4cfa64fe4fe93c1804ae823f4b01e (diff) | |
download | cpython-f1d50684c691bb310244e5f7b1f309c097c2b48e.zip cpython-f1d50684c691bb310244e5f7b1f309c097c2b48e.tar.gz cpython-f1d50684c691bb310244e5f7b1f309c097c2b48e.tar.bz2 |
Fix problem handling EXTENDED_ARGs from SF bug # 1333982
-rw-r--r-- | Python/compile.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/Python/compile.c b/Python/compile.c index 604c8a1..8426038 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -3886,17 +3886,20 @@ static void assemble_jump_offsets(struct assembler *a, struct compiler *c) { basicblock *b; - int bsize, totsize = 0; + int bsize, totsize, extended_arg_count, last_extended_arg_count = 0; int i; /* Compute the size of each block and fixup jump args. Replace block pointer with position in bytecode. */ +start: + totsize = 0; for (i = a->a_nblocks - 1; i >= 0; i--) { b = a->a_postorder[i]; bsize = blocksize(b); b->b_offset = totsize; totsize += bsize; } + extended_arg_count = 0; for (b = c->u->u_blocks; b != NULL; b = b->b_list) { bsize = b->b_offset; for (i = 0; i < b->b_iused; i++) { @@ -3912,8 +3915,34 @@ assemble_jump_offsets(struct assembler *a, struct compiler *c) int delta = instr->i_target->b_offset - bsize; instr->i_oparg = delta; } + else + continue; + if (instr->i_oparg > 0xffff) + extended_arg_count++; } } + + /* XXX: This is an awful hack that could hurt performance, but + on the bright side it should work until we come up + with a better solution. + + In the meantime, should the goto be dropped in favor + of a loop? + + The issue is that in the first loop blocksize() is called + which calls instrsize() which requires i_oparg be set + appropriately. There is a bootstrap problem because + i_oparg is calculated in the second loop above. + + So we loop until we stop seeing new EXTENDED_ARGs. + The only EXTENDED_ARGs that could be popping up are + ones in jump instructions. So this should converge + fairly quickly. + */ + if (last_extended_arg_count != extended_arg_count) { + last_extended_arg_count = extended_arg_count; + goto start; + } } static PyObject * |