b980def84e
Also make the machine the singleton and space hang off it Many repercussions, not all fixed in this commit
51 lines
2.5 KiB
Ruby
51 lines
2.5 KiB
Ruby
module Virtual
|
|
# This implements the creation of new frame and message object
|
|
|
|
# Frames and Message are very similar apart from the class name
|
|
# - All existing instances are stored in the space for both
|
|
# - Size is currently 2, ie 16 words (TODO a little flexibility here would not hurt, but the mountain is big)
|
|
# - Unused instances for a linked list with their first instance variable. This is HARD coded to avoid any lookup
|
|
|
|
# Just as a reminder: a message object is created before a send and holds return address/message and arguemnts + self
|
|
# frames are created upon entering a method and hold local and temporary variables
|
|
# as a result one of each is created for every single method call. A LOT, so make it fast luke
|
|
# Note: this is off course the reason for stack based implementations that just increment a known pointer/register or
|
|
# something. But i think most programs are memory bound and a few extra instructions don't hurt.
|
|
# After all, we are buying a big prize:oo, otherwise known as sanity.
|
|
|
|
class FrameImplementation
|
|
def run block
|
|
block.codes.dup.each do |code|
|
|
if code.is_a?(NewFrame)
|
|
kind = :next_frame
|
|
elsif code.is_a?(NewMessage)
|
|
kind = :next_message
|
|
else
|
|
next
|
|
end
|
|
space = Space.space
|
|
slot = Virtual::Slot
|
|
# a place to store a reference to the space, we grab the next_frame from the space
|
|
space_tmp = Register::RegisterReference.new(Virtual::Message::TMP_REG)
|
|
# a temporary place to store the new frame
|
|
frame_tmp = space_tmp.next_reg_use
|
|
# move the spave to it's register (mov instruction gets the address of the object)
|
|
new_codes = [ Register::LoadConstant.new( space_tmp , space )]
|
|
# find index in the space wehre to grab frame/message
|
|
ind = space.layout[:names].index(kind)
|
|
raise "index not found for :#{kind}" unless ind
|
|
# load the frame/message from space by index
|
|
new_codes << Register::GetSlot.new( frame_tmp , space_tmp , 5 )
|
|
# save the frame in real frame register
|
|
new_codes << Register::RegisterTransfer.new( Virtual::Message::FRAME_REG , frame_tmp )
|
|
# get the next_frame
|
|
new_codes << Register::GetSlot.new( frame_tmp , frame_tmp , 2 ) # 2 index of next_frame
|
|
# save next frame into space
|
|
new_codes << Register::SetSlot.new( frame_tmp , space_tmp , ind)
|
|
block.replace(code , new_codes )
|
|
end
|
|
end
|
|
end
|
|
Virtual::Machine.instance.add_pass "Virtual::FrameImplementation"
|
|
end
|