diff options
-rw-r--r-- | Lib/dis.py | 52 |
1 files changed, 24 insertions, 28 deletions
@@ -60,21 +60,8 @@ def distb(tb=None): def disassemble(co, lasti=-1): """Disassemble a code object.""" code = co.co_code - - byte_increments = [ord(c) for c in co.co_lnotab[0::2]] - line_increments = [ord(c) for c in co.co_lnotab[1::2]] - table_length = len(byte_increments) # == len(line_increments) - - lineno = co.co_firstlineno - table_index = 0 - while (table_index < table_length - and byte_increments[table_index] == 0): - lineno += line_increments[table_index] - table_index += 1 - addr = 0 - line_incr = 0 - labels = findlabels(code) + linestarts = dict(findlinestarts(co)) n = len(code) i = 0 extended_arg = 0 @@ -82,20 +69,10 @@ def disassemble(co, lasti=-1): while i < n: c = code[i] op = ord(c) - - if i >= addr: - lineno += line_incr - while table_index < table_length: - addr += byte_increments[table_index] - line_incr = line_increments[table_index] - table_index += 1 - if line_incr: - break - else: - addr = sys.maxint + if i in linestarts: if i > 0: print - print "%3d"%lineno, + print "%3d" % linestarts[i], else: print ' ', @@ -137,8 +114,6 @@ def disassemble_string(code, lasti=-1, varnames=None, names=None, while i < n: c = code[i] op = ord(c) - if op == opmap['SET_LINENO'] and i > 0: - print # Extra blank line if i == lasti: print '-->', else: print ' ', if i in labels: print '>>', @@ -199,6 +174,27 @@ def findlabels(code): labels.append(label) return labels +def findlinestarts(code): + """Find the offsets in a byte code which are start of lines in the source. + + Generate pairs (offset, lineno) as described in Python/compile.c. + + """ + byte_increments = [ord(c) for c in code.co_lnotab[0::2]] + line_increments = [ord(c) for c in code.co_lnotab[1::2]] + + lastlineno = None + lineno = code.co_firstlineno + addr = 0 + for byte_incr, line_incr in zip(byte_increments, line_increments): + if byte_incr: + if lineno != lastlineno: + yield (addr, lineno) + lastlineno = lineno + addr += byte_incr + lineno += line_incr + if lineno != lastlineno: + yield (addr, lineno) def _test(): """Simple test program to disassemble a file.""" |