diff --git a/lib/arm/constants.rb b/lib/arm/constants.rb index 2ab95c4e..a2e2fa8c 100644 --- a/lib/arm/constants.rb +++ b/lib/arm/constants.rb @@ -59,7 +59,12 @@ module Arm if name.is_a? Vm::Word name = "r#{name.register}" end - REGISTERS[name.to_s] + if name.is_a? Fixnum + name = "r#{name}" + end + r = REGISTERS[name.to_s] + raise "no reg #{name}" if r == nil + r end def calculate_u8_with_rr(arg) diff --git a/lib/arm/stack_instruction.rb b/lib/arm/stack_instruction.rb index 6f0a7195..cd20ab03 100644 --- a/lib/arm/stack_instruction.rb +++ b/lib/arm/stack_instruction.rb @@ -58,8 +58,8 @@ module Arm regs = @first if (regs.is_a?(Array)) @operand = 0 - regs.each do |reg | - next unless reg + regs.each_with_index do |reg , index| + raise "nil register in push, index #{index}" if reg == nil @operand |= (1 << reg_code(reg)) end else diff --git a/lib/ast/call_site_expression.rb b/lib/ast/call_site_expression.rb index 71a19e2f..3bf0d517 100644 --- a/lib/ast/call_site_expression.rb +++ b/lib/ast/call_site_expression.rb @@ -11,25 +11,14 @@ module Ast function = context.program.get_or_create_function(name) raise "Forward declaration not implemented (#{name}) #{inspect}" if function == nil call = Vm::CallSite.new( name , params , function) - save_locals context , into + current_function = context.function + current_function.save_locals(context , into) if current_function call.load_args into call.do_call into - restore_locals context , into + current_function.restore_locals(context , into) if current_function function.return_type end - def save_locals context , into - into.instance_eval do - push [:r0,:r1 , :r2 , :r3] - end - end - - def restore_locals context , into - into.instance_eval do - pop [:r0,:r1, :r2 , :r3] - end - end - def inspect self.class.name + ".new(" + name.inspect + ", ["+ args.collect{|m| m.inspect }.join( ",") +"] )" diff --git a/lib/vm/function.rb b/lib/vm/function.rb index 3639c019..5f0c6e06 100644 --- a/lib/vm/function.rb +++ b/lib/vm/function.rb @@ -67,6 +67,16 @@ module Vm l end + def save_locals context , into + save = args.collect{|a| a.register } + @locals.collect{|l| l.register} + into.push save + end + + def restore_locals context , into + restore = args.collect{|a| a.register } + @locals.collect{|l| l.register} + into.pop restore + end + def new_block name block = Block.new(name , self) @blocks << block diff --git a/lib/vm/values.rb b/lib/vm/values.rb index b019d77c..72a95518 100644 --- a/lib/vm/values.rb +++ b/lib/vm/values.rb @@ -59,6 +59,7 @@ module Vm end def initialize reg @register = reg + raise inspect if reg == nil end def length 4