From 278eccbed531b6cc00c2cacacf351a498fb37626 Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Sat, 14 Nov 2015 15:04:04 +0200 Subject: [PATCH] derive binary code form word long ago hacked the binary code to use integers (thus forsaking correct arm binaries) Finally fix by deriving from Word which now has correct binary access Dumped binary.name in the process, that is available from the method --- lib/elf/object_writer.rb | 5 ++++- lib/parfait/binary_code.rb | 18 ++---------------- lib/parfait/method.rb | 2 +- lib/parfait/word.rb | 6 +++++- lib/register/assembler.rb | 28 ++++++++++++++++------------ lib/register/boot.rb | 5 +++-- lib/register/positioned.rb | 2 +- test/parfait/helper.rb | 2 +- 8 files changed, 33 insertions(+), 35 deletions(-) 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