diff --git a/lib/parfait/frame.rb b/lib/parfait/frame.rb index 2ab0d85c..aada088f 100644 --- a/lib/parfait/frame.rb +++ b/lib/parfait/frame.rb @@ -7,6 +7,10 @@ # A Message and a Frame make up the two sides of message passing: # A Message (see details there) is created by the sender and control is transferred # A Frame is created by the receiver +# PS: it turns out that both messages and frames are created at compile, not run-time, and +# just constantly reused. Each message has a frame object ready and ist also linked +# to the next message. +# The better way to say above is that a messages is *used* by the caller, and a frame by the callee. # In static languages these two objects are one, because the method is known at compile time. # In that case the whole frame is usually on the stack, for leaves even omitted and all data is @@ -22,9 +26,5 @@ module Parfait class Frame < Object - def initialize next_f - @next_frame = next_f - super() - end end end diff --git a/lib/parfait/message.rb b/lib/parfait/message.rb index 1fa93e3e..d6ecb316 100644 --- a/lib/parfait/message.rb +++ b/lib/parfait/message.rb @@ -2,14 +2,27 @@ # A message is what is sent when you invoke a method. Args and stuff are packed up in to a Message # and the Message is sent to the receiver. +# Part of the housekeeping (see attributes) makes messages a double linked list (next_message and +# caller) , and maybe surprisingly this means that we can create all messages at runtime +# and link them up and never have to touch that list again. +# All the args and receiver data changes, but the list of messages stays constant. + module Parfait class Message < Object - def initialize next_m @next_message = next_m + @frame = Frame.new() + @caller = nil super() end + attr_reader :next_message , :frame , :caller # aka prev_message + attr_reader :receiver , :return_address , :return_value , :method + + def set_caller caller + @caller = caller + end + def get_type_for(name) index = @layout.get_index(name) get_at(index) diff --git a/lib/parfait/space.rb b/lib/parfait/space.rb index 5b274d0e..efdaf25c 100644 --- a/lib/parfait/space.rb +++ b/lib/parfait/space.rb @@ -27,19 +27,17 @@ module Parfait @classes = Parfait::Dictionary.new_object @syscall_message = nil # a hack sto store the message during syscall end - attr_reader :classes , :next_message , :next_frame + attr_reader :classes , :first_message # need a two phase init for the object space (and generally parfait) because the space # is an interconnected graph, so not everthing is ready def late_init - counter = 0 - @next_message = Message.new(nil) - @next_frame = Frame.new(nil) - 5.times do |i| - @next_message = Message.new @next_message - @next_frame = Frame.new @next_frame + message = Message.new(nil) + 5.times do + new_message = Message.new message + message.set_caller new_message end - @init_message = Message.new @next_message + @first_message = Message.new message init_layout end diff --git a/lib/register/builtin/kernel.rb b/lib/register/builtin/kernel.rb index 73bd0e82..c3c32f7b 100644 --- a/lib/register/builtin/kernel.rb +++ b/lib/register/builtin/kernel.rb @@ -14,7 +14,7 @@ module Register #Set up the Space as self upon init space = Parfait::Space.object_space function.info.add_code LoadConstant.new( space , Register.self_reg) - message_ind = Register.resolve_index( :space , :init_message ) + message_ind = Register.resolve_index( :space , :first_message ) # Load the message to new message register (r3) function.info.add_code Register.get_slot( :self , message_ind , :new_message) # And store the space as the new self (so the call can move it back as self)