From f1d50684c691bb310244e5f7b1f309c097c2b48e Mon Sep 17 00:00:00 2001 From: Neal Norwitz Date: Sun, 23 Oct 2005 23:00:41 +0000 Subject: [PATCH] Fix problem handling EXTENDED_ARGs from SF bug # 1333982 --- Python/compile.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/Python/compile.c b/Python/compile.c index 604c8a1676a..8426038221b 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 *