2014-07-16 23:53:19 +02:00
|
|
|
module Virtual
|
2014-07-24 20:56:31 +02:00
|
|
|
# So when an object calls a method, or sends a message, this is what it sends: a Message
|
2014-07-16 23:53:19 +02:00
|
|
|
|
|
|
|
# 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
|
2014-07-24 20:56:31 +02:00
|
|
|
@arguments = arguments
|
2014-07-16 23:53:19 +02:00
|
|
|
# a frame represents the local and temporary variables at a point in the program.
|
2014-07-24 20:56:31 +02:00
|
|
|
@frame = nil
|
2014-07-16 23:53:19 +02:00
|
|
|
end
|
2014-07-24 20:56:31 +02:00
|
|
|
attr_reader :me, :next_normal, :next_exception, :arguments , :frame
|
2014-07-16 23:53:19 +02:00
|
|
|
|
|
|
|
# dummy for the eventual
|
|
|
|
def new_frame
|
2014-07-24 20:56:31 +02:00
|
|
|
raise self.inspect
|
2014-07-16 23:53:19 +02:00
|
|
|
end
|
|
|
|
#
|
|
|
|
def compile_get method , name
|
2014-07-25 19:28:38 +02:00
|
|
|
if method.has_arg(name)
|
2014-08-13 10:59:51 +02:00
|
|
|
method.add_code MessageGet.new(name)
|
2014-07-25 19:28:38 +02:00
|
|
|
else
|
2014-08-13 10:59:51 +02:00
|
|
|
method.add_code FrameGet.new(name)
|
2014-07-25 19:28:38 +02:00
|
|
|
end
|
2014-07-16 23:53:19 +02:00
|
|
|
method.get_var(name)
|
|
|
|
end
|
|
|
|
|
|
|
|
def compile_send method , name , me , with = []
|
2014-08-13 10:59:51 +02:00
|
|
|
method.add_code Virtual::LoadSelf.new(me)
|
|
|
|
method.add_code MessageSend.new(name , with )
|
2014-07-16 23:53:19 +02:00
|
|
|
Return.new( method.return_type )
|
|
|
|
end
|
|
|
|
|
|
|
|
def compile_set method , name , val
|
|
|
|
method.set_var(name,val)
|
2014-07-25 19:28:38 +02:00
|
|
|
if method.has_arg(name)
|
2014-08-13 10:59:51 +02:00
|
|
|
method.add_code MessageSet.new(name , val )
|
2014-07-25 19:28:38 +02:00
|
|
|
else
|
2014-08-13 10:59:51 +02:00
|
|
|
method.add_code FrameSet.new(name , val )
|
2014-07-25 19:28:38 +02:00
|
|
|
end
|
2014-07-16 23:53:19 +02:00
|
|
|
method.get_var(name)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|