From 8322fca7b3f002d1d55a3b8d0451586d06ade614 Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Tue, 29 May 2018 20:26:00 +0300 Subject: [PATCH] give labels an integer that will end up being the position at runtime Since integers are first class objects, we need to use an integer object as the return address. The actual address can not be stored in an instance variable since it is not an object. The address is unique to the label and never changes after positioning (using the int is next up) --- lib/arm/translator.rb | 2 +- lib/mom/instruction/basic_values.rb | 3 ++- lib/mom/instruction/dynamic_call.rb | 2 +- lib/mom/instruction/label.rb | 5 +++-- lib/mom/instruction/simple_call.rb | 4 ++-- lib/risc/instructions/label.rb | 11 +++++++---- test/risc/position/test_code_position.rb | 4 ++-- test/risc/position/test_instruction_position.rb | 2 +- test/risc/test_builder.rb | 2 +- test/risc/test_instructions.rb | 6 +++--- test/risc/test_interpreter_platform.rb | 2 +- 11 files changed, 24 insertions(+), 19 deletions(-) diff --git a/lib/arm/translator.rb b/lib/arm/translator.rb index 00c3aec8..409af3b2 100644 --- a/lib/arm/translator.rb +++ b/lib/arm/translator.rb @@ -13,7 +13,7 @@ module Arm end def translate_Label( code ) - Risc::Label.new( code.source , code.name ) + Risc.label( code.source , code.name , code.integer) end # arm indexes are diff --git a/lib/mom/instruction/basic_values.rb b/lib/mom/instruction/basic_values.rb index 6afcba71..8b6af583 100644 --- a/lib/mom/instruction/basic_values.rb +++ b/lib/mom/instruction/basic_values.rb @@ -11,7 +11,8 @@ module Mom @value = value end def to_parfait(compiler) - value = Parfait::Integer.new(@value) + value = Parfait.object_space.get_integer + value.set_value(@value) compiler.add_constant(value) value end diff --git a/lib/mom/instruction/dynamic_call.rb b/lib/mom/instruction/dynamic_call.rb index 4b22ca8c..f4125e3b 100644 --- a/lib/mom/instruction/dynamic_call.rb +++ b/lib/mom/instruction/dynamic_call.rb @@ -33,7 +33,7 @@ module Mom def to_risc(compiler) compiler.add_constant( @cache_entry ) reg = compiler.use_reg( :Object ) - return_label = Risc::Label.new(self,"continue_#{object_id}") + return_label = Risc.label(self, "continue_#{object_id}") save_return = SlotLoad.new([:message,:next_message,:return_address],[return_label],self) moves = save_return.to_risc(compiler) moves << Risc.slot_to_reg(self, :message , :next_message , Risc.message_reg) diff --git a/lib/mom/instruction/label.rb b/lib/mom/instruction/label.rb index c51f1149..01c46794 100644 --- a/lib/mom/instruction/label.rb +++ b/lib/mom/instruction/label.rb @@ -31,8 +31,9 @@ module Mom # Off course some specific place still has to be responsible for actually # adding the label to the instruction list (usually an if/while) def to_risc(compiler) - - @risc_label ||= Risc::Label.new(self,name) + int = Parfait.object_space.get_integer + compiler.add_constant(int) + @risc_label ||= Risc.label(self,name , int , nil) end end end diff --git a/lib/mom/instruction/simple_call.rb b/lib/mom/instruction/simple_call.rb index 7b19b4d0..c780f40f 100644 --- a/lib/mom/instruction/simple_call.rb +++ b/lib/mom/instruction/simple_call.rb @@ -19,11 +19,11 @@ module Mom end # Calling a Method is basically jumping to the Binary (+ offset). # We just swap in the new message and go. - # + # # For returning, we add a label after the call, and load it's address into the # return_address of the next_message, for the ReturnSequence to pick it up. def to_risc(compiler) - return_label = Risc::Label.new(self,"continue_#{object_id}") + return_label = Risc.label(self,"continue_#{object_id}") save_return = SlotLoad.new([:message,:next_message,:return_address],[return_label],self) moves = save_return.to_risc(compiler) moves << Risc.slot_to_reg(self, :message , :next_message , Risc.message_reg) diff --git a/lib/risc/instructions/label.rb b/lib/risc/instructions/label.rb index 4cd7f1c4..cd1686ae 100644 --- a/lib/risc/instructions/label.rb +++ b/lib/risc/instructions/label.rb @@ -8,11 +8,13 @@ module Risc # class Label < Instruction - def initialize( source , name , nekst = nil) + def initialize( source , name , int , nekst = nil) super(source , nekst) @name = name + @integer = int + raise "Not int #{int}" if int and !int.is_a?(Parfait::Integer) end - attr_reader :name + attr_reader :name , :integer def to_cpu(translator) @cpu_label ||= super @@ -51,7 +53,8 @@ module Risc alias :padded_length :byte_length end - def self.label( source , name , nekst = nil) - Label.new( source , name , nekst = nil) + def self.label( source , name , position = nil , nekst = nil) + position ||= Parfait.object_space.get_integer + Label.new( source , name , position, nekst ) end end diff --git a/test/risc/position/test_code_position.rb b/test/risc/position/test_code_position.rb index 86a01475..70e941ba 100644 --- a/test/risc/position/test_code_position.rb +++ b/test/risc/position/test_code_position.rb @@ -7,7 +7,7 @@ module Risc Risc.machine.boot @binary = Parfait::BinaryCode.new(1) @method = Parfait.object_space.types.values.first.methods - @label = Label.new("hi","ho") + @label = Risc.label("hi","ho") end def test_set_bin pos = Position.set( @binary , 0 , @method) @@ -29,7 +29,7 @@ module Risc machine.translate(:interpreter) @binary = Parfait::BinaryCode.new(1) @method = Parfait.object_space.types.values.first.methods - @label = Label.new("hi","ho") + @label = Risc.label("hi","ho") end def test_bin_propagates_existing diff --git a/test/risc/position/test_instruction_position.rb b/test/risc/position/test_instruction_position.rb index 6be243ff..3140094d 100644 --- a/test/risc/position/test_instruction_position.rb +++ b/test/risc/position/test_instruction_position.rb @@ -8,7 +8,7 @@ module Risc Risc.machine.boot @binary = Parfait::BinaryCode.new(1) Position.set(@binary , 0 , Parfait.object_space.get_main) - @label = Label.new("hi","ho") + @label = Risc.label("hi","ho") end def test_set_instr pos = Position.set( @label , 8 , @binary) diff --git a/test/risc/test_builder.rb b/test/risc/test_builder.rb index ee7849a8..ae3ae19d 100644 --- a/test/risc/test_builder.rb +++ b/test/risc/test_builder.rb @@ -7,7 +7,7 @@ module Risc Risc.machine.boot init = Parfait.object_space.get_init @builder = Risc::MethodCompiler.new( init ).builder(false , init) - @label = Risc::Label.new("source","name") + @label = Risc.label("source","name") end def test_has_build assert @builder.respond_to?(:build) diff --git a/test/risc/test_instructions.rb b/test/risc/test_instructions.rb index abbd6dc4..86b13430 100644 --- a/test/risc/test_instructions.rb +++ b/test/risc/test_instructions.rb @@ -3,7 +3,7 @@ require_relative "../helper" module Risc class TestInstructions < MiniTest::Test def setup - @label = Label.new("test" , "test") + @label = Label.new("test" , "test",nil) @branch = Branch.new("test" , @label) @instruction = Instruction.new("test") end @@ -19,7 +19,7 @@ module Risc assert @label.to_s.include?("Label") end def test_label_tos2 - assert Label.new(nil,nil).to_s.include?("Label") + assert Label.new(nil,nil,nil).to_s.include?("Label") end def test_last_empty assert_equal @instruction, @instruction.last @@ -55,7 +55,7 @@ module Risc assert_nil @instruction.next(2) end def test_label_is_method - label = Label.new("test" , "Object.test") + label = Label.new("test" , "Object.test" , nil) assert label.is_method end def test_label_is_not_method diff --git a/test/risc/test_interpreter_platform.rb b/test/risc/test_interpreter_platform.rb index 18c23b2e..504d75dd 100644 --- a/test/risc/test_interpreter_platform.rb +++ b/test/risc/test_interpreter_platform.rb @@ -26,7 +26,7 @@ module Risc end def test_load_translates_label - label = Label.new("test" , "test") + label = Risc.label("test" , "test",nil) load = Risc.load_constant("source" , label , :r1) translated = @translator.translate(load) assert label != translated.constant