summaryrefslogtreecommitdiff
path: root/Python
diff options
context:
space:
mode:
authorAmaury Forgeot d'Arc <amauryfa@gmail.com>2008-02-04 22:34:57 +0000
committerAmaury Forgeot d'Arc <amauryfa@gmail.com>2008-02-04 22:34:57 +0000
commit316f8a8d3c965d2e1809b1b90677733478184c89 (patch)
tree53786f52b14bbd90823bded4f16ebb6202942c85 /Python
parentd66e94d0e6681345c6b203e7e6bd56e5a82ceb82 (diff)
downloadcpython-git-316f8a8d3c965d2e1809b1b90677733478184c89.tar.gz
backport of r60575 (issue #1750076): Debugger did not step on every iteration of a while statement.
The mapping between bytecode offsets and source lines (lnotab) did not contain an entry for the beginning of the loop. Now it does, and the lnotab can be a bit larger: in particular, several statements on the same line generate several entries. However, this does not bother the settrace function, which will trigger only one 'line' event. The lnotab seems to be exactly the same as with python2.4.
Diffstat (limited to 'Python')
-rw-r--r--Python/compile.c29
1 files changed, 15 insertions, 14 deletions
diff --git a/Python/compile.c b/Python/compile.c
index 8e96ddfa62..6df09dc53c 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -1298,11 +1298,16 @@ compiler_next_instr(struct compiler *c, basicblock *b)
return b->b_iused++;
}
-/* Set the i_lineno member of the instruction at offse off if the
- line number for the current expression/statement (?) has not
+/* Set the i_lineno member of the instruction at offset off if the
+ line number for the current expression/statement has not
already been set. If it has been set, the call has no effect.
- Every time a new node is b
+ The line number is reset in the following cases:
+ - when entering a new scope
+ - on each statement
+ - on each expression that start a new line
+ - before the "except" clause
+ - before the "for" and "while" expressions
*/
static void
@@ -2234,9 +2239,8 @@ compiler_for(struct compiler *c, stmt_ty s)
VISIT(c, expr, s->v.For.iter);
ADDOP(c, GET_ITER);
compiler_use_next_block(c, start);
- /* XXX(nnorwitz): is there a better way to handle this?
- for loops are special, we want to be able to trace them
- each time around, so we need to set an extra line number. */
+ /* for expressions must be traced on each iteration,
+ so we need to set an extra line number. */
c->u->u_lineno_set = false;
ADDOP_JREL(c, FOR_ITER, cleanup);
VISIT(c, expr, s->v.For.target);
@@ -2283,6 +2287,9 @@ compiler_while(struct compiler *c, stmt_ty s)
if (!compiler_push_fblock(c, LOOP, loop))
return 0;
if (constant == -1) {
+ /* while expressions must be traced on each iteration,
+ so we need to set an extra line number. */
+ c->u->u_lineno_set = false;
VISIT(c, expr, s->v.While.test);
ADDOP_JREL(c, JUMP_IF_FALSE, anchor);
ADDOP(c, POP_TOP);
@@ -2464,8 +2471,8 @@ compiler_try_except(struct compiler *c, stmt_ty s)
s->v.TryExcept.handlers, i);
if (!handler->type && i < n-1)
return compiler_error(c, "default 'except:' must be last");
- c->u->u_lineno_set = false;
- c->u->u_lineno = handler->lineno;
+ c->u->u_lineno_set = false;
+ c->u->u_lineno = handler->lineno;
except = compiler_new_block(c);
if (except == NULL)
return 0;
@@ -4184,12 +4191,6 @@ assemble_lnotab(struct assembler *a, struct instr *i)
assert(d_bytecode >= 0);
assert(d_lineno >= 0);
- /* XXX(nnorwitz): is there a better way to handle this?
- for loops are special, we want to be able to trace them
- each time around, so we need to set an extra line number. */
- if (d_lineno == 0 && i->i_opcode != FOR_ITER)
- return 1;
-
if (d_bytecode > 255) {
int j, nbytes, ncodes = d_bytecode / 255;
nbytes = a->a_lnotab_off + 2 * ncodes;