diff --git a/lib/parfait/message.rb b/lib/parfait/message.rb index ba147e8c..b6ca7cc0 100644 --- a/lib/parfait/message.rb +++ b/lib/parfait/message.rb @@ -10,12 +10,12 @@ module Parfait class Message < Object - # :next_message => :Message, :receiver => :Object, :locals => :NamedList , + # :next_message => :Message, :receiver => :Object, :frame => :NamedList , # :return_address => :Integer, :return_value => :Integer, # :caller => :Message , :name => :Word , :arguments => :NamedList attr_accessor :next_message - attr_reader :receiver , :locals + attr_reader :receiver , :frame attr_reader :return_address, :return_value attr_reader :caller , :name , :arguments diff --git a/lib/parfait/typed_method.rb b/lib/parfait/typed_method.rb index 74d519e1..8cfa571c 100644 --- a/lib/parfait/typed_method.rb +++ b/lib/parfait/typed_method.rb @@ -21,7 +21,7 @@ module Parfait class TypedMethod < Object - attr_reader :name , :instructions , :for_type ,:arguments , :locals , :binary + attr_reader :name , :instructions , :for_type ,:arguments , :frame , :binary # not part of the parfait model, hence ruby accessor attr_accessor :source @@ -35,7 +35,7 @@ module Parfait @name = name @binary = BinaryCode.new 0 @arguments = arguments - @locals = Parfait.object_space.get_class_by_name( :NamedList ).instance_type + @frame = Parfait.object_space.get_class_by_name( :NamedList ).instance_type end def set_instructions(inst) @@ -67,26 +67,26 @@ module Parfait # determine if method has a local variable or tmp (anonymous local) by given name def has_local( name ) raise "has_local #{name}.#{name.class}" unless name.is_a? Symbol - index = locals.variable_index( name ) + index = frame.variable_index( name ) index ? (index - 1) : index end def add_local( name , type ) index = has_local name return index if index - @locals = @locals.add_instance_variable(name,type) + @frame = @frame.add_instance_variable(name,type) end - def locals_length + def frame_length locals.instance_length - 1 end def locals_name( index ) - locals.names.get(index + 1) + frame.names.get(index + 1) end def locals_type( index ) - locals.types.get(index + 1) + frame.types.get(index + 1) end def sof_reference_name diff --git a/lib/parfait/vool_method.rb b/lib/parfait/vool_method.rb index 036d33ce..f11c4076 100644 --- a/lib/parfait/vool_method.rb +++ b/lib/parfait/vool_method.rb @@ -12,7 +12,7 @@ module Parfait # class VoolMethod - attr_reader :name , :args_type , :locals_type , :source + attr_reader :name , :args_type , :frame_type , :source def initialize(name , args_type , locals_type , source ) @name , @args_type , @locals_type , @source = name , args_type, locals_type , source diff --git a/lib/risc/boot.rb b/lib/risc/boot.rb index 13824a5c..148f0f4e 100644 --- a/lib/risc/boot.rb +++ b/lib/risc/boot.rb @@ -125,7 +125,7 @@ module Risc def type_names { :Word => {:char_length => :Integer} , :List => {:indexed_length => :Integer} , - :Message => { :next_message => :Message, :receiver => :Object, :locals => :NamedList , + :Message => { :next_message => :Message, :receiver => :Object, :frame => :NamedList , :return_address => :Integer, :return_value => :Integer, :caller => :Message , :name => :Word , :arguments => :NamedList }, :Integer => {}, @@ -140,7 +140,7 @@ module Risc :super_class_name => :Word , :instance_names => :List }, :Dictionary => {:keys => :List , :values => :List } , :TypedMethod => {:name => :Word, :source => :Object, :instructions => :Object, :binary => :Object, - :arguments => :Type , :for_type => :Type, :locals => :Type } , + :arguments => :Type , :for_type => :Type, :frame => :Type } , } end diff --git a/lib/risc/method_compiler.rb b/lib/risc/method_compiler.rb index a17fc499..ca4e9f4a 100644 --- a/lib/risc/method_compiler.rb +++ b/lib/risc/method_compiler.rb @@ -50,11 +50,11 @@ module Risc @current = @method.set_instructions( Risc.label(source, name)) # add the type of the locals to the existing NamedList instance - locals_reg = use_reg(:Type , method.locals ) + frame_reg = use_reg(:Type , method.frame ) list_reg = use_reg(:NamedList ) - add_load_constant("#{name} load locals type", method.locals , locals_reg) - add_slot_to_reg( "#{name} get locals from method" , :message , :locals , list_reg ) - add_reg_to_slot( "#{name} store locals type in locals" , locals_reg , list_reg , 1 ) + add_load_constant("#{name} load frame type", method.frame , frame_reg) + add_slot_to_reg( "#{name} get frame from method" , :message , :frame , list_reg ) + add_reg_to_slot( "#{name} store frame type in frame" , frame_reg , list_reg , 1 ) enter = @current # this is where method body goes add_label( source, "return #{name}") @@ -89,9 +89,19 @@ module Risc @current = c end - # add an instruction after the current (insertion point) + # convert the given mom instruction to_risc and then add it (see add_code) + # continue down the instruction chain unti depleted + # (adding moves the insertion point so the whole mom chain is added as a risc chain) + def add_mom( instruction ) + while( instruction ) + risc = instruction.to_risc( self ) + add_code(risc) + instruction = instruction.next + end + end + # add a risc instruction after the current (insertion point) # the added instruction will become the new insertion point - def add_code instruction + def add_code( instruction ) raise instruction.to_s unless instruction.is_a?(Risc::Instruction) raise instruction.to_s if( instruction.class.name.split("::").first == "Arm") @current.insert(instruction) #insert after current @@ -99,6 +109,8 @@ module Risc self end + # for computationally building code (ie writing assembler) these short cuts + # help to instantiate risc instructions and add them immediately [:label, :reg_to_slot , :slot_to_reg , :load_constant, :function_return , :transfer , :reg_to_slot , :byte_to_reg , :reg_to_byte].each do |method| define_method("add_#{method}".to_sym) do |*args| @@ -120,13 +132,13 @@ module Risc def copy( reg , source ) copied = use_reg reg.type - add_code Reister.transfer source , reg , copied + add_code Register.transfer( source , reg , copied ) copied end # releasing a register (accuired by use_reg) makes it available for use again # thus avoiding possibly using too many registers - def release_reg reg + def release_reg( reg ) last = @regs.pop raise "released register in wrong order, expect #{last} but was #{reg}" if reg != last end diff --git a/stash/vm/method_compiler/name_expression.rb b/stash/vm/method_compiler/name_expression.rb index 570014af..570e2a9a 100644 --- a/stash/vm/method_compiler/name_expression.rb +++ b/stash/vm/method_compiler/name_expression.rb @@ -30,7 +30,7 @@ module Vm index = @method.has_local( name ) raise "must define local '#{name}' before using it" unless index named_list = use_reg :NamedList - add_slot_to_reg("#{name} load locals" , :message , :locals , named_list ) + add_slot_to_reg("#{name} load locals" , :message , :frame , named_list ) ret = use_reg @method.locals_type( index ) add_slot_to_reg("#{name} load from locals" , named_list , index + 1, ret ) return ret diff --git a/test/parfait/test_message.rb b/test/parfait/test_message.rb index cde4e936..47e6fa77 100644 --- a/test/parfait/test_message.rb +++ b/test/parfait/test_message.rb @@ -22,7 +22,7 @@ module Parfait assert_equal Message , @mess.next_message.class end def test_locals - assert_equal NamedList , @mess.locals.class + assert_equal NamedList , @mess.frame.class end def test_arguments assert_equal NamedList , @mess.arguments.class diff --git a/test/parfait/test_named_list.rb b/test/parfait/test_named_list.rb index 5ebcda54..41cd183f 100644 --- a/test/parfait/test_named_list.rb +++ b/test/parfait/test_named_list.rb @@ -5,7 +5,7 @@ class TestNamedLists < MiniTest::Test def setup Risc.machine.boot @space = Parfait.object_space - @named_list = @space.first_message.locals + @named_list = @space.first_message.frame @type = @named_list.get_type end diff --git a/test/parfait/test_space.rb b/test/parfait/test_space.rb index 0c71c6d4..cef409ca 100644 --- a/test/parfait/test_space.rb +++ b/test/parfait/test_space.rb @@ -95,7 +95,7 @@ class TestSpace < MiniTest::Test all = [] while mess all << mess - assert mess.locals + assert mess.frame mess = mess.next_message end assert_equal all.length , all.uniq.length diff --git a/test/parfait/test_typed_method.rb b/test/parfait/test_typed_method.rb index 24cb1b19..2d2ebad6 100644 --- a/test/parfait/test_typed_method.rb +++ b/test/parfait/test_typed_method.rb @@ -56,8 +56,8 @@ class TestMethod < MiniTest::Test end def test_local1 - assert_equal 2 , @method.locals_length , @method.locals.inspect - assert_equal Symbol , @method.locals.names.first.class + assert_equal 2 , @method.frame_length , @method.frame.inspect + assert_equal Symbol , @method.frame.names.first.class assert_equal :local_bar , @method.locals_name(1) end @@ -68,7 +68,7 @@ class TestMethod < MiniTest::Test def test_add_local @method.add_local(:foo2 , :Object) - assert_equal 3 , @method.locals_length + assert_equal 3 , @method.frame_length assert_equal :foo2 , @method.locals_name(3) assert_equal :Object , @method.locals_type(3) end