diff --git a/lib/risc/block_compiler.rb b/lib/risc/block_compiler.rb index 236d6387..2ec07e86 100644 --- a/lib/risc/block_compiler.rb +++ b/lib/risc/block_compiler.rb @@ -16,6 +16,20 @@ module Risc "#{@method.self_type.name}.init" end + # resolve the type of the slot, by inferring from it's name, using the type + # scope related slots are resolved by the compiler by method/block + # + # This mainly calls super, and only for :caller adds extra info + # Using the info, means assuming that the block is not passed around (FIXME in 2020) + def slot_type( slot , type) + new_type = super + if slot == :caller + extra_info = { type_frame: @method.frame_type , + type_arguments: @method.arguments_type , + type_self: @method.self_type} + end + return new_type , extra_info + end # determine how given name need to be accsessed. # For blocks the options are args or frame # or then the methods arg or frame diff --git a/lib/risc/callable_compiler.rb b/lib/risc/callable_compiler.rb index c060aeba..9e0da821 100644 --- a/lib/risc/callable_compiler.rb +++ b/lib/risc/callable_compiler.rb @@ -66,7 +66,7 @@ module Risc end # resolve the type of the slot, by inferring from it's name, using the type - # scope related slots are resolved by the compiler by methood/block + # scope related slots are resolved by the compiler by method/block def slot_type( slot , type) case slot when :frame diff --git a/lib/risc/register_value.rb b/lib/risc/register_value.rb index 241f9366..62a33fab 100644 --- a/lib/risc/register_value.rb +++ b/lib/risc/register_value.rb @@ -9,7 +9,7 @@ module Risc # results of dsl operations (like <<) back to the builder class RegisterValue - attr_reader :symbol , :type , :value + attr_reader :symbol , :type , :extra attr_accessor :builder @@ -20,13 +20,14 @@ module Risc # be :value, or :value_XX or :type_XX to indicate value or type information # for an XX instance def initialize( reg , type , extra = {}) + extra = {} unless extra raise "Not Hash #{extra}" unless extra.is_a?(Hash) raise "not reg #{reg}" unless self.class.look_like_reg( reg ) raise "No type " unless type type = Parfait.object_space.get_type_by_class_name(type) if type.is_a?(Symbol) @type = type @symbol = reg - @value = extra + @extra = extra end # using the registers type, resolve the slot to an index @@ -54,18 +55,19 @@ module Risc # overwrite the message) # We get the type with resolve_new_type def get_new_left(slot, compiler) - new_type = compiler.slot_type(slot , type) + new_type = extra["type_#{slot}".to_sym] + new_type , extra = compiler.slot_type(slot , type) unless new_type if( @symbol == :r0 ) - new_left = compiler.use_reg( new_type ) + new_left = compiler.use_reg( new_type , extra) else - new_left = RegisterValue.new( @symbol , new_type) + new_left = RegisterValue.new( @symbol , new_type , extra) end new_left end def to_s s = "#{symbol}:#{type}" - s += ":#{value}" if value + s += ":#{extra}" unless extra.empty? s end @@ -93,11 +95,11 @@ module Risc end #helper method to calculate with register symbols - def next_reg_use( type , value = nil ) + def next_reg_use( type , extra = {} ) int = @symbol[1,3].to_i raise "No more registers #{self}" if int > 11 sym = "r#{int + 1}".to_sym - RegisterValue.new( sym , type, value) + RegisterValue.new( sym , type, extra) end def rxf_reference_name diff --git a/test/arm/helper.rb b/test/arm/helper.rb index 347bea51..c0d49fbb 100644 --- a/test/arm/helper.rb +++ b/test/arm/helper.rb @@ -15,6 +15,7 @@ module Arm end module ArmHelper def setup + Parfait.boot! @machine = Arm::ArmMachine @binary = FakeBin.new Risc::Position.clear_positions diff --git a/test/mom/test_block_statement.rb b/test/mom/test_block_statement.rb index 514d1475..4d484882 100644 --- a/test/mom/test_block_statement.rb +++ b/test/mom/test_block_statement.rb @@ -39,7 +39,7 @@ module Vool assert_equal 1, @block.frame_type.variable_index(:local) end end - class TestBlockMethod #< MiniTest::Test + class TestBlockMethod < MiniTest::Test include MomCompile def setup Parfait.boot! diff --git a/test/risc/test_register_value1.rb b/test/risc/test_register_value1.rb index ba7cb778..4857cec9 100644 --- a/test/risc/test_register_value1.rb +++ b/test/risc/test_register_value1.rb @@ -19,6 +19,9 @@ module Risc def test_get_new_left_0 assert_equal RegisterValue , @r0.get_new_left(:caller , @compiler).class end + def test_get_new_left_no_extra + assert @r0.get_new_left(:caller , @compiler).extra.empty? + end def test_get_new_left_0_reg assert_equal :r1 , @r0.get_new_left(:caller , @compiler).symbol end @@ -28,5 +31,10 @@ module Risc def test_get_new_left_1_reg assert_equal :r1 , @r0.get_new_left(:caller , @compiler).symbol end + def test_get_left_uses_extra + @r1 = RegisterValue.new(:r1 , :Space , type_arguments: @r0.type) + # works with nil as compiler, because extra is used + assert_equal :Message , @r1.get_new_left(:arguments , nil).type.class_name + end end end diff --git a/test/support/fake_compiler.rb b/test/support/fake_compiler.rb index 403a2e5f..942073f8 100644 --- a/test/support/fake_compiler.rb +++ b/test/support/fake_compiler.rb @@ -6,7 +6,7 @@ module Risc def resolve_type(name) Parfait.object_space.types.values.first end - def use_reg(type) + def use_reg(type , extra = {}) RegisterValue.new(:r1 , type) end def reset_regs