You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 00:45:53 +08:00
pydisassemble disassemble without grammar mangling
Some other small cleanups as well
This commit is contained in:
@@ -40,10 +40,13 @@ import uncompyle6.scanner as scan
|
||||
|
||||
class Scanner3(scan.Scanner):
|
||||
|
||||
## FIXME opnames should be passed in here
|
||||
def __init__(self, version):
|
||||
self.version = version
|
||||
scan.Scanner.__init__(self, version)
|
||||
|
||||
|
||||
## FIXME opnames should be moved to init
|
||||
def disassemble3(self, co, opnames, classname=None, code_objects={}):
|
||||
|
||||
# import dis; dis.disassemble(co) # DEBUG
|
||||
@@ -51,24 +54,12 @@ class Scanner3(scan.Scanner):
|
||||
# Container for tokens
|
||||
tokens = []
|
||||
|
||||
customize = {}
|
||||
self.code = array('B', co.co_code)
|
||||
self.build_lines_data(co)
|
||||
self.build_prev_op()
|
||||
|
||||
bytecode = dis3.Bytecode(co, opnames)
|
||||
|
||||
# self.lines contains (block,addrLastInstr)
|
||||
if classname:
|
||||
classname = '_' + classname.lstrip('_') + '__'
|
||||
|
||||
def unmangle(name):
|
||||
if name.startswith(classname) and name[-2:] != '__':
|
||||
return name[len(classname) - 2:]
|
||||
return name
|
||||
else:
|
||||
pass
|
||||
|
||||
# Scan for assertions. Later we will
|
||||
# turn 'LOAD_GLOBAL' to 'LOAD_ASSERT' for those
|
||||
# assertions
|
||||
@@ -131,7 +122,7 @@ class Scanner3(scan.Scanner):
|
||||
opname = 'MAKE_FUNCTION_N%d' % name_pair_args
|
||||
pass
|
||||
if annotate_args > 0:
|
||||
opname = '%s_A_%d' % [op_name, annotate_args]
|
||||
opname = '%s_A_%d' % [opname, annotate_args]
|
||||
pass
|
||||
opname = '%s_%d' % (opname, pos_args)
|
||||
pattr = ("%d positional, %d keyword pair, %d annotated" %
|
||||
@@ -150,16 +141,14 @@ class Scanner3(scan.Scanner):
|
||||
'RAISE_VARARGS'
|
||||
):
|
||||
pos_args = inst.argval
|
||||
if inst.opname != 'BUILD_SLICE':
|
||||
customize[opname] = pos_args
|
||||
pass
|
||||
opname = '%s_%d' % (opname, pos_args)
|
||||
elif opname == 'JUMP_ABSOLUTE':
|
||||
pattr = inst.argval
|
||||
target = self.get_target(inst.offset)
|
||||
if target < inst.offset:
|
||||
next_opname = opnames[self.code[inst.offset+3]]
|
||||
if (inst.offset in self.stmts and
|
||||
self.code[inst.offset+3] not in (END_FINALLY, POP_BLOCK)
|
||||
next_opname not in ('END_FINALLY', 'POP_BLOCK')
|
||||
and inst.offset not in self.not_continue):
|
||||
opname = 'CONTINUE'
|
||||
else:
|
||||
@@ -180,6 +169,32 @@ class Scanner3(scan.Scanner):
|
||||
pass
|
||||
return tokens, {}
|
||||
|
||||
def disassemble3_native(self, co, opnames, classname=None, code_objects={}):
|
||||
"""
|
||||
Like disassemble3 but doesn't try to adjust any opcodes.
|
||||
"""
|
||||
# Container for tokens
|
||||
tokens = []
|
||||
|
||||
self.code = array('B', co.co_code)
|
||||
|
||||
bytecode = dis3.Bytecode(co, opnames)
|
||||
|
||||
for inst in bytecode:
|
||||
pattr = inst.argrepr
|
||||
opname = inst.opname
|
||||
tokens.append(
|
||||
Token(
|
||||
type_ = opname,
|
||||
attr = inst.argval,
|
||||
pattr = pattr,
|
||||
offset = inst.offset,
|
||||
linestart = inst.starts_line,
|
||||
)
|
||||
)
|
||||
pass
|
||||
return tokens, {}
|
||||
|
||||
def disassemble_generic(self, co, classname=None, code_objects={}):
|
||||
"""
|
||||
Convert code object <co> into a sequence of tokens.
|
||||
|
Reference in New Issue
Block a user