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
|
# 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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user