Movatterモバイル変換


[0]ホーム

URL:


Google Git
Sign in
chromium /external /github.com /python /cpython /refs/tags/v2.0.1 /. /Lib /dis.py
blob: 8f74add59f3f2d0bdcab924b6b3476abde9e8fea [file] [log] [blame]
"""Disassembler of Python byte code into mnemonics."""
import sys
import string
import types
def dis(x=None):
"""Disassemble classes, methods, functions, or code.
With no argument, disassemble the last traceback.
"""
ifnot x:
distb()
return
if type(x)is types.InstanceType:
x= x.__class__
if hasattr(x,'__dict__'):
items= x.__dict__.items()
items.sort()
for name, x1in items:
if type(x1)in(types.MethodType,
types.FunctionType,
types.CodeType):
print"Disassembly of %s:"% name
try:
dis(x1)
exceptTypeError, 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:
raiseTypeError, \
"don't know how to disassemble %s objects"% \
type(x).__name__
def distb(tb=None):
"""Disassemble a traceback (default: last traceback)."""
ifnot tb:
try:
tb= sys.last_traceback
exceptAttributeError:
raiseRuntimeError,"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_LINENOand i>0:print# Extra blank line
if i== lasti:print'-->',
else:print' ',
if iin 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 opin hasconst:
print'('+`co.co_consts[oparg]`+')',
elif opin hasname:
print'('+ co.co_names[oparg]+')',
elif opin hasjrel:
print'(to '+`i+ oparg`+')',
elif opin haslocal:
print'('+ co.co_varnames[oparg]+')',
elif opin 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 opin hasjrel:
label= i+oparg
elif opin hasjabs:
label= oparg
if label>=0:
if labelnotin labels:
labels.append(label)
return labels
cmp_op=('<','<=','==','!=','>','>=','in','not in','is',
'is not','exception match','BAD')
hasconst=[]
hasname=[]
hasjrel=[]
hasjabs=[]
haslocal=[]
hascompare=[]
opname=['']*256
for opin range(256): opname[op]='<'+`op`+'>'
def def_op(name, op):
opname[op]= name
def name_op(name, op):
opname[op]= name
hasname.append(op)
def jrel_op(name, op):
opname[op]= name
hasjrel.append(op)
def jabs_op(name, op):
opname[op]= name
hasjabs.append(op)
# Instruction opcodes for compiled code
def_op('STOP_CODE',0)
def_op('POP_TOP',1)
def_op('ROT_TWO',2)
def_op('ROT_THREE',3)
def_op('DUP_TOP',4)
def_op('ROT_FOUR',5)
def_op('UNARY_POSITIVE',10)
def_op('UNARY_NEGATIVE',11)
def_op('UNARY_NOT',12)
def_op('UNARY_CONVERT',13)
def_op('UNARY_INVERT',15)
def_op('BINARY_POWER',19)
def_op('BINARY_MULTIPLY',20)
def_op('BINARY_DIVIDE',21)
def_op('BINARY_MODULO',22)
def_op('BINARY_ADD',23)
def_op('BINARY_SUBTRACT',24)
def_op('BINARY_SUBSCR',25)
def_op('SLICE+0',30)
def_op('SLICE+1',31)
def_op('SLICE+2',32)
def_op('SLICE+3',33)
def_op('STORE_SLICE+0',40)
def_op('STORE_SLICE+1',41)
def_op('STORE_SLICE+2',42)
def_op('STORE_SLICE+3',43)
def_op('DELETE_SLICE+0',50)
def_op('DELETE_SLICE+1',51)
def_op('DELETE_SLICE+2',52)
def_op('DELETE_SLICE+3',53)
def_op('INPLACE_ADD',55)
def_op('INPLACE_SUBTRACT',56)
def_op('INPLACE_MULTIPLY',57)
def_op('INPLACE_DIVIDE',58)
def_op('INPLACE_MODULO',59)
def_op('STORE_SUBSCR',60)
def_op('DELETE_SUBSCR',61)
def_op('BINARY_LSHIFT',62)
def_op('BINARY_RSHIFT',63)
def_op('BINARY_AND',64)
def_op('BINARY_XOR',65)
def_op('BINARY_OR',66)
def_op('INPLACE_POWER',67)
def_op('PRINT_EXPR',70)
def_op('PRINT_ITEM',71)
def_op('PRINT_NEWLINE',72)
def_op('PRINT_ITEM_TO',73)
def_op('PRINT_NEWLINE_TO',74)
def_op('INPLACE_LSHIFT',75)
def_op('INPLACE_RSHIFT',76)
def_op('INPLACE_AND',77)
def_op('INPLACE_XOR',78)
def_op('INPLACE_OR',79)
def_op('BREAK_LOOP',80)
def_op('LOAD_LOCALS',82)
def_op('RETURN_VALUE',83)
def_op('IMPORT_STAR',84)
def_op('EXEC_STMT',85)
def_op('POP_BLOCK',87)
def_op('END_FINALLY',88)
def_op('BUILD_CLASS',89)
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_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
hascompare.append(106)
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
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)# ""
def_op('LOAD_FAST',124)# Local variable number
haslocal.append(124)
def_op('STORE_FAST',125)# Local variable number
haslocal.append(125)
def_op('DELETE_FAST',126)# Local variable number
haslocal.append(126)
def_op('SET_LINENO',127)# Current line number
SET_LINENO=127
def_op('RAISE_VARARGS',130)# Number of raise arguments (1, 2, or 3)
def_op('CALL_FUNCTION',131)# #args + (#kwargs << 8)
def_op('MAKE_FUNCTION',132)# Number of args with default values
def_op('BUILD_SLICE',133)# Number of items
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)
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]
ifnot fnor fn=="-":
fn=None
else:
fn=None
ifnot 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()

[8]ページ先頭

©2009-2025 Movatter.jp