diff --git a/lib/phisol/compiler/assignment.rb b/lib/phisol/compiler/assignment.rb index 374c8506..e2951914 100644 --- a/lib/phisol/compiler/assignment.rb +++ b/lib/phisol/compiler/assignment.rb @@ -16,7 +16,9 @@ module Phisol index = @method.has_local( name ) if(index) # TODO, check type @method.locals[index].type - code = Register.set_slot(statement , v , :frame , index ) + frame = use_reg(:Frame) + @method.source.add_code Register.get_slot(statement , :message , :frame , frame ) + code = Register.set_slot(statement , v , frame , index ) end end if( code ) diff --git a/lib/phisol/compiler/call_site.rb b/lib/phisol/compiler/call_site.rb index b5d21ae4..4b0d14c0 100644 --- a/lib/phisol/compiler/call_site.rb +++ b/lib/phisol/compiler/call_site.rb @@ -7,14 +7,15 @@ module Phisol name = name.to_a.first raise "not inside method " unless @method reset_regs - if receiver - me = process( receiver.to_a.first ) - else - me = Register.self_reg @method.for_class.name - end #move the new message (that we need to populate to make a call) to std register new_message = Register.resolve_to_register(:new_message) @method.source.add_code Register.get_slot(@method, :message , :next_message , new_message ) + if receiver + me = process( receiver.to_a.first ) + else + me = use_reg @method.for_class.name + @method.source.add_code Register.get_slot(@method, :message , :receiver , me ) + end # move our receiver there @method.source.add_code Register.set_slot( statement , me , :new_message , :receiver) # load method name and set to new message (for exceptions/debug) diff --git a/lib/phisol/compiler/field_access.rb b/lib/phisol/compiler/field_access.rb index 7b9f1b02..3b36817b 100644 --- a/lib/phisol/compiler/field_access.rb +++ b/lib/phisol/compiler/field_access.rb @@ -11,8 +11,10 @@ module Phisol when :self index = @clazz.object_layout.variable_index(field_name) raise "field access, but no such field:#{field_name} for class #{@clazz.name}" unless index - value = use_reg(:Integer) #TODO, need types in layout - move = Register.get_slot(statement, :self , index , value ) + value = use_reg(@clazz.name) #TODO incorrect, this is the self, but should be the type of variable at index + @method.source.add_code Register.get_slot(statement , :message , :receiver , value ) + # reuse the register for next move + move = Register.get_slot(statement, value , index , value ) @method.source.add_code move return value when :message diff --git a/lib/phisol/compiler/name_expression.rb b/lib/phisol/compiler/name_expression.rb index 73e6849a..89d18b7c 100644 --- a/lib/phisol/compiler/name_expression.rb +++ b/lib/phisol/compiler/name_expression.rb @@ -7,7 +7,11 @@ module Phisol # whichever way this goes the result is stored in the return slot (as all compiles) def on_name statement name = statement.to_a.first - return Register.self_reg(@clazz.name ) if(name == :self) + if( name == :self) + ret = use_reg @clazz.name + @method.source.add_code Register.get_slot(statement , :message , :receiver , ret ) + return ret + end # either an argument, so it's stored in message if( index = @method.has_arg(name)) ret = use_reg @method.arguments[index].type @@ -16,8 +20,10 @@ module Phisol else # or a local so it is in the frame index = @method.has_local( name ) if(index) + frame = use_reg :Frame + @method.source.add_code Register.get_slot(statement , :message , :frame , frame ) ret = use_reg @method.locals[index].type - @method.source.add_code Register.get_slot(statement , :frame , index , ret ) + @method.source.add_code Register.get_slot(statement , frame , index , ret ) return ret end end diff --git a/lib/register/builtin/integer.rb b/lib/register/builtin/integer.rb index d0505931..ab6cfc93 100644 --- a/lib/register/builtin/integer.rb +++ b/lib/register/builtin/integer.rb @@ -3,6 +3,7 @@ module Register module Builtin module Integer module ClassMethods + include AST::Sexp def plus c plus_function = Virtual::MethodSource.create_method(:Integer,:Integer,:plus , [:Integer] ) plus_function.source.set_return_type :Integer @@ -11,8 +12,12 @@ module Register tmp = Register.tmp_reg :Integer index = Register.arg_index 1 plus_function.source.add_code Register.get_slot( plus_function , :message , index , tmp ) - add = Register::OperatorInstruction.new( plus_function, :add , Register.self_reg(:Integer) , tmp ) + + me = Register.tmp_reg :Integer + plus_function.source.add_code Register.get_slot(plus_function , :message , :receiver , me ) + add = Register::OperatorInstruction.new( plus_function, :add , me , tmp ) plus_function.source.add_code add + plus_function.source.add_code Register.set_slot(plus_function , me , :message , :return_value ) return plus_function end diff --git a/lib/register/builtin/kernel.rb b/lib/register/builtin/kernel.rb index c3e73d0e..65c0c1a7 100644 --- a/lib/register/builtin/kernel.rb +++ b/lib/register/builtin/kernel.rb @@ -13,12 +13,13 @@ module Register function.source.blocks.last.codes.pop # no Method return #Set up the Space as self upon init space = Parfait::Space.object_space - function.source.add_code LoadConstant.new(function, space , Register.self_reg(:Space)) + space_reg = Register.tmp_reg(:Space) + function.source.add_code LoadConstant.new(function, space , space_reg) message_ind = Register.resolve_index( :space , :first_message ) - # Load the message to new message register (r3) - function.source.add_code Register.get_slot( function , :self , message_ind , :new_message) + # Load the message to new message register (r1) + function.source.add_code Register.get_slot( function , space_reg , message_ind , :new_message) # And store the space as the new self (so the call can move it back as self) - function.source.add_code Register.set_slot( function, :self , :new_message , :receiver) + function.source.add_code Register.set_slot( function, space_reg , :new_message , :receiver) # now we are set up to issue a call to the main function.source.add_code Virtual::MethodCall.new(Virtual.machine.space.get_main) emit_syscall( function , :exit ) @@ -63,8 +64,6 @@ module Register # save the return value into the message function.source.add_code Register.set_slot( function, return_tmp , :message , :return_value ) # and "unroll" self and frame - function.source.add_code Register.get_slot(function, :message , :receiver, :self ) - function.source.add_code Register.get_slot(function, :message , :frame , :frame) end end extend ClassMethods diff --git a/lib/register/builtin/word.rb b/lib/register/builtin/word.rb index 6bd77922..b5a378e4 100644 --- a/lib/register/builtin/word.rb +++ b/lib/register/builtin/word.rb @@ -4,6 +4,7 @@ module Register module ClassMethods def putstring context function = Virtual::MethodSource.create_method(:Word,:Integer , :putstring , [] ) + function.source.add_code Register.get_slot( function , :message , :receiver , :new_message ) Kernel.emit_syscall( function , :putstring ) function end diff --git a/lib/register/passes/call_implementation.rb b/lib/register/passes/call_implementation.rb index b529b59e..cbf259ca 100644 --- a/lib/register/passes/call_implementation.rb +++ b/lib/register/passes/call_implementation.rb @@ -14,8 +14,6 @@ module Register new_codes = [] # move the current new_message to message new_codes << RegisterTransfer.new(code, Register.new_message_reg , Register.message_reg ) - # "roll out" self into its register - new_codes << Register.get_slot( code , :message , :receiver, :self ) # do the register call new_codes << FunctionCall.new( code , code.method ) block.replace(code , new_codes ) diff --git a/lib/register/passes/return_implementation.rb b/lib/register/passes/return_implementation.rb index ba306273..cabd23cc 100644 --- a/lib/register/passes/return_implementation.rb +++ b/lib/register/passes/return_implementation.rb @@ -8,11 +8,8 @@ module Register new_codes << RegisterTransfer.new(code, Register.message_reg , Register.new_message_reg ) # and restore the message from saved value in new_message new_codes << Register.get_slot(code,:new_message , :caller , :message ) - # "roll out" self and frame into their registers - new_codes << Register.get_slot(code, :message , :receiver , :self ) - new_codes << Register.get_slot(code, :message , :frame , :frame ) #load the return address into pc, affecting return. (other cpus have commands for this, but not arm) - new_codes << FunctionReturn.new( code , Register.message_reg , Register.resolve_index(:message , :return_address) ) + new_codes << FunctionReturn.new( code , Register.new_message_reg , Register.resolve_index(:message , :return_address) ) block.replace(code , new_codes ) end end diff --git a/lib/register/register_value.rb b/lib/register/register_value.rb index 4a1890e9..6fce513d 100644 --- a/lib/register/register_value.rb +++ b/lib/register/register_value.rb @@ -65,27 +65,16 @@ module Register RegisterValue.new :r0 , :Message end - # A register to hold the receiver of the current message, in oo terms the self. :r1 - def self.self_reg type - RegisterValue.new :r1 , type - end - - # The register to hold a possible frame of the currently executing method. :r2 - # May be nil if the method has no local variables - def self.frame_reg - RegisterValue.new :r2 , :Frame - end - # The register we use to store the new message object is :r3 # The new message is the one being built, to be sent def self.new_message_reg - RegisterValue.new :r3 , :Message + RegisterValue.new :r1 , :Message end # The first scratch register. There is a next_reg_use to get a next and next. # Current thinking is that scratch is schatch between instructions def self.tmp_reg type , value = nil - RegisterValue.new :r4 , type , value + RegisterValue.new :r2 , type , value end # The first arg is a class name (possibly lowercase) and the second an instance variable name. @@ -116,8 +105,10 @@ module Register when :new_message register = new_message_reg when :self + raise "self good?" register = self_reg(:Object) #TODO , probably have to get rid of this resolve method when :frame + raise "frame good?" register = frame_reg else raise "not recognized register reference #{reference}" diff --git a/lib/virtual/passes/enter_implementation.rb b/lib/virtual/passes/enter_implementation.rb index 722cb13c..cbec12ef 100644 --- a/lib/virtual/passes/enter_implementation.rb +++ b/lib/virtual/passes/enter_implementation.rb @@ -7,10 +7,6 @@ module Virtual new_codes = [] # save return register to the message at instance return_address new_codes << Register.save_return(code, :message , :return_address) - # and create a new frame if needed - unless code.method.locals.empty? - new_codes << Register.get_slot( code, :message , :frame , Register.resolve_to_register(:frame)) - end block.replace(code , new_codes ) end end diff --git a/test/compiler/statements/test_assign.rb b/test/compiler/statements/test_assign.rb index 87351c94..a1172f8d 100644 --- a/test/compiler/statements/test_assign.rb +++ b/test/compiler/statements/test_assign.rb @@ -29,7 +29,7 @@ class Object end end HERE - @expect = [[Virtual::MethodEnter,LoadConstant,SetSlot] , [Virtual::MethodReturn]] + @expect = [[Virtual::MethodEnter,LoadConstant,GetSlot,SetSlot] , [Virtual::MethodReturn]] check end @@ -42,7 +42,7 @@ end end HERE @expect = [[Virtual::MethodEnter,LoadConstant,LoadConstant, - OperatorInstruction,SetSlot],[Virtual::MethodReturn]] + OperatorInstruction,GetSlot,SetSlot],[Virtual::MethodReturn]] check end @@ -55,7 +55,7 @@ class Object end end HERE - @expect = [[Virtual::MethodEnter,LoadConstant,SetSlot] , [Virtual::MethodReturn]] + @expect = [[Virtual::MethodEnter,LoadConstant,GetSlot,SetSlot] , [Virtual::MethodReturn]] check end @@ -67,7 +67,7 @@ class Object end end HERE - @expect = [[Virtual::MethodEnter,LoadConstant, SetSlot] , [Virtual::MethodReturn]] + @expect = [[Virtual::MethodEnter,LoadConstant, GetSlot,SetSlot] , [Virtual::MethodReturn]] check end @@ -79,8 +79,8 @@ class Object end end HERE - @expect = [[Virtual::MethodEnter,GetSlot,SetSlot, LoadConstant, - SetSlot,Virtual::MethodCall,GetSlot,SetSlot] , [Virtual::MethodReturn]] + @expect = [[Virtual::MethodEnter,GetSlot,GetSlot,SetSlot, LoadConstant,SetSlot, + Virtual::MethodCall,GetSlot,GetSlot,SetSlot] , [Virtual::MethodReturn]] check end end diff --git a/test/compiler/statements/test_call.rb b/test/compiler/statements/test_call.rb index d2f0196d..dc03d658 100644 --- a/test/compiler/statements/test_call.rb +++ b/test/compiler/statements/test_call.rb @@ -17,7 +17,7 @@ class Object end end HERE - @expect = [[Virtual::MethodEnter,LoadConstant,GetSlot, + @expect = [[Virtual::MethodEnter,GetSlot,LoadConstant, SetSlot,LoadConstant,SetSlot,Virtual::MethodCall,GetSlot] , [Virtual::MethodReturn]] check @@ -37,7 +37,7 @@ class Object end end HERE - @expect = [[Virtual::MethodEnter,LoadConstant,GetSlot, + @expect = [[Virtual::MethodEnter,GetSlot,LoadConstant, SetSlot,LoadConstant,SetSlot,Virtual::MethodCall,GetSlot] , [Virtual::MethodReturn]] check @@ -57,8 +57,8 @@ class Object end end HERE - @expect = [ [Virtual::MethodEnter,LoadConstant,SetSlot,GetSlot, - GetSlot,SetSlot,LoadConstant,SetSlot,Virtual::MethodCall, + @expect = [ [Virtual::MethodEnter,LoadConstant,GetSlot,SetSlot,GetSlot, + GetSlot,GetSlot,SetSlot,LoadConstant,SetSlot,Virtual::MethodCall, GetSlot] ,[Virtual::MethodReturn] ] check end @@ -77,13 +77,13 @@ class Object end end HERE - @expect = [ [Virtual::MethodEnter,GetSlot,GetSlot,SetSlot, + @expect = [ [Virtual::MethodEnter,GetSlot,GetSlot,GetSlot,SetSlot, LoadConstant,SetSlot,Virtual::MethodCall, GetSlot] ,[Virtual::MethodReturn] ] check end - def test_puts_string + def test_call_puts @string_input = <