fix logic error in vool dynamic send
using receiver of current method instead of receiver of next message
This commit is contained in:
parent
580c53cdae
commit
fabe4db4f6
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user