From 6786855e95b9b2e96a8c13c462c29b7589626170 Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Sun, 24 May 2015 13:55:05 +0300 Subject: [PATCH] start on passes after all that booting and vm/parfait changes passes have gone out of sync, start to fix --- lib/virtual/passes/frame_implementation.rb | 8 ++++---- lib/virtual/passes/send_implementation.rb | 16 ++++++++++++---- lib/virtual/type.rb | 13 +++++++++---- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/lib/virtual/passes/frame_implementation.rb b/lib/virtual/passes/frame_implementation.rb index 7a21d01c..024b675d 100644 --- a/lib/virtual/passes/frame_implementation.rb +++ b/lib/virtual/passes/frame_implementation.rb @@ -5,25 +5,25 @@ module Virtual # - 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. + # 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) + if code.is_a?(NewFrame) kind = :next_frame elsif code.is_a?(NewMessage) kind = :next_message else next end - space = Space.space + space = Parfait::Space.object_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) diff --git a/lib/virtual/passes/send_implementation.rb b/lib/virtual/passes/send_implementation.rb index dbc57259..db9e2f84 100644 --- a/lib/virtual/passes/send_implementation.rb +++ b/lib/virtual/passes/send_implementation.rb @@ -13,7 +13,7 @@ module Virtual next unless code.is_a? MessageSend new_codes = [ ] ref = code.me - raise "only refs implemented #{ref.inspect}" unless ( ref.type == Reference) + raise "only refs implemented #{ref.type}" unless ( ref.type.is_a? Reference) # value known at compile time, got do something with it if(ref.value) me = ref.value @@ -34,9 +34,17 @@ module Virtual raise "unimplemented: \n#{code}" end else - # must defer send to run-time - # So inlining the code from message.send (in the future) - raise "not constant/ known object for send #{ref.inspect}" + if ref.type.is_a?(Reference) and ref.type.of_class + #find method and call + clazz = ref.type.of_class + method = clazz.resolve_method Virtual.new_word(code.name) + raise "No method found #{code.name}" unless method + new_codes << MethodCall.new( method ) + else + # must defer send to run-time + # So inlining the code from message.send (in the future) + raise "not constant/ known object for send #{ref.inspect}" + end end block.replace(code , new_codes ) end diff --git a/lib/virtual/type.rb b/lib/virtual/type.rb index 4f563ced..90a37c4d 100644 --- a/lib/virtual/type.rb +++ b/lib/virtual/type.rb @@ -4,17 +4,22 @@ module Virtual # The Mystery Type has unknown type and has only casting methods. So it must be cast to be useful. class Type def == other - return false unless other.class == self.class + return false unless other.class == self.class return true end end - + class Integer < Type end - + class Reference < Type + # possibly unknown value, but known class (as in methods) + def initialize clazz = nil + @of_class = clazz + end + attr_reader :of_class end - + class Mystery < Type end