1 """Disassembler of Python byte code into mnemonics."""
7 from opcode
import __all__
as _opcodes_all
9 __all__
= ["dis","disassemble","distb","disco"] + _opcodes_all
13 """Disassemble classes, methods, functions, or code.
15 With no argument, disassemble the last traceback.
21 if type(x
) is types
.InstanceType
:
23 if hasattr(x
, 'im_func'):
25 if hasattr(x
, 'func_code'):
27 if hasattr(x
, '__dict__'):
28 items
= x
.__dict
__.items()
30 for name
, x1
in items
:
31 if type(x1
) in (types
.MethodType
,
35 print "Disassembly of %s:" % name
38 except TypeError, msg
:
41 elif hasattr(x
, 'co_code'):
43 elif isinstance(x
, str):
47 "don't know how to disassemble %s objects" % \
51 """Disassemble a traceback (default: last traceback)."""
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
)
60 def disassemble(co
, lasti
=-1):
61 """Disassemble a code object."""
64 byte_increments
= [ord(c
) for c
in co
.co_lnotab
[0::2]]
65 line_increments
= [ord(c
) for c
in co
.co_lnotab
[1::2]]
66 table_length
= len(byte_increments
) # == len(line_increments)
68 lineno
= co
.co_firstlineno
70 while (table_index
< table_length
71 and byte_increments
[table_index
] == 0):
72 lineno
+= line_increments
[table_index
]
77 labels
= findlabels(code
)
88 while table_index
< table_length
:
89 addr
+= byte_increments
[table_index
]
90 line_incr
= line_increments
[table_index
]
102 if i
== lasti
: print '-->',
104 if i
in labels
: print '>>',
107 print opname
[op
].ljust(20),
109 if op
>= HAVE_ARGUMENT
:
110 oparg
= ord(code
[i
]) + ord(code
[i
+1])*256 + extended_arg
113 if op
== EXTENDED_ARG
:
114 extended_arg
= oparg
*65536L
115 print `oparg`
.rjust(5),
117 print '(' + `co
.co_consts
[oparg
]`
+ ')',
119 print '(' + co
.co_names
[oparg
] + ')',
121 print '(to ' + `i
+ oparg`
+ ')',
123 print '(' + co
.co_varnames
[oparg
] + ')',
124 elif op
in hascompare
:
125 print '(' + cmp_op
[oparg
] + ')',
128 free
= co
.co_cellvars
+ co
.co_freevars
129 print '(' + free
[oparg
] + ')',
132 def disassemble_string(code
, lasti
=-1, varnames
=None, names
=None,
134 labels
= findlabels(code
)
140 if op
== opmap
['SET_LINENO'] and i
> 0:
141 print # Extra blank line
142 if i
== lasti
: print '-->',
144 if i
in labels
: print '>>',
147 print opname
[op
].ljust(15),
149 if op
>= HAVE_ARGUMENT
:
150 oparg
= ord(code
[i
]) + ord(code
[i
+1])*256
152 print `oparg`
.rjust(5),
155 print '(' + `constants
[oparg
]`
+ ')',
159 if names
is not None:
160 print '(' + names
[oparg
] + ')',
164 print '(to ' + `i
+ oparg`
+ ')',
167 print '(' + varnames
[oparg
] + ')',
169 print '(%d)' % oparg
,
170 elif op
in hascompare
:
171 print '(' + cmp_op
[oparg
] + ')',
174 disco
= disassemble
# XXX For backwards compatibility
176 def findlabels(code
):
177 """Detect all offsets in a byte code which are jump targets.
179 Return the list of offsets.
189 if op
>= HAVE_ARGUMENT
:
190 oparg
= ord(code
[i
]) + ord(code
[i
+1])*256
198 if label
not in labels
:
204 """Simple test program to disassemble a file."""
207 sys
.stderr
.write("usage: python dis.py [-|file]\n")
210 if not fn
or fn
== "-":
223 code
= compile(source
, fn
, "exec")
226 if __name__
== "__main__":