You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 00:45:53 +08:00
39 lines
1.3 KiB
Python
39 lines
1.3 KiB
Python
"""
|
|
Detect control flow as much as possible.
|
|
The basic idea here is to put in explicit end instructions that make
|
|
grammar parsing simpler and more precise.
|
|
"""
|
|
|
|
from collections import namedtuple
|
|
from xdis.bytecode import Bytecode
|
|
|
|
control_flow_start = namedtuple('control_flow_start', ['name', 'type', 'offset'])
|
|
control_flow_end = namedtuple('control_flow_end', ['name', 'type', 'offset'])
|
|
|
|
class ControlFlow():
|
|
def __init__(self, scanner):
|
|
self.scanner = scanner
|
|
self.opc = self.scanner.opc
|
|
self.setup_ops = self.scanner.setup_ops
|
|
self.op_range = self.scanner.op_range
|
|
|
|
# Control-flow nesting
|
|
self.offset_action = {}
|
|
self.cf_end = []
|
|
|
|
def detect_control_flow(self, co):
|
|
self.bytecode = Bytecode(co, self.opc)
|
|
for inst in self.bytecode:
|
|
if inst.opcode in self.setup_ops:
|
|
# Use part after SETUP_
|
|
name = inst.opname[len('SETUP_'):]
|
|
self.offset_action[inst.offset] = control_flow_start(name, 'start', inst.offset)
|
|
self.offset_action[inst.argval] = control_flow_end(name, 'end', inst.offset)
|
|
pass
|
|
pass
|
|
# import pprint
|
|
# pp = pprint.PrettyPrinter(indent=4)
|
|
# pp.pprint(self.offset_action)
|
|
|
|
return self.offset_action
|