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)
This commit is contained in:
Torsten Ruger 2018-05-29 20:26:00 +03:00
parent 7847420d49
commit 8322fca7b3
11 changed files with 24 additions and 19 deletions

@ -13,7 +13,7 @@ module Arm
end end
def translate_Label( code ) def translate_Label( code )
Risc::Label.new( code.source , code.name ) Risc.label( code.source , code.name , code.integer)
end end
# arm indexes are # arm indexes are

@ -11,7 +11,8 @@ module Mom
@value = value @value = value
end end
def to_parfait(compiler) def to_parfait(compiler)
value = Parfait::Integer.new(@value) value = Parfait.object_space.get_integer
value.set_value(@value)
compiler.add_constant(value) compiler.add_constant(value)
value value
end end

@ -33,7 +33,7 @@ module Mom
def to_risc(compiler) def to_risc(compiler)
compiler.add_constant( @cache_entry ) compiler.add_constant( @cache_entry )
reg = compiler.use_reg( :Object ) 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) save_return = SlotLoad.new([:message,:next_message,:return_address],[return_label],self)
moves = save_return.to_risc(compiler) moves = save_return.to_risc(compiler)
moves << Risc.slot_to_reg(self, :message , :next_message , Risc.message_reg) moves << Risc.slot_to_reg(self, :message , :next_message , Risc.message_reg)

@ -31,8 +31,9 @@ module Mom
# Off course some specific place still has to be responsible for actually # Off course some specific place still has to be responsible for actually
# adding the label to the instruction list (usually an if/while) # adding the label to the instruction list (usually an if/while)
def to_risc(compiler) def to_risc(compiler)
int = Parfait.object_space.get_integer
@risc_label ||= Risc::Label.new(self,name) compiler.add_constant(int)
@risc_label ||= Risc.label(self,name , int , nil)
end end
end end
end end

@ -23,7 +23,7 @@ module Mom
# For returning, we add a label after the call, and load it's address into the # 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. # return_address of the next_message, for the ReturnSequence to pick it up.
def to_risc(compiler) 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) save_return = SlotLoad.new([:message,:next_message,:return_address],[return_label],self)
moves = save_return.to_risc(compiler) moves = save_return.to_risc(compiler)
moves << Risc.slot_to_reg(self, :message , :next_message , Risc.message_reg) moves << Risc.slot_to_reg(self, :message , :next_message , Risc.message_reg)

@ -8,11 +8,13 @@ module Risc
# #
class Label < Instruction class Label < Instruction
def initialize( source , name , nekst = nil) def initialize( source , name , int , nekst = nil)
super(source , nekst) super(source , nekst)
@name = name @name = name
@integer = int
raise "Not int #{int}" if int and !int.is_a?(Parfait::Integer)
end end
attr_reader :name attr_reader :name , :integer
def to_cpu(translator) def to_cpu(translator)
@cpu_label ||= super @cpu_label ||= super
@ -51,7 +53,8 @@ module Risc
alias :padded_length :byte_length alias :padded_length :byte_length
end end
def self.label( source , name , nekst = nil) def self.label( source , name , position = nil , nekst = nil)
Label.new( source , name , nekst = nil) position ||= Parfait.object_space.get_integer
Label.new( source , name , position, nekst )
end end
end end

@ -7,7 +7,7 @@ module Risc
Risc.machine.boot Risc.machine.boot
@binary = Parfait::BinaryCode.new(1) @binary = Parfait::BinaryCode.new(1)
@method = Parfait.object_space.types.values.first.methods @method = Parfait.object_space.types.values.first.methods
@label = Label.new("hi","ho") @label = Risc.label("hi","ho")
end end
def test_set_bin def test_set_bin
pos = Position.set( @binary , 0 , @method) pos = Position.set( @binary , 0 , @method)
@ -29,7 +29,7 @@ module Risc
machine.translate(:interpreter) machine.translate(:interpreter)
@binary = Parfait::BinaryCode.new(1) @binary = Parfait::BinaryCode.new(1)
@method = Parfait.object_space.types.values.first.methods @method = Parfait.object_space.types.values.first.methods
@label = Label.new("hi","ho") @label = Risc.label("hi","ho")
end end
def test_bin_propagates_existing def test_bin_propagates_existing

@ -8,7 +8,7 @@ module Risc
Risc.machine.boot Risc.machine.boot
@binary = Parfait::BinaryCode.new(1) @binary = Parfait::BinaryCode.new(1)
Position.set(@binary , 0 , Parfait.object_space.get_main) Position.set(@binary , 0 , Parfait.object_space.get_main)
@label = Label.new("hi","ho") @label = Risc.label("hi","ho")
end end
def test_set_instr def test_set_instr
pos = Position.set( @label , 8 , @binary) pos = Position.set( @label , 8 , @binary)

@ -7,7 +7,7 @@ module Risc
Risc.machine.boot Risc.machine.boot
init = Parfait.object_space.get_init init = Parfait.object_space.get_init
@builder = Risc::MethodCompiler.new( init ).builder(false , init) @builder = Risc::MethodCompiler.new( init ).builder(false , init)
@label = Risc::Label.new("source","name") @label = Risc.label("source","name")
end end
def test_has_build def test_has_build
assert @builder.respond_to?(:build) assert @builder.respond_to?(:build)

@ -3,7 +3,7 @@ require_relative "../helper"
module Risc module Risc
class TestInstructions < MiniTest::Test class TestInstructions < MiniTest::Test
def setup def setup
@label = Label.new("test" , "test") @label = Label.new("test" , "test",nil)
@branch = Branch.new("test" , @label) @branch = Branch.new("test" , @label)
@instruction = Instruction.new("test") @instruction = Instruction.new("test")
end end
@ -19,7 +19,7 @@ module Risc
assert @label.to_s.include?("Label") assert @label.to_s.include?("Label")
end end
def test_label_tos2 def test_label_tos2
assert Label.new(nil,nil).to_s.include?("Label") assert Label.new(nil,nil,nil).to_s.include?("Label")
end end
def test_last_empty def test_last_empty
assert_equal @instruction, @instruction.last assert_equal @instruction, @instruction.last
@ -55,7 +55,7 @@ module Risc
assert_nil @instruction.next(2) assert_nil @instruction.next(2)
end end
def test_label_is_method def test_label_is_method
label = Label.new("test" , "Object.test") label = Label.new("test" , "Object.test" , nil)
assert label.is_method assert label.is_method
end end
def test_label_is_not_method def test_label_is_not_method

@ -26,7 +26,7 @@ module Risc
end end
def test_load_translates_label def test_load_translates_label
label = Label.new("test" , "test") label = Risc.label("test" , "test",nil)
load = Risc.load_constant("source" , label , :r1) load = Risc.load_constant("source" , label , :r1)
translated = @translator.translate(load) translated = @translator.translate(load)
assert label != translated.constant assert label != translated.constant