]> granicus.if.org Git - python/commitdiff
Fixed dis.disassemble_string().
authorArmin Rigo <arigo@tunes.org>
Tue, 28 Oct 2003 12:17:25 +0000 (12:17 +0000)
committerArmin Rigo <arigo@tunes.org>
Tue, 28 Oct 2003 12:17:25 +0000 (12:17 +0000)
Added dis.findlinestarts().
SF bug 811294

Lib/dis.py

index f878d11ab911f1bdcf5883c523fcc3d1df3ee0ff..3208011ea9dd659c437de180884d72ec9c93e2f9 100644 (file)
@@ -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."""