From 698c84529718c6dfb007460eed21a2752ccd0f0a Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Fri, 15 Jun 2018 22:00:49 +0300 Subject: [PATCH] seperate position create and register many test fixes --- lib/risc/machine.rb | 2 +- lib/risc/position/code_listener.rb | 4 +- lib/risc/position/instruction_listener.rb | 6 +-- lib/risc/position/position.rb | 51 +++++++++++++++---- lib/risc/text_writer.rb | 14 +---- test/arm/helper.rb | 2 +- test/arm/test_call.rb | 4 +- test/arm/test_logic.rb | 6 +-- test/arm/test_move.rb | 2 +- .../position/test_instruction_listener.rb | 8 +-- test/risc/position/test_label_listener.rb | 4 +- test/risc/position/test_position.rb | 6 +-- test/risc/position/test_position1.rb | 6 +-- test/risc/position/test_position2.rb | 10 ++-- test/risc/position/test_position_listener.rb | 4 +- test/risc/test_text_writer.rb | 1 + 16 files changed, 75 insertions(+), 55 deletions(-) diff --git a/lib/risc/machine.rb b/lib/risc/machine.rb index e0733e03..2fec8cb6 100644 --- a/lib/risc/machine.rb +++ b/lib/risc/machine.rb @@ -103,7 +103,7 @@ module Risc end previous = nil sorted.each do |objekt| - next if objekt.is_a?( Parfait::BinaryCode) or objekt.is_a?( Risc::Label ) + next unless Position.is_object(objekt) before = at unless( Position.set?(objekt)) raise objekt.class diff --git a/lib/risc/position/code_listener.rb b/lib/risc/position/code_listener.rb index bf5d1f79..eae0cc39 100644 --- a/lib/risc/position/code_listener.rb +++ b/lib/risc/position/code_listener.rb @@ -45,7 +45,7 @@ module Risc translator = Risc.machine.platform.translator cpu_jump = translator.translate(jump) pos = at + code.padded_length - cpu_jump.byte_length - Position.new(cpu_jump , pos) + Position.create(cpu_jump).set(pos) cpu_jump.assemble(JumpWriter.new(code)) end @@ -55,7 +55,7 @@ module Risc first = nil while code raise "Not Binary Code #{code.class}" unless code.is_a?(Parfait::BinaryCode) - position = Position.new(code , -1) + position = Position.get_or_create(code) first = position unless first position.position_listener(CodeListener.new) code = code.next diff --git a/lib/risc/position/instruction_listener.rb b/lib/risc/position/instruction_listener.rb index 525255a4..570424a0 100644 --- a/lib/risc/position/instruction_listener.rb +++ b/lib/risc/position/instruction_listener.rb @@ -69,7 +69,7 @@ module Risc # - trigger change for this (fake) to set position of inserted def position_inserted(position) inserted = position.object.next - new_pos = Position.new(inserted , -1) + new_pos = Position.get_or_create(inserted) new_pos.position_listener(InstructionListener.new(@binary)) position.trigger_changing(position.at) @@ -89,13 +89,13 @@ module Risc raise "Must init with instruction, not nil" unless instruction first = nil while(instruction) - position = Position.new(instruction , -1) + position = Position.get_or_create(instruction) first = position unless first il = InstructionListener.new( code ) position.position_listener(il) if instruction.respond_to?(:branch) # label_pos = Position.get(instruction.branch) -# label_pos.position_listener( BranchListener.new(il)) +# label_pos.position_listener( BranchListener.new(il)) end instruction = instruction.next end diff --git a/lib/risc/position/position.rb b/lib/risc/position/position.rb index 1e0f602d..59e0ef98 100644 --- a/lib/risc/position/position.rb +++ b/lib/risc/position/position.rb @@ -20,18 +20,19 @@ module Risc include Util::Logging log_level :info + INVALID = -1 + include Util::Eventable attr_reader :at , :object # initialize with a given object, first parameter - # The object ill be the key in global position map - # Give an integer as the actual position, where -1 - # which means no legal position known - def initialize(object , pos ) - @at = pos + # The object will be the key in global position map + # + # The actual position starts as -1 (invalid) + def initialize(object) + @at = INVALID @object = object - Position.set_to(self , pos) end # utility to register events of type :position_changed @@ -62,7 +63,7 @@ module Risc end def valid? - @at != -1 + @at != INVALID end def set(int) @@ -71,7 +72,7 @@ module Risc Position.set_to(self , int) @at = int trigger_changed - int + self end # helper to fire the event that the position is about to change @@ -164,6 +165,23 @@ module Risc pos end + # creating means instantiating and caching + def self.create(object) + pos = Position.new(object) + self.positions[object] = pos + log.debug "Initialize for #{object.class} #{object.object_id.to_s(16)}" + pos + end + + def self.get_or_create(object) + if self.positions.has_key?(object) + pos = self.get(object) + else + pos = self.create(object) + end + return pos + end + # populate the position caches (forward and revese) with the given position # forward caches object -> position # reverse caches position.at > position @@ -178,13 +196,26 @@ module Risc end self.positions[position.object] = position @reverse_cache[to] = position unless position.object.is_a?(Label) - if to == -1 - log.debug "Initialize for #{position.object.class} #{position.object.object_id.to_s(16)}" + if to == INVALID + raise "Old style, change code" else log.debug "Set #{position} to 0x#{to.to_s(16)} for #{position.object.class} #{position.object.object_id.to_s(16)}" end position end + + def self.is_object(object) + case object + when Risc::Label , Parfait::BinaryCode + return false + when Parfait::Object , Symbol + return true + when Arm::Instruction , Risc::Branch + return false + else + raise "Class #{object.class}" + end + end end end require_relative "position_listener" diff --git a/lib/risc/text_writer.rb b/lib/risc/text_writer.rb index 7645a7ba..d560aef4 100644 --- a/lib/risc/text_writer.rb +++ b/lib/risc/text_writer.rb @@ -50,22 +50,10 @@ module Risc # Write all the objects in the order that they have been positioed def write_objects sorted_objects.each do |objekt| - next unless is_object(objekt) + next unless Position.is_object(objekt) write_any( objekt ) end end - def is_object(object) - case object - when Risc::Label , Parfait::BinaryCode - return false - when Parfait::Object , Symbol - return true - when Arm::Instruction - return false - else - raise "Class #{object.class}" - end - end # Write the BinaryCode objects of all methods to stream. # Really like any other object, it's just about the ordering diff --git a/test/arm/helper.rb b/test/arm/helper.rb index d2145a8b..347bea51 100644 --- a/test/arm/helper.rb +++ b/test/arm/helper.rb @@ -18,7 +18,7 @@ module Arm @machine = Arm::ArmMachine @binary = FakeBin.new Risc::Position.clear_positions - Risc::Position.new(@binary , 0) + Risc::Position.create(@binary).set(0) end # code is what the generator spits out, at least one instruction worth (.first) diff --git a/test/arm/test_call.rb b/test/arm/test_call.rb index 932f4226..c5668276 100644 --- a/test/arm/test_call.rb +++ b/test/arm/test_call.rb @@ -18,9 +18,9 @@ module Arm def test_method_call Risc.machine.boot bin = Parfait::BinaryCode.new(1) - Risc::Position.new(bin , 0x20) + Risc::Position.new(bin).set(0x20) code = @machine.call( bin ,{} )#this jumps to the next instruction - Risc::Position.new(code, 0) + Risc::Position.new(code).set(0) assert_code code , :call, [0x08,0x0,0x0,0xeb] end def test_swi diff --git a/test/arm/test_logic.rb b/test/arm/test_logic.rb index 8c78c482..2cb63adb 100644 --- a/test/arm/test_logic.rb +++ b/test/arm/test_logic.rb @@ -82,7 +82,7 @@ module Arm end def test_too_big_add code = @machine.add :r1 , :r1, 0x222 - Risc::Position.new(code,0) + Risc::Position.create(code).set(0) # add 0x02 (first instruction) and then 0x220 shifted assert_code code , :add , [0x02,0x1c,0x91,0xe2] #e2 91 1e 02 # added extra instruction to add "extra" @@ -91,14 +91,14 @@ module Arm def label( pos = 0x22 + 8) label = Risc::Label.new("some" , "Label" , FakeAddress.new(pos)) - Risc::Position.new(label , pos) + Risc::Position.create(label).set(pos) #Risc::Position.set(l , pos , @binary) label end def test_move_object code = @machine.add( :r1 , label) - Risc::Position.new(code,0) + Risc::Position.create(code).set(0) assert_code code , :add , [0x22,0x10,0x9f,0xe2] #e2 9f 10 22 end diff --git a/test/arm/test_move.rb b/test/arm/test_move.rb index 3fda4141..cc55af17 100644 --- a/test/arm/test_move.rb +++ b/test/arm/test_move.rb @@ -26,7 +26,7 @@ module Arm end def test_mov_big code = @machine.mov :r0, 0x222 # is not 8 bit and can't be rotated by the arm system in one instruction - Risc::Position.new(code,0) + Risc::Position.new(code).set(0) # mov 512(0x200) = e3 a0 0c 02 add 34(0x22) = e2 90 00 22 assert_code code , :mov , [ 0x02,0x0c,0xb0,0xe3] assert_code code.next , :add , [ 0x22,0x00,0x90,0xe2] diff --git a/test/risc/position/test_instruction_listener.rb b/test/risc/position/test_instruction_listener.rb index 6cf267e5..30ecdbba 100644 --- a/test/risc/position/test_instruction_listener.rb +++ b/test/risc/position/test_instruction_listener.rb @@ -5,13 +5,13 @@ module Risc def setup Risc.machine.boot @binary = Parfait::BinaryCode.new(1) - @bin_pos = Position.new(@binary,0) + @bin_pos = Position.new(@binary).set(0) @instruction = DummyInstruction.new(DummyInstruction.new) @position = InstructionListener.init(@instruction , @binary) end def test_label_address label = Label.new("hi" ,"ho" , FakeAddress.new(0)) - label_pos = Position.new( label , -1 ) + label_pos = Position.new( label ) label_pos.position_listener(InstructionListener.new(@binary)) label_pos.set(8) assert_equal 8 , label_pos.object.address.value @@ -52,8 +52,8 @@ module Risc def test_label_at_branch label = Label.new("Hi","Ho" , FakeAddress.new(5) , @instruction) branch = Branch.new("b" , label) - Position.new(label , 8 ) - Position.new(branch , 8 ) + Position.new(label ).set(8) + Position.new(branch).set(8) at_8 = Position.at(8) assert_equal Position , at_8.class assert_equal Branch , at_8.object.class diff --git a/test/risc/position/test_label_listener.rb b/test/risc/position/test_label_listener.rb index aaf7a986..55c15418 100644 --- a/test/risc/position/test_label_listener.rb +++ b/test/risc/position/test_label_listener.rb @@ -6,9 +6,9 @@ module Risc def setup Risc.machine.boot @label = Label.new("Hi","Ho" , FakeAddress.new(5)) - @label_pos = Position.new(@label , -1) + @label_pos = Position.new(@label ).set(4) @code = Parfait::BinaryCode.new(1) - @code_pos = Position.new(@code , -1) + @code_pos = Position.new(@code) @code_pos.position_listener( LabelListener.new(@label)) end diff --git a/test/risc/position/test_position.rb b/test/risc/position/test_position.rb index aa480616..03bf834b 100644 --- a/test/risc/position/test_position.rb +++ b/test/risc/position/test_position.rb @@ -5,7 +5,7 @@ module Risc class TestPosition < MiniTest::Test def setup - @pos = Position.new(self , -1) + @pos = Position.new(self ) end def test_new assert @pos @@ -15,7 +15,7 @@ module Risc end def test_next_slot mov = Arm::ArmMachine.mov(:r1 , :r1) - position = Position.new(mov , 0) + position = Position.new(mov ).set(0) assert_equal 4, position.next_slot end def test_has_get_code @@ -38,7 +38,7 @@ module Risc assert_equal 1 , @pos.position_listeners.length end def test_set - assert_equal 0 , @pos.set(0) + assert_equal 0 , @pos.set(0).at end end end diff --git a/test/risc/position/test_position1.rb b/test/risc/position/test_position1.rb index 0a15dbf2..ad264d41 100644 --- a/test/risc/position/test_position1.rb +++ b/test/risc/position/test_position1.rb @@ -5,7 +5,7 @@ module Risc def setup Position.clear_positions @instruction = DummyInstruction.new - @position = Position.new(@instruction , 0) + @position = Position.new(@instruction).set(0) @listener = PositionListener.new( @instruction ) end def test_has_register @@ -24,7 +24,7 @@ module Risc end def test_no_fire_after_unregister @object = @instruction - Position.new(self, 10) + Position.new(self).set(10) assert @position.register_event(:position_changed , self)#can't use helper assert @position.remove_position_listener(self) @position.trigger(:position_changed , @position) @@ -38,7 +38,7 @@ module Risc end def test_position_set_triggers @object = @instruction - Position.new(self, 0) + Position.new(self).set(0) @position.register_event(:position_changed , self)#can't use helper @position.set(10) assert_equal @position , @trigger diff --git a/test/risc/position/test_position2.rb b/test/risc/position/test_position2.rb index 6a7c2b19..b0fbcdbb 100644 --- a/test/risc/position/test_position2.rb +++ b/test/risc/position/test_position2.rb @@ -4,7 +4,7 @@ module Risc class TestPositionMath < MiniTest::Test def setup - @pos = Position.new(self , 5) + @pos = Position.new(self).set(5) end def test_add res = @pos + 5 @@ -15,24 +15,24 @@ module Risc assert_equal 2 , res end def test_sub_pos - res = @pos - Position.new(@pos,4) + res = @pos - Position.new(@pos).set(4) assert_equal 1 , res end def test_lg - assert @pos > Position.new(@pos,4) + assert @pos > Position.new(@pos).set(2) end def test_tos assert_equal "0x5" , @pos.to_s end def test_reset_ok pos = @pos.set(10) - assert_equal 10 , pos + assert_equal 10 , pos.at end def test_object_class_test assert_equal :object , @pos.object_class end def test_object_class_instr - assert_equal :instruction , Position.new(Label.new("hi","ho",FakeAddress.new(1)),4).object_class + assert_equal :instruction , Position.new(Label.new("hi","ho",FakeAddress.new(1))).set(4).object_class end def test_at pos = Position.at(5) diff --git a/test/risc/position/test_position_listener.rb b/test/risc/position/test_position_listener.rb index 27f93d35..007e79c4 100644 --- a/test/risc/position/test_position_listener.rb +++ b/test/risc/position/test_position_listener.rb @@ -6,8 +6,8 @@ module Risc def setup @object = Dummy.new @dependent = Dummy.new - @pos = Position.new(@object,0) - Position.new(@dependent,0) + @pos = Position.new(@object).set(0) + Position.new(@dependent).set(0) @listener = PositionListener.new(@dependent) end def test_register diff --git a/test/risc/test_text_writer.rb b/test/risc/test_text_writer.rb index c4407b55..184aadf1 100644 --- a/test/risc/test_text_writer.rb +++ b/test/risc/test_text_writer.rb @@ -20,6 +20,7 @@ module Risc @machine = Risc.machine.boot @machine.translate(:arm) @machine.position_all + @machine.create_binary @text_writer = TextWriter.new(@machine) end def test_write_all