diff --git a/lib/mom/instruction/slot_load.rb b/lib/mom/instruction/slot_load.rb index 048952de..1801eb8b 100644 --- a/lib/mom/instruction/slot_load.rb +++ b/lib/mom/instruction/slot_load.rb @@ -108,7 +108,10 @@ module Mom # desctructively replace the existing value to be loaded if more slots index = Risc.resolve_to_index(slots[0] , slots[1] ,compiler) const << Risc::SlotToReg.new( instruction , right ,index, right) - raise "more slots not implemented #{slots}" if slots.length > 2 + if slots.length > 2 + raise "3 slots only for type #{slots}" unless slots[2] == :type + const << Risc::SlotToReg.new( instruction , right , 1, right) + end end const end diff --git a/lib/vool/statements/send_statement.rb b/lib/vool/statements/send_statement.rb index ce1c5a7a..78c7eb97 100644 --- a/lib/vool/statements/send_statement.rb +++ b/lib/vool/statements/send_statement.rb @@ -93,8 +93,8 @@ module Vool # conceptually easy in ruby, but we have to compile that "easy" ruby def cache_check(in_method) ok = Mom::Label.new("cache_ok_#{self.object_id}") - check = build_condition(ok) # if cached_type != current_type - check << Mom::SlotLoad.new([dynamic_call.cache_entry, :cached_type] , [:message , :receiver , :type]) + check = build_condition(ok, in_method) # if cached_type != current_type + check << Mom::SlotLoad.new([dynamic_call.cache_entry, :cached_type] , receiver_type_definition(in_method)) check << Mom::ResolveMethod.new( @name , dynamic_call.cache_entry ) check << ok end @@ -106,9 +106,14 @@ module Vool end private - def build_condition(ok_label) + def receiver_type_definition(in_method) + defi = @receiver.slot_definition(in_method) + defi.slots << :type + defi + end + def build_condition(ok_label, in_method) cached_type = Mom::SlotDefinition.new(dynamic_call.cache_entry , [:cached_type]) - current_type = Mom::SlotDefinition.new(:message , [:receiver , :type]) + current_type = receiver_type_definition(in_method) Mom::NotSameCheck.new(cached_type , current_type, ok_label) end end diff --git a/test/mom/send/test_send_dynamic.rb b/test/mom/send/test_send_dynamic.rb index 34cc2b08..366412aa 100644 --- a/test/mom/send/test_send_dynamic.rb +++ b/test/mom/send/test_send_dynamic.rb @@ -7,18 +7,19 @@ module Risc def setup super @input = "@a.mod4" - @expect = [LoadConstant, SlotToReg, SlotToReg, SlotToReg, OperatorInstruction, - IsZero, SlotToReg, SlotToReg, LoadConstant, RegToSlot, - LoadConstant, LoadConstant, SlotToReg, SlotToReg, Label, - LoadConstant, SlotToReg, OperatorInstruction, IsZero, SlotToReg, - OperatorInstruction, IsZero, SlotToReg, Branch, Label, - Transfer, Syscall, Transfer, Transfer, LoadConstant, - SlotToReg, SlotToReg, RegToSlot, RegToSlot, RegToSlot, - Label, RegToSlot, Label, LoadConstant, LoadConstant, - SlotToReg, RegToSlot, RegToSlot, SlotToReg, SlotToReg, - RegToSlot, SlotToReg, SlotToReg, RegToSlot, SlotToReg, - RegToSlot, SlotToReg, RegToSlot, SlotToReg, SlotToReg, - SlotToReg, RegToSlot, LoadConstant, SlotToReg, DynamicJump] + @expect = [LoadConstant, SlotToReg, SlotToReg, SlotToReg, SlotToReg, + OperatorInstruction, IsZero, SlotToReg, SlotToReg, SlotToReg, + LoadConstant, RegToSlot, LoadConstant, LoadConstant, SlotToReg, + SlotToReg, Label, LoadConstant, SlotToReg, OperatorInstruction, + IsZero, SlotToReg, OperatorInstruction, IsZero, SlotToReg, + Branch, Label, Transfer, Syscall, Transfer, + Transfer, LoadConstant, SlotToReg, SlotToReg, RegToSlot, + RegToSlot, RegToSlot, Label, RegToSlot, Label, + LoadConstant, LoadConstant, SlotToReg, RegToSlot, RegToSlot, + SlotToReg, SlotToReg, RegToSlot, SlotToReg, SlotToReg, + RegToSlot, SlotToReg, RegToSlot, SlotToReg, RegToSlot, + SlotToReg, SlotToReg, SlotToReg, RegToSlot, LoadConstant, + SlotToReg, DynamicJump] end def test_send_instructions @@ -26,23 +27,23 @@ module Risc end def test_sys produced = produce_body - assert_equal Syscall , produced.next(26).class - assert_equal :exit , produced.next(26).name + assert_equal Syscall , produced.next(28).class + assert_equal :exit , produced.next(28).name end def test_load_address produced = produce_body - assert_equal LoadConstant , produced.next(38).class - assert_equal Parfait::CacheEntry , produced.next(38).constant.class + assert_equal LoadConstant , produced.next(40).class + assert_equal Parfait::CacheEntry , produced.next(40).constant.class end def test_function_call produced = produce_body - assert_equal DynamicJump , produced.next(59).class + assert_equal DynamicJump , produced.next(61).class end def test_cache_check produced = produce_body - assert_equal IsZero , produced.next(5).class - assert_equal Label , produced.next(37).class - assert_equal produced.next(37) , produced.next(5).label + assert_equal IsZero , produced.next(6).class + assert_equal Label , produced.next(39).class + assert_equal produced.next(39) , produced.next(6).label end end end diff --git a/test/vool/to_mom/send/test_send_cached_simple.rb b/test/vool/to_mom/send/test_send_cached_simple.rb index 8a33dbea..0ae179ec 100644 --- a/test/vool/to_mom/send/test_send_cached_simple.rb +++ b/test/vool/to_mom/send/test_send_cached_simple.rb @@ -15,8 +15,9 @@ module Vool def test_type_update load = @ins.next(2) assert_equal :message , load.right.known_object , load - assert_equal :receiver , load.right.slots[0] , load - assert_equal :type , load.right.slots[1] , load + assert_equal :frame , load.right.slots[0] , load + assert_equal :a , load.right.slots[1] , load + assert_equal :type , load.right.slots[2] , load end def test_check_resolve_call assert_equal ResolveMethod , @ins.next(3).class , @ins