diff options
author | Jeffrey Yasskin <jyasskin@gmail.com> | 2009-05-23 23:23:01 +0000 |
---|---|---|
committer | Jeffrey Yasskin <jyasskin@gmail.com> | 2009-05-23 23:23:01 +0000 |
commit | 655d835415800085cddbacecfc8a22111d70a5ef (patch) | |
tree | 313b44ddc5a8af0d3c1ec29cc2b1fb35b4b118c3 /Python/ceval.c | |
parent | 3724d6c3923f45f4c284e1b3d44a60c3090017d1 (diff) | |
download | cpython-git-655d835415800085cddbacecfc8a22111d70a5ef.tar.gz |
Issue #6042:
lnotab-based tracing is very complicated and isn't documented very well. There
were at least 3 comment blocks purporting to document co_lnotab, and none did a
very good job. This patch unifies them into Objects/lnotab_notes.txt which
tries to completely capture the current state of affairs.
I also discovered that we've attached 2 layers of patches to the basic tracing
scheme. The first layer avoids jumping to instructions that don't start a line,
to avoid problems in if statements and while loops. The second layer
discovered that jumps backward do need to trace at instructions that don't
start a line, so it added extra lnotab entries for 'while' and 'for' loops, and
added a special case for backward jumps within the same line. I replaced these
patches by just treating forward and backward jumps differently.
Diffstat (limited to 'Python/ceval.c')
-rw-r--r-- | Python/ceval.c | 25 |
1 files changed, 11 insertions, 14 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index 474a8851db..4f0877b9fa 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -3591,33 +3591,30 @@ _PyEval_CallTracing(PyObject *func, PyObject *args) return result; } +/* See Objects/lnotab_notes.txt for a description of how tracing works. */ static int maybe_call_line_trace(Py_tracefunc func, PyObject *obj, PyFrameObject *frame, int *instr_lb, int *instr_ub, int *instr_prev) { int result = 0; + int line = frame->f_lineno; /* If the last instruction executed isn't in the current - instruction window, reset the window. If the last - instruction happens to fall at the start of a line or if it - represents a jump backwards, call the trace function. + instruction window, reset the window. */ - if ((frame->f_lasti < *instr_lb || frame->f_lasti >= *instr_ub)) { - int line; + if (frame->f_lasti < *instr_lb || frame->f_lasti >= *instr_ub) { PyAddrPair bounds; - - line = PyCode_CheckLineNumber(frame->f_code, frame->f_lasti, - &bounds); - if (line >= 0) { - frame->f_lineno = line; - result = call_trace(func, obj, frame, - PyTrace_LINE, Py_None); - } + line = _PyCode_CheckLineNumber(frame->f_code, frame->f_lasti, + &bounds); *instr_lb = bounds.ap_lower; *instr_ub = bounds.ap_upper; } - else if (frame->f_lasti <= *instr_prev) { + /* If the last instruction falls at the start of a line or if + it represents a jump backwards, update the frame's line + number and call the trace function. */ + if (frame->f_lasti == *instr_lb || frame->f_lasti < *instr_prev) { + frame->f_lineno = line; result = call_trace(func, obj, frame, PyTrace_LINE, Py_None); } *instr_prev = frame->f_lasti; |