rename locals to frame
includes temps and tradition
This commit is contained in:
parent
83d957377e
commit
2aa7d37a83
@ -10,12 +10,12 @@
|
|||||||
module Parfait
|
module Parfait
|
||||||
class Message < Object
|
class Message < Object
|
||||||
|
|
||||||
# :next_message => :Message, :receiver => :Object, :locals => :NamedList ,
|
# :next_message => :Message, :receiver => :Object, :frame => :NamedList ,
|
||||||
# :return_address => :Integer, :return_value => :Integer,
|
# :return_address => :Integer, :return_value => :Integer,
|
||||||
# :caller => :Message , :name => :Word , :arguments => :NamedList
|
# :caller => :Message , :name => :Word , :arguments => :NamedList
|
||||||
|
|
||||||
attr_accessor :next_message
|
attr_accessor :next_message
|
||||||
attr_reader :receiver , :locals
|
attr_reader :receiver , :frame
|
||||||
attr_reader :return_address, :return_value
|
attr_reader :return_address, :return_value
|
||||||
attr_reader :caller , :name , :arguments
|
attr_reader :caller , :name , :arguments
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ module Parfait
|
|||||||
|
|
||||||
class TypedMethod < Object
|
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
|
# not part of the parfait model, hence ruby accessor
|
||||||
attr_accessor :source
|
attr_accessor :source
|
||||||
@ -35,7 +35,7 @@ module Parfait
|
|||||||
@name = name
|
@name = name
|
||||||
@binary = BinaryCode.new 0
|
@binary = BinaryCode.new 0
|
||||||
@arguments = arguments
|
@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
|
end
|
||||||
|
|
||||||
def set_instructions(inst)
|
def set_instructions(inst)
|
||||||
@ -67,26 +67,26 @@ module Parfait
|
|||||||
# determine if method has a local variable or tmp (anonymous local) by given name
|
# determine if method has a local variable or tmp (anonymous local) by given name
|
||||||
def has_local( name )
|
def has_local( name )
|
||||||
raise "has_local #{name}.#{name.class}" unless name.is_a? Symbol
|
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
|
index ? (index - 1) : index
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_local( name , type )
|
def add_local( name , type )
|
||||||
index = has_local name
|
index = has_local name
|
||||||
return index if index
|
return index if index
|
||||||
@locals = @locals.add_instance_variable(name,type)
|
@frame = @frame.add_instance_variable(name,type)
|
||||||
end
|
end
|
||||||
|
|
||||||
def locals_length
|
def frame_length
|
||||||
locals.instance_length - 1
|
locals.instance_length - 1
|
||||||
end
|
end
|
||||||
|
|
||||||
def locals_name( index )
|
def locals_name( index )
|
||||||
locals.names.get(index + 1)
|
frame.names.get(index + 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
def locals_type( index )
|
def locals_type( index )
|
||||||
locals.types.get(index + 1)
|
frame.types.get(index + 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
def sof_reference_name
|
def sof_reference_name
|
||||||
|
@ -12,7 +12,7 @@ module Parfait
|
|||||||
#
|
#
|
||||||
class VoolMethod
|
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 )
|
def initialize(name , args_type , locals_type , source )
|
||||||
@name , @args_type , @locals_type , @source = name , args_type, locals_type , source
|
@name , @args_type , @locals_type , @source = name , args_type, locals_type , source
|
||||||
|
@ -125,7 +125,7 @@ module Risc
|
|||||||
def type_names
|
def type_names
|
||||||
{ :Word => {:char_length => :Integer} ,
|
{ :Word => {:char_length => :Integer} ,
|
||||||
:List => {:indexed_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,
|
:return_address => :Integer, :return_value => :Integer,
|
||||||
:caller => :Message , :name => :Word , :arguments => :NamedList },
|
:caller => :Message , :name => :Word , :arguments => :NamedList },
|
||||||
:Integer => {},
|
:Integer => {},
|
||||||
@ -140,7 +140,7 @@ module Risc
|
|||||||
:super_class_name => :Word , :instance_names => :List },
|
:super_class_name => :Word , :instance_names => :List },
|
||||||
:Dictionary => {:keys => :List , :values => :List } ,
|
:Dictionary => {:keys => :List , :values => :List } ,
|
||||||
:TypedMethod => {:name => :Word, :source => :Object, :instructions => :Object, :binary => :Object,
|
:TypedMethod => {:name => :Word, :source => :Object, :instructions => :Object, :binary => :Object,
|
||||||
:arguments => :Type , :for_type => :Type, :locals => :Type } ,
|
:arguments => :Type , :for_type => :Type, :frame => :Type } ,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -50,11 +50,11 @@ module Risc
|
|||||||
@current = @method.set_instructions( Risc.label(source, name))
|
@current = @method.set_instructions( Risc.label(source, name))
|
||||||
|
|
||||||
# add the type of the locals to the existing NamedList instance
|
# 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 )
|
list_reg = use_reg(:NamedList )
|
||||||
add_load_constant("#{name} load locals type", method.locals , locals_reg)
|
add_load_constant("#{name} load frame type", method.frame , frame_reg)
|
||||||
add_slot_to_reg( "#{name} get locals from method" , :message , :locals , list_reg )
|
add_slot_to_reg( "#{name} get frame from method" , :message , :frame , list_reg )
|
||||||
add_reg_to_slot( "#{name} store locals type in locals" , locals_reg , list_reg , 1 )
|
add_reg_to_slot( "#{name} store frame type in frame" , frame_reg , list_reg , 1 )
|
||||||
|
|
||||||
enter = @current # this is where method body goes
|
enter = @current # this is where method body goes
|
||||||
add_label( source, "return #{name}")
|
add_label( source, "return #{name}")
|
||||||
@ -89,9 +89,19 @@ module Risc
|
|||||||
@current = c
|
@current = c
|
||||||
end
|
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
|
# 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 unless instruction.is_a?(Risc::Instruction)
|
||||||
raise instruction.to_s if( instruction.class.name.split("::").first == "Arm")
|
raise instruction.to_s if( instruction.class.name.split("::").first == "Arm")
|
||||||
@current.insert(instruction) #insert after current
|
@current.insert(instruction) #insert after current
|
||||||
@ -99,6 +109,8 @@ module Risc
|
|||||||
self
|
self
|
||||||
end
|
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 ,
|
[:label, :reg_to_slot , :slot_to_reg , :load_constant, :function_return ,
|
||||||
:transfer , :reg_to_slot , :byte_to_reg , :reg_to_byte].each do |method|
|
:transfer , :reg_to_slot , :byte_to_reg , :reg_to_byte].each do |method|
|
||||||
define_method("add_#{method}".to_sym) do |*args|
|
define_method("add_#{method}".to_sym) do |*args|
|
||||||
@ -120,13 +132,13 @@ module Risc
|
|||||||
|
|
||||||
def copy( reg , source )
|
def copy( reg , source )
|
||||||
copied = use_reg reg.type
|
copied = use_reg reg.type
|
||||||
add_code Reister.transfer source , reg , copied
|
add_code Register.transfer( source , reg , copied )
|
||||||
copied
|
copied
|
||||||
end
|
end
|
||||||
|
|
||||||
# releasing a register (accuired by use_reg) makes it available for use again
|
# releasing a register (accuired by use_reg) makes it available for use again
|
||||||
# thus avoiding possibly using too many registers
|
# thus avoiding possibly using too many registers
|
||||||
def release_reg reg
|
def release_reg( reg )
|
||||||
last = @regs.pop
|
last = @regs.pop
|
||||||
raise "released register in wrong order, expect #{last} but was #{reg}" if reg != last
|
raise "released register in wrong order, expect #{last} but was #{reg}" if reg != last
|
||||||
end
|
end
|
||||||
|
@ -30,7 +30,7 @@ module Vm
|
|||||||
index = @method.has_local( name )
|
index = @method.has_local( name )
|
||||||
raise "must define local '#{name}' before using it" unless index
|
raise "must define local '#{name}' before using it" unless index
|
||||||
named_list = use_reg :NamedList
|
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 )
|
ret = use_reg @method.locals_type( index )
|
||||||
add_slot_to_reg("#{name} load from locals" , named_list , index + 1, ret )
|
add_slot_to_reg("#{name} load from locals" , named_list , index + 1, ret )
|
||||||
return ret
|
return ret
|
||||||
|
@ -22,7 +22,7 @@ module Parfait
|
|||||||
assert_equal Message , @mess.next_message.class
|
assert_equal Message , @mess.next_message.class
|
||||||
end
|
end
|
||||||
def test_locals
|
def test_locals
|
||||||
assert_equal NamedList , @mess.locals.class
|
assert_equal NamedList , @mess.frame.class
|
||||||
end
|
end
|
||||||
def test_arguments
|
def test_arguments
|
||||||
assert_equal NamedList , @mess.arguments.class
|
assert_equal NamedList , @mess.arguments.class
|
||||||
|
@ -5,7 +5,7 @@ class TestNamedLists < MiniTest::Test
|
|||||||
def setup
|
def setup
|
||||||
Risc.machine.boot
|
Risc.machine.boot
|
||||||
@space = Parfait.object_space
|
@space = Parfait.object_space
|
||||||
@named_list = @space.first_message.locals
|
@named_list = @space.first_message.frame
|
||||||
@type = @named_list.get_type
|
@type = @named_list.get_type
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ class TestSpace < MiniTest::Test
|
|||||||
all = []
|
all = []
|
||||||
while mess
|
while mess
|
||||||
all << mess
|
all << mess
|
||||||
assert mess.locals
|
assert mess.frame
|
||||||
mess = mess.next_message
|
mess = mess.next_message
|
||||||
end
|
end
|
||||||
assert_equal all.length , all.uniq.length
|
assert_equal all.length , all.uniq.length
|
||||||
|
@ -56,8 +56,8 @@ class TestMethod < MiniTest::Test
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_local1
|
def test_local1
|
||||||
assert_equal 2 , @method.locals_length , @method.locals.inspect
|
assert_equal 2 , @method.frame_length , @method.frame.inspect
|
||||||
assert_equal Symbol , @method.locals.names.first.class
|
assert_equal Symbol , @method.frame.names.first.class
|
||||||
assert_equal :local_bar , @method.locals_name(1)
|
assert_equal :local_bar , @method.locals_name(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ class TestMethod < MiniTest::Test
|
|||||||
|
|
||||||
def test_add_local
|
def test_add_local
|
||||||
@method.add_local(:foo2 , :Object)
|
@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 :foo2 , @method.locals_name(3)
|
||||||
assert_equal :Object , @method.locals_type(3)
|
assert_equal :Object , @method.locals_type(3)
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user