From 405a6935d46c18b4c2cf25a07fefb564e0d21fc4 Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Sat, 24 Oct 2015 17:12:36 +0300 Subject: [PATCH] lots of stuff to move to linked lists and remove the blocks more position stuff coming, but the list part should be ok --- lib/register/instruction.rb | 23 ++++++++++++++- lib/register/instructions/branch.rb | 22 ++++++++++++-- lib/register/instructions/label.rb | 23 +++++++++++++-- lib/register/method_source.rb | 2 +- lib/register/parfait_adapter.rb | 2 +- lib/register/positioned.rb | 2 +- test/register/test_all.rb | 1 + test/register/test_instructions.rb | 46 +++++++++++++++++++++++++++++ 8 files changed, 112 insertions(+), 9 deletions(-) create mode 100644 test/register/test_instructions.rb diff --git a/lib/register/instruction.rb b/lib/register/instruction.rb index adf6bb46..092deff8 100644 --- a/lib/register/instruction.rb +++ b/lib/register/instruction.rb @@ -13,6 +13,7 @@ module Register # Branches fan out, Labels collect # Labels are the only valid branch targets class Instruction + include Positioned def initialize source , nekst = nil @source = source @@ -34,7 +35,7 @@ module Register def replace_next nekst old = @next @next = nekst - @next.append old.next + @next.append old.next if old end # get the next instruction (without arg given ) @@ -75,6 +76,26 @@ module Register ret end + # derived classes must provide a byte_length + def byte_length + raise "Abstract called on #{self}" + end + + def total_byte_length labels = [] + ret = self.byte_length + ret += self.next.total_byte_length(labels) if self.next + ret + end + + def set_position position , labels = [] + self.position = position + position += byte_length + if self.next + self.next.set_position(position , labels) + else + position + end + end end end diff --git a/lib/register/instructions/branch.rb b/lib/register/instructions/branch.rb index ac11053c..88d996c7 100644 --- a/lib/register/instructions/branch.rb +++ b/lib/register/instructions/branch.rb @@ -5,7 +5,6 @@ module Register class Branch < Instruction def initialize source , to super(source) - raise "No block" unless to @label = to end attr_reader :label @@ -16,12 +15,29 @@ module Register alias :inspect :to_s def length labels = [] - super(labels) + self.label.length(labels) + ret = super(labels) + ret += self.label.length(labels) if self.label + ret end def to_ac labels = [] - super(labels) + self.label.to_ac(labels) + ret = super(labels) + ret += self.label.to_ac(labels) if self.label + ret end + + def total_byte_length labels = [] + ret = super + ret += label.total_byte_length(labels) if self.label + ret + end + + # labels have the same position as their next + def set_position position , labels = [] + position = self.label.set_position( position , labels ) if self.label + super(position,labels) + end + end class IsZero < Branch diff --git a/lib/register/instructions/label.rb b/lib/register/instructions/label.rb index e0f62610..23b86ed2 100644 --- a/lib/register/instructions/label.rb +++ b/lib/register/instructions/label.rb @@ -21,14 +21,33 @@ module Register def to_ac labels = [] return [] if labels.include?(self) labels << self - self.next.to_ac(labels) + super end def length labels = [] return 0 if labels.include?(self) labels << self - 1 + self.next.length(labels) + ret = 1 + ret += self.next.length(labels) if self.next + ret end + def byte_length + 0 + end + + def total_byte_length labels = [] + return 0 if labels.include?(self) + labels << self + self.next.length(labels) + end + + # labels have the same position as their next + def set_position position , labels = [] + return position if labels.include?(self) + labels << self + self.position = position + self.next.set_position(position,labels) + end end end diff --git a/lib/register/method_source.rb b/lib/register/method_source.rb index c7eeba27..145419ef 100644 --- a/lib/register/method_source.rb +++ b/lib/register/method_source.rb @@ -84,7 +84,7 @@ module Register end def byte_length - @instructions.byte_length + @instructions.total_byte_length end # position of the function is the position of the entry block, is where we call diff --git a/lib/register/parfait_adapter.rb b/lib/register/parfait_adapter.rb index a9380e4a..f4f0a88a 100644 --- a/lib/register/parfait_adapter.rb +++ b/lib/register/parfait_adapter.rb @@ -47,7 +47,7 @@ class Symbol end pos end - def set_position pos + def position= pos # resetting of position used to be error, but since relink and dynamic instruction size it is ok. # in measures (of 32) old = cache_positions[self] diff --git a/lib/register/positioned.rb b/lib/register/positioned.rb index 5238f2ae..cf744d5f 100644 --- a/lib/register/positioned.rb +++ b/lib/register/positioned.rb @@ -8,7 +8,7 @@ module Positioned end @position end - def set_position pos + def position= pos raise "Setting of nil not allowed" if pos.nil? # resetting of position used to be error, but since relink and dynamic instruction size it is ok. # in measures (of 32) diff --git a/test/register/test_all.rb b/test/register/test_all.rb index 15e6af1c..7b1cde50 100644 --- a/test/register/test_all.rb +++ b/test/register/test_all.rb @@ -2,3 +2,4 @@ require_relative "test_compat" require_relative "test_padding" require_relative "test_positioning" +require_relative "test_instructions" diff --git a/test/register/test_instructions.rb b/test/register/test_instructions.rb new file mode 100644 index 00000000..832f2c04 --- /dev/null +++ b/test/register/test_instructions.rb @@ -0,0 +1,46 @@ +require_relative "../helper" + +module Register + class TestInstructions < MiniTest::Test + def setup + @label = Label.new(nil , "test") + @branch = Branch.new(nil , @label) + @instruction = Instruction.new(nil) + end + def test_last_empty + assert_equal @instruction, @instruction.last + end + def test_last_not_empty + @instruction.set_next @branch + assert_equal @branch, @instruction.last + end + def test_append_empty + @instruction.append @branch + assert_equal @branch, @instruction.last + end + def test_insert + @instruction.insert @branch + assert_equal @branch, @instruction.last + end + def test_append_not_empty + @instruction.append @branch + @instruction.append @label + assert_equal @label, @instruction.last + end + def test_next1 + assert_equal nil , @instruction.next + end + def test_next2 + @instruction.set_next @label + assert_equal @label , @instruction.next + assert_equal nil , @instruction.next(2) + end + def test_replace + @instruction.append @branch + @instruction.replace_next @label + assert_equal @label, @instruction.last + assert_equal @label, @instruction.next + assert_equal 2 , @instruction.length , @instruction.to_ac + end + end +end