diff --git a/lib/mom/argument_transfer.rb b/lib/mom/argument_transfer.rb new file mode 100644 index 00000000..4901d789 --- /dev/null +++ b/lib/mom/argument_transfer.rb @@ -0,0 +1,29 @@ +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 + # 1. make optimisations easier + # 2. localise the inevitable change + # + # 1. The optimal 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. + # + class ArgumentTransfer < Instruction + + attr_reader :receiver , :arguments + + def initialize( receiver,arguments ) + @receiver , @arguments = receiver , arguments + end + end + + +end diff --git a/lib/mom/instruction.rb b/lib/mom/instruction.rb index 4cf511f7..fe995d23 100644 --- a/lib/mom/instruction.rb +++ b/lib/mom/instruction.rb @@ -24,4 +24,6 @@ require_relative "truth_check" require_relative "jump" require_relative "slot_load" require_relative "return_sequence" +require_relative "message_setup" +require_relative "argument_transfer" require_relative "statement" diff --git a/lib/mom/message_setup.rb b/lib/mom/message_setup.rb new file mode 100644 index 00000000..d779392b --- /dev/null +++ b/lib/mom/message_setup.rb @@ -0,0 +1,22 @@ +module Mom + + # Preamble when entering the method body. + # Acquiring the message basically. + # + # Currently messages are hardwired as a linked list, + # but this does not account for continuations or closures and + # so will have to be changed. + # + # With the current setup this maps to a single SlotMove, ie 2 risc Instructions + # But clearer this way. + # + class MessageSetup < Instruction + attr_reader :method + + def initialize(method) + @method = method + end + end + + +end diff --git a/lib/vool/statements/send_statement.rb b/lib/vool/statements/send_statement.rb index 524b6fc0..d6750374 100644 --- a/lib/vool/statements/send_statement.rb +++ b/lib/vool/statements/send_statement.rb @@ -42,23 +42,25 @@ module Vool end def message_setup(method) - pops = [@receiver.slot_class.new([:message , :next_message , :receiver] , @receiver) ] + setup = [Mom::MessageSetup.new(method)] + receiver = @receiver.slot_class.new([:message , :next_message , :receiver] , @receiver) arg_target = [:message , :next_message , :arguments] + args = [] @arguments.each_with_index do |arg , index| - pops << arg.slot_class.new( arg_target + [index] , arg) + args << arg.slot_class.new( arg_target + [index] , arg) end - pops + setup << Mom::ArgumentTransfer.new( receiver , args ) end def simple_call(method) type = @receiver.ct_type method = type.resolve_method(@name) raise "No method #{@name} for #{type}" unless method - Mom::Statements.new( message_setup(method) << Mom::SimpleCall.new( method) ) + Mom::Statements.new( message_setup(method) << Mom::SimpleCall.new( method) ) end def cached_call(method) - raise "Not implemented" + raise "Not implemented #{method}" Mom::Statements.new( message_setup + call_instruction ) [@receiver.slot_class.new([:message , :next_message , :receiver] , @receiver) ] end