diff --git a/lib/risc/instructions/branch.rb b/lib/risc/instructions/branch.rb index 72c9cd3e..4c9f53e5 100644 --- a/lib/risc/instructions/branch.rb +++ b/lib/risc/instructions/branch.rb @@ -23,8 +23,8 @@ module Risc end alias :inspect :to_s - # if branch is implemented it must return the label it branches to - def branch + # if branch_to is implemented it must return the label it branches to + def branch_to label end end diff --git a/lib/risc/position/branch_listener.rb b/lib/risc/position/branch_listener.rb index b807aacc..bce8e461 100644 --- a/lib/risc/position/branch_listener.rb +++ b/lib/risc/position/branch_listener.rb @@ -3,12 +3,13 @@ module Risc class BranchListener # initialize with the instruction listener - def initialize(listener) - @listener = listener + def initialize(branch) + @branch = branch end - + # incoming position is the labels def position_changed(position) + @branch.precheck end # don't react to insertion, as the CodeListener will take care diff --git a/lib/risc/position/instruction_listener.rb b/lib/risc/position/instruction_listener.rb index 1ca0a716..9868527f 100644 --- a/lib/risc/position/instruction_listener.rb +++ b/lib/risc/position/instruction_listener.rb @@ -88,16 +88,18 @@ module Risc raise "Not Binary Code #{code.class}" unless code.is_a?(Parfait::BinaryCode) raise "Must init with instruction, not nil" unless instruction first = nil + branches = [] while(instruction) position = Position.get_or_create(instruction) first = position unless first position.position_listener( InstructionListener.new( code ) ) - if instruction.respond_to?(:branch) -# label_pos = Position.get(instruction.branch) -# label_pos.position_listener( BranchListener.new(il)) - end + branches << instruction if instruction.respond_to?(:branch_to) instruction = instruction.next end + branches.each do |branch| + label_pos = Position.get(branch.branch_to) + label_pos.position_listener( BranchListener.new(branch) ) + end first end end diff --git a/lib/risc/position/position.rb b/lib/risc/position/position.rb index 5e4139ea..bd800df4 100644 --- a/lib/risc/position/position.rb +++ b/lib/risc/position/position.rb @@ -220,5 +220,6 @@ module Risc end require_relative "position_listener" require_relative "instruction_listener" +require_relative "branch_listener" require_relative "code_listener" require_relative "label_listener" diff --git a/test/risc/position/helper.rb b/test/risc/position/helper.rb index f08c549f..f2ba37fa 100644 --- a/test/risc/position/helper.rb +++ b/test/risc/position/helper.rb @@ -37,6 +37,14 @@ module Risc DummyInstruction.new end end + class DummyBranch < Branch + attr_reader :precheck_called + + def precheck + @precheck_called = true + end + end + class DummyInstruction < Dummy include Util::List def initialize(nekst = nil) diff --git a/test/risc/position/test_branch_listener.rb b/test/risc/position/test_branch_listener.rb index 9bffdf92..fb8fc6b4 100644 --- a/test/risc/position/test_branch_listener.rb +++ b/test/risc/position/test_branch_listener.rb @@ -1,14 +1,35 @@ require_relative "helper" +require 'minitest/mock' module Risc - class TestBranchListener < MiniTest::Test + class TestBranchListenerBooted < MiniTest::Test + def setup + DummyPlatform.boot + @binary = Parfait::BinaryCode.new(1) + @bin_pos = CodeListener.init(@binary).set(0) + @label = Label.new("HI","ho" , FakeAddress.new(2)) + @branch = DummyBranch.new( "Dummy" , @label ) + @branch.insert @label + InstructionListener.init(@branch , @binary) + @position = Position.get(@label) + end + def test_init_add_listener + assert_equal BranchListener , @position.event_table.values.first.last.class + end + def test_set + Position.get(@branch).set(12) + assert_equal 16 , Position.get(@label).at + end + def test_set_fires + Position.get(@label).set(20) + assert @branch.precheck_called + end + end + class TestBranchListenerPositioned < MiniTest::Test def setup @machine = Risc.machine.boot @machine.translate(:interpreter) @machine.position_all end - - def test_has_init - end end end