split frame into message (caller) and frame (receiver)
This commit is contained in:
parent
58298ab62b
commit
f8e3f17660
@ -1,48 +1,21 @@
|
|||||||
module Virtual
|
module Virtual
|
||||||
# A frame, or activation frame, represents a function call during calling. So not the static definition of the function
|
# A Message and a Frame make up the two sides of message passing:
|
||||||
# but the dynamic invokation of it.
|
# A Message (see details there) is created by the sender and control is transferred
|
||||||
|
# A Frame is created by the receiver
|
||||||
|
|
||||||
|
# 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 held in registers
|
||||||
#
|
#
|
||||||
# In a minimal c world this would be just the return address, but with exceptions and continuations things get more
|
# In a dynamic language the method is dynamically resolved, and so the size of the frame is not know to the caller
|
||||||
# complicated. How much more we shall see
|
# Also exceptions (with the possibility of retry) and the idea of being able to take and store bindings
|
||||||
#
|
# make it to say the very least unsensibly tricky to store them on the stack. So we don't.
|
||||||
# The current list comprises
|
|
||||||
# - next normal instruction
|
# Also at runtime Messages and frames remain completely "normal" objects
|
||||||
# - next exception instruction
|
|
||||||
# - self (me)
|
|
||||||
# - argument mappings
|
|
||||||
# - local variable mapping, together with last called binding
|
|
||||||
class Frame
|
class Frame
|
||||||
def initialize normal , exceptional , me
|
def initialize variables
|
||||||
@next_normal = normal
|
@variables = variables
|
||||||
@next_exception = exceptional
|
|
||||||
@me = me
|
|
||||||
# a binding represents the local variables at a point in the program.
|
|
||||||
# The amount of local variables is assumed to be relatively small, and so the
|
|
||||||
# storage is a linked list. Has the same api as a ha
|
|
||||||
@binding = List.new
|
|
||||||
end
|
|
||||||
attr_reader :next_normal, :next_exception, :me, :binding
|
|
||||||
|
|
||||||
# dummy for the eventual
|
|
||||||
def new_frame
|
|
||||||
self
|
|
||||||
end
|
|
||||||
#
|
|
||||||
def compile_get method , name
|
|
||||||
method.add FrameGet.new(name)
|
|
||||||
method.get_var(name)
|
|
||||||
end
|
|
||||||
|
|
||||||
def compile_send method , name , me , with = []
|
|
||||||
method.add Virtual::LoadSelf.new(me)
|
|
||||||
method.add FrameSend.new(name , with )
|
|
||||||
Return.new( method.return_type )
|
|
||||||
end
|
|
||||||
|
|
||||||
def compile_set method , name , val
|
|
||||||
method.set_var(name,val)
|
|
||||||
method.add FrameSet.new(name , val )
|
|
||||||
method.get_var(name)
|
|
||||||
end
|
end
|
||||||
|
attr_accessor :variables
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -34,7 +34,7 @@ module Virtual
|
|||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
the_end = Halt.new
|
the_end = Halt.new
|
||||||
@frame = Frame.new(the_end , the_end , :Object)
|
@frame = Message.new(the_end , the_end , :Object)
|
||||||
end
|
end
|
||||||
attr_reader :frame
|
attr_reader :frame
|
||||||
|
|
||||||
@ -54,6 +54,7 @@ require_relative "list"
|
|||||||
require_relative "instruction"
|
require_relative "instruction"
|
||||||
require_relative "method_definition"
|
require_relative "method_definition"
|
||||||
require_relative "frame"
|
require_relative "frame"
|
||||||
|
require_relative "message"
|
||||||
require_relative "value"
|
require_relative "value"
|
||||||
require_relative "type"
|
require_relative "type"
|
||||||
require_relative "object"
|
require_relative "object"
|
||||||
|
54
lib/virtual/message.rb
Normal file
54
lib/virtual/message.rb
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
module Virtual
|
||||||
|
# So when an object calls a method, or sends a message, this is what a sends: a Message
|
||||||
|
|
||||||
|
# A message contains the sender, return and exceptional return addresses,the arguments, and a slot for the frame.
|
||||||
|
|
||||||
|
# As such it is a very run-time object, deep in the machinery as it were, and does not have meaningful
|
||||||
|
# methods you could call at compile time.
|
||||||
|
|
||||||
|
# The methods that are there, are nevertheless meant to be called at compile time and generate code, rather than
|
||||||
|
# executing it.
|
||||||
|
|
||||||
|
# The caller creates the Message and passes control to the receiver's method
|
||||||
|
|
||||||
|
# The receiver create a new Frame to hold local and temporary variables and (later) creates default values for
|
||||||
|
# arguments that were not passed
|
||||||
|
|
||||||
|
# How the actual finding of the method takes place (acording to the ruby rules) is not simple, but as there is a
|
||||||
|
# guaranteed result (be it method_missing) it does not matter to the passing mechanism described
|
||||||
|
|
||||||
|
# During compilation Message and frame objects are created to do type analysis
|
||||||
|
|
||||||
|
class Message
|
||||||
|
def initialize me , normal , exceptional
|
||||||
|
@me = me
|
||||||
|
@next_normal = normal
|
||||||
|
@next_exception = exceptional
|
||||||
|
# a frame represents the local and temporary variables at a point in the program.
|
||||||
|
@frame = []
|
||||||
|
end
|
||||||
|
attr_reader :me, :next_normal, :next_exception, :frame
|
||||||
|
|
||||||
|
# dummy for the eventual
|
||||||
|
def new_frame
|
||||||
|
self
|
||||||
|
end
|
||||||
|
#
|
||||||
|
def compile_get method , name
|
||||||
|
method.add FrameGet.new(name)
|
||||||
|
method.get_var(name)
|
||||||
|
end
|
||||||
|
|
||||||
|
def compile_send method , name , me , with = []
|
||||||
|
method.add Virtual::LoadSelf.new(me)
|
||||||
|
method.add FrameSend.new(name , with )
|
||||||
|
Return.new( method.return_type )
|
||||||
|
end
|
||||||
|
|
||||||
|
def compile_set method , name , val
|
||||||
|
method.set_var(name,val)
|
||||||
|
method.add FrameSet.new(name , val )
|
||||||
|
method.get_var(name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
x
Reference in New Issue
Block a user