diff -r f0e80c7404a5 -r dd04caae6647 Objects/codeobject.c --- a/Objects/codeobject.c Sun Jan 13 06:27:51 2013 -0800 +++ b/Objects/codeobject.c Sun Jan 13 18:20:09 2013 +0000 @@ -552,7 +552,7 @@ addr += *p++; if (addr > addrq) break; - line += *p++; + line += (signed char)(*p++); } return line; } @@ -589,7 +589,7 @@ addr += *p++; if (*p) bounds->ap_lower = addr; - line += *p++; + line += (signed char)(*p++); --size; } diff -r f0e80c7404a5 -r dd04caae6647 Objects/frameobject.c --- a/Objects/frameobject.c Sun Jan 13 06:27:51 2013 -0800 +++ b/Objects/frameobject.c Sun Jan 13 18:20:09 2013 +0000 @@ -141,7 +141,7 @@ new_lasti = -1; for (offset = 0; offset < lnotab_len; offset += 2) { addr += lnotab[offset]; - line += lnotab[offset+1]; + line += ((signed char *)lnotab)[offset+1]; if (line >= new_lineno) { new_lasti = addr; new_lineno = line; diff -r f0e80c7404a5 -r dd04caae6647 Python/compile.c --- a/Python/compile.c Sun Jan 13 06:27:51 2013 -0800 +++ b/Python/compile.c Sun Jan 13 18:20:09 2013 +0000 @@ -1906,7 +1906,7 @@ static int compiler_while(struct compiler *c, stmt_ty s) { - basicblock *loop, *orelse, *end, *anchor = NULL; + basicblock *loop, *orelse, *end, *test = NULL; int constant = expr_constant(c, s->v.While.test); if (constant == 0) { @@ -1917,8 +1917,8 @@ loop = compiler_new_block(c); end = compiler_new_block(c); if (constant == -1) { - anchor = compiler_new_block(c); - if (anchor == NULL) + test = compiler_new_block(c); + if (test == NULL) return 0; } if (loop == NULL || end == NULL) @@ -1932,25 +1932,30 @@ orelse = NULL; ADDOP_JREL(c, SETUP_LOOP, end); + if (constant == -1) + ADDOP_JREL(c, JUMP_FORWARD, test); compiler_use_next_block(c, loop); - if (!compiler_push_fblock(c, LOOP, loop)) - return 0; if (constant == -1) { - VISIT(c, expr, s->v.While.test); - ADDOP_JABS(c, POP_JUMP_IF_FALSE, anchor); + if (!compiler_push_fblock(c, LOOP, test)) + return 0; + } + else { + if (!compiler_push_fblock(c, LOOP, loop)) + return 0; } VISIT_SEQ(c, stmt, s->v.While.body); - ADDOP_JABS(c, JUMP_ABSOLUTE, loop); - - /* XXX should the two POP instructions be in a separate block - if there is no else clause ? - */ - if (constant == -1) { - compiler_use_next_block(c, anchor); + compiler_use_next_block(c, test); + VISIT(c, expr, s->v.While.test); + ADDOP_JABS(c, POP_JUMP_IF_TRUE, loop); ADDOP(c, POP_BLOCK); + compiler_pop_fblock(c, LOOP, test); } - compiler_pop_fblock(c, LOOP, loop); + else { + assert(constant == 1); + ADDOP_JABS(c, JUMP_ABSOLUTE, loop); + compiler_pop_fblock(c, LOOP, loop); + } if (orelse != NULL) /* what if orelse is just pass? */ VISIT_SEQ(c, stmt, s->v.While.orelse); compiler_use_next_block(c, end); @@ -3860,82 +3865,60 @@ d_lineno = i->i_lineno - a->a_lineno; assert(d_bytecode >= 0); - assert(d_lineno >= 0); if(d_bytecode == 0 && d_lineno == 0) return 1; - - if (d_bytecode > 255) { - int j, nbytes, ncodes = d_bytecode / 255; - nbytes = a->a_lnotab_off + 2 * ncodes; - len = PyBytes_GET_SIZE(a->a_lnotab); - if (nbytes >= len) { - if ((len <= INT_MAX / 2) && (len * 2 < nbytes)) - len = nbytes; - else if (len <= INT_MAX / 2) - len *= 2; - else { - PyErr_NoMemory(); - return 0; - } + + lnotab = (unsigned char *) + PyBytes_AS_STRING(a->a_lnotab) + a->a_lnotab_off; + len = PyBytes_GET_SIZE(a->a_lnotab); + + while(d_bytecode > 255) { + if (a->a_lnotab_off + 2 > len) { + len *= 2; if (_PyBytes_Resize(&a->a_lnotab, len) < 0) return 0; + lnotab = (unsigned char *) + PyBytes_AS_STRING(a->a_lnotab) + a->a_lnotab_off; } - lnotab = (unsigned char *) - PyBytes_AS_STRING(a->a_lnotab) + a->a_lnotab_off; - for (j = 0; j < ncodes; j++) { - *lnotab++ = 255; - *lnotab++ = 0; - } - d_bytecode -= ncodes * 255; - a->a_lnotab_off += ncodes * 2; + d_bytecode -= 255; + *lnotab++ = 255; + *lnotab++ = 0; + a->a_lnotab_off += 2; } assert(d_bytecode <= 255); - if (d_lineno > 255) { - int j, nbytes, ncodes = d_lineno / 255; - nbytes = a->a_lnotab_off + 2 * ncodes; + while(abs(d_lineno) > 127) { + int part_delta = d_lineno > 0 ? 127 : -127; len = PyBytes_GET_SIZE(a->a_lnotab); - if (nbytes >= len) { - if ((len <= INT_MAX / 2) && len * 2 < nbytes) - len = nbytes; - else if (len <= INT_MAX / 2) - len *= 2; - else { - PyErr_NoMemory(); - return 0; - } + if (a->a_lnotab_off + 2 > len) { + len *= 2; if (_PyBytes_Resize(&a->a_lnotab, len) < 0) return 0; + lnotab = (unsigned char *) + PyBytes_AS_STRING(a->a_lnotab) + a->a_lnotab_off; } - lnotab = (unsigned char *) - PyBytes_AS_STRING(a->a_lnotab) + a->a_lnotab_off; + d_lineno -= part_delta; *lnotab++ = d_bytecode; - *lnotab++ = 255; d_bytecode = 0; - for (j = 1; j < ncodes; j++) { - *lnotab++ = 0; - *lnotab++ = 255; - } - d_lineno -= ncodes * 255; - a->a_lnotab_off += ncodes * 2; + *lnotab++ = (unsigned char)part_delta; + a->a_lnotab_off += 2; } - - len = PyBytes_GET_SIZE(a->a_lnotab); + assert(abs(d_lineno) <= 127); + if (a->a_lnotab_off + 2 >= len) { if (_PyBytes_Resize(&a->a_lnotab, len * 2) < 0) return 0; + lnotab = (unsigned char *) + PyBytes_AS_STRING(a->a_lnotab) + a->a_lnotab_off; } - lnotab = (unsigned char *) - PyBytes_AS_STRING(a->a_lnotab) + a->a_lnotab_off; - a->a_lnotab_off += 2; if (d_bytecode) { *lnotab++ = d_bytecode; - *lnotab++ = d_lineno; + *lnotab++ = (unsigned char)d_lineno; } else { /* First line of a block; def stmt, etc. */ *lnotab++ = 0; - *lnotab++ = d_lineno; + *lnotab++ = (unsigned char)d_lineno; } a->a_lineno = i->i_lineno; a->a_lineno_off = a->a_offset;