diff options
Diffstat (limited to 'Lib/dis.py')
-rw-r--r-- | Lib/dis.py | 328 |
1 files changed, 164 insertions, 164 deletions
@@ -5,115 +5,115 @@ import string import types def dis(x=None): - """Disassemble classes, methods, functions, or code. - - With no argument, disassemble the last traceback. - - """ - if not x: - distb() - return - if type(x) is types.InstanceType: - x = x.__class__ - if hasattr(x, '__dict__'): - items = x.__dict__.items() - items.sort() - for name, x1 in items: - if type(x1) in (types.MethodType, - types.FunctionType, - types.CodeType): - print "Disassembly of %s:" % name - try: - dis(x1) - except TypeError, msg: - print "Sorry:", msg - print - else: - if hasattr(x, 'im_func'): - x = x.im_func - if hasattr(x, 'func_code'): - x = x.func_code - if hasattr(x, 'co_code'): - disassemble(x) - else: - raise TypeError, \ - "don't know how to disassemble %s objects" % \ - type(x).__name__ + """Disassemble classes, methods, functions, or code. + + With no argument, disassemble the last traceback. + + """ + if not x: + distb() + return + if type(x) is types.InstanceType: + x = x.__class__ + if hasattr(x, '__dict__'): + items = x.__dict__.items() + items.sort() + for name, x1 in items: + if type(x1) in (types.MethodType, + types.FunctionType, + types.CodeType): + print "Disassembly of %s:" % name + try: + dis(x1) + except TypeError, msg: + print "Sorry:", msg + print + else: + if hasattr(x, 'im_func'): + x = x.im_func + if hasattr(x, 'func_code'): + x = x.func_code + if hasattr(x, 'co_code'): + disassemble(x) + else: + raise TypeError, \ + "don't know how to disassemble %s objects" % \ + type(x).__name__ def distb(tb=None): - """Disassemble a traceback (default: last traceback).""" - if not tb: - try: - tb = sys.last_traceback - except AttributeError: - raise RuntimeError, "no last traceback to disassemble" - while tb.tb_next: tb = tb.tb_next - disassemble(tb.tb_frame.f_code, tb.tb_lasti) + """Disassemble a traceback (default: last traceback).""" + if not tb: + try: + tb = sys.last_traceback + except AttributeError: + raise RuntimeError, "no last traceback to disassemble" + while tb.tb_next: tb = tb.tb_next + disassemble(tb.tb_frame.f_code, tb.tb_lasti) def disassemble(co, lasti=-1): - """Disassemble a code object.""" - code = co.co_code - labels = findlabels(code) - n = len(code) - i = 0 - extended_arg = 0 - while i < n: - c = code[i] - op = ord(c) - if op == SET_LINENO and i > 0: print # Extra blank line - if i == lasti: print '-->', - else: print ' ', - if i in labels: print '>>', - else: print ' ', - print string.rjust(`i`, 4), - print string.ljust(opname[op], 20), - i = i+1 - if op >= HAVE_ARGUMENT: - oparg = ord(code[i]) + ord(code[i+1])*256 + extended_arg - extended_arg = 0 - i = i+2 - if op == EXTENDED_ARG: - extended_arg = oparg*65536L - print string.rjust(`oparg`, 5), - if op in hasconst: - print '(' + `co.co_consts[oparg]` + ')', - elif op in hasname: - print '(' + co.co_names[oparg] + ')', - elif op in hasjrel: - print '(to ' + `i + oparg` + ')', - elif op in haslocal: - print '(' + co.co_varnames[oparg] + ')', - elif op in hascompare: - print '(' + cmp_op[oparg] + ')', - print - -disco = disassemble # XXX For backwards compatibility + """Disassemble a code object.""" + code = co.co_code + labels = findlabels(code) + n = len(code) + i = 0 + extended_arg = 0 + while i < n: + c = code[i] + op = ord(c) + if op == SET_LINENO and i > 0: print # Extra blank line + if i == lasti: print '-->', + else: print ' ', + if i in labels: print '>>', + else: print ' ', + print string.rjust(`i`, 4), + print string.ljust(opname[op], 20), + i = i+1 + if op >= HAVE_ARGUMENT: + oparg = ord(code[i]) + ord(code[i+1])*256 + extended_arg + extended_arg = 0 + i = i+2 + if op == EXTENDED_ARG: + extended_arg = oparg*65536L + print string.rjust(`oparg`, 5), + if op in hasconst: + print '(' + `co.co_consts[oparg]` + ')', + elif op in hasname: + print '(' + co.co_names[oparg] + ')', + elif op in hasjrel: + print '(to ' + `i + oparg` + ')', + elif op in haslocal: + print '(' + co.co_varnames[oparg] + ')', + elif op in hascompare: + print '(' + cmp_op[oparg] + ')', + print + +disco = disassemble # XXX For backwards compatibility def findlabels(code): - """Detect all offsets in a byte code which are jump targets. - - Return the list of offsets. - - """ - labels = [] - n = len(code) - i = 0 - while i < n: - c = code[i] - op = ord(c) - i = i+1 - if op >= HAVE_ARGUMENT: - oparg = ord(code[i]) + ord(code[i+1])*256 - i = i+2 - label = -1 - if op in hasjrel: - label = i+oparg - elif op in hasjabs: - label = oparg - if label >= 0: - if label not in labels: - labels.append(label) - return labels + """Detect all offsets in a byte code which are jump targets. + + Return the list of offsets. + + """ + labels = [] + n = len(code) + i = 0 + while i < n: + c = code[i] + op = ord(c) + i = i+1 + if op >= HAVE_ARGUMENT: + oparg = ord(code[i]) + ord(code[i+1])*256 + i = i+2 + label = -1 + if op in hasjrel: + label = i+oparg + elif op in hasjabs: + label = oparg + if label >= 0: + if label not in labels: + labels.append(label) + return labels cmp_op = ('<', '<=', '==', '!=', '>', '>=', 'in', 'not in', 'is', 'is not', 'exception match', 'BAD') @@ -129,19 +129,19 @@ opname = [''] * 256 for op in range(256): opname[op] = '<' + `op` + '>' def def_op(name, op): - opname[op] = name + opname[op] = name def name_op(name, op): - opname[op] = name - hasname.append(op) + opname[op] = name + hasname.append(op) def jrel_op(name, op): - opname[op] = name - hasjrel.append(op) + opname[op] = name + hasjrel.append(op) def jabs_op(name, op): - opname[op] = name - hasjabs.append(op) + opname[op] = name + hasjabs.append(op) # Instruction opcodes for compiled code @@ -219,49 +219,49 @@ def_op('POP_BLOCK', 87) def_op('END_FINALLY', 88) def_op('BUILD_CLASS', 89) -HAVE_ARGUMENT = 90 # Opcodes from here have an argument: +HAVE_ARGUMENT = 90 # Opcodes from here have an argument: -name_op('STORE_NAME', 90) # Index in name list -name_op('DELETE_NAME', 91) # "" -def_op('UNPACK_SEQUENCE', 92) # Number of tuple items +name_op('STORE_NAME', 90) # Index in name list +name_op('DELETE_NAME', 91) # "" +def_op('UNPACK_SEQUENCE', 92) # Number of tuple items -name_op('STORE_ATTR', 95) # Index in name list -name_op('DELETE_ATTR', 96) # "" -name_op('STORE_GLOBAL', 97) # "" -name_op('DELETE_GLOBAL', 98) # "" -def_op('DUP_TOPX', 99) # number of items to duplicate -def_op('LOAD_CONST', 100) # Index in const list +name_op('STORE_ATTR', 95) # Index in name list +name_op('DELETE_ATTR', 96) # "" +name_op('STORE_GLOBAL', 97) # "" +name_op('DELETE_GLOBAL', 98) # "" +def_op('DUP_TOPX', 99) # number of items to duplicate +def_op('LOAD_CONST', 100) # Index in const list hasconst.append(100) -name_op('LOAD_NAME', 101) # Index in name list -def_op('BUILD_TUPLE', 102) # Number of tuple items -def_op('BUILD_LIST', 103) # Number of list items -def_op('BUILD_MAP', 104) # Always zero for now -name_op('LOAD_ATTR', 105) # Index in name list -def_op('COMPARE_OP', 106) # Comparison operator +name_op('LOAD_NAME', 101) # Index in name list +def_op('BUILD_TUPLE', 102) # Number of tuple items +def_op('BUILD_LIST', 103) # Number of list items +def_op('BUILD_MAP', 104) # Always zero for now +name_op('LOAD_ATTR', 105) # Index in name list +def_op('COMPARE_OP', 106) # Comparison operator hascompare.append(106) -name_op('IMPORT_NAME', 107) # Index in name list -name_op('IMPORT_FROM', 108) # Index in name list +name_op('IMPORT_NAME', 107) # Index in name list +name_op('IMPORT_FROM', 108) # Index in name list -jrel_op('JUMP_FORWARD', 110) # Number of bytes to skip -jrel_op('JUMP_IF_FALSE', 111) # "" -jrel_op('JUMP_IF_TRUE', 112) # "" -jabs_op('JUMP_ABSOLUTE', 113) # Target byte offset from beginning of code -jrel_op('FOR_LOOP', 114) # Number of bytes to skip +jrel_op('JUMP_FORWARD', 110) # Number of bytes to skip +jrel_op('JUMP_IF_FALSE', 111) # "" +jrel_op('JUMP_IF_TRUE', 112) # "" +jabs_op('JUMP_ABSOLUTE', 113) # Target byte offset from beginning of code +jrel_op('FOR_LOOP', 114) # Number of bytes to skip -name_op('LOAD_GLOBAL', 116) # Index in name list +name_op('LOAD_GLOBAL', 116) # Index in name list -jrel_op('SETUP_LOOP', 120) # Distance to target address -jrel_op('SETUP_EXCEPT', 121) # "" -jrel_op('SETUP_FINALLY', 122) # "" +jrel_op('SETUP_LOOP', 120) # Distance to target address +jrel_op('SETUP_EXCEPT', 121) # "" +jrel_op('SETUP_FINALLY', 122) # "" -def_op('LOAD_FAST', 124) # Local variable number +def_op('LOAD_FAST', 124) # Local variable number haslocal.append(124) -def_op('STORE_FAST', 125) # Local variable number +def_op('STORE_FAST', 125) # Local variable number haslocal.append(125) -def_op('DELETE_FAST', 126) # Local variable number +def_op('DELETE_FAST', 126) # Local variable number haslocal.append(126) -def_op('SET_LINENO', 127) # Current line number +def_op('SET_LINENO', 127) # Current line number SET_LINENO = 127 def_op('RAISE_VARARGS', 130) # Number of raise arguments (1, 2, or 3) @@ -273,31 +273,31 @@ def_op('CALL_FUNCTION_VAR', 140) # #args + (#kwargs << 8) def_op('CALL_FUNCTION_KW', 141) # #args + (#kwargs << 8) def_op('CALL_FUNCTION_VAR_KW', 142) # #args + (#kwargs << 8) -def_op('EXTENDED_ARG', 143) +def_op('EXTENDED_ARG', 143) EXTENDED_ARG = 143 def _test(): - """Simple test program to disassemble a file.""" - if sys.argv[1:]: - if sys.argv[2:]: - sys.stderr.write("usage: python dis.py [-|file]\n") - sys.exit(2) - fn = sys.argv[1] - if not fn or fn == "-": - fn = None - else: - fn = None - if not fn: - f = sys.stdin - else: - f = open(fn) - source = f.read() - if fn: - f.close() - else: - fn = "<stdin>" - code = compile(source, fn, "exec") - dis(code) + """Simple test program to disassemble a file.""" + if sys.argv[1:]: + if sys.argv[2:]: + sys.stderr.write("usage: python dis.py [-|file]\n") + sys.exit(2) + fn = sys.argv[1] + if not fn or fn == "-": + fn = None + else: + fn = None + if not fn: + f = sys.stdin + else: + f = open(fn) + source = f.read() + if fn: + f.close() + else: + fn = "<stdin>" + code = compile(source, fn, "exec") + dis(code) if __name__ == "__main__": - _test() + _test() |