diff --git a/lib/elf/object_writer.rb b/lib/elf/object_writer.rb index e1ca5c7a..98d43625 100644 --- a/lib/elf/object_writer.rb +++ b/lib/elf/object_writer.rb @@ -30,14 +30,17 @@ module Elf end Register.machine.objects.each do |id,slot| + next if slot.is_a?(Parfait::BinaryCode) if( slot.respond_to? :sof_reference_name ) label = "#{slot.sof_reference_name}" else label = "#{slot.class.name}::#{slot.position.to_s(16)}" end label += "=#{slot}" if slot.is_a?(Symbol) or slot.is_a?(String) - label += "=#{slot.name}" if slot.is_a?(Parfait::BinaryCode) add_symbol label , slot.position + if slot.is_a?(Parfait::Method) + add_symbol slot.name.to_s , slot.binary.position + end end end attr_reader :text diff --git a/lib/parfait/binary_code.rb b/lib/parfait/binary_code.rb index 2d4bfd94..7f2b7b47 100644 --- a/lib/parfait/binary_code.rb +++ b/lib/parfait/binary_code.rb @@ -3,29 +3,15 @@ # But the code that the method represents, the binary, is held as an array # in one of these. # -# The BinaryCode is really just a name to make sure that when we call a method -# it is really the code we call. module Parfait # obviously not a "Word" but a ByteArray , but no such class yet # As on the other hand has no encoding (yet) it is close enough - class BinaryCode < Object - attribute :name - - include Indexed - self.offset(2) - - def initialize name - super() - self.name = name - end + class BinaryCode < Word def to_s - "BinaryCode #{self.name}" + "BinaryCode #{self.char_length}" end - def == other - self.object_id == other.object_id - end end end diff --git a/lib/parfait/method.rb b/lib/parfait/method.rb index 2418aac0..e0583af8 100644 --- a/lib/parfait/method.rb +++ b/lib/parfait/method.rb @@ -23,7 +23,7 @@ module Parfait raise "No class #{name}" unless clazz self.for_class = clazz self.name = name - self.binary = BinaryCode.new name + self.binary = BinaryCode.new 0 raise "Wrong type, expect List not #{arguments.class}" unless arguments.is_a? List arguments.each do |var| raise "Must be variable argument, not #{var}" unless var.is_a? Variable diff --git a/lib/parfait/word.rb b/lib/parfait/word.rb index 90a9fbfc..a9f1a276 100644 --- a/lib/parfait/word.rb +++ b/lib/parfait/word.rb @@ -152,9 +152,13 @@ module Parfait "'" + to_s + "'" end + def padded_length + padded( 4 * get_layout().instance_length + self.char_length ) + end + private def check_length - raise "Length out of bounds #{self.char_length}" if self.char_length > 32 + raise "Length out of bounds #{self.char_length}" if self.char_length > 108 end end end diff --git a/lib/register/assembler.rb b/lib/register/assembler.rb index eee28891..8d18269e 100644 --- a/lib/register/assembler.rb +++ b/lib/register/assembler.rb @@ -24,14 +24,14 @@ module Register @machine.init.set_position(at) at += @machine.init.byte_length at += 8 # thats the padding - # want to have the methods first in the executable (ie the BinaryCode objects) + # want to have the methods first in the executable @machine.objects.each do |id , objekt| next unless objekt.is_a? Parfait::Method objekt.binary.position = at objekt.instructions.set_position at len = objekt.instructions.total_byte_length log.debug "CODE #{objekt.name} at #{objekt.binary.position} len: #{len}" - objekt.binary.set_length(len/4) + objekt.binary.set_length(len , 0) at += objekt.binary.padded_length end # and then everything else @@ -104,33 +104,33 @@ module Register end index = 1 stream.rewind - log.debug "Assembled #{method.name} with length #{stream.length}" - raise "length error #{method.binary.get_length} != #{method.instructions.total_byte_length}" if method.binary.get_length*4 != method.instructions.total_byte_length + log.debug "Assembled code #{method.name} with length #{stream.length}" + raise "length error #{method.binary.char_length} != #{method.instructions.total_byte_length}" if method.binary.char_length != method.instructions.total_byte_length raise "length error #{stream.length} != #{method.instructions.total_byte_length}" if method.instructions.total_byte_length != stream.length stream.each_byte do |b| - method.binary.set((index - 1) / 4 + 1 , b ) + method.binary.set_char(index , b ) index = index + 1 end end def write_any obj - log.debug "Assemble #{obj.class}(#{obj.object_id}) at stream #{stream_position} pos:#{obj.position} , len:#{obj.padded_length}" + log.debug "Write #{obj.class}(#{obj.object_id}) at stream #{stream_position} pos:#{obj.position} , len:#{obj.padded_length}" if @stream.length != obj.position - raise "Assemble #{obj.class} #{obj.object_id} at #{stream_position} not #{obj.position}" + raise "Write #{obj.class} #{obj.object_id} at #{stream_position} not #{obj.position}" end if obj.is_a?(Parfait::Word) or obj.is_a?(Symbol) write_String obj else write_object obj end - log.debug "Assemble #{obj.class}(#{obj.object_id}) at stream #{stream_position} pos:#{obj.position} , len:#{obj.padded_length}" + log.debug "Wrote #{obj.class}(#{obj.object_id}) at stream #{stream_position} pos:#{obj.position} , len:#{obj.padded_length}" obj.position end # write type and layout of the instance, and the variables that are passed # variables ar values, ie int or refs. For refs the object needs to save the object first def write_object( object ) - log.debug "Write #{object.class} #{object.inspect}" + log.debug "Write object #{object.class} #{object.inspect}" unless @machine.objects.has_key? object.object_id raise "Object(#{object.object_id}) not linked #{object.inspect}" end @@ -160,12 +160,16 @@ module Register end def write_String( string ) - str = string.to_string if string.is_a? Parfait::Word + if string.is_a? Parfait::Word + str = string.to_string + raise "length mismatch #{str.length} != #{string.char_length}" if str.length != string.char_length + end str = string.to_s if string.is_a? Symbol - log.debug "String is #{string} at #{string.position} length #{string.length}" + log.debug "#{string.class} is #{string} at #{string.position} length #{string.length}" write_ref_for( string.get_layout ) #ref + @stream.write_sint32( str.length ) #int @stream.write str - pad_after(str.length + 4) + pad_after(str.length + 8) log.debug "String (#{string.length}) stream #{@stream.length}" end diff --git a/lib/register/boot.rb b/lib/register/boot.rb index 1e67b5e6..f3684da8 100644 --- a/lib/register/boot.rb +++ b/lib/register/boot.rb @@ -76,7 +76,8 @@ module Register classes[name] = cl end # superclasses other than default object - supers = { :Object => :Kernel , :Kernel => :Value, :Integer => :Value } + supers = { :Object => :Kernel , :Kernel => :Value, + :Integer => :Value , :BinaryCode => :Word } layout_names.each do |classname , ivar| next if classname == :Value # has no superclass clazz = classes[classname] @@ -116,7 +117,7 @@ module Register :Integer => {}, :Object => {}, :Kernel => {}, #fix, kernel is a class, but should be a module - :BinaryCode => {:name => :Word}, + :BinaryCode => {:char_length => :Integer} , :Space => {:classes => :Dictionary , :first_message => :Message}, :Frame => {:next_frame => :Frame, :indexed_length => :Integer}, :Layout => {:object_class => :Class, :instance_methods => :List , :indexed_length => :Integer} , diff --git a/lib/register/positioned.rb b/lib/register/positioned.rb index eea8e374..d0357081 100644 --- a/lib/register/positioned.rb +++ b/lib/register/positioned.rb @@ -12,7 +12,7 @@ module Positioned raise "Setting of nil not allowed" if pos.nil? # resetting of position used to be error, but since relink and dynamic instruction size it is ok. # in measures (of 32) - if @position != nil and ((@position - pos).abs > 32) + if @position != nil and ((@position - pos).abs > 10000) raise "position set again #{pos}!=#{@position} for #{self}" end @position = pos diff --git a/test/parfait/helper.rb b/test/parfait/helper.rb index db68115a..b9e93c09 100644 --- a/test/parfait/helper.rb +++ b/test/parfait/helper.rb @@ -29,7 +29,7 @@ HERE @interpreter.tick end while( ! @interpreter.instruction.nil?) assert_equal @stdout , @interpreter.stdout -# write_file if true + write_file if true end def write_file