diff --git a/lib/arm/memory_instruction.rb b/lib/arm/memory_instruction.rb index 3c8ab569..bc06f126 100644 --- a/lib/arm/memory_instruction.rb +++ b/lib/arm/memory_instruction.rb @@ -17,7 +17,7 @@ module Arm @is_load = opcode.to_s[0] == "l" ? 1 : 0 #L (load) flag end - def assemble(io , assembler ) + def assemble(io ) # don't overwrite instance variables, to make assembly repeatable rn = @rn operand = @operand diff --git a/lib/arm/move_instruction.rb b/lib/arm/move_instruction.rb index 2aa0cca7..beb5e178 100644 --- a/lib/arm/move_instruction.rb +++ b/lib/arm/move_instruction.rb @@ -72,7 +72,10 @@ module Arm immediate = 1 raise "hmm" else - raise "cannot fit numeric literal argument in operand #{right.inspect}" + operand = right.integer / 256 + immediate = 1 + +# raise "cannot fit numeric literal argument in operand #{right.inspect}" end elsif (right.is_a?(Symbol) or right.is_a?(Virtual::Integer)) operand = reg_code(right) #integer means the register the integer is in (otherwise constant) diff --git a/lib/elf/text_section.rb b/lib/elf/text_section.rb index a4d08bce..ca3a03cc 100644 --- a/lib/elf/text_section.rb +++ b/lib/elf/text_section.rb @@ -14,7 +14,7 @@ module Elf Elf::Constants::SHF_WRITE | Elf::Constants::SHF_ALLOC | Elf::Constants::SHF_EXECINSTR end - def mem_length + def length @text.length end def to_s diff --git a/lib/register/assembler.rb b/lib/register/assembler.rb index 4a34c6ec..405460b6 100644 --- a/lib/register/assembler.rb +++ b/lib/register/assembler.rb @@ -79,9 +79,9 @@ module Register raise "Object(#{object.object_id}) not linked #{object.inspect}" unless @objects[object.object_id] type = type_word(variables) @stream.write_uint32( type ) - write_ref_for(object.layout[:names] , object ) + write_ref_for(object.layout[:names] ) variables.each do |var| - write_ref_for(var , object) + write_ref_for(var) end pad_after( variables.length * 4 ) object.position @@ -90,9 +90,9 @@ module Register def assemble_Array array type = type_word(array) @stream.write_uint32( type ) - write_ref_for(layout[:names],array) #ref + write_ref_for(array.layout[:names]) #ref array.each do |var| - write_ref_for(var,array) + write_ref_for(var) end pad_after( array.length * 4 ) array.position @@ -112,13 +112,13 @@ module Register end def assemble_CompiledMethod(method) - count = method.blocks.inject(0) { |c , block| c += block.length } + count = method.blocks.inject(0) { |c , block| c += block.mem_length } word = (count+7) / 32 # all object are multiple of 8 words (7 for header) raise "Method too long, splitting not implemented #{method.name}/#{count}" if word > 15 # first line is integers, convention is that following lines are the same TYPE_LENGTH.times { word = ((word << TYPE_BITS) + TYPE_INT) } @stream.write_uint32( word ) - write_ref_for(method.layout[:names] , method) #ref of layout + write_ref_for(method.layout[:names]) #ref of layout # TODO the assembly may have to move to the object to be more extensible method.blocks.each do |block| block.codes.each do |code| @@ -131,14 +131,14 @@ module Register def assemble_String( str ) str = str.string if str.is_a? Virtual::StringConstant str = str.to_s if str.is_a? Symbol - word = (str.mem_length + 7) / 32 # all object are multiple of 8 words (7 for header) + word = (str.length + 7) / 32 # all object are multiple of 8 words (7 for header) raise "String too long (implement split string!) #{word}" if word > 15 # first line is integers, convention is that following lines are the same TYPE_LENGTH.times { word = ((word << TYPE_BITS) + TYPE_INT) } @stream.write_uint32( word ) - write_ref_for( str.layout[:names] , slot) #ref + write_ref_for( str.layout[:names] ) #ref @stream.write str - pad_after(str.mem_length) + pad_after(str.length) #puts "String (#{slot.mem_length}) stream #{@stream.mem_length.to_s(16)}" end @@ -181,6 +181,7 @@ module Register add_object(clazz.instance_methods) end def add_CompiledMethod(method) + add_object(method.name) end def add_String( str) end @@ -194,8 +195,7 @@ module Register # write means we write the resulting address straight into the assembler stream (ie don't return it) # object means the object of which we write the address # and we write the address into the self, given as second parameter - def write_ref_for object , self_ref - raise "Object (#{object.object_id}) not linked #{object.inspect}" unless slot + def write_ref_for object @stream.write_sint32 object.position end @@ -218,7 +218,7 @@ module Register pad.times do @stream.write_uint8(0) end - #puts "padded #{length} with #{pad} stream pos #{@stream.mem_length.to_s(16)}" + puts "padded #{length} with #{pad} stream pos #{@stream.length.to_s(16)}" end end diff --git a/lib/virtual/compiled_method.rb b/lib/virtual/compiled_method.rb index 1a89b532..1a548a9d 100644 --- a/lib/virtual/compiled_method.rb +++ b/lib/virtual/compiled_method.rb @@ -172,15 +172,13 @@ module Virtual end # position of the function is the position of the entry block, is where we call def set_position at + super at += 8 #for the 2 header words @blocks.each do |block| block.set_position at at = at + block.mem_length end end - def position - @blocks.first.position - end end end diff --git a/lib/virtual/constants.rb b/lib/virtual/constants.rb index f9264cf3..63987b75 100644 --- a/lib/virtual/constants.rb +++ b/lib/virtual/constants.rb @@ -53,6 +53,11 @@ module Virtual def mem_length padded(1 + string.length) end + def position + return @position if @position + return @string.position if @string.position + super + end end end \ No newline at end of file diff --git a/lib/virtual/object.rb b/lib/virtual/object.rb index 406b3b5c..2fe963a0 100644 --- a/lib/virtual/object.rb +++ b/lib/virtual/object.rb @@ -22,7 +22,7 @@ module Virtual end attr_accessor :length , :layout def position - raise "position accessed but not set at #{length} for #{self.objekt}" if @position == nil + raise "position accessed but not set at #{length} for #{self.inspect}" if @position == nil @position end def set_position pos @@ -75,21 +75,12 @@ module Virtual def padded_words words padded(words*4) # 4 == word length, a constant waiting for a home end - - # pad_after is always in bytes and pads (writes 0's) up to the next 8 word boundary - def pad_after length - pad = padded(length) - length - 8 # for header, type and layout - pad.times do - @stream.write_uint8(0) - end - #puts "padded #{length} with #{pad} stream pos #{@stream.length.to_s(16)}" - end end end Parfait::Hash.class_eval do - @@HASH = { :names => [:keys,:values] , :types => [Virtual::Reference,Virtual::Reference]} + HASH = { :names => [:keys,:values] , :types => [Virtual::Reference,Virtual::Reference]} def layout - @@HASH + HASH end def set_position pos @position = pos