class SyntaxTree::YARV::ControlFlowGraph


cfg = SyntaxTree::YARV::ControlFlowGraph.compile(iseq)
iseq = SyntaxTree::YARV::InstructionSequence.from(iseq.to_a)
iseq = RubyVM::InstructionSequence.compile(“1 + 2”)
YARV instruction sequence. It will return a control flow graph object.
You can use this class by calling the ::compile method and passing it a
instructions from the instruction sequence.
It constructs a graph of basic blocks that hold subsets of the list of
This class represents a control flow graph of a YARV instruction sequence.

def self.compile(iseq)

def self.compile(iseq)
  Compiler.new(iseq).compile
end

def disasm

def disasm
  fmt = Disassembler.new(iseq)
  fmt.puts("== cfg: #{iseq.inspect}")
  blocks.each do |block|
    fmt.puts(block.id)
    fmt.with_prefix("    ") do |prefix|
      unless block.incoming_blocks.empty?
        from = block.incoming_blocks.map(&:id)
        fmt.puts("#{prefix}== from: #{from.join(", ")}")
      end
      fmt.format_insns!(block.insns, block.block_start)
      to = block.outgoing_blocks.map(&:id)
      to << "leaves" if block.insns.last.leaves?
      fmt.puts("#{prefix}== to: #{to.join(", ")}")
    end
  end
  fmt.string
end

def initialize(iseq, insns, blocks)

def initialize(iseq, insns, blocks)
  @iseq = iseq
  @insns = insns
  @blocks = blocks
end

def to_dfg

def to_dfg
  DataFlowGraph.compile(self)
end

def to_mermaid

def to_mermaid
  Mermaid.flowchart do |flowchart|
    disasm = Disassembler::Squished.new
    blocks.each do |block|
      flowchart.subgraph(block.id) do
        previous = nil
        block.each_with_length do |insn, length|
          node =
            flowchart.node(
              "node_#{length}",
              "%04d %s" % [length, insn.disasm(disasm)]
            )
          flowchart.link(previous, node) if previous
          previous = node
        end
      end
    end
    blocks.each do |block|
      block.outgoing_blocks.each do |outgoing|
        offset =
          block.block_start + block.insns.sum(&:length) -
            block.insns.last.length
        from = flowchart.fetch("node_#{offset}")
        to = flowchart.fetch("node_#{outgoing.block_start}")
        flowchart.link(from, to)
      end
    end
  end
end

def to_son

def to_son
  to_dfg.to_son
end

def verify

formed.
formed. It does this by checking that each basic block is itself well
This method is used to verify that the control flow graph is well
def verify
  blocks.each(&:verify)
end