diff --git a/lib/risc/machine.rb b/lib/risc/machine.rb index 1aa05b0f..f6d70f33 100644 --- a/lib/risc/machine.rb +++ b/lib/risc/machine.rb @@ -114,7 +114,7 @@ module Risc before = at nekst = method.binary while(nekst) - Position.set_position(nekst , at) + Position.set_position(nekst , at , method) at += nekst.padded_length nekst = nekst.next end diff --git a/lib/risc/position.rb b/lib/risc/position.rb index 31bbbcc1..b0f7faf7 100644 --- a/lib/risc/position.rb +++ b/lib/risc/position.rb @@ -35,7 +35,13 @@ module Risc def to_s "0x#{@at.to_s(16)}" end - + def reset_to(pos) + if((at - pos).abs > 1000) + raise "position set too far off #{pos}!=#{at} for #{object}:#{object.class}" + end + @at = pos + self + end def self.positions @positions end @@ -51,15 +57,40 @@ module Risc pos end - def self.set_position( object , pos ) + def self.set_position( object , pos , extra = nil) # resetting of position used to be error, but since relink and dynamic instruction size it is ok. # in measures (of 32) #puts "Setting #{pos} for #{self.class}" old = Position.positions[object] - if old != nil and ((old - pos).abs > 1000) - raise "position set too far off #{pos}!=#{old} for #{object}:#{object.class}" + return old.reset_to(pos) if old != nil + self.positions[object] = for_at( object , pos , extra) + end + + def self.for_at(object , at , extra) + case object + when Parfait::BinaryCode + BPosition.new(object,at , extra) + when Arm::Instruction , Risc::Label + IPosition.new(object,at) + else + Position.new(at) end - self.positions[object] = Position.new( pos ) + end + end + # handle event propagation + class IPosition < Position + attr_reader :instruction + def initialize(instruction, pos) + super(pos) + @instruction = instruction + end + end + class BPosition < Position + attr_reader :code , :method + def initialize(code, pos , method) + super(pos) + @code = code + @method = method end end end diff --git a/test/risc/test_position.rb b/test/risc/test_position.rb index 0d5068bc..763aefaa 100644 --- a/test/risc/test_position.rb +++ b/test/risc/test_position.rb @@ -25,6 +25,10 @@ module Risc pos = Position.set_position(self , 5) assert_equal 5 , pos.at end + def test_set_instr + pos = Position.set_position( Risc::Label.new("hi","ho") , 0) + assert_equal IPosition , pos.class + end def tet_tos assert_equal "0x10" , Position.set_position(self).to_s end