Fix problem handling EXTENDED_ARGs from SF bug # 1333982

This commit is contained in:
Neal Norwitz 2005-10-23 23:00:41 +00:00
parent 7d37f2ff40
commit f1d50684c6
1 changed files with 30 additions and 1 deletions

View File

@ -3886,17 +3886,20 @@ static void
assemble_jump_offsets(struct assembler *a, struct compiler *c) assemble_jump_offsets(struct assembler *a, struct compiler *c)
{ {
basicblock *b; basicblock *b;
int bsize, totsize = 0; int bsize, totsize, extended_arg_count, last_extended_arg_count = 0;
int i; int i;
/* Compute the size of each block and fixup jump args. /* Compute the size of each block and fixup jump args.
Replace block pointer with position in bytecode. */ Replace block pointer with position in bytecode. */
start:
totsize = 0;
for (i = a->a_nblocks - 1; i >= 0; i--) { for (i = a->a_nblocks - 1; i >= 0; i--) {
b = a->a_postorder[i]; b = a->a_postorder[i];
bsize = blocksize(b); bsize = blocksize(b);
b->b_offset = totsize; b->b_offset = totsize;
totsize += bsize; totsize += bsize;
} }
extended_arg_count = 0;
for (b = c->u->u_blocks; b != NULL; b = b->b_list) { for (b = c->u->u_blocks; b != NULL; b = b->b_list) {
bsize = b->b_offset; bsize = b->b_offset;
for (i = 0; i < b->b_iused; i++) { 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; int delta = instr->i_target->b_offset - bsize;
instr->i_oparg = delta; 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 * static PyObject *