blob: 30053bf7794f73e9ea2631ab76fe93800bdaccb9 [file] [log] [blame]
Guido van Rossum421c2241997-11-18 15:47:55 +00001"""Disassembler of Python byte code into mnemonics."""
Guido van Rossum217a5fa1990-12-26 15:40:07 +00002
3import sys
Guido van Rossum18aef3c1997-03-14 04:15:43 +00004import types
Guido van Rossum217a5fa1990-12-26 15:40:07 +00005
Skip Montanaroe99d5ea2001-01-20 19:54:20 +00006__all__ = ["dis","disassemble","distb","disco","opname","cmp_op",
7 "hasconst","hasname","hasjrel","hasjabs","haslocal",
Jeremy Hyltona39414b2001-01-25 20:08:47 +00008 "hascompare", "hasfree"]
Skip Montanaroe99d5ea2001-01-20 19:54:20 +00009
Guido van Rossumbd307951997-01-17 20:05:04 +000010def dis(x=None):
Tim Peters88869f92001-01-14 23:36:06 +000011 """Disassemble classes, methods, functions, or code.
Guido van Rossum421c2241997-11-18 15:47:55 +000012
Tim Peters88869f92001-01-14 23:36:06 +000013 With no argument, disassemble the last traceback.
Guido van Rossum421c2241997-11-18 15:47:55 +000014
Tim Peters88869f92001-01-14 23:36:06 +000015 """
Raymond Hettinger0f4940c2002-06-01 00:57:55 +000016 if x is None:
Tim Peters88869f92001-01-14 23:36:06 +000017 distb()
18 return
19 if type(x) is types.InstanceType:
20 x = x.__class__
Guido van Rossumfc53c132001-01-19 02:41:41 +000021 if hasattr(x, 'im_func'):
22 x = x.im_func
23 if hasattr(x, 'func_code'):
24 x = x.func_code
Tim Peters88869f92001-01-14 23:36:06 +000025 if hasattr(x, '__dict__'):
26 items = x.__dict__.items()
27 items.sort()
28 for name, x1 in items:
29 if type(x1) in (types.MethodType,
30 types.FunctionType,
31 types.CodeType):
32 print "Disassembly of %s:" % name
33 try:
34 dis(x1)
35 except TypeError, msg:
36 print "Sorry:", msg
37 print
Guido van Rossumfc53c132001-01-19 02:41:41 +000038 elif hasattr(x, 'co_code'):
39 disassemble(x)
Tim Peters88869f92001-01-14 23:36:06 +000040 else:
Guido van Rossumfc53c132001-01-19 02:41:41 +000041 raise TypeError, \
42 "don't know how to disassemble %s objects" % \
43 type(x).__name__
Guido van Rossum217a5fa1990-12-26 15:40:07 +000044
Guido van Rossumbd307951997-01-17 20:05:04 +000045def distb(tb=None):
Tim Peters88869f92001-01-14 23:36:06 +000046 """Disassemble a traceback (default: last traceback)."""
Raymond Hettinger0f4940c2002-06-01 00:57:55 +000047 if tb is None:
Tim Peters88869f92001-01-14 23:36:06 +000048 try:
49 tb = sys.last_traceback
50 except AttributeError:
51 raise RuntimeError, "no last traceback to disassemble"
52 while tb.tb_next: tb = tb.tb_next
53 disassemble(tb.tb_frame.f_code, tb.tb_lasti)
Guido van Rossum217a5fa1990-12-26 15:40:07 +000054
Guido van Rossumbd307951997-01-17 20:05:04 +000055def disassemble(co, lasti=-1):
Tim Peters88869f92001-01-14 23:36:06 +000056 """Disassemble a code object."""
57 code = co.co_code
Michael W. Hudsondd32a912002-08-15 14:59:02 +000058
59 byte_increments = [ord(c) for c in co.co_lnotab[0::2]]
60 line_increments = [ord(c) for c in co.co_lnotab[1::2]]
61 table_length = len(byte_increments) # == len(line_increments)
62
63 lineno = co.co_firstlineno
64 table_index = 0
65 while (table_index < table_length
66 and byte_increments[table_index] == 0):
67 lineno += line_increments[table_index]
68 table_index += 1
69 addr = 0
70 line_incr = 0
Tim Peters280488b2002-08-23 18:19:30 +000071
Tim Peters88869f92001-01-14 23:36:06 +000072 labels = findlabels(code)
73 n = len(code)
74 i = 0
75 extended_arg = 0
Jeremy Hyltona39414b2001-01-25 20:08:47 +000076 free = None
Tim Peters88869f92001-01-14 23:36:06 +000077 while i < n:
78 c = code[i]
79 op = ord(c)
Michael W. Hudsondd32a912002-08-15 14:59:02 +000080
81 if i >= addr:
82 lineno += line_incr
83 while table_index < table_length:
84 addr += byte_increments[table_index]
85 line_incr = line_increments[table_index]
86 table_index += 1
87 if line_incr:
88 break
89 else:
90 addr = sys.maxint
91 if i > 0:
92 print
93 print "%3d"%lineno,
94 else:
95 print ' ',
96
Tim Peters88869f92001-01-14 23:36:06 +000097 if i == lasti: print '-->',
98 else: print ' ',
99 if i in labels: print '>>',
100 else: print ' ',
Eric S. Raymond373c55e2001-02-09 08:25:29 +0000101 print `i`.rjust(4),
102 print opname[op].ljust(20),
Tim Peters88869f92001-01-14 23:36:06 +0000103 i = i+1
104 if op >= HAVE_ARGUMENT:
105 oparg = ord(code[i]) + ord(code[i+1])*256 + extended_arg
106 extended_arg = 0
107 i = i+2
108 if op == EXTENDED_ARG:
109 extended_arg = oparg*65536L
Eric S. Raymond373c55e2001-02-09 08:25:29 +0000110 print `oparg`.rjust(5),
Tim Peters88869f92001-01-14 23:36:06 +0000111 if op in hasconst:
112 print '(' + `co.co_consts[oparg]` + ')',
113 elif op in hasname:
114 print '(' + co.co_names[oparg] + ')',
115 elif op in hasjrel:
116 print '(to ' + `i + oparg` + ')',
117 elif op in haslocal:
118 print '(' + co.co_varnames[oparg] + ')',
119 elif op in hascompare:
120 print '(' + cmp_op[oparg] + ')',
Jeremy Hyltona39414b2001-01-25 20:08:47 +0000121 elif op in hasfree:
122 if free is None:
123 free = co.co_cellvars + co.co_freevars
124 print '(' + free[oparg] + ')',
Tim Peters88869f92001-01-14 23:36:06 +0000125 print
Guido van Rossum217a5fa1990-12-26 15:40:07 +0000126
Tim Peters88869f92001-01-14 23:36:06 +0000127disco = disassemble # XXX For backwards compatibility
Guido van Rossumbd307951997-01-17 20:05:04 +0000128
Guido van Rossum217a5fa1990-12-26 15:40:07 +0000129def findlabels(code):
Tim Peters88869f92001-01-14 23:36:06 +0000130 """Detect all offsets in a byte code which are jump targets.
Guido van Rossum421c2241997-11-18 15:47:55 +0000131
Tim Peters88869f92001-01-14 23:36:06 +0000132 Return the list of offsets.
Guido van Rossum421c2241997-11-18 15:47:55 +0000133
Tim Peters88869f92001-01-14 23:36:06 +0000134 """
135 labels = []
136 n = len(code)
137 i = 0
138 while i < n:
139 c = code[i]
140 op = ord(c)
141 i = i+1
142 if op >= HAVE_ARGUMENT:
143 oparg = ord(code[i]) + ord(code[i+1])*256
144 i = i+2
145 label = -1
146 if op in hasjrel:
147 label = i+oparg
148 elif op in hasjabs:
149 label = oparg
150 if label >= 0:
151 if label not in labels:
152 labels.append(label)
153 return labels
Guido van Rossum217a5fa1990-12-26 15:40:07 +0000154
Guido van Rossumd0bc9cb1997-01-16 18:52:24 +0000155cmp_op = ('<', '<=', '==', '!=', '>', '>=', 'in', 'not in', 'is',
156 'is not', 'exception match', 'BAD')
157
Guido van Rossum217a5fa1990-12-26 15:40:07 +0000158hasconst = []
159hasname = []
160hasjrel = []
161hasjabs = []
Guido van Rossum934a4ce1996-09-12 17:39:36 +0000162haslocal = []
Guido van Rossumd0bc9cb1997-01-16 18:52:24 +0000163hascompare = []
Jeremy Hyltona39414b2001-01-25 20:08:47 +0000164hasfree = []
Guido van Rossum217a5fa1990-12-26 15:40:07 +0000165
Guido van Rossume65cce51993-11-08 15:05:21 +0000166opname = [''] * 256
167for op in range(256): opname[op] = '<' + `op` + '>'
Neal Norwitzaa38aa52002-02-11 18:14:22 +0000168del op
Guido van Rossum217a5fa1990-12-26 15:40:07 +0000169
170def def_op(name, op):
Tim Peters88869f92001-01-14 23:36:06 +0000171 opname[op] = name
Guido van Rossum217a5fa1990-12-26 15:40:07 +0000172
173def name_op(name, op):
Tim Peters88869f92001-01-14 23:36:06 +0000174 opname[op] = name
175 hasname.append(op)
Guido van Rossum217a5fa1990-12-26 15:40:07 +0000176
177def jrel_op(name, op):
Tim Peters88869f92001-01-14 23:36:06 +0000178 opname[op] = name
179 hasjrel.append(op)
Guido van Rossum217a5fa1990-12-26 15:40:07 +0000180
181def jabs_op(name, op):
Tim Peters88869f92001-01-14 23:36:06 +0000182 opname[op] = name
183 hasjabs.append(op)
Guido van Rossum217a5fa1990-12-26 15:40:07 +0000184
185# Instruction opcodes for compiled code
186
187def_op('STOP_CODE', 0)
188def_op('POP_TOP', 1)
189def_op('ROT_TWO', 2)
190def_op('ROT_THREE', 3)
191def_op('DUP_TOP', 4)
Thomas Wouters6af3b372000-08-24 22:44:53 +0000192def_op('ROT_FOUR', 5)
Guido van Rossum217a5fa1990-12-26 15:40:07 +0000193
194def_op('UNARY_POSITIVE', 10)
195def_op('UNARY_NEGATIVE', 11)
196def_op('UNARY_NOT', 12)
197def_op('UNARY_CONVERT', 13)
Guido van Rossumd0f23721997-05-09 03:21:44 +0000198
Guido van Rossum8379ed51993-03-30 19:13:03 +0000199def_op('UNARY_INVERT', 15)
Guido van Rossum217a5fa1990-12-26 15:40:07 +0000200
Guido van Rossum6e21ceb1996-07-21 02:16:53 +0000201def_op('BINARY_POWER', 19)
Guido van Rossumd0f23721997-05-09 03:21:44 +0000202
Guido van Rossum217a5fa1990-12-26 15:40:07 +0000203def_op('BINARY_MULTIPLY', 20)
204def_op('BINARY_DIVIDE', 21)
205def_op('BINARY_MODULO', 22)
206def_op('BINARY_ADD', 23)
207def_op('BINARY_SUBTRACT', 24)
208def_op('BINARY_SUBSCR', 25)
Jeremy Hylton96d68d52001-08-29 18:02:21 +0000209def_op('BINARY_FLOOR_DIVIDE', 26)
210def_op('BINARY_TRUE_DIVIDE', 27)
211def_op('INPLACE_FLOOR_DIVIDE', 28)
212def_op('INPLACE_TRUE_DIVIDE', 29)
Guido van Rossum217a5fa1990-12-26 15:40:07 +0000213
214def_op('SLICE+0', 30)
215def_op('SLICE+1', 31)
216def_op('SLICE+2', 32)
217def_op('SLICE+3', 33)
218
219def_op('STORE_SLICE+0', 40)
220def_op('STORE_SLICE+1', 41)
221def_op('STORE_SLICE+2', 42)
222def_op('STORE_SLICE+3', 43)
223
224def_op('DELETE_SLICE+0', 50)
225def_op('DELETE_SLICE+1', 51)
226def_op('DELETE_SLICE+2', 52)
227def_op('DELETE_SLICE+3', 53)
228
Thomas Wouters104a7bc2000-08-24 20:14:10 +0000229def_op('INPLACE_ADD', 55)
230def_op('INPLACE_SUBTRACT', 56)
231def_op('INPLACE_MULTIPLY', 57)
232def_op('INPLACE_DIVIDE', 58)
233def_op('INPLACE_MODULO', 59)
Guido van Rossum217a5fa1990-12-26 15:40:07 +0000234def_op('STORE_SUBSCR', 60)
235def_op('DELETE_SUBSCR', 61)
Guido van Rossumd0f23721997-05-09 03:21:44 +0000236
Guido van Rossumd0bc9cb1997-01-16 18:52:24 +0000237def_op('BINARY_LSHIFT', 62)
238def_op('BINARY_RSHIFT', 63)
239def_op('BINARY_AND', 64)
240def_op('BINARY_XOR', 65)
241def_op('BINARY_OR', 66)
Thomas Wouters104a7bc2000-08-24 20:14:10 +0000242def_op('INPLACE_POWER', 67)
Guido van Rossum59d1d2b2001-04-20 19:13:02 +0000243def_op('GET_ITER', 68)
Guido van Rossum217a5fa1990-12-26 15:40:07 +0000244
245def_op('PRINT_EXPR', 70)
246def_op('PRINT_ITEM', 71)
247def_op('PRINT_NEWLINE', 72)
Barry Warsaw203da6d2000-08-21 17:18:40 +0000248def_op('PRINT_ITEM_TO', 73)
249def_op('PRINT_NEWLINE_TO', 74)
Thomas Wouters104a7bc2000-08-24 20:14:10 +0000250def_op('INPLACE_LSHIFT', 75)
251def_op('INPLACE_RSHIFT', 76)
252def_op('INPLACE_AND', 77)
253def_op('INPLACE_XOR', 78)
254def_op('INPLACE_OR', 79)
Guido van Rossum217a5fa1990-12-26 15:40:07 +0000255def_op('BREAK_LOOP', 80)
Guido van Rossumd0f23721997-05-09 03:21:44 +0000256
Guido van Rossum217a5fa1990-12-26 15:40:07 +0000257def_op('LOAD_LOCALS', 82)
258def_op('RETURN_VALUE', 83)
Thomas Wouters52152252000-08-17 22:55:00 +0000259def_op('IMPORT_STAR', 84)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260def_op('EXEC_STMT', 85)
Guido van Rossum9f709bf2002-06-11 21:17:35 +0000261def_op('YIELD_VALUE', 86)
Guido van Rossumd0f23721997-05-09 03:21:44 +0000262
Guido van Rossum217a5fa1990-12-26 15:40:07 +0000263def_op('POP_BLOCK', 87)
264def_op('END_FINALLY', 88)
265def_op('BUILD_CLASS', 89)
266
Tim Peters88869f92001-01-14 23:36:06 +0000267HAVE_ARGUMENT = 90 # Opcodes from here have an argument:
Guido van Rossum217a5fa1990-12-26 15:40:07 +0000268
Tim Peters88869f92001-01-14 23:36:06 +0000269name_op('STORE_NAME', 90) # Index in name list
270name_op('DELETE_NAME', 91) # ""
271def_op('UNPACK_SEQUENCE', 92) # Number of tuple items
Jeremy Hylton318e1672001-08-28 15:32:48 +0000272jrel_op('FOR_ITER', 93)
Thomas Wouters0be5aab2000-08-11 22:15:52 +0000273
Tim Peters88869f92001-01-14 23:36:06 +0000274name_op('STORE_ATTR', 95) # Index in name list
275name_op('DELETE_ATTR', 96) # ""
276name_op('STORE_GLOBAL', 97) # ""
277name_op('DELETE_GLOBAL', 98) # ""
278def_op('DUP_TOPX', 99) # number of items to duplicate
279def_op('LOAD_CONST', 100) # Index in const list
Guido van Rossum217a5fa1990-12-26 15:40:07 +0000280hasconst.append(100)
Tim Peters88869f92001-01-14 23:36:06 +0000281name_op('LOAD_NAME', 101) # Index in name list
282def_op('BUILD_TUPLE', 102) # Number of tuple items
283def_op('BUILD_LIST', 103) # Number of list items
284def_op('BUILD_MAP', 104) # Always zero for now
285name_op('LOAD_ATTR', 105) # Index in name list
286def_op('COMPARE_OP', 106) # Comparison operator
Guido van Rossumd0f23721997-05-09 03:21:44 +0000287hascompare.append(106)
Tim Peters88869f92001-01-14 23:36:06 +0000288name_op('IMPORT_NAME', 107) # Index in name list
289name_op('IMPORT_FROM', 108) # Index in name list
Guido van Rossum217a5fa1990-12-26 15:40:07 +0000290
Tim Peters88869f92001-01-14 23:36:06 +0000291jrel_op('JUMP_FORWARD', 110) # Number of bytes to skip
292jrel_op('JUMP_IF_FALSE', 111) # ""
293jrel_op('JUMP_IF_TRUE', 112) # ""
294jabs_op('JUMP_ABSOLUTE', 113) # Target byte offset from beginning of code
Guido van Rossum217a5fa1990-12-26 15:40:07 +0000295
Tim Peters88869f92001-01-14 23:36:06 +0000296name_op('LOAD_GLOBAL', 116) # Index in name list
Guido van Rossumd0f23721997-05-09 03:21:44 +0000297
Jeremy Hylton3faa52e2001-02-01 22:48:12 +0000298jabs_op('CONTINUE_LOOP', 119) # Target address
Tim Peters88869f92001-01-14 23:36:06 +0000299jrel_op('SETUP_LOOP', 120) # Distance to target address
300jrel_op('SETUP_EXCEPT', 121) # ""
301jrel_op('SETUP_FINALLY', 122) # ""
Guido van Rossum217a5fa1990-12-26 15:40:07 +0000302
Tim Peters88869f92001-01-14 23:36:06 +0000303def_op('LOAD_FAST', 124) # Local variable number
Guido van Rossum934a4ce1996-09-12 17:39:36 +0000304haslocal.append(124)
Tim Peters88869f92001-01-14 23:36:06 +0000305def_op('STORE_FAST', 125) # Local variable number
Guido van Rossum934a4ce1996-09-12 17:39:36 +0000306haslocal.append(125)
Tim Peters88869f92001-01-14 23:36:06 +0000307def_op('DELETE_FAST', 126) # Local variable number
Guido van Rossum934a4ce1996-09-12 17:39:36 +0000308haslocal.append(126)
Guido van Rossum8379ed51993-03-30 19:13:03 +0000309
Jeremy Hylton76901512000-03-28 23:49:17 +0000310def_op('RAISE_VARARGS', 130) # Number of raise arguments (1, 2, or 3)
311def_op('CALL_FUNCTION', 131) # #args + (#kwargs << 8)
312def_op('MAKE_FUNCTION', 132) # Number of args with default values
313def_op('BUILD_SLICE', 133) # Number of items
314
Jeremy Hyltona39414b2001-01-25 20:08:47 +0000315def_op('MAKE_CLOSURE', 134)
316def_op('LOAD_CLOSURE', 135)
317hasfree.append(135)
318def_op('LOAD_DEREF', 136)
319hasfree.append(136)
320def_op('STORE_DEREF', 137)
321hasfree.append(137)
322
Jeremy Hylton76901512000-03-28 23:49:17 +0000323def_op('CALL_FUNCTION_VAR', 140) # #args + (#kwargs << 8)
324def_op('CALL_FUNCTION_KW', 141) # #args + (#kwargs << 8)
325def_op('CALL_FUNCTION_VAR_KW', 142) # #args + (#kwargs << 8)
Guido van Rossum1fdae122000-02-04 17:47:55 +0000326
Tim Peters88869f92001-01-14 23:36:06 +0000327def_op('EXTENDED_ARG', 143)
Fred Drakeef8ace32000-08-24 00:32:09 +0000328EXTENDED_ARG = 143
Guido van Rossum1fdae122000-02-04 17:47:55 +0000329
330def _test():
Tim Peters88869f92001-01-14 23:36:06 +0000331 """Simple test program to disassemble a file."""
332 if sys.argv[1:]:
333 if sys.argv[2:]:
334 sys.stderr.write("usage: python dis.py [-|file]\n")
335 sys.exit(2)
336 fn = sys.argv[1]
337 if not fn or fn == "-":
338 fn = None
339 else:
340 fn = None
Raymond Hettinger0f4940c2002-06-01 00:57:55 +0000341 if fn is None:
Tim Peters88869f92001-01-14 23:36:06 +0000342 f = sys.stdin
343 else:
344 f = open(fn)
345 source = f.read()
Raymond Hettinger0f4940c2002-06-01 00:57:55 +0000346 if fn is not None:
Tim Peters88869f92001-01-14 23:36:06 +0000347 f.close()
348 else:
349 fn = "<stdin>"
350 code = compile(source, fn, "exec")
351 dis(code)
Guido van Rossum1fdae122000-02-04 17:47:55 +0000352
353if __name__ == "__main__":
Tim Peters88869f92001-01-14 23:36:06 +0000354 _test()