From 8dc0950980fa09bef8a966b90492704c32d73ab1 Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Tue, 20 Mar 2018 22:31:39 +0530 Subject: [PATCH] implement ArgumentTransfer also unite with the receiver which was handled incorrectly (left as a Vool constant) --- lib/mom/instruction/argument_transfer.rb | 22 ++++++++++++++++------ lib/vool/statements/send_statement.rb | 13 ++++++++++--- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/lib/mom/instruction/argument_transfer.rb b/lib/mom/instruction/argument_transfer.rb index 843b3099..ec88cd4d 100644 --- a/lib/mom/instruction/argument_transfer.rb +++ b/lib/mom/instruction/argument_transfer.rb @@ -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 diff --git a/lib/vool/statements/send_statement.rb b/lib/vool/statements/send_statement.rb index 4675f7d9..ac91c005 100644 --- a/lib/vool/statements/send_statement.rb +++ b/lib/vool/statements/send_statement.rb @@ -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)