Fixed dis.disassemble_string().

Added dis.findlinestarts().
SF bug 811294
This commit is contained in:
Armin Rigo 2003-10-28 12:17:25 +00:00
parent 3be6d5d320
commit 9c8f7eafca
1 changed files with 24 additions and 28 deletions

View File

@ -60,21 +60,8 @@ def distb(tb=None):
def disassemble(co, lasti=-1): def disassemble(co, lasti=-1):
"""Disassemble a code object.""" """Disassemble a code object."""
code = co.co_code 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) labels = findlabels(code)
linestarts = dict(findlinestarts(co))
n = len(code) n = len(code)
i = 0 i = 0
extended_arg = 0 extended_arg = 0
@ -82,20 +69,10 @@ def disassemble(co, lasti=-1):
while i < n: while i < n:
c = code[i] c = code[i]
op = ord(c) op = ord(c)
if i in linestarts:
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 > 0: if i > 0:
print print
print "%3d"%lineno, print "%3d" % linestarts[i],
else: else:
print ' ', print ' ',
@ -137,8 +114,6 @@ def disassemble_string(code, lasti=-1, varnames=None, names=None,
while i < n: while i < n:
c = code[i] c = code[i]
op = ord(c) op = ord(c)
if op == opmap['SET_LINENO'] and i > 0:
print # Extra blank line
if i == lasti: print '-->', if i == lasti: print '-->',
else: print ' ', else: print ' ',
if i in labels: print '>>', if i in labels: print '>>',
@ -199,6 +174,27 @@ def findlabels(code):
labels.append(label) labels.append(label)
return labels 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(): def _test():
"""Simple test program to disassemble a file.""" """Simple test program to disassemble a file."""