@@ -6,6 +6,15 @@ module YARV
66 # control-flow-graph. Data flow is discovered locally and then globally. The
77 # graph only considers data flow through the stack - local variables and
88 # objects are considered fully escaped in this analysis.
9+ #
10+ # You can use this class by calling the ::compile method and passing it a
11+ # control flow graph. It will return a data flow graph object.
12+ #
13+ # iseq = RubyVM::InstructionSequence.compile("1 + 2")
14+ # iseq = SyntaxTree::YARV::InstructionSequence.from(iseq.to_a)
15+ # cfg = SyntaxTree::YARV::ControlFlowGraph.compile(iseq)
16+ # dfg = SyntaxTree::YARV::DataFlowGraph.compile(cfg)
17+ #
918 class DataFlowGraph
1019 # This object represents the flow of data between instructions.
1120 class DataFlow
@@ -28,42 +37,42 @@ def initialize(cfg, insn_flows, block_flows)
2837
2938 def disasm
3039 fmt = Disassembler . new ( cfg . iseq )
31- fmt . output . puts ( "== dfg: #{ cfg . iseq . inspect } " )
40+ fmt . puts ( "== dfg: #{ cfg . iseq . inspect } " )
3241
3342 cfg . blocks . each do |block |
34- fmt . output . puts ( block . id )
43+ fmt . puts ( block . id )
3544 fmt . with_prefix ( " " ) do |prefix |
3645 unless block . incoming_blocks . empty?
3746 from = block . incoming_blocks . map ( &:id )
38- fmt . output . puts ( "#{ prefix } == from: #{ from . join ( ", " ) } " )
47+ fmt . puts ( "#{ prefix } == from: #{ from . join ( ", " ) } " )
3948 end
4049
4150 block_flow = block_flows . fetch ( block . id )
4251 unless block_flow . in . empty?
43- fmt . output . puts ( "#{ prefix } == in: #{ block_flow . in . join ( ", " ) } " )
52+ fmt . puts ( "#{ prefix } == in: #{ block_flow . in . join ( ", " ) } " )
4453 end
4554
4655 fmt . format_insns! ( block . insns , block . block_start ) do |_ , length |
4756 insn_flow = insn_flows [ length ]
4857 next if insn_flow . in . empty? && insn_flow . out . empty?
4958
50- fmt . output . print ( " # " )
59+ fmt . print ( " # " )
5160 unless insn_flow . in . empty?
52- fmt . output . print ( "in: #{ insn_flow . in . join ( ", " ) } " )
53- fmt . output . print ( "; " ) unless insn_flow . out . empty?
61+ fmt . print ( "in: #{ insn_flow . in . join ( ", " ) } " )
62+ fmt . print ( "; " ) unless insn_flow . out . empty?
5463 end
5564
5665 unless insn_flow . out . empty?
57- fmt . output . print ( "out: #{ insn_flow . out . join ( ", " ) } " )
66+ fmt . print ( "out: #{ insn_flow . out . join ( ", " ) } " )
5867 end
5968 end
6069
6170 to = block . outgoing_blocks . map ( &:id )
6271 to << "leaves" if block . insns . last . leaves?
63- fmt . output . puts ( "#{ prefix } == to: #{ to . join ( ", " ) } " )
72+ fmt . puts ( "#{ prefix } == to: #{ to . join ( ", " ) } " )
6473
6574 unless block_flow . out . empty?
66- fmt . output . puts ( "#{ prefix } == out: #{ block_flow . out . join ( ", " ) } " )
75+ fmt . puts ( "#{ prefix } == out: #{ block_flow . out . join ( ", " ) } " )
6776 end
6877 end
6978 end
0 commit comments