Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 7d1cf1c

Browse files
committed
Properly use disassembler for DFG
1 parent d66c977 commit 7d1cf1c

File tree

5 files changed

+67
-71
lines changed

5 files changed

+67
-71
lines changed

lib/syntax_tree/yarv/control_flow_graph.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ def initialize(iseq, insns, blocks)
3434

3535
def disasm
3636
fmt = Disassembler.new(iseq)
37-
fmt.output.print("== cfg: #<ISeq:#{iseq.name}@<compiled>:1 ")
38-
fmt.output.puts("(#{iseq.line},0)-(#{iseq.line},0)>")
37+
fmt.output.puts("== cfg: #{iseq.inspect}")
3938

4039
blocks.each do |block|
4140
fmt.output.puts(block.id)

lib/syntax_tree/yarv/data_flow_graph.rb

Lines changed: 30 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -27,56 +27,48 @@ def initialize(cfg, insn_flows, block_flows)
2727
end
2828

2929
def disasm
30-
fmt = Disassembler.new
31-
output = StringIO.new
32-
output.puts "== dfg #{cfg.iseq.name}"
30+
fmt = Disassembler.new(cfg.iseq)
31+
fmt.output.puts("== dfg: #{cfg.iseq.inspect}")
3332

3433
cfg.blocks.each do |block|
35-
output.print(block.id)
36-
unless block.incoming_blocks.empty?
37-
srcs = block.incoming_blocks.map(&:id)
38-
output.print(" # from: #{srcs.join(", ")}")
39-
end
40-
output.puts
41-
42-
block_flow = block_flows.fetch(block.id)
43-
unless block_flow.in.empty?
44-
output.puts " # in: #{block_flow.in.join(", ")}"
45-
end
46-
47-
block.each_with_length do |insn, length|
48-
output.print(" ")
49-
output.print(insn.disasm(fmt))
50-
51-
insn_flow = insn_flows[length]
52-
if insn_flow.in.empty? && insn_flow.out.empty?
53-
output.puts
54-
next
34+
fmt.output.puts(block.id)
35+
fmt.with_prefix(" ") do
36+
unless block.incoming_blocks.empty?
37+
from = block.incoming_blocks.map(&:id).join(", ")
38+
fmt.output.puts("#{fmt.current_prefix}== from: #{from}")
5539
end
5640

57-
output.print(" # ")
58-
unless insn_flow.in.empty?
59-
output.print("in: #{insn_flow.in.join(", ")}")
60-
output.print("; ") unless insn_flow.out.empty?
41+
block_flow = block_flows.fetch(block.id)
42+
unless block_flow.in.empty?
43+
fmt.output.puts("#{fmt.current_prefix}== in: #{block_flow.in.join(", ")}")
6144
end
6245

63-
unless insn_flow.out.empty?
64-
output.print("out: #{insn_flow.out.join(", ")}")
46+
fmt.format_insns!(block.insns, block.block_start) do |insn, length|
47+
insn_flow = insn_flows[length]
48+
next if insn_flow.in.empty? && insn_flow.out.empty?
49+
50+
fmt.output.print(" # ")
51+
unless insn_flow.in.empty?
52+
fmt.output.print("in: #{insn_flow.in.join(", ")}")
53+
fmt.output.print("; ") unless insn_flow.out.empty?
54+
end
55+
56+
unless insn_flow.out.empty?
57+
fmt.output.print("out: #{insn_flow.out.join(", ")}")
58+
end
6559
end
6660

67-
output.puts
68-
end
69-
70-
dests = block.outgoing_blocks.map(&:id)
71-
dests << "leaves" if block.insns.last.leaves?
72-
output.puts(" # to: #{dests.join(", ")}") unless dests.empty?
61+
to = block.outgoing_blocks.map(&:id)
62+
to << "leaves" if block.insns.last.leaves?
63+
fmt.output.puts("#{fmt.current_prefix}== to: #{to.join(", ")}")
7364

74-
unless block_flow.out.empty?
75-
output.puts " # out: #{block_flow.out.join(", ")}"
65+
unless block_flow.out.empty?
66+
fmt.output.puts("#{fmt.current_prefix}== out: #{block_flow.out.join(", ")}")
67+
end
7668
end
7769
end
7870

79-
output.string
71+
fmt.string
8072
end
8173

8274
# Verify that we constructed the data flow graph correctly.

lib/syntax_tree/yarv/disassembler.rb

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,10 @@ def format_insns!(insns, length = 0)
146146
events.clear
147147
end
148148

149+
# A hook here to allow for custom formatting of instructions after
150+
# the main body has been processed.
151+
yield insn, length if block_given?
152+
149153
output << "\n"
150154
length += insn.length
151155
end
@@ -166,13 +170,7 @@ def with_prefix(value)
166170
private
167171

168172
def format_iseq(iseq)
169-
output << "#{current_prefix}== disasm: "
170-
output << "#<ISeq:#{iseq.name}@<compiled>:1 "
171-
172-
location = Location.fixed(line: iseq.line, char: 0, column: 0)
173-
output << "(#{location.start_line},#{location.start_column})-"
174-
output << "(#{location.end_line},#{location.end_column})"
175-
output << "> "
173+
output << "#{current_prefix}== disasm: #{iseq.inspect} "
176174

177175
if iseq.catch_table.any?
178176
output << "(catch: TRUE)\n"

lib/syntax_tree/yarv/instruction_sequence.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,10 @@ def disasm
276276
fmt.string
277277
end
278278

279+
def inspect
280+
"#<ISeq:#{name}@<compiled>:1 (#{line},#{0})-(#{line},#{0})>"
281+
end
282+
279283
# This method converts our linked list of instructions into a final array
280284
# and performs any other compilation steps necessary.
281285
def compile!

test/yarv_test.rb

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -335,31 +335,34 @@ def test_dfg
335335
dfg = SyntaxTree::YARV::DataFlowGraph.compile(cfg)
336336

337337
assert_equal(<<~DFG, dfg.disasm)
338-
== dfg <compiled>
338+
== dfg: #<ISeq:<compiled>@<compiled>:1 (1,0)-(1,0)>
339339
block_0
340-
putobject 100 # out: out_0
341-
putobject 14 # out: 5
342-
putobject_INT2FIX_0_ # out: 5
343-
opt_lt <calldata!mid:<, argc:1, ARGS_SIMPLE> # in: 2, 4; out: 7
344-
branchunless 13 # in: 5
345-
# to: block_13, block_9
346-
# out: 0
347-
block_9 # from: block_0
348-
# in: pass_0
349-
putobject -1 # out: out_0
350-
jump 14
351-
# to: block_14
352-
# out: pass_0, 9
353-
block_13 # from: block_0
354-
# in: pass_0
355-
putobject_INT2FIX_1_ # out: out_0
356-
# to: block_14
357-
# out: pass_0, 13
358-
block_14 # from: block_9, block_13
359-
# in: in_0, in_1
360-
opt_plus <calldata!mid:+, argc:1, ARGS_SIMPLE> # in: in_0, in_1; out: 16
361-
leave # in: 14
362-
# to: leaves
340+
0000 putobject 100 # out: out_0
341+
0002 putobject 14 # out: 5
342+
0004 putobject_INT2FIX_0_ # out: 5
343+
0005 opt_lt <calldata!mid:<, argc:1, ARGS_SIMPLE> # in: 2, 4; out: 7
344+
0007 branchunless 13 # in: 5
345+
== to: block_13, block_9
346+
== out: 0
347+
block_9
348+
== from: block_0
349+
== in: pass_0
350+
0009 putobject -1 # out: out_0
351+
0011 jump 14
352+
== to: block_14
353+
== out: pass_0, 9
354+
block_13
355+
== from: block_0
356+
== in: pass_0
357+
0013 putobject_INT2FIX_1_ # out: out_0
358+
== to: block_14
359+
== out: pass_0, 13
360+
block_14
361+
== from: block_9, block_13
362+
== in: in_0, in_1
363+
0014 opt_plus <calldata!mid:+, argc:1, ARGS_SIMPLE> # in: in_0, in_1; out: 16
364+
0016 leave # in: 14
365+
== to: leaves
363366
DFG
364367
end
365368

0 commit comments

Comments
 (0)