summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeal Norwitz <nnorwitz@gmail.com>2005-10-23 23:00:41 (GMT)
committerNeal Norwitz <nnorwitz@gmail.com>2005-10-23 23:00:41 (GMT)
commitf1d50684c691bb310244e5f7b1f309c097c2b48e (patch)
treecd335974c05010f072a18ad085f33e94360aa6c1
parent7d37f2ff40c4cfa64fe4fe93c1804ae823f4b01e (diff)
downloadcpython-f1d50684c691bb310244e5f7b1f309c097c2b48e.zip
cpython-f1d50684c691bb310244e5f7b1f309c097c2b48e.tar.gz
cpython-f1d50684c691bb310244e5f7b1f309c097c2b48e.tar.bz2
Fix problem handling EXTENDED_ARGs from SF bug # 1333982
-rw-r--r--Python/compile.c31
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 *