rubyx/lib/virtual/block.rb
2014-08-19 22:54:28 +03:00

59 lines
1.4 KiB
Ruby

require_relative "object"
module Virtual
# Think flowcharts: blocks are the boxes. The smallest unit of linear code
# Blocks must end in control instructions (jump/call/return).
# And the only valid argument for a jump is a Block
# Blocks form a graph, which is managed by the method
class Block < Virtual::Object
def initialize(name , method )
super()
@method = method
@name = name.to_sym
@branch = nil
@codes = []
end
attr_reader :name , :codes , :method
attr_accessor :branch
def reachable ret = []
add_next ret
add_branch ret
ret
end
def add_code kode
@codes << kode
self
end
# returns if this is a block that ends in a call (and thus needs local variable handling)
def call_block?
return false unless codes.last.is_a?(CallInstruction)
return false unless codes.last.opcode == :call
codes.dup.reverse.find{ |c| c.is_a? StackInstruction }
end
private
# helper for determining reachable blocks
def add_next ret
return if @next.nil?
return if ret.include? @next
ret << @next
@next.reachable ret
end
# helper for determining reachable blocks
def add_branch ret
return if @branch.nil?
return if ret.include? @branch
ret << @branch
@branch.reachable ret
end
end
end