NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

dis.py (6052B)


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