/
__init__.py
95 lines (85 loc) · 3.18 KB
/
__init__.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
from bytecode import Bytecode, UNSET, Label, BasicBlock, ConcreteBytecode, ControlFlowGraph
def dump_bytecode(bytecode, *, lineno=False, io=None):
def format_line(index, line):
nonlocal cur_lineno, prev_lineno
if lineno:
if cur_lineno != prev_lineno:
line = 'L.% 3s % 3s: %s' % (cur_lineno, index, line)
prev_lineno = cur_lineno
else:
line = ' % 3s: %s' % (index, line)
else:
line = line
return line
def format_instr(instr, labels=None):
text = instr.name
arg = instr._arg
if arg is not UNSET:
if isinstance(arg, Label):
try:
arg = '<%s>' % labels[arg]
except KeyError:
arg = '<error: unknown label>'
elif isinstance(arg, BasicBlock):
try:
arg = '<%s>' % labels[id(arg)]
except KeyError:
arg = '<error: unknown block>'
else:
arg = repr(arg)
text = '%s %s' % (text, arg)
return text
indent = ' ' * 4
cur_lineno = bytecode.first_lineno
prev_lineno = None
if isinstance(bytecode, ConcreteBytecode):
offset = 0
for instr in bytecode:
fields = []
if instr.lineno is not None:
cur_lineno = instr.lineno
if lineno:
fields.append(format_instr(instr))
line = ''.join(fields)
line = format_line(offset, line)
else:
fields.append("% 3s %s" % (offset, format_instr(instr)))
line = ''.join(fields)
io(line)
offset += instr.size
elif isinstance(bytecode, Bytecode):
labels = {}
for index, instr in enumerate(bytecode):
if isinstance(instr, Label):
labels[instr] = 'label_instr%s' % index
for index, instr in enumerate(bytecode):
if isinstance(instr, Label):
label = labels[instr]
line = "%s:" % label
if index != 0:
io()
else:
if instr.lineno is not None:
cur_lineno = instr.lineno
line = format_instr(instr, labels)
line = indent + format_line(index, line)
io(line)
io()
elif isinstance(bytecode, ControlFlowGraph):
labels = {}
for block_index, block in enumerate(bytecode, 1):
labels[id(block)] = 'block%s' % block_index
for block_index, block in enumerate(bytecode, 1):
io('%s:' % labels[id(block)])
prev_lineno = None
for index, instr in enumerate(block):
if instr.lineno is not None:
cur_lineno = instr.lineno
line = format_instr(instr, labels)
line = indent + format_line(index, line)
io(line)
if block.next_block is not None:
io(indent + "-> %s" % labels[id(block.next_block)])
io()
else:
raise TypeError("unknown bytecode class")