From 80d937e986300d8e0cae93cb29bcb4211a65f92c Mon Sep 17 00:00:00 2001 From: Armin Rigo Date: Mon, 22 Mar 2004 17:52:53 +0000 Subject: [PATCH] Fix for line events in the case: def f(a): if a: print 5 else: pass --- Python/compile.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/Python/compile.c b/Python/compile.c index 328c57bb0fd..7bbcd62e745 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -629,7 +629,10 @@ struct compiling { int c_maxstacklevel; /* Maximum stack level */ int c_firstlineno; PyObject *c_lnotab; /* Table mapping address to line number */ - int c_last_addr, c_last_line, c_lnotab_next; + int c_last_addr; /* last op addr seen and recorded in lnotab */ + int c_last_line; /* last line seen and recorded in lnotab */ + int c_lnotab_next; /* current length of lnotab */ + int c_lnotab_last; /* start of last lnotab record added */ char *c_private; /* for private name mangling */ int c_tmpname; /* temporary local name counter */ int c_nested; /* Is block nested funcdef or lamdef? */ @@ -848,6 +851,7 @@ com_init(struct compiling *c, const char *filename) c->c_last_addr = 0; c->c_last_line = 0; c->c_lnotab_next = 0; + c->c_lnotab_last = 0; c->c_tmpname = 0; c->c_nested = 0; c->c_closure = 0; @@ -964,6 +968,7 @@ com_set_lineno(struct compiling *c, int lineno) else { int incr_addr = c->c_nexti - c->c_last_addr; int incr_line = lineno - c->c_last_line; + c->c_lnotab_last = c->c_lnotab_next; while (incr_addr > 255) { com_add_lnotab(c, 255, 0); incr_addr -= 255; @@ -980,6 +985,27 @@ com_set_lineno(struct compiling *c, int lineno) } } +static void +com_strip_lnotab(struct compiling *c) +{ + /* strip the last lnotab entry if no opcode were emitted. + * This prevents a line number to be generated on a final + * pass, like in the following example: + * + * if a: + * print 5 + * else: + * pass + * + * Without the fix, a line trace event would be generated + * on the pass even if a is true (because of the implicit + * return). + */ + if (c->c_nexti == c->c_last_addr && c->c_lnotab_last > 0) { + c->c_lnotab_next = c->c_lnotab_last; + } +} + static void com_addoparg(struct compiling *c, int op, int arg) { @@ -4167,6 +4193,7 @@ compile_funcdef(struct compiling *c, node *n) c->c_infunction = 1; com_node(c, CHILD(n, 4)); c->c_infunction = 0; + com_strip_lnotab(c); com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None)); com_push(c, 1); com_addbyte(c, RETURN_VALUE); @@ -4218,6 +4245,7 @@ compile_classdef(struct compiling *c, node *n) else (void) com_addconst(c, Py_None); com_node(c, ch); + com_strip_lnotab(c); com_addbyte(c, LOAD_LOCALS); com_push(c, 1); com_addbyte(c, RETURN_VALUE); @@ -4237,6 +4265,7 @@ compile_node(struct compiling *c, node *n) n = CHILD(n, 0); if (TYPE(n) != NEWLINE) com_node(c, n); + com_strip_lnotab(c); com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None)); com_push(c, 1); com_addbyte(c, RETURN_VALUE); @@ -4246,6 +4275,7 @@ compile_node(struct compiling *c, node *n) case file_input: /* A whole file, or built-in function exec() */ com_file_input(c, n); + com_strip_lnotab(c); com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None)); com_push(c, 1); com_addbyte(c, RETURN_VALUE);