implement ArgumentTransfer
also unite with the receiver which was handled incorrectly (left as a Vool constant)
This commit is contained in:
parent
77084dc894
commit
8dc0950980
@ -3,29 +3,39 @@ module Mom
|
||||
# Transering the arguments from the current frame into the next frame
|
||||
#
|
||||
# This could be _done_ at this level, and in fact used to be.
|
||||
# The instructions was introduced to
|
||||
# The instruction was introduced to
|
||||
# 1. make optimisations easier
|
||||
# 2. localise the inevitable change
|
||||
#
|
||||
# 1. The optimal implementation for this loads old and new frames into registers
|
||||
# 1. The optimal risc implementation for this loads old and new frames into registers
|
||||
# and does a whole bunch of transfers
|
||||
# But if we do individual SlotMoves here, each one has to load the frames,
|
||||
# thus making advanced analysis/optimisation neccessary to achieve the same effect.
|
||||
#
|
||||
# 2. Closures will have to have access to variables after the frame goes out of scope
|
||||
# and in fact be able to change the parents variables. This design does not allow for
|
||||
# this, and so will have to be change in the not so distant future.
|
||||
# and in fact be able to change the parents variables. The current design does not allow
|
||||
# for this, and so will have to be change in the not so distant future.
|
||||
#
|
||||
class ArgumentTransfer < Instruction
|
||||
|
||||
attr_reader :receiver , :arguments
|
||||
|
||||
# receiver is a slot_definition
|
||||
# arguments is an array of SlotLoads
|
||||
def initialize( receiver,arguments )
|
||||
@receiver , @arguments = receiver , arguments
|
||||
raise "Receiver not SlotDefinition #{@receiver}" unless @receiver.is_a?(SlotDefinition)
|
||||
@arguments.each{|a| raise "args not SlotLoad #{a}" unless a.is_a?(SlotLoad)}
|
||||
end
|
||||
|
||||
def to_risc(context)
|
||||
Risc::Label.new(self,"ArgumentTransfer")
|
||||
def to_risc(compiler)
|
||||
transfer = SlotLoad.new([:message , :next_message , :receiver] , @receiver).to_risc(compiler)
|
||||
compiler.reset_regs
|
||||
@arguments.each do |arg|
|
||||
transfer << arg.to_risc(compiler)
|
||||
compiler.reset_regs
|
||||
end
|
||||
transfer
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -18,6 +18,13 @@ module Vool
|
||||
end
|
||||
|
||||
def normalize
|
||||
#TODO normalize arguments. In first stage args must be variables or hoisted (like while/if)
|
||||
# later sends ok, but then they must execute
|
||||
# (currently we only use the args as slot_definition so they are not "momed")
|
||||
@arguments.each_with_index do |arg , index |
|
||||
raise "arg #{index} does not provide slot definition #{arg}" unless arg.respond_to?(:slot_definition)
|
||||
raise "Sends not implemented yet at #{index}:#{arg}" if arg.is_a?(SendStatement)
|
||||
end
|
||||
SendStatement.new(@name, @receiver , @arguments)
|
||||
end
|
||||
|
||||
@ -57,14 +64,14 @@ module Vool
|
||||
end
|
||||
|
||||
def message_setup(in_method)
|
||||
setup = Mom::MessageSetup.new(in_method) <<
|
||||
Mom::SlotLoad.new([:message , :next_message , :receiver] , @receiver.slot_definition(in_method))
|
||||
setup = Mom::MessageSetup.new(in_method)
|
||||
mom_receive = @receiver.slot_definition(in_method)
|
||||
arg_target = [:message , :next_message , :arguments]
|
||||
args = []
|
||||
@arguments.each_with_index do |arg , index|
|
||||
args << Mom::SlotLoad.new( arg_target + [index] , arg.slot_definition(in_method))
|
||||
end
|
||||
setup << Mom::ArgumentTransfer.new( receiver , args )
|
||||
setup << Mom::ArgumentTransfer.new( mom_receive , args )
|
||||
end
|
||||
|
||||
def simple_call(in_method)
|
||||
|
Loading…
Reference in New Issue
Block a user