extracting some of the calling into own instructions

This commit is contained in:
Torsten Ruger 2017-09-11 14:22:33 +03:00
parent b6939fe4b3
commit afbcbca4da
4 changed files with 60 additions and 5 deletions

View File

@ -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

View File

@ -24,4 +24,6 @@ require_relative "truth_check"
require_relative "jump" require_relative "jump"
require_relative "slot_load" require_relative "slot_load"
require_relative "return_sequence" require_relative "return_sequence"
require_relative "message_setup"
require_relative "argument_transfer"
require_relative "statement" require_relative "statement"

22
lib/mom/message_setup.rb Normal file
View File

@ -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

View File

@ -42,23 +42,25 @@ module Vool
end end
def message_setup(method) 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] arg_target = [:message , :next_message , :arguments]
args = []
@arguments.each_with_index do |arg , index| @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 end
pops setup << Mom::ArgumentTransfer.new( receiver , args )
end end
def simple_call(method) def simple_call(method)
type = @receiver.ct_type type = @receiver.ct_type
method = type.resolve_method(@name) method = type.resolve_method(@name)
raise "No method #{@name} for #{type}" unless method 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 end
def cached_call(method) def cached_call(method)
raise "Not implemented" raise "Not implemented #{method}"
Mom::Statements.new( message_setup + call_instruction ) Mom::Statements.new( message_setup + call_instruction )
[@receiver.slot_class.new([:message , :next_message , :receiver] , @receiver) ] [@receiver.slot_class.new([:message , :next_message , :receiver] , @receiver) ]
end end