Mercurial > cpython-lru_cache-weakref
annotate Lib/dis.py @ 5817:48b94de85bf3 legacy-trunk
Extensive changes by AMK.
| author | Guido van Rossum <guido@python.org> |
|---|---|
| date | Thu, 17 Jul 1997 16:29:42 +0000 |
| parents | a86ea2cceaec |
| children | 14025a4f793e |
| rev | line source |
|---|---|
| 103 | 1 # Disassembler |
| 2 | |
| 3 import sys | |
| 4 import string | |
|
5189
bab9196a8f30
Support disassembly of a variety of objects through dis.dis().
Guido van Rossum <guido@python.org>
parents:
4989
diff
changeset
|
5 import types |
| 103 | 6 |
|
4988
df385cc0d2e3
More user friedly interface:
Guido van Rossum <guido@python.org>
parents:
4974
diff
changeset
|
7 def dis(x=None): |
|
df385cc0d2e3
More user friedly interface:
Guido van Rossum <guido@python.org>
parents:
4974
diff
changeset
|
8 if not x: |
|
df385cc0d2e3
More user friedly interface:
Guido van Rossum <guido@python.org>
parents:
4974
diff
changeset
|
9 distb() |
|
5189
bab9196a8f30
Support disassembly of a variety of objects through dis.dis().
Guido van Rossum <guido@python.org>
parents:
4989
diff
changeset
|
10 return |
|
bab9196a8f30
Support disassembly of a variety of objects through dis.dis().
Guido van Rossum <guido@python.org>
parents:
4989
diff
changeset
|
11 if type(x) is types.InstanceType: |
|
bab9196a8f30
Support disassembly of a variety of objects through dis.dis().
Guido van Rossum <guido@python.org>
parents:
4989
diff
changeset
|
12 x = x.__class__ |
|
bab9196a8f30
Support disassembly of a variety of objects through dis.dis().
Guido van Rossum <guido@python.org>
parents:
4989
diff
changeset
|
13 if hasattr(x, '__dict__'): |
|
bab9196a8f30
Support disassembly of a variety of objects through dis.dis().
Guido van Rossum <guido@python.org>
parents:
4989
diff
changeset
|
14 items = x.__dict__.items() |
|
bab9196a8f30
Support disassembly of a variety of objects through dis.dis().
Guido van Rossum <guido@python.org>
parents:
4989
diff
changeset
|
15 items.sort() |
|
bab9196a8f30
Support disassembly of a variety of objects through dis.dis().
Guido van Rossum <guido@python.org>
parents:
4989
diff
changeset
|
16 for name, x1 in items: |
|
bab9196a8f30
Support disassembly of a variety of objects through dis.dis().
Guido van Rossum <guido@python.org>
parents:
4989
diff
changeset
|
17 if type(x1) in (types.MethodType, |
|
bab9196a8f30
Support disassembly of a variety of objects through dis.dis().
Guido van Rossum <guido@python.org>
parents:
4989
diff
changeset
|
18 types.FunctionType, |
|
bab9196a8f30
Support disassembly of a variety of objects through dis.dis().
Guido van Rossum <guido@python.org>
parents:
4989
diff
changeset
|
19 types.CodeType): |
|
bab9196a8f30
Support disassembly of a variety of objects through dis.dis().
Guido van Rossum <guido@python.org>
parents:
4989
diff
changeset
|
20 print "Disassembly of %s:" % name |
|
bab9196a8f30
Support disassembly of a variety of objects through dis.dis().
Guido van Rossum <guido@python.org>
parents:
4989
diff
changeset
|
21 try: |
|
bab9196a8f30
Support disassembly of a variety of objects through dis.dis().
Guido van Rossum <guido@python.org>
parents:
4989
diff
changeset
|
22 dis(x1) |
|
bab9196a8f30
Support disassembly of a variety of objects through dis.dis().
Guido van Rossum <guido@python.org>
parents:
4989
diff
changeset
|
23 except TypeError, msg: |
|
bab9196a8f30
Support disassembly of a variety of objects through dis.dis().
Guido van Rossum <guido@python.org>
parents:
4989
diff
changeset
|
24 print "Sorry:", msg |
|
bab9196a8f30
Support disassembly of a variety of objects through dis.dis().
Guido van Rossum <guido@python.org>
parents:
4989
diff
changeset
|
25 print |
|
4988
df385cc0d2e3
More user friedly interface:
Guido van Rossum <guido@python.org>
parents:
4974
diff
changeset
|
26 else: |
|
df385cc0d2e3
More user friedly interface:
Guido van Rossum <guido@python.org>
parents:
4974
diff
changeset
|
27 if hasattr(x, 'im_func'): |
|
df385cc0d2e3
More user friedly interface:
Guido van Rossum <guido@python.org>
parents:
4974
diff
changeset
|
28 x = x.im_func |
|
df385cc0d2e3
More user friedly interface:
Guido van Rossum <guido@python.org>
parents:
4974
diff
changeset
|
29 if hasattr(x, 'func_code'): |
|
df385cc0d2e3
More user friedly interface:
Guido van Rossum <guido@python.org>
parents:
4974
diff
changeset
|
30 x = x.func_code |
|
df385cc0d2e3
More user friedly interface:
Guido van Rossum <guido@python.org>
parents:
4974
diff
changeset
|
31 if hasattr(x, 'co_code'): |
|
df385cc0d2e3
More user friedly interface:
Guido van Rossum <guido@python.org>
parents:
4974
diff
changeset
|
32 disassemble(x) |
|
df385cc0d2e3
More user friedly interface:
Guido van Rossum <guido@python.org>
parents:
4974
diff
changeset
|
33 else: |
|
4989
65148ded5108
Of course, when the type of the argument to dis() is unsupported, it
Guido van Rossum <guido@python.org>
parents:
4988
diff
changeset
|
34 raise TypeError, \ |
|
4988
df385cc0d2e3
More user friedly interface:
Guido van Rossum <guido@python.org>
parents:
4974
diff
changeset
|
35 "don't know how to disassemble %s objects" % \ |
|
df385cc0d2e3
More user friedly interface:
Guido van Rossum <guido@python.org>
parents:
4974
diff
changeset
|
36 type(x).__name__ |
| 103 | 37 |
|
4988
df385cc0d2e3
More user friedly interface:
Guido van Rossum <guido@python.org>
parents:
4974
diff
changeset
|
38 def distb(tb=None): |
|
df385cc0d2e3
More user friedly interface:
Guido van Rossum <guido@python.org>
parents:
4974
diff
changeset
|
39 if not tb: |
|
df385cc0d2e3
More user friedly interface:
Guido van Rossum <guido@python.org>
parents:
4974
diff
changeset
|
40 try: |
|
df385cc0d2e3
More user friedly interface:
Guido van Rossum <guido@python.org>
parents:
4974
diff
changeset
|
41 tb = sys.last_traceback |
|
df385cc0d2e3
More user friedly interface:
Guido van Rossum <guido@python.org>
parents:
4974
diff
changeset
|
42 except AttributeError: |
|
df385cc0d2e3
More user friedly interface:
Guido van Rossum <guido@python.org>
parents:
4974
diff
changeset
|
43 raise RuntimeError, "no last traceback to disassemble" |
|
df385cc0d2e3
More user friedly interface:
Guido van Rossum <guido@python.org>
parents:
4974
diff
changeset
|
44 while tb.tb_next: tb = tb.tb_next |
| 103 | 45 disassemble(tb.tb_frame.f_code, tb.tb_lasti) |
| 46 | |
|
4988
df385cc0d2e3
More user friedly interface:
Guido van Rossum <guido@python.org>
parents:
4974
diff
changeset
|
47 def disassemble(co, lasti=-1): |
| 103 | 48 code = co.co_code |
| 49 labels = findlabels(code) | |
| 50 n = len(code) | |
| 51 i = 0 | |
| 52 while i < n: | |
| 53 c = code[i] | |
| 54 op = ord(c) | |
| 559 | 55 if op == SET_LINENO and i > 0: print # Extra blank line |
| 56 if i == lasti: print '-->', | |
| 103 | 57 else: print ' ', |
| 58 if i in labels: print '>>', | |
| 59 else: print ' ', | |
| 60 print string.rjust(`i`, 4), | |
| 61 print string.ljust(opname[op], 15), | |
| 62 i = i+1 | |
| 63 if op >= HAVE_ARGUMENT: | |
| 64 oparg = ord(code[i]) + ord(code[i+1])*256 | |
| 65 i = i+2 | |
| 66 print string.rjust(`oparg`, 5), | |
| 67 if op in hasconst: | |
| 68 print '(' + `co.co_consts[oparg]` + ')', | |
| 69 elif op in hasname: | |
| 70 print '(' + co.co_names[oparg] + ')', | |
| 71 elif op in hasjrel: | |
| 72 print '(to ' + `i + oparg` + ')', | |
|
4303
388f9c2220ce
Show names of locals in disco (Ka-Ping Yee)
Guido van Rossum <guido@python.org>
parents:
4271
diff
changeset
|
73 elif op in haslocal: |
|
388f9c2220ce
Show names of locals in disco (Ka-Ping Yee)
Guido van Rossum <guido@python.org>
parents:
4271
diff
changeset
|
74 print '(' + co.co_varnames[oparg] + ')', |
| 4974 | 75 elif op in hascompare: |
| 76 print '(' + cmp_op[oparg] + ')', | |
| 103 | 77 print |
| 78 | |
|
4988
df385cc0d2e3
More user friedly interface:
Guido van Rossum <guido@python.org>
parents:
4974
diff
changeset
|
79 disco = disassemble |
|
df385cc0d2e3
More user friedly interface:
Guido van Rossum <guido@python.org>
parents:
4974
diff
changeset
|
80 |
| 103 | 81 def findlabels(code): |
| 82 labels = [] | |
| 83 n = len(code) | |
| 84 i = 0 | |
| 85 while i < n: | |
| 86 c = code[i] | |
| 87 op = ord(c) | |
| 88 i = i+1 | |
| 89 if op >= HAVE_ARGUMENT: | |
| 90 oparg = ord(code[i]) + ord(code[i+1])*256 | |
| 91 i = i+2 | |
| 92 label = -1 | |
| 93 if op in hasjrel: | |
| 94 label = i+oparg | |
| 95 elif op in hasjabs: | |
| 96 label = oparg | |
| 97 if label >= 0: | |
| 98 if label not in labels: | |
| 99 labels.append(label) | |
| 100 return labels | |
| 101 | |
| 4974 | 102 cmp_op = ('<', '<=', '==', '!=', '>', '>=', 'in', 'not in', 'is', |
| 103 'is not', 'exception match', 'BAD') | |
| 104 | |
| 103 | 105 hasconst = [] |
| 106 hasname = [] | |
| 107 hasjrel = [] | |
| 108 hasjabs = [] | |
|
4303
388f9c2220ce
Show names of locals in disco (Ka-Ping Yee)
Guido van Rossum <guido@python.org>
parents:
4271
diff
changeset
|
109 haslocal = [] |
| 4974 | 110 hascompare = [] |
| 103 | 111 |
|
1403
6278933d02e3
* string.py: added rindex(), rfind(); changed index() to interpret
Guido van Rossum <guido@python.org>
parents:
1264
diff
changeset
|
112 opname = [''] * 256 |
|
6278933d02e3
* string.py: added rindex(), rfind(); changed index() to interpret
Guido van Rossum <guido@python.org>
parents:
1264
diff
changeset
|
113 for op in range(256): opname[op] = '<' + `op` + '>' |
| 103 | 114 |
| 115 def def_op(name, op): | |
| 116 opname[op] = name | |
| 117 | |
| 118 def name_op(name, op): | |
| 119 opname[op] = name | |
| 120 hasname.append(op) | |
| 121 | |
| 122 def jrel_op(name, op): | |
| 123 opname[op] = name | |
| 124 hasjrel.append(op) | |
| 125 | |
| 126 def jabs_op(name, op): | |
| 127 opname[op] = name | |
| 128 hasjabs.append(op) | |
| 129 | |
| 130 # Instruction opcodes for compiled code | |
| 131 | |
| 132 def_op('STOP_CODE', 0) | |
| 133 def_op('POP_TOP', 1) | |
| 134 def_op('ROT_TWO', 2) | |
| 135 def_op('ROT_THREE', 3) | |
| 136 def_op('DUP_TOP', 4) | |
| 137 | |
| 138 def_op('UNARY_POSITIVE', 10) | |
| 139 def_op('UNARY_NEGATIVE', 11) | |
| 140 def_op('UNARY_NOT', 12) | |
| 141 def_op('UNARY_CONVERT', 13) | |
| 5475 | 142 |
|
1264
6c58dc1d2f9d
Updated because of new opcodes introduced for "fast" local variables.
Guido van Rossum <guido@python.org>
parents:
559
diff
changeset
|
143 def_op('UNARY_INVERT', 15) |
| 103 | 144 |
|
3753
97d2278a331b
New opcodes BINARY_POWER, RAISE_VARARGS, CALL_FUNCTION, MAKE_FUNCTION
Guido van Rossum <guido@python.org>
parents:
1746
diff
changeset
|
145 def_op('BINARY_POWER', 19) |
| 5475 | 146 |
| 103 | 147 def_op('BINARY_MULTIPLY', 20) |
| 148 def_op('BINARY_DIVIDE', 21) | |
| 149 def_op('BINARY_MODULO', 22) | |
| 150 def_op('BINARY_ADD', 23) | |
| 151 def_op('BINARY_SUBTRACT', 24) | |
| 152 def_op('BINARY_SUBSCR', 25) | |
| 153 | |
| 154 def_op('SLICE+0', 30) | |
| 155 def_op('SLICE+1', 31) | |
| 156 def_op('SLICE+2', 32) | |
| 157 def_op('SLICE+3', 33) | |
| 158 | |
| 159 def_op('STORE_SLICE+0', 40) | |
| 160 def_op('STORE_SLICE+1', 41) | |
| 161 def_op('STORE_SLICE+2', 42) | |
| 162 def_op('STORE_SLICE+3', 43) | |
| 163 | |
| 164 def_op('DELETE_SLICE+0', 50) | |
| 165 def_op('DELETE_SLICE+1', 51) | |
| 166 def_op('DELETE_SLICE+2', 52) | |
| 167 def_op('DELETE_SLICE+3', 53) | |
| 168 | |
| 169 def_op('STORE_SUBSCR', 60) | |
| 170 def_op('DELETE_SUBSCR', 61) | |
| 5475 | 171 |
| 4974 | 172 def_op('BINARY_LSHIFT', 62) |
| 173 def_op('BINARY_RSHIFT', 63) | |
| 174 def_op('BINARY_AND', 64) | |
| 175 def_op('BINARY_XOR', 65) | |
| 176 def_op('BINARY_OR', 66) | |
| 103 | 177 |
| 178 def_op('PRINT_EXPR', 70) | |
| 179 def_op('PRINT_ITEM', 71) | |
| 180 def_op('PRINT_NEWLINE', 72) | |
| 181 | |
| 182 def_op('BREAK_LOOP', 80) | |
| 5475 | 183 |
| 103 | 184 def_op('LOAD_LOCALS', 82) |
| 185 def_op('RETURN_VALUE', 83) | |
| 5475 | 186 |
|
1746
1940892d2fe3
Merge alpha100 branch back to main trunk
Guido van Rossum <guido@python.org>
parents:
1403
diff
changeset
|
187 def_op('EXEC_STMT', 85) |
| 5475 | 188 |
| 103 | 189 def_op('POP_BLOCK', 87) |
| 190 def_op('END_FINALLY', 88) | |
| 191 def_op('BUILD_CLASS', 89) | |
| 192 | |
| 193 HAVE_ARGUMENT = 90 # Opcodes from here have an argument: | |
| 194 | |
| 195 name_op('STORE_NAME', 90) # Index in name list | |
| 196 name_op('DELETE_NAME', 91) # "" | |
| 197 def_op('UNPACK_TUPLE', 92) # Number of tuple items | |
| 198 def_op('UNPACK_LIST', 93) # Number of list items | |
|
490
023c7f69d240
New opcodes: UNPACK_ARG, STORE_GLOBAL, DELETE_GLOBAL, LOAD_LOCAL, LOAD_GLOBAL
Guido van Rossum <guido@python.org>
parents:
103
diff
changeset
|
199 def_op('UNPACK_ARG', 94) # Number of arguments expected |
| 103 | 200 name_op('STORE_ATTR', 95) # Index in name list |
|
490
023c7f69d240
New opcodes: UNPACK_ARG, STORE_GLOBAL, DELETE_GLOBAL, LOAD_LOCAL, LOAD_GLOBAL
Guido van Rossum <guido@python.org>
parents:
103
diff
changeset
|
201 name_op('DELETE_ATTR', 96) # "" |
|
023c7f69d240
New opcodes: UNPACK_ARG, STORE_GLOBAL, DELETE_GLOBAL, LOAD_LOCAL, LOAD_GLOBAL
Guido van Rossum <guido@python.org>
parents:
103
diff
changeset
|
202 name_op('STORE_GLOBAL', 97) # "" |
|
023c7f69d240
New opcodes: UNPACK_ARG, STORE_GLOBAL, DELETE_GLOBAL, LOAD_LOCAL, LOAD_GLOBAL
Guido van Rossum <guido@python.org>
parents:
103
diff
changeset
|
203 name_op('DELETE_GLOBAL', 98) # "" |
|
1264
6c58dc1d2f9d
Updated because of new opcodes introduced for "fast" local variables.
Guido van Rossum <guido@python.org>
parents:
559
diff
changeset
|
204 name_op('UNPACK_VARARG', 99) # Minimal number of arguments |
| 103 | 205 |
| 206 def_op('LOAD_CONST', 100) # Index in const list | |
| 207 hasconst.append(100) | |
| 208 name_op('LOAD_NAME', 101) # Index in name list | |
| 209 def_op('BUILD_TUPLE', 102) # Number of tuple items | |
| 210 def_op('BUILD_LIST', 103) # Number of list items | |
| 211 def_op('BUILD_MAP', 104) # Always zero for now | |
| 212 name_op('LOAD_ATTR', 105) # Index in name list | |
| 213 def_op('COMPARE_OP', 106) # Comparison operator | |
| 5475 | 214 hascompare.append(106) |
| 103 | 215 name_op('IMPORT_NAME', 107) # Index in name list |
| 216 name_op('IMPORT_FROM', 108) # Index in name list | |
| 217 | |
| 218 jrel_op('JUMP_FORWARD', 110) # Number of bytes to skip | |
| 219 jrel_op('JUMP_IF_FALSE', 111) # "" | |
| 220 jrel_op('JUMP_IF_TRUE', 112) # "" | |
| 221 jabs_op('JUMP_ABSOLUTE', 113) # Target byte offset from beginning of code | |
| 222 jrel_op('FOR_LOOP', 114) # Number of bytes to skip | |
| 223 | |
|
490
023c7f69d240
New opcodes: UNPACK_ARG, STORE_GLOBAL, DELETE_GLOBAL, LOAD_LOCAL, LOAD_GLOBAL
Guido van Rossum <guido@python.org>
parents:
103
diff
changeset
|
224 name_op('LOAD_LOCAL', 115) # Index in name list |
|
023c7f69d240
New opcodes: UNPACK_ARG, STORE_GLOBAL, DELETE_GLOBAL, LOAD_LOCAL, LOAD_GLOBAL
Guido van Rossum <guido@python.org>
parents:
103
diff
changeset
|
225 name_op('LOAD_GLOBAL', 116) # Index in name list |
| 5475 | 226 |
|
1746
1940892d2fe3
Merge alpha100 branch back to main trunk
Guido van Rossum <guido@python.org>
parents:
1403
diff
changeset
|
227 def_op('SET_FUNC_ARGS', 117) # Argcount |
|
490
023c7f69d240
New opcodes: UNPACK_ARG, STORE_GLOBAL, DELETE_GLOBAL, LOAD_LOCAL, LOAD_GLOBAL
Guido van Rossum <guido@python.org>
parents:
103
diff
changeset
|
228 |
| 103 | 229 jrel_op('SETUP_LOOP', 120) # Distance to target address |
| 230 jrel_op('SETUP_EXCEPT', 121) # "" | |
| 231 jrel_op('SETUP_FINALLY', 122) # "" | |
| 232 | |
|
1264
6c58dc1d2f9d
Updated because of new opcodes introduced for "fast" local variables.
Guido van Rossum <guido@python.org>
parents:
559
diff
changeset
|
233 def_op('LOAD_FAST', 124) # Local variable number |
|
4303
388f9c2220ce
Show names of locals in disco (Ka-Ping Yee)
Guido van Rossum <guido@python.org>
parents:
4271
diff
changeset
|
234 haslocal.append(124) |
|
1264
6c58dc1d2f9d
Updated because of new opcodes introduced for "fast" local variables.
Guido van Rossum <guido@python.org>
parents:
559
diff
changeset
|
235 def_op('STORE_FAST', 125) # Local variable number |
|
4303
388f9c2220ce
Show names of locals in disco (Ka-Ping Yee)
Guido van Rossum <guido@python.org>
parents:
4271
diff
changeset
|
236 haslocal.append(125) |
|
1264
6c58dc1d2f9d
Updated because of new opcodes introduced for "fast" local variables.
Guido van Rossum <guido@python.org>
parents:
559
diff
changeset
|
237 def_op('DELETE_FAST', 126) # Local variable number |
|
4303
388f9c2220ce
Show names of locals in disco (Ka-Ping Yee)
Guido van Rossum <guido@python.org>
parents:
4271
diff
changeset
|
238 haslocal.append(126) |
|
1264
6c58dc1d2f9d
Updated because of new opcodes introduced for "fast" local variables.
Guido van Rossum <guido@python.org>
parents:
559
diff
changeset
|
239 |
| 103 | 240 def_op('SET_LINENO', 127) # Current line number |
| 241 SET_LINENO = 127 | |
|
3753
97d2278a331b
New opcodes BINARY_POWER, RAISE_VARARGS, CALL_FUNCTION, MAKE_FUNCTION
Guido van Rossum <guido@python.org>
parents:
1746
diff
changeset
|
242 |
|
97d2278a331b
New opcodes BINARY_POWER, RAISE_VARARGS, CALL_FUNCTION, MAKE_FUNCTION
Guido van Rossum <guido@python.org>
parents:
1746
diff
changeset
|
243 def_op('RAISE_VARARGS', 130) |
|
97d2278a331b
New opcodes BINARY_POWER, RAISE_VARARGS, CALL_FUNCTION, MAKE_FUNCTION
Guido van Rossum <guido@python.org>
parents:
1746
diff
changeset
|
244 def_op('CALL_FUNCTION', 131) |
|
97d2278a331b
New opcodes BINARY_POWER, RAISE_VARARGS, CALL_FUNCTION, MAKE_FUNCTION
Guido van Rossum <guido@python.org>
parents:
1746
diff
changeset
|
245 def_op('MAKE_FUNCTION', 132) |
|
3820
f7f3e4b5693c
Added BUILD_SLICE opcode.
Guido van Rossum <guido@python.org>
parents:
3753
diff
changeset
|
246 def_op('BUILD_SLICE', 133) |
