From 903fc3e4cf2e109f6604c06160f935cfad02f57c Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Tue, 27 Dec 2016 20:39:39 +0200 Subject: [PATCH] much ripples from changing the calling convention See previous commit Now args and locals are arrays in the Message --- lib/register/builtin/compile_helper.rb | 16 ++++++------- lib/register/builtin/kernel.rb | 24 ++++++++------------ lib/register/instructions/function_call.rb | 19 ++++++---------- lib/typed/method_compiler/assignment.rb | 2 +- lib/typed/method_compiler/name_expression.rb | 22 ++++++++++-------- 5 files changed, 37 insertions(+), 46 deletions(-) diff --git a/lib/register/builtin/compile_helper.rb b/lib/register/builtin/compile_helper.rb index 28581269..ef35733b 100644 --- a/lib/register/builtin/compile_helper.rb +++ b/lib/register/builtin/compile_helper.rb @@ -4,12 +4,9 @@ module Register module CompileHelper def self_and_int_arg(compiler , source) - #Load self by "calling" on_name me = compiler.process( Typed::Tree::NameExpression.new( :self) ) - # Load the argument - index = compiler.use_reg :Integer - compiler.add_code Register.slot_to_reg(source , :message , 1 , index ) - return me , index + int_arg = load_int_arg_at(compiler , source , 1 ) + return me , int_arg end def compiler_for( type , method_name , extra_args = {}) @@ -18,10 +15,11 @@ module Register end # Load the value - def load_arg_at(compiler, source , at) - value = compiler.use_reg :Integer - compiler.add_code Register.slot_to_reg(source , :message , at , value ) - value + def load_int_arg_at(compiler, source , at) + int_arg = compiler.use_reg :Integer + compiler.add_code Register.slot_to_reg(source , :message , :arguments , int_arg ) + compiler.add_code Register.slot_to_reg(source , int_arg , at + 1, int_arg ) #1 for type + return int_arg end end diff --git a/lib/register/builtin/kernel.rb b/lib/register/builtin/kernel.rb index c4542152..6b2f3cba 100644 --- a/lib/register/builtin/kernel.rb +++ b/lib/register/builtin/kernel.rb @@ -6,28 +6,22 @@ module Register # it isn't really a function, ie it is jumped to (not called), exits and may not return # so it is responsible for initial setup def __init__ context - source = "__init__" compiler = Typed::MethodCompiler.new.create_method(:Kernel,:__init__ ) - # no method enter or return (automatically added), remove - new_start = Label.new(source , source ) + new_start = Label.new("__init__ start" , "__init__" ) compiler.method.instructions = new_start compiler.set_current new_start - #Set up the Space as self upon init space = Parfait::Space.object_space - space_reg = compiler.use_reg(:Space) - compiler.add_code LoadConstant.new(source, space , space_reg) + space_reg = compiler.use_reg(:Space) #Set up the Space as self upon init + compiler.add_code LoadConstant.new("__init__ load Space", space , space_reg) message_ind = Register.resolve_index( :space , :first_message ) - # Load the message to new message register (r1) - compiler.add_code Register.slot_to_reg( source , space_reg , message_ind , :message) - # And store the space as the new self (so the call can move it back as self) - compiler.add_code Register.reg_to_slot( source, space_reg , :message , :receiver) - exit_label = Label.new("_exit_label" , "#{compiler.type.object_class.name}.#{compiler.method.name}" ) + compiler.add_code Register.slot_to_reg( "__init__ load 1st message" , space_reg , message_ind , :message) + compiler.add_code Register.reg_to_slot( "__init__ store Space in message", space_reg , :message , :receiver) + exit_label = Label.new("_exit_label for __init__" , "#{compiler.type.object_class.name}.#{compiler.method.name}" ) ret_tmp = compiler.use_reg(:Label) - compiler.add_code Register::LoadConstant.new(source, exit_label , ret_tmp) - compiler.add_code Register.reg_to_slot(source, ret_tmp , :message , :return_address) - # do the register call - compiler.add_code FunctionCall.new( source , Register.machine.space.get_main ) + compiler.add_code Register::LoadConstant.new("__init__ load return", exit_label , ret_tmp) + compiler.add_code Register.reg_to_slot("__init__ store return", ret_tmp , :message , :return_address) + compiler.add_code FunctionCall.new( "__init__ issue call" , Register.machine.space.get_main ) compiler.add_code exit_label emit_syscall( compiler , :exit ) return compiler.method diff --git a/lib/register/instructions/function_call.rb b/lib/register/instructions/function_call.rb index 5cf9d25f..498a214c 100644 --- a/lib/register/instructions/function_call.rb +++ b/lib/register/instructions/function_call.rb @@ -16,19 +16,14 @@ module Register end def self.issue_call( compiler , callee ) - source = "_issue_call(#{callee.name})" - return_label = Label.new("_return_label" , "#{compiler.type.object_class.name}.#{compiler.method.name}" ) + return_label = Label.new("_return_label #{callee.name}" , "#{compiler.type.object_class.name}.#{compiler.method.name}" ) ret_tmp = compiler.use_reg(:Label) - compiler.add_code Register::LoadConstant.new(source, return_label , ret_tmp) - compiler.add_code Register.reg_to_slot(source, ret_tmp , :new_message , :return_address) - # move the current new_message to message - compiler.add_code RegisterTransfer.new(source, Register.new_message_reg , Register.message_reg ) - # do the register call - compiler.add_code FunctionCall.new( source , callee ) + compiler.add_code Register::LoadConstant.new("#{callee.name} load ret", return_label , ret_tmp) + compiler.add_code Register.reg_to_slot("#{callee.name} store ret", ret_tmp , :new_message , :return_address) + compiler.add_code RegisterTransfer.new("#{callee.name} move new message", Register.new_message_reg , Register.message_reg ) + compiler.add_code FunctionCall.new( "#{callee.name} call" , callee ) compiler.add_code return_label - # move the current message to new_message - compiler.add_code Register::RegisterTransfer.new(source, Register.message_reg , Register.new_message_reg ) - # and restore the message from saved value in new_message - compiler.add_code Register.slot_to_reg(source , :new_message , :caller , :message ) + compiler.add_code Register::RegisterTransfer.new("#{callee.name} remove new message", Register.message_reg , Register.new_message_reg ) + compiler.add_code Register.slot_to_reg("#{callee.name} restore message" , :new_message , :caller , :message ) end end diff --git a/lib/typed/method_compiler/assignment.rb b/lib/typed/method_compiler/assignment.rb index b15fad87..2d77a887 100644 --- a/lib/typed/method_compiler/assignment.rb +++ b/lib/typed/method_compiler/assignment.rb @@ -27,7 +27,7 @@ module Typed end # TODO, check type @method.locals[index].type add_code Register.slot_to_reg(statement , :message , type , named_list ) - return Register.reg_to_slot(statement , value , named_list , index ) + return Register.reg_to_slot(statement , value , named_list , index + 1 ) # one for type end end end diff --git a/lib/typed/method_compiler/name_expression.rb b/lib/typed/method_compiler/name_expression.rb index d5e8f264..f2e5f7ca 100644 --- a/lib/typed/method_compiler/name_expression.rb +++ b/lib/typed/method_compiler/name_expression.rb @@ -12,9 +12,11 @@ module Typed end # either an argument, so it's stored in message if( index = @method.has_arg(name)) + named_list = use_reg :NamedList ret = use_reg @method.argument_type(index) #puts "For #{name} at #{index} got #{@method.arguments.inspect}" - add_code Register.slot_to_reg(statement , :message , index, ret ) + add_code Register.slot_to_reg("#{statement} load args" , :message , :arguments, named_list ) + add_code Register.slot_to_reg("#{statement} load #{name}" , named_list , index + 1, ret ) return ret end # or a local so it is in the named_list @@ -23,31 +25,33 @@ module Typed private - def handle_local statement - index = @method.has_local( statement.name ) - raise "must define variable '#{statement.name}' before using it" unless index + def handle_local( statement ) + name = statement.name + index = @method.has_local( name ) + raise "must define variable '#{name}' before using it" unless index named_list = use_reg :NamedList - add_code Register.slot_to_reg(statement , :message , :locals , named_list ) + add_code Register.slot_to_reg("#{name} load locals" , :message , :locals , named_list ) ret = use_reg @method.locals_type( index ) - add_code Register.slot_to_reg(statement , named_list , index, ret ) + add_code Register.slot_to_reg("#{name} load from locals" , named_list , index + 1, ret ) return ret end def handle_special_self(statement) ret = use_reg @type - add_code Register.slot_to_reg(statement , :message , :receiver , ret ) + add_code Register.slot_to_reg("#{statement} load self" , :message , :receiver , ret ) return ret end def handle_special_space(statement) space = Parfait::Space.object_space reg = use_reg :Space , space - add_code Register::LoadConstant.new( statement, space , reg ) + add_code Register::LoadConstant.new( "#{statement} load space", space , reg ) return reg end + def handle_special_message(statement) reg = use_reg :Message - add_code Register::RegisterTransfer.new( statement, Register.message_reg , reg ) + add_code Register::RegisterTransfer.new( "#{statement} load message", Register.message_reg , reg ) return reg end end #module