fix logic error in vool dynamic send

using receiver of current method
instead of receiver of next message
This commit is contained in:
Torsten Ruger 2018-04-08 22:59:42 +03:00
parent 580c53cdae
commit fabe4db4f6
4 changed files with 37 additions and 27 deletions

View File

@ -108,7 +108,10 @@ module Mom
# desctructively replace the existing value to be loaded if more slots # desctructively replace the existing value to be loaded if more slots
index = Risc.resolve_to_index(slots[0] , slots[1] ,compiler) index = Risc.resolve_to_index(slots[0] , slots[1] ,compiler)
const << Risc::SlotToReg.new( instruction , right ,index, right) 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 end
const const
end end

View File

@ -93,8 +93,8 @@ module Vool
# conceptually easy in ruby, but we have to compile that "easy" ruby # conceptually easy in ruby, but we have to compile that "easy" ruby
def cache_check(in_method) def cache_check(in_method)
ok = Mom::Label.new("cache_ok_#{self.object_id}") ok = Mom::Label.new("cache_ok_#{self.object_id}")
check = build_condition(ok) # if cached_type != current_type check = build_condition(ok, in_method) # if cached_type != current_type
check << Mom::SlotLoad.new([dynamic_call.cache_entry, :cached_type] , [:message , :receiver , :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 << Mom::ResolveMethod.new( @name , dynamic_call.cache_entry )
check << ok check << ok
end end
@ -106,9 +106,14 @@ module Vool
end end
private 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]) 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) Mom::NotSameCheck.new(cached_type , current_type, ok_label)
end end
end end

View File

@ -7,18 +7,19 @@ module Risc
def setup def setup
super super
@input = "@a.mod4" @input = "@a.mod4"
@expect = [LoadConstant, SlotToReg, SlotToReg, SlotToReg, OperatorInstruction, @expect = [LoadConstant, SlotToReg, SlotToReg, SlotToReg, SlotToReg,
IsZero, SlotToReg, SlotToReg, LoadConstant, RegToSlot, OperatorInstruction, IsZero, SlotToReg, SlotToReg, SlotToReg,
LoadConstant, LoadConstant, SlotToReg, SlotToReg, Label, LoadConstant, RegToSlot, LoadConstant, LoadConstant, SlotToReg,
LoadConstant, SlotToReg, OperatorInstruction, IsZero, SlotToReg, SlotToReg, Label, LoadConstant, SlotToReg, OperatorInstruction,
OperatorInstruction, IsZero, SlotToReg, Branch, Label, IsZero, SlotToReg, OperatorInstruction, IsZero, SlotToReg,
Transfer, Syscall, Transfer, Transfer, LoadConstant, Branch, Label, Transfer, Syscall, Transfer,
SlotToReg, SlotToReg, RegToSlot, RegToSlot, RegToSlot, Transfer, LoadConstant, SlotToReg, SlotToReg, RegToSlot,
Label, RegToSlot, Label, LoadConstant, LoadConstant, RegToSlot, RegToSlot, Label, RegToSlot, Label,
SlotToReg, RegToSlot, RegToSlot, SlotToReg, SlotToReg, LoadConstant, LoadConstant, SlotToReg, RegToSlot, RegToSlot,
RegToSlot, SlotToReg, SlotToReg, RegToSlot, SlotToReg, SlotToReg, SlotToReg, RegToSlot, SlotToReg, SlotToReg,
RegToSlot, SlotToReg, RegToSlot, SlotToReg, SlotToReg, RegToSlot, SlotToReg, RegToSlot, SlotToReg, RegToSlot,
SlotToReg, RegToSlot, LoadConstant, SlotToReg, DynamicJump] SlotToReg, SlotToReg, SlotToReg, RegToSlot, LoadConstant,
SlotToReg, DynamicJump]
end end
def test_send_instructions def test_send_instructions
@ -26,23 +27,23 @@ module Risc
end end
def test_sys def test_sys
produced = produce_body produced = produce_body
assert_equal Syscall , produced.next(26).class assert_equal Syscall , produced.next(28).class
assert_equal :exit , produced.next(26).name assert_equal :exit , produced.next(28).name
end end
def test_load_address def test_load_address
produced = produce_body produced = produce_body
assert_equal LoadConstant , produced.next(38).class assert_equal LoadConstant , produced.next(40).class
assert_equal Parfait::CacheEntry , produced.next(38).constant.class assert_equal Parfait::CacheEntry , produced.next(40).constant.class
end end
def test_function_call def test_function_call
produced = produce_body produced = produce_body
assert_equal DynamicJump , produced.next(59).class assert_equal DynamicJump , produced.next(61).class
end end
def test_cache_check def test_cache_check
produced = produce_body produced = produce_body
assert_equal IsZero , produced.next(5).class assert_equal IsZero , produced.next(6).class
assert_equal Label , produced.next(37).class assert_equal Label , produced.next(39).class
assert_equal produced.next(37) , produced.next(5).label assert_equal produced.next(39) , produced.next(6).label
end end
end end
end end

View File

@ -15,8 +15,9 @@ module Vool
def test_type_update def test_type_update
load = @ins.next(2) load = @ins.next(2)
assert_equal :message , load.right.known_object , load assert_equal :message , load.right.known_object , load
assert_equal :receiver , load.right.slots[0] , load assert_equal :frame , load.right.slots[0] , load
assert_equal :type , load.right.slots[1] , load assert_equal :a , load.right.slots[1] , load
assert_equal :type , load.right.slots[2] , load
end end
def test_check_resolve_call def test_check_resolve_call
assert_equal ResolveMethod , @ins.next(3).class , @ins assert_equal ResolveMethod , @ins.next(3).class , @ins