symbian-qemu-0.9.1-12/python-2.6.1/Lib/dis.py
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 """Disassembler of Python byte code into mnemonics."""
       
     2 
       
     3 import sys
       
     4 import types
       
     5 
       
     6 from opcode import *
       
     7 from opcode import __all__ as _opcodes_all
       
     8 
       
     9 __all__ = ["dis","disassemble","distb","disco"] + _opcodes_all
       
    10 del _opcodes_all
       
    11 
       
    12 def dis(x=None):
       
    13     """Disassemble classes, methods, functions, or code.
       
    14 
       
    15     With no argument, disassemble the last traceback.
       
    16 
       
    17     """
       
    18     if x is None:
       
    19         distb()
       
    20         return
       
    21     if type(x) is types.InstanceType:
       
    22         x = x.__class__
       
    23     if hasattr(x, 'im_func'):
       
    24         x = x.im_func
       
    25     if hasattr(x, 'func_code'):
       
    26         x = x.func_code
       
    27     if hasattr(x, '__dict__'):
       
    28         items = x.__dict__.items()
       
    29         items.sort()
       
    30         for name, x1 in items:
       
    31             if type(x1) in (types.MethodType,
       
    32                             types.FunctionType,
       
    33                             types.CodeType,
       
    34                             types.ClassType):
       
    35                 print "Disassembly of %s:" % name
       
    36                 try:
       
    37                     dis(x1)
       
    38                 except TypeError, msg:
       
    39                     print "Sorry:", msg
       
    40                 print
       
    41     elif hasattr(x, 'co_code'):
       
    42         disassemble(x)
       
    43     elif isinstance(x, str):
       
    44         disassemble_string(x)
       
    45     else:
       
    46         raise TypeError, \
       
    47               "don't know how to disassemble %s objects" % \
       
    48               type(x).__name__
       
    49 
       
    50 def distb(tb=None):
       
    51     """Disassemble a traceback (default: last traceback)."""
       
    52     if tb is None:
       
    53         try:
       
    54             tb = sys.last_traceback
       
    55         except AttributeError:
       
    56             raise RuntimeError, "no last traceback to disassemble"
       
    57         while tb.tb_next: tb = tb.tb_next
       
    58     disassemble(tb.tb_frame.f_code, tb.tb_lasti)
       
    59 
       
    60 def disassemble(co, lasti=-1):
       
    61     """Disassemble a code object."""
       
    62     code = co.co_code
       
    63     labels = findlabels(code)
       
    64     linestarts = dict(findlinestarts(co))
       
    65     n = len(code)
       
    66     i = 0
       
    67     extended_arg = 0
       
    68     free = None
       
    69     while i < n:
       
    70         c = code[i]
       
    71         op = ord(c)
       
    72         if i in linestarts:
       
    73             if i > 0:
       
    74                 print
       
    75             print "%3d" % linestarts[i],
       
    76         else:
       
    77             print '   ',
       
    78 
       
    79         if i == lasti: print '-->',
       
    80         else: print '   ',
       
    81         if i in labels: print '>>',
       
    82         else: print '  ',
       
    83         print repr(i).rjust(4),
       
    84         print opname[op].ljust(20),
       
    85         i = i+1
       
    86         if op >= HAVE_ARGUMENT:
       
    87             oparg = ord(code[i]) + ord(code[i+1])*256 + extended_arg
       
    88             extended_arg = 0
       
    89             i = i+2
       
    90             if op == EXTENDED_ARG:
       
    91                 extended_arg = oparg*65536L
       
    92             print repr(oparg).rjust(5),
       
    93             if op in hasconst:
       
    94                 print '(' + repr(co.co_consts[oparg]) + ')',
       
    95             elif op in hasname:
       
    96                 print '(' + co.co_names[oparg] + ')',
       
    97             elif op in hasjrel:
       
    98                 print '(to ' + repr(i + oparg) + ')',
       
    99             elif op in haslocal:
       
   100                 print '(' + co.co_varnames[oparg] + ')',
       
   101             elif op in hascompare:
       
   102                 print '(' + cmp_op[oparg] + ')',
       
   103             elif op in hasfree:
       
   104                 if free is None:
       
   105                     free = co.co_cellvars + co.co_freevars
       
   106                 print '(' + free[oparg] + ')',
       
   107         print
       
   108 
       
   109 def disassemble_string(code, lasti=-1, varnames=None, names=None,
       
   110                        constants=None):
       
   111     labels = findlabels(code)
       
   112     n = len(code)
       
   113     i = 0
       
   114     while i < n:
       
   115         c = code[i]
       
   116         op = ord(c)
       
   117         if i == lasti: print '-->',
       
   118         else: print '   ',
       
   119         if i in labels: print '>>',
       
   120         else: print '  ',
       
   121         print repr(i).rjust(4),
       
   122         print opname[op].ljust(15),
       
   123         i = i+1
       
   124         if op >= HAVE_ARGUMENT:
       
   125             oparg = ord(code[i]) + ord(code[i+1])*256
       
   126             i = i+2
       
   127             print repr(oparg).rjust(5),
       
   128             if op in hasconst:
       
   129                 if constants:
       
   130                     print '(' + repr(constants[oparg]) + ')',
       
   131                 else:
       
   132                     print '(%d)'%oparg,
       
   133             elif op in hasname:
       
   134                 if names is not None:
       
   135                     print '(' + names[oparg] + ')',
       
   136                 else:
       
   137                     print '(%d)'%oparg,
       
   138             elif op in hasjrel:
       
   139                 print '(to ' + repr(i + oparg) + ')',
       
   140             elif op in haslocal:
       
   141                 if varnames:
       
   142                     print '(' + varnames[oparg] + ')',
       
   143                 else:
       
   144                     print '(%d)' % oparg,
       
   145             elif op in hascompare:
       
   146                 print '(' + cmp_op[oparg] + ')',
       
   147         print
       
   148 
       
   149 disco = disassemble                     # XXX For backwards compatibility
       
   150 
       
   151 def findlabels(code):
       
   152     """Detect all offsets in a byte code which are jump targets.
       
   153 
       
   154     Return the list of offsets.
       
   155 
       
   156     """
       
   157     labels = []
       
   158     n = len(code)
       
   159     i = 0
       
   160     while i < n:
       
   161         c = code[i]
       
   162         op = ord(c)
       
   163         i = i+1
       
   164         if op >= HAVE_ARGUMENT:
       
   165             oparg = ord(code[i]) + ord(code[i+1])*256
       
   166             i = i+2
       
   167             label = -1
       
   168             if op in hasjrel:
       
   169                 label = i+oparg
       
   170             elif op in hasjabs:
       
   171                 label = oparg
       
   172             if label >= 0:
       
   173                 if label not in labels:
       
   174                     labels.append(label)
       
   175     return labels
       
   176 
       
   177 def findlinestarts(code):
       
   178     """Find the offsets in a byte code which are start of lines in the source.
       
   179 
       
   180     Generate pairs (offset, lineno) as described in Python/compile.c.
       
   181 
       
   182     """
       
   183     byte_increments = [ord(c) for c in code.co_lnotab[0::2]]
       
   184     line_increments = [ord(c) for c in code.co_lnotab[1::2]]
       
   185 
       
   186     lastlineno = None
       
   187     lineno = code.co_firstlineno
       
   188     addr = 0
       
   189     for byte_incr, line_incr in zip(byte_increments, line_increments):
       
   190         if byte_incr:
       
   191             if lineno != lastlineno:
       
   192                 yield (addr, lineno)
       
   193                 lastlineno = lineno
       
   194             addr += byte_incr
       
   195         lineno += line_incr
       
   196     if lineno != lastlineno:
       
   197         yield (addr, lineno)
       
   198 
       
   199 def _test():
       
   200     """Simple test program to disassemble a file."""
       
   201     if sys.argv[1:]:
       
   202         if sys.argv[2:]:
       
   203             sys.stderr.write("usage: python dis.py [-|file]\n")
       
   204             sys.exit(2)
       
   205         fn = sys.argv[1]
       
   206         if not fn or fn == "-":
       
   207             fn = None
       
   208     else:
       
   209         fn = None
       
   210     if fn is None:
       
   211         f = sys.stdin
       
   212     else:
       
   213         f = open(fn)
       
   214     source = f.read()
       
   215     if fn is not None:
       
   216         f.close()
       
   217     else:
       
   218         fn = "<stdin>"
       
   219     code = compile(source, fn, "exec")
       
   220     dis(code)
       
   221 
       
   222 if __name__ == "__main__":
       
   223     _test()