diff --git a/lib/register/builtin/kernel.rb b/lib/register/builtin/kernel.rb index 32866f40..ee5eea04 100644 --- a/lib/register/builtin/kernel.rb +++ b/lib/register/builtin/kernel.rb @@ -13,12 +13,12 @@ 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( space , Register.self_reg) + function.source.add_code LoadConstant.new(function, space , Register.self_reg) message_ind = Register.resolve_index( :space , :first_message ) # Load the message to new message register (r3) - function.source.add_code Register.get_slot( :self , message_ind , :new_message) + function.source.add_code Register.get_slot( function , :self , 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( :self , :new_message , :receiver) + function.source.add_code Register.set_slot( function, :self , :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 ) @@ -40,29 +40,29 @@ module Register def emit_syscall function , name save_message( function ) - function.source.add_code Syscall.new( name ) + function.source.add_code Syscall.new(function, name ) restore_message(function) end # save the current message, as the syscall destroys all context # # This relies on linux to save and restore all registers - # + # def save_message(function) - function.source.add_code RegisterTransfer.new( Register.message_reg , :r8 ) + function.source.add_code RegisterTransfer.new(function, Register.message_reg , :r8 ) end def restore_message(function) return_tmp = Register.tmp_reg # get the sys return out of the way - function.source.add_code RegisterTransfer.new( Register.message_reg , return_tmp ) + function.source.add_code RegisterTransfer.new(function, Register.message_reg , return_tmp ) # load the stored message into the base RegisterMachine - function.source.add_code RegisterTransfer.new( :r8 , Register.message_reg ) + function.source.add_code RegisterTransfer.new(function, :r8 , Register.message_reg ) # save the return value into the message - function.source.add_code Register.set_slot( return_tmp , :message , :return_value ) + 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(:message , :receiver, :self ) - function.source.add_code Register.get_slot(:message , :frame , :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/instruction.rb b/lib/register/instruction.rb index d599ef8c..85bd7541 100644 --- a/lib/register/instruction.rb +++ b/lib/register/instruction.rb @@ -12,7 +12,7 @@ module Register def initialize source @source = source end - attr_reader :block , :source + attr_reader :source # returns an array of registers (RegisterReferences) that this instruction uses. # ie for r1 = r2 + r3 diff --git a/lib/register/instructions/function_call.rb b/lib/register/instructions/function_call.rb index ab2e4b4b..88c8a69f 100644 --- a/lib/register/instructions/function_call.rb +++ b/lib/register/instructions/function_call.rb @@ -4,7 +4,8 @@ module Register # assembly takes care of the rest (ie getting the address) class FunctionCall < Instruction - def initialize method + def initialize source , method + super(source) @method = method end attr_reader :method diff --git a/lib/register/instructions/function_return.rb b/lib/register/instructions/function_return.rb index 93393178..6e4247fc 100644 --- a/lib/register/instructions/function_return.rb +++ b/lib/register/instructions/function_return.rb @@ -4,7 +4,8 @@ module Register # register and index specify where the return address is stored class FunctionReturn < Instruction - def initialize register , index + def initialize source , register , index + super(source) @register = register @index = index end diff --git a/lib/register/instructions/get_slot.rb b/lib/register/instructions/get_slot.rb index 5e7b5cf9..1189388f 100644 --- a/lib/register/instructions/get_slot.rb +++ b/lib/register/instructions/get_slot.rb @@ -18,30 +18,31 @@ module Register # the instruction would do register = array[index] # The arguments are in the order that makes sense for the Instruciton name # So GetSlot means the slot (array and index) moves to the register (last argument) - def initialize array , index , register - @register = register + def initialize source , array , index , register + super(source) @array = array @index = index + @register = register raise "not integer #{index}" unless index.is_a? Numeric raise "Not register #{register}" unless Register::RegisterReference.look_like_reg(register) raise "Not register #{array}" unless Register::RegisterReference.look_like_reg(array) end - attr_accessor :register , :array , :index + attr_accessor :array , :index , :register def to_s - "GetSlot: #{register} -> #{array} [#{index}]" + "GetSlot: #{array} [#{index}] -> #{register}" end end # Produce a GetSlot instruction. - # From and to are registers or symbols that can be transformed to a register by resolve_to_register + # Array and to are registers or symbols that can be transformed to a register by resolve_to_register # index resolves with resolve_index. - def self.get_slot from , index , to - index = resolve_index( from , index) - from = resolve_to_register from + def self.get_slot source , array , index , to + index = resolve_index( array , index) + array = resolve_to_register array to = resolve_to_register to - GetSlot.new( from , index , to) + GetSlot.new( source , array , index , to) end end diff --git a/lib/register/instructions/load_constant.rb b/lib/register/instructions/load_constant.rb index 00f52b97..614125d2 100644 --- a/lib/register/instructions/load_constant.rb +++ b/lib/register/instructions/load_constant.rb @@ -5,7 +5,8 @@ module Register # second argument is the register the constant is loaded into class LoadConstant < Instruction - def initialize constant , register + def initialize source , constant , register + super(source) @register = register @constant = constant end diff --git a/lib/register/instructions/register_transfer.rb b/lib/register/instructions/register_transfer.rb index 91945fde..382f1a8f 100644 --- a/lib/register/instructions/register_transfer.rb +++ b/lib/register/instructions/register_transfer.rb @@ -16,7 +16,8 @@ module Register # second arguemnt to # # Note: this may be reversed from some assembler notations (also arm) - def initialize from , to + def initialize source , from , to + super(source) @from = wrap_register(from) @to = wrap_register(to) end diff --git a/lib/register/instructions/save_return.rb b/lib/register/instructions/save_return.rb index 910346b8..9eb41a1a 100644 --- a/lib/register/instructions/save_return.rb +++ b/lib/register/instructions/save_return.rb @@ -7,7 +7,8 @@ module Register # address. In arm that is a register, but intel may (?) push it, and who knows, what other machines do. class SaveReturn < Instruction - def initialize register , index + def initialize source , register , index + super(source) @register = register @index = index end @@ -22,10 +23,10 @@ module Register # Produce a SaveReturn instruction. # From is a register or symbol that can be transformed to a register by resolve_to_register # index resolves with resolve_index. - def self.save_return from , index + def self.save_return code, from , index index = resolve_index( from , index) from = resolve_to_register from - SaveReturn.new( from , index ) + SaveReturn.new( code , from , index ) end end diff --git a/lib/register/instructions/set_slot.rb b/lib/register/instructions/set_slot.rb index 926fc562..d56577ce 100644 --- a/lib/register/instructions/set_slot.rb +++ b/lib/register/instructions/set_slot.rb @@ -17,7 +17,8 @@ module Register # If you had a c array and index offset # the instruction would do array[index] = register # So SetSlot means the register (first argument) moves to the slot (array and index) - def initialize register , array , index + def initialize source , register , array , index + super(source) @register = register @array = array @index = index @@ -35,11 +36,11 @@ module Register # Produce a SetSlot instruction. # From and to are registers or symbols that can be transformed to a register by resolve_to_register # index resolves with resolve_index. - def self.set_slot from , to , index - index = resolve_index( to , index) + def self.set_slot source , from , to , index from = resolve_to_register from + index = resolve_index( to , index) to = resolve_to_register to - SetSlot.new( from , to , index) + SetSlot.new( source, from , to , index) end end diff --git a/lib/register/instructions/syscall.rb b/lib/register/instructions/syscall.rb index a96f83be..11c9d975 100644 --- a/lib/register/instructions/syscall.rb +++ b/lib/register/instructions/syscall.rb @@ -9,7 +9,8 @@ module Register class Syscall < Instruction - def initialize name + def initialize source ,name + super(source) @name = name end attr_reader :name diff --git a/lib/register/passes/call_implementation.rb b/lib/register/passes/call_implementation.rb index 1ad73646..b529b59e 100644 --- a/lib/register/passes/call_implementation.rb +++ b/lib/register/passes/call_implementation.rb @@ -13,11 +13,11 @@ module Register next unless code.is_a? Virtual::MethodCall new_codes = [] # move the current new_message to message - new_codes << RegisterTransfer.new( Register.new_message_reg , Register.message_reg ) + new_codes << RegisterTransfer.new(code, Register.new_message_reg , Register.message_reg ) # "roll out" self into its register - new_codes << Register.get_slot( :message , :receiver, :self ) + new_codes << Register.get_slot( code , :message , :receiver, :self ) # do the register call - new_codes << FunctionCall.new( code.method ) + new_codes << FunctionCall.new( code , code.method ) block.replace(code , new_codes ) end end diff --git a/lib/register/passes/frame_implementation.rb b/lib/register/passes/frame_implementation.rb index 44c59141..3382bdcc 100644 --- a/lib/register/passes/frame_implementation.rb +++ b/lib/register/passes/frame_implementation.rb @@ -13,7 +13,7 @@ module Register block.codes.dup.each do |code| next unless code.is_a?(Virtual::NewFrame) # load the frame from message by index, simple get_slot - new_codes = [ Register.get_slot( :message , :frame , Register.resolve_to_register(:frame))] + new_codes = [ Register.get_slot( code, :message , :frame , Register.resolve_to_register(:frame))] block.replace(code , new_codes ) end end diff --git a/lib/register/passes/message_implementation.rb b/lib/register/passes/message_implementation.rb index 38a03e34..f5e5255d 100644 --- a/lib/register/passes/message_implementation.rb +++ b/lib/register/passes/message_implementation.rb @@ -23,7 +23,7 @@ module Register block.codes.dup.each do |code| next unless code.is_a?(Virtual::NewMessage) # load the new_message from message by index, simple get_slot - new_codes = [ Register.get_slot( :message , :next_message , Register.resolve_to_register(:new_message))] + new_codes = [ Register.get_slot(code, :message , :next_message , Register.resolve_to_register(:new_message))] block.replace(code , new_codes ) end end diff --git a/lib/register/passes/return_implementation.rb b/lib/register/passes/return_implementation.rb index 2fba2cd4..ba306273 100644 --- a/lib/register/passes/return_implementation.rb +++ b/lib/register/passes/return_implementation.rb @@ -5,14 +5,14 @@ module Register next unless code.is_a? Virtual::MethodReturn new_codes = [] # move the current message to new_message - new_codes << RegisterTransfer.new( Register.message_reg , Register.new_message_reg ) + 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(:new_message , :caller , :message ) + new_codes << Register.get_slot(code,:new_message , :caller , :message ) # "roll out" self and frame into their registers - new_codes << Register.get_slot( :message , :receiver , :self ) - new_codes << Register.get_slot( :message , :frame , :frame ) + 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( Register.message_reg , Register.resolve_index(:message , :return_address) ) + new_codes << FunctionReturn.new( code , Register.message_reg , Register.resolve_index(:message , :return_address) ) block.replace(code , new_codes ) end end diff --git a/lib/register/passes/set_implementation.rb b/lib/register/passes/set_implementation.rb index 13da1ca9..bca5a573 100644 --- a/lib/register/passes/set_implementation.rb +++ b/lib/register/passes/set_implementation.rb @@ -11,11 +11,11 @@ module Register tmp = Register.tmp_reg # for constants we have to "move" the constants value if( code.from.is_a?(Parfait::Value) or code.from.is_a?(Symbol)) - move1 = LoadConstant.new( code.from , tmp ) + move1 = LoadConstant.new(code, code.from , tmp ) else # while otherwise we "load" - move1 = Register.get_slot( code.from.object_name , get_index(code.from) , tmp ) + move1 = Register.get_slot(code, code.from.object_name , get_index(code.from) , tmp ) end - move2 = Register.set_slot( tmp , code.to.object_name , get_index(code.to) ) + move2 = Register.set_slot( code , tmp , code.to.object_name , get_index(code.to) ) block.replace(code , [move1,move2] ) end end diff --git a/lib/virtual/passes/enter_implementation.rb b/lib/virtual/passes/enter_implementation.rb index d5529675..378cd006 100644 --- a/lib/virtual/passes/enter_implementation.rb +++ b/lib/virtual/passes/enter_implementation.rb @@ -6,7 +6,7 @@ module Virtual next unless code.is_a? Virtual::MethodEnter new_codes = [] # save return register to the message at instance return_address - new_codes << Register.save_return(:message , :return_address) + new_codes << Register.save_return(code, :message , :return_address) # and create a new frame if needed unless code.method.locals.empty? and code.method.tmps.empty? new_codes << Virtual::NewFrame.new