| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent add8806 commit dd32a91
19 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -23,17 +23,15 @@ \section{\module{dis} --- | |||
| 23 | 23 | ||
| 24 | 24 | \begin{verbatim} | |
| 25 | 25 | >>> dis.dis(myfunc) | |
| 26 | - 0 SET_LINENO 1 | ||
| 27 | - | ||
| 28 | - 3 SET_LINENO 2 | ||
| 29 | - 6 LOAD_GLOBAL 0 (len) | ||
| 30 | - 9 LOAD_FAST 0 (alist) | ||
| 31 | - 12 CALL_FUNCTION 1 | ||
| 32 | - 15 RETURN_VALUE | ||
| 33 | - 16 LOAD_CONST 0 (None) | ||
| 34 | - 19 RETURN_VALUE | ||
| 26 | + 2 0 LOAD_GLOBAL 0 (len) | ||
| 27 | + 3 LOAD_FAST 0 (alist) | ||
| 28 | + 6 CALL_FUNCTION 1 | ||
| 29 | + 9 RETURN_VALUE | ||
| 30 | + 10 RETURN_NONE | ||
| 35 | 31 | \end{verbatim} | |
| 36 | 32 | ||
| 33 | + (The ``2'' is a line number). | ||
| 34 | + | ||
| 37 | 35 | The \module{dis} module defines the following functions and constants: | |
| 38 | 36 | ||
| 39 | 37 | \begin{funcdesc}{dis}{\optional{bytesource}} | |
@@ -56,6 +54,7 @@ \section{\module{dis} --- | |||
| 56 | 54 | was provided. The output is divided in the following columns: | |
| 57 | 55 | ||
| 58 | 56 | \begin{enumerate} | |
| 57 | + \item the line number, for the first instruction of each line | ||
| 59 | 58 | \item the current instruction, indicated as \samp{-->}, | |
| 60 | 59 | \item a labelled instruction, indicated with \samp{>\code{>}}, | |
| 61 | 60 | \item the address of the instruction, | |
@@ -402,6 +401,14 @@ \subsection{Python Byte Code Instructions} | |||
| 402 | 401 | Returns with TOS to the caller of the function. | |
| 403 | 402 | \end{opcodedesc} | |
| 404 | 403 | ||
| 404 | + \begin{opcodedesc}{RETURN_NONE}{} | ||
| 405 | + Returns \constant{None} to the caller of the function. This opcode is | ||
| 406 | + generated as the last opcode of every function and only then, for | ||
| 407 | + reasons to do with tracing support. See the comments in the function | ||
| 408 | + \cfunction{maybe_call_line_trace} in \file{Python/ceval.c} for the | ||
| 409 | + gory details. \versionadded{2.3}. | ||
| 410 | + \end{opcodedesc} | ||
| 411 | + | ||
| 405 | 412 | \begin{opcodedesc}{YIELD_VALUE}{} | |
| 406 | 413 | Pops \code{TOS} and yields it from a generator. | |
| 407 | 414 | \end{opcodedesc} | |
@@ -621,7 +628,7 @@ \subsection{Python Byte Code Instructions} | |||
| 621 | 628 | \end{opcodedesc} | |
| 622 | 629 | ||
| 623 | 630 | \begin{opcodedesc}{SET_LINENO}{lineno} | |
| 624 | - Sets the current line number to \var{lineno}. | ||
| 631 | + This opcode is obsolete. | ||
| 625 | 632 | \end{opcodedesc} | |
| 626 | 633 | ||
| 627 | 634 | \begin{opcodedesc}{RAISE_VARARGS}{argc} | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -118,10 +118,10 @@ \section{\module{traceback} --- | |||
| 118 | 118 | ||
| 119 | 119 | \begin{funcdesc}{tb_lineno}{tb} | |
| 120 | 120 | This function returns the current line number set in the traceback | |
| 121 | - object. This is normally the same as the \code{\var{tb}.tb_lineno} | ||
| 122 | - field of the object, but when optimization is used (the -O flag) this | ||
| 123 | - field is not updated correctly; this function calculates the correct | ||
| 124 | - value. | ||
| 121 | + object. This function was necessary because in versions of Python | ||
| 122 | + prior to 2.3 when the \programopt{O} flag was passed to Python the | ||
| 123 | + \code{\var{tb}.tb_lineno} was not updated correctly. This function | ||
| 124 | + has no use in versions past 2.3. | ||
| 125 | 125 | \end{funcdesc} | |
| 126 | 126 | ||
| 127 | 127 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2340,12 +2340,11 @@ \subsection{``Compiled'' Python files} | |||
| 2340 | 2340 | ||
| 2341 | 2341 | \item | |
| 2342 | 2342 | When the Python interpreter is invoked with the \programopt{-O} flag, | |
| 2343 | - optimized code is generated and stored in \file{.pyo} files. | ||
| 2344 | - The optimizer currently doesn't help much; it only removes | ||
| 2345 | - \keyword{assert} statements and \code{SET_LINENO} instructions. | ||
| 2346 | - When \programopt{-O} is used, \emph{all} bytecode is optimized; | ||
| 2347 | - \code{.pyc} files are ignored and \code{.py} files are compiled to | ||
| 2348 | - optimized bytecode. | ||
| 2343 | + optimized code is generated and stored in \file{.pyo} files. The | ||
| 2344 | + optimizer currently doesn't help much; it only removes | ||
| 2345 | + \keyword{assert} statements. When \programopt{-O} is used, \emph{all} | ||
| 2346 | + bytecode is optimized; \code{.pyc} files are ignored and \code{.py} | ||
| 2347 | + files are compiled to optimized bytecode. | ||
| 2349 | 2348 | ||
| 2350 | 2349 | \item | |
| 2351 | 2350 | Passing two \programopt{-O} flags to the Python interpreter | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -658,7 +658,6 @@ \section{Other Language Changes} | |||
| 658 | 658 | ||
| 659 | 659 | \end{itemize} | |
| 660 | 660 | ||
| 661 | - | ||
| 662 | 661 | %====================================================================== | |
| 663 | 662 | \section{New and Improved Modules} | |
| 664 | 663 | ||
@@ -987,9 +986,9 @@ \section{Build and C API Changes} | |||
| 987 | 986 | when running Python's \file{configure} script. (Contributed by Ondrej | |
| 988 | 987 | Palkovsky.) | |
| 989 | 988 | ||
| 990 | - \item The \csimplemacro{DL_EXPORT} and \csimplemacro{DL_IMPORT} macros are now | ||
| 991 | - deprecated. Initialization functions for Python extension modules | ||
| 992 | - should now be declared using the new macro | ||
| 989 | + \item The \csimplemacro{DL_EXPORT} and \csimplemacro{DL_IMPORT} macros | ||
| 990 | + are now deprecated. Initialization functions for Python extension | ||
| 991 | + modules should now be declared using the new macro | ||
| 993 | 992 | \csimplemacro{PyMODINIT_FUNC}, while the Python core will generally | |
| 994 | 993 | use the \csimplemacro{PyAPI_FUNC} and \csimplemacro{PyAPI_DATA} | |
| 995 | 994 | macros. | |
@@ -1076,6 +1075,29 @@ \section{Other Changes and Fixes} | |||
| 1076 | 1075 | \item The tools used to build the documentation now work under Cygwin | |
| 1077 | 1076 | as well as \UNIX. | |
| 1078 | 1077 | ||
| 1078 | + \item The \code{SET_LINENO} opcode has been removed. Back in the | ||
| 1079 | + mists of time, this opcode was needed to produce line numbers in | ||
| 1080 | + tracebacks and support trace functions (for, e.g., \module{pdb}). | ||
| 1081 | + Since Python 1.5, the line numbers in tracebacks have been computed | ||
| 1082 | + using a different mechanism that works with ``python -O''. For Python | ||
| 1083 | + 2.3 Michael Hudson implemented a similar scheme to determine when to | ||
| 1084 | + call the trace function, removing the need for \code{SET_LINENO} | ||
| 1085 | + entirely. | ||
| 1086 | + | ||
| 1087 | + Python code will be hard pushed to notice a difference from this | ||
| 1088 | + change, apart from a slight speed up when python is run without | ||
| 1089 | + \programopt{-O}. | ||
| 1090 | + | ||
| 1091 | + C extensions that access the \member{f_lineno} field of frame objects | ||
| 1092 | + should instead call \code{PyCode_Addr2Line(f->f_code, f->f_lasti)}. | ||
| 1093 | + This will have the added effect of making the code work as desired | ||
| 1094 | + under ``python -O'' in earlier versions of Python. | ||
| 1095 | + | ||
| 1096 | + To make tracing work as expected, it was found necessary to add a new | ||
| 1097 | + opcode, \cdata{RETURN_NONE}, to the VM. If you want to know why, read | ||
| 1098 | + the comments in the function \cfunction{maybe_call_line_trace} in | ||
| 1099 | + \file{Python/ceval.c}. | ||
| 1100 | + | ||
| 1079 | 1101 | \end{itemize} | |
| 1080 | 1102 | ||
| 1081 | 1103 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -71,6 +71,9 @@ extern "C" { | |||
| 71 | 71 | #define INPLACE_OR 79 | |
| 72 | 72 | #define BREAK_LOOP 80 | |
| 73 | 73 | ||
| 74 | + #define RETURN_NONE 81 /* *only* for function epilogues | ||
| 75 | + -- see comments in | ||
| 76 | + ceval.c:maybe_call_line_trace for why */ | ||
| 74 | 77 | #define LOAD_LOCALS 82 | |
| 75 | 78 | #define RETURN_VALUE 83 | |
| 76 | 79 | #define IMPORT_STAR 84 | |
@@ -119,8 +122,6 @@ extern "C" { | |||
| 119 | 122 | #define STORE_FAST 125 /* Local variable number */ | |
| 120 | 123 | #define DELETE_FAST 126 /* Local variable number */ | |
| 121 | 124 | ||
| 122 | - #define SET_LINENO 127 /* Current line number */ | ||
| 123 | - | ||
| 124 | 125 | #define RAISE_VARARGS 130 /* Number of raise arguments (1, 2 or 3) */ | |
| 125 | 126 | /* CALL_FUNCTION_XXX opcodes defined below depend on this definition */ | |
| 126 | 127 | #define CALL_FUNCTION 131 /* #args + (#kwargs<<8) */ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -55,6 +55,20 @@ def distb(tb=None): | |||
| 55 | 55 | def disassemble(co, lasti=-1): | |
| 56 | 56 | """Disassemble a code object.""" | |
| 57 | 57 | code = co.co_code | |
| 58 | + | ||
| 59 | + byte_increments = [ord(c) for c in co.co_lnotab[0::2]] | ||
| 60 | + line_increments = [ord(c) for c in co.co_lnotab[1::2]] | ||
| 61 | + table_length = len(byte_increments) # == len(line_increments) | ||
| 62 | + | ||
| 63 | + lineno = co.co_firstlineno | ||
| 64 | + table_index = 0 | ||
| 65 | + while (table_index < table_length | ||
| 66 | + and byte_increments[table_index] == 0): | ||
| 67 | + lineno += line_increments[table_index] | ||
| 68 | + table_index += 1 | ||
| 69 | + addr = 0 | ||
| 70 | + line_incr = 0 | ||
| 71 | + | ||
| 58 | 72 | labels = findlabels(code) | |
| 59 | 73 | n = len(code) | |
| 60 | 74 | i = 0 | |
@@ -63,7 +77,23 @@ def disassemble(co, lasti=-1): | |||
| 63 | 77 | while i < n: | |
| 64 | 78 | c = code[i] | |
| 65 | 79 | op = ord(c) | |
| 66 | - if op == SET_LINENO and i > 0: print # Extra blank line | ||
| 80 | + | ||
| 81 | + if i >= addr: | ||
| 82 | + lineno += line_incr | ||
| 83 | + while table_index < table_length: | ||
| 84 | + addr += byte_increments[table_index] | ||
| 85 | + line_incr = line_increments[table_index] | ||
| 86 | + table_index += 1 | ||
| 87 | + if line_incr: | ||
| 88 | + break | ||
| 89 | + else: | ||
| 90 | + addr = sys.maxint | ||
| 91 | + if i > 0: | ||
| 92 | + print | ||
| 93 | + print "%3d"%lineno, | ||
| 94 | + else: | ||
| 95 | + print ' ', | ||
| 96 | + | ||
| 67 | 97 | if i == lasti: print '-->', | |
| 68 | 98 | else: print ' ', | |
| 69 | 99 | if i in labels: print '>>', | |
@@ -224,6 +254,7 @@ def jabs_op(name, op): | |||
| 224 | 254 | def_op('INPLACE_OR', 79) | |
| 225 | 255 | def_op('BREAK_LOOP', 80) | |
| 226 | 256 | ||
| 257 | + def_op('RETURN_NONE', 81) | ||
| 227 | 258 | def_op('LOAD_LOCALS', 82) | |
| 228 | 259 | def_op('RETURN_VALUE', 83) | |
| 229 | 260 | def_op('IMPORT_STAR', 84) | |
@@ -277,9 +308,6 @@ def jabs_op(name, op): | |||
| 277 | 308 | def_op('DELETE_FAST', 126) # Local variable number | |
| 278 | 309 | haslocal.append(126) | |
| 279 | 310 | ||
| 280 | - def_op('SET_LINENO', 127) # Current line number | ||
| 281 | - SET_LINENO = 127 | ||
| 282 | - | ||
| 283 | 311 | def_op('RAISE_VARARGS', 130) # Number of raise arguments (1, 2, or 3) | |
| 284 | 312 | def_op('CALL_FUNCTION', 131) # #args + (#kwargs << 8) | |
| 285 | 313 | def_op('MAKE_FUNCTION', 132) # Number of args with default values | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -711,7 +711,7 @@ def getframeinfo(frame, context=1): | |||
| 711 | 711 | raise TypeError, 'arg is not a frame or traceback object' | |
| 712 | 712 | ||
| 713 | 713 | filename = getsourcefile(frame) or getfile(frame) | |
| 714 | - lineno = getlineno(frame) | ||
| 714 | + lineno = frame.f_lineno | ||
| 715 | 715 | if context > 0: | |
| 716 | 716 | start = lineno - 1 - context//2 | |
| 717 | 717 | try: | |
@@ -730,18 +730,8 @@ def getframeinfo(frame, context=1): | |||
| 730 | 730 | ||
| 731 | 731 | def getlineno(frame): | |
| 732 | 732 | """Get the line number from a frame object, allowing for optimization.""" | |
| 733 | - # Written by Marc-André Lemburg; revised by Jim Hugunin and Fredrik Lundh. | ||
| 734 | - lineno = frame.f_lineno | ||
| 735 | - code = frame.f_code | ||
| 736 | - if hasattr(code, 'co_lnotab'): | ||
| 737 | - table = code.co_lnotab | ||
| 738 | - lineno = code.co_firstlineno | ||
| 739 | - addr = 0 | ||
| 740 | - for i in range(0, len(table), 2): | ||
| 741 | - addr = addr + ord(table[i]) | ||
| 742 | - if addr > frame.f_lasti: break | ||
| 743 | - lineno = lineno + ord(table[i+1]) | ||
| 744 | - return lineno | ||
| 733 | + # FrameType.f_lineno is now a descriptor that grovels co_lnotab | ||
| 734 | + return frame.f_lineno | ||
| 745 | 735 | ||
| 746 | 736 | def getouterframes(frame, context=1): | |
| 747 | 737 | """Get a list of records for a frame and all higher (calling) frames. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -105,7 +105,13 @@ def execRcLines(self): | |||
| 105 | 105 | if len(line) > 0 and line[0] != '#': | |
| 106 | 106 | self.onecmd(line) | |
| 107 | 107 | ||
| 108 | - # Override Bdb methods (except user_call, for now) | ||
| 108 | + # Override Bdb methods | ||
| 109 | + | ||
| 110 | + def user_call(self, frame, argument_list): | ||
| 111 | + """This method is called when there is the remote possibility | ||
| 112 | + that we ever need to stop in this function.""" | ||
| 113 | + print '--Call--' | ||
| 114 | + self.interaction(frame, None) | ||
| 109 | 115 | ||
| 110 | 116 | def user_line(self, frame): | |
| 111 | 117 | """This function is called when we stop or break at this line.""" | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -91,10 +91,8 @@ def g(): | |||
| 91 | 91 | f_lineno = f.func_code.co_firstlineno | |
| 92 | 92 | g_lineno = g.func_code.co_firstlineno | |
| 93 | 93 | events = [(ENTER, ("test_hotshot", g_lineno, "g")), | |
| 94 | - (LINE, ("test_hotshot", g_lineno, "g")), | ||
| 95 | 94 | (LINE, ("test_hotshot", g_lineno+1, "g")), | |
| 96 | 95 | (ENTER, ("test_hotshot", f_lineno, "f")), | |
| 97 | - (LINE, ("test_hotshot", f_lineno, "f")), | ||
| 98 | 96 | (LINE, ("test_hotshot", f_lineno+1, "f")), | |
| 99 | 97 | (LINE, ("test_hotshot", f_lineno+2, "f")), | |
| 100 | 98 | (EXIT, ("test_hotshot", f_lineno, "f")), | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -59,7 +59,7 @@ def print_tb(tb, limit=None, file=None): | |||
| 59 | 59 | n = 0 | |
| 60 | 60 | while tb is not None and (limit is None or n < limit): | |
| 61 | 61 | f = tb.tb_frame | |
| 62 | - lineno = tb_lineno(tb) | ||
| 62 | + lineno = tb.tb_lineno | ||
| 63 | 63 | co = f.f_code | |
| 64 | 64 | filename = co.co_filename | |
| 65 | 65 | name = co.co_name | |
@@ -92,7 +92,7 @@ def extract_tb(tb, limit = None): | |||
| 92 | 92 | n = 0 | |
| 93 | 93 | while tb is not None and (limit is None or n < limit): | |
| 94 | 94 | f = tb.tb_frame | |
| 95 | - lineno = tb_lineno(tb) | ||
| 95 | + lineno = tb.tb_lineno | ||
| 96 | 96 | co = f.f_code | |
| 97 | 97 | filename = co.co_filename | |
| 98 | 98 | name = co.co_name | |
@@ -263,7 +263,7 @@ def extract_stack(f=None, limit = None): | |||
| 263 | 263 | list = [] | |
| 264 | 264 | n = 0 | |
| 265 | 265 | while f is not None and (limit is None or n < limit): | |
| 266 | - lineno = f.f_lineno # XXX Too bad if -O is used | ||
| 266 | + lineno = f.f_lineno | ||
| 267 | 267 | co = f.f_code | |
| 268 | 268 | filename = co.co_filename | |
| 269 | 269 | name = co.co_name | |
@@ -279,23 +279,6 @@ def extract_stack(f=None, limit = None): | |||
| 279 | 279 | def tb_lineno(tb): | |
| 280 | 280 | """Calculate correct line number of traceback given in tb. | |
| 281 | 281 | ||
| 282 | - Even works with -O on. | ||
| 282 | + Obsolete in 2.3. | ||
| 283 | 283 | """ | |
| 284 | - # Coded by Marc-Andre Lemburg from the example of PyCode_Addr2Line() | ||
| 285 | - # in compile.c. | ||
| 286 | - # Revised version by Jim Hugunin to work with JPython too. | ||
| 287 | - | ||
| 288 | - c = tb.tb_frame.f_code | ||
| 289 | - if not hasattr(c, 'co_lnotab'): | ||
| 290 | - return tb.tb_lineno | ||
| 291 | - | ||
| 292 | - tab = c.co_lnotab | ||
| 293 | - line = c.co_firstlineno | ||
| 294 | - stopat = tb.tb_lasti | ||
| 295 | - addr = 0 | ||
| 296 | - for i in range(0, len(tab), 2): | ||
| 297 | - addr = addr + ord(tab[i]) | ||
| 298 | - if addr > stopat: | ||
| 299 | - break | ||
| 300 | - line = line + ord(tab[i+1]) | ||
| 301 | - return line | ||
| 284 | + return tb.tb_lineno | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments