diff --git a/lib/arm/instructions/instruction.rb b/lib/arm/instructions/instruction.rb index fa625fcd..29c2ecb6 100644 --- a/lib/arm/instructions/instruction.rb +++ b/lib/arm/instructions/instruction.rb @@ -25,7 +25,7 @@ module Arm super my_pos = Risc::Position.get(self) # set my position to set next according to rules - Risc::Position.set( self , my_pos.at , my_pos.binary) + Risc::Position::InstructionListener.init(instruction , my_pos.get_code) end end end diff --git a/lib/risc/machine.rb b/lib/risc/machine.rb index de36c2bf..3f72b8bd 100644 --- a/lib/risc/machine.rb +++ b/lib/risc/machine.rb @@ -117,14 +117,15 @@ module Risc # # start at code_start. def position_code(code_start) - prev = nil + prev_code = nil Parfait.object_space.types.values.each do |type| next unless type.methods type.methods.each_method do |method| - last = Position::CodeListener.init(method.binary , code_start) - last.register_event(:position_changed , prev.object) if prev - prev = last - code_start = last.next_slot + last_code = Position::CodeListener.init(method.binary , code_start) + Position::InstructionListener.init(method.cpu_instructions, method.binary) + last_code.register_event(:position_changed , prev_code.object) if prev_code + prev_code = last_code + code_start = last_code.next_slot end end #Position.set( first_method.cpu_instructions, code_start + Parfait::BinaryCode.byte_offset , first_method.binary) diff --git a/lib/risc/position/instruction_position.rb b/lib/risc/position/instruction_listener.rb similarity index 78% rename from lib/risc/position/instruction_position.rb rename to lib/risc/position/instruction_listener.rb index 7922a8b2..d7d418dd 100644 --- a/lib/risc/position/instruction_position.rb +++ b/lib/risc/position/instruction_listener.rb @@ -14,11 +14,10 @@ module Risc # When propagating positions we have to see that the next position assembles into # the same BinaryCode, or else move it and the code along # - class InstructionPosition < ObjectPosition + class InstructionListener attr_reader :instruction , :binary def initialize(instruction , binary) pos = 0 - super(instruction) @instruction = instruction @binary = binary end @@ -50,21 +49,26 @@ module Risc # initialize the dependency graph for instructions # - # starting from the given instruction, create InstructionPositions - # for it and the whole chain + # starting from the given instruction, create ObjectPositions + # for it and the whole chain. Then attach InstructionListeners + # for dependency tracking. All positions are initialized with -1 + # and so setting the first will trigger a chain reaction # - # Set the next created to be dependent on the previous - def self.init( instruction , code) + # return the position for the first instruction which may be used to + # set all positions in the chain + def self.init( instruction , code ) + first = nil while(instruction) - position = InstructionPosition.new(instruction , code) + position = ObjectPosition.new(instruction , -1) + first = position unless first nekst = instruction.next if nekst - listener = InstructionListener.new( nekst ) + listener = InstructionListener.new( nekst , code ) position.register_event(:position_changed , listener) end instruction = nekst end - position + first end end end diff --git a/lib/risc/position/object_position.rb b/lib/risc/position/object_position.rb index fb21ea75..878b2fc6 100644 --- a/lib/risc/position/object_position.rb +++ b/lib/risc/position/object_position.rb @@ -12,10 +12,17 @@ module Risc # Give an integer as the actual position, where -1 # which means no legal position known def initialize(object , pos ) - @at = 0 + @at = pos @object = object + Position.set_to(self , pos) end + #look for InstructionListener and return its code if found + def get_code + listener = event_table.find{|one| one.class == InstructionListener} + return nil unless listener + listener.code + end def +(offset) offset = offset.at if offset.is_a?(ObjectPosition) @at + offset diff --git a/lib/risc/position/position.rb b/lib/risc/position/position.rb index 8120e9f3..ad23477b 100644 --- a/lib/risc/position/position.rb +++ b/lib/risc/position/position.rb @@ -57,7 +57,7 @@ module Risc end def self.set_to( position , to) - postest = Position.positions[position.object] + postest = Position.positions[position.object] unless to < 0 raise "Mismatch #{position}" if postest and postest != position @reverse_cache.delete(position.at) unless position.object.is_a? Label testing = self.at( position.at ) if position.at >= 0 @@ -73,5 +73,5 @@ module Risc end require_relative "object_position" require_relative "object_listener" -require_relative "instruction_position" +require_relative "instruction_listener" require_relative "code_listener" diff --git a/test/risc/position/test_instruction_position.rb b/test/risc/position/test_instruction_listener.rb similarity index 94% rename from test/risc/position/test_instruction_position.rb rename to test/risc/position/test_instruction_listener.rb index 2e7ff51b..b7542ac4 100644 --- a/test/risc/position/test_instruction_position.rb +++ b/test/risc/position/test_instruction_listener.rb @@ -3,7 +3,7 @@ require_relative "helper" module Risc module Position # tests that require a boot and test propagation - class TestInstructionPosition < MiniTest::Test + class TestInstructionListener < MiniTest::Test def setup Risc.machine.boot @binary = Parfait::BinaryCode.new(1) @@ -11,7 +11,7 @@ module Risc @label = Risc.label("hi","ho") end def test_init - assert InstructionPosition.init(@label , nil) + assert InstructionListener.init(@label , @binary) end def pest_set_instr pos = Position.set( @label , 8 , @binary) diff --git a/test/risc/position/test_object_position.rb b/test/risc/position/test_object_position.rb index c202e4ee..9c792f38 100644 --- a/test/risc/position/test_object_position.rb +++ b/test/risc/position/test_object_position.rb @@ -3,7 +3,7 @@ require_relative "helper" module Risc module Position # tests that do no require a boot and only test basic positioning - class TestPositionBasic < MiniTest::Test + class TestObjectPosition < MiniTest::Test def test_init assert ObjectPosition.init(self , -1) @@ -13,6 +13,9 @@ module Risc position = ObjectPosition.new(mov , 0) assert_equal 4, position.next_slot end + def test_has_get_code + assert_nil ObjectPosition.init(self , -1).get_code + end def pest_creation_ok assert ObjectPosition.new(self,0) end