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
This commit is contained in:
Torsten Ruger 2015-11-14 15:04:04 +02:00
parent 8fa92515b5
commit 278eccbed5
8 changed files with 33 additions and 35 deletions

View File

@ -30,14 +30,17 @@ module Elf
end end
Register.machine.objects.each do |id,slot| Register.machine.objects.each do |id,slot|
next if slot.is_a?(Parfait::BinaryCode)
if( slot.respond_to? :sof_reference_name ) if( slot.respond_to? :sof_reference_name )
label = "#{slot.sof_reference_name}" label = "#{slot.sof_reference_name}"
else else
label = "#{slot.class.name}::#{slot.position.to_s(16)}" label = "#{slot.class.name}::#{slot.position.to_s(16)}"
end end
label += "=#{slot}" if slot.is_a?(Symbol) or slot.is_a?(String) 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 add_symbol label , slot.position
if slot.is_a?(Parfait::Method)
add_symbol slot.name.to_s , slot.binary.position
end
end end
end end
attr_reader :text attr_reader :text

View File

@ -3,29 +3,15 @@
# But the code that the method represents, the binary, is held as an array # But the code that the method represents, the binary, is held as an array
# in one of these. # 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 module Parfait
# obviously not a "Word" but a ByteArray , but no such class yet # 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 # As on the other hand has no encoding (yet) it is close enough
class BinaryCode < Object class BinaryCode < Word
attribute :name
include Indexed
self.offset(2)
def initialize name
super()
self.name = name
end
def to_s def to_s
"BinaryCode #{self.name}" "BinaryCode #{self.char_length}"
end end
def == other
self.object_id == other.object_id
end
end end
end end

View File

@ -23,7 +23,7 @@ module Parfait
raise "No class #{name}" unless clazz raise "No class #{name}" unless clazz
self.for_class = clazz self.for_class = clazz
self.name = name 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 raise "Wrong type, expect List not #{arguments.class}" unless arguments.is_a? List
arguments.each do |var| arguments.each do |var|
raise "Must be variable argument, not #{var}" unless var.is_a? Variable raise "Must be variable argument, not #{var}" unless var.is_a? Variable

View File

@ -152,9 +152,13 @@ module Parfait
"'" + to_s + "'" "'" + to_s + "'"
end end
def padded_length
padded( 4 * get_layout().instance_length + self.char_length )
end
private private
def check_length 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 end
end end

View File

@ -24,14 +24,14 @@ module Register
@machine.init.set_position(at) @machine.init.set_position(at)
at += @machine.init.byte_length at += @machine.init.byte_length
at += 8 # thats the padding 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| @machine.objects.each do |id , objekt|
next unless objekt.is_a? Parfait::Method next unless objekt.is_a? Parfait::Method
objekt.binary.position = at objekt.binary.position = at
objekt.instructions.set_position at objekt.instructions.set_position at
len = objekt.instructions.total_byte_length len = objekt.instructions.total_byte_length
log.debug "CODE #{objekt.name} at #{objekt.binary.position} len: #{len}" 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 at += objekt.binary.padded_length
end end
# and then everything else # and then everything else
@ -104,33 +104,33 @@ module Register
end end
index = 1 index = 1
stream.rewind stream.rewind
log.debug "Assembled #{method.name} with length #{stream.length}" log.debug "Assembled code #{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 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 raise "length error #{stream.length} != #{method.instructions.total_byte_length}" if method.instructions.total_byte_length != stream.length
stream.each_byte do |b| stream.each_byte do |b|
method.binary.set((index - 1) / 4 + 1 , b ) method.binary.set_char(index , b )
index = index + 1 index = index + 1
end end
end end
def write_any obj 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 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 end
if obj.is_a?(Parfait::Word) or obj.is_a?(Symbol) if obj.is_a?(Parfait::Word) or obj.is_a?(Symbol)
write_String obj write_String obj
else else
write_object obj write_object obj
end 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 obj.position
end end
# write type and layout of the instance, and the variables that are passed # 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 # variables ar values, ie int or refs. For refs the object needs to save the object first
def write_object( object ) 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 unless @machine.objects.has_key? object.object_id
raise "Object(#{object.object_id}) not linked #{object.inspect}" raise "Object(#{object.object_id}) not linked #{object.inspect}"
end end
@ -160,12 +160,16 @@ module Register
end end
def write_String( string ) 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 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 write_ref_for( string.get_layout ) #ref
@stream.write_sint32( str.length ) #int
@stream.write str @stream.write str
pad_after(str.length + 4) pad_after(str.length + 8)
log.debug "String (#{string.length}) stream #{@stream.length}" log.debug "String (#{string.length}) stream #{@stream.length}"
end end

View File

@ -76,7 +76,8 @@ module Register
classes[name] = cl classes[name] = cl
end end
# superclasses other than default object # 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| layout_names.each do |classname , ivar|
next if classname == :Value # has no superclass next if classname == :Value # has no superclass
clazz = classes[classname] clazz = classes[classname]
@ -116,7 +117,7 @@ module Register
:Integer => {}, :Integer => {},
:Object => {}, :Object => {},
:Kernel => {}, #fix, kernel is a class, but should be a module :Kernel => {}, #fix, kernel is a class, but should be a module
:BinaryCode => {:name => :Word}, :BinaryCode => {:char_length => :Integer} ,
:Space => {:classes => :Dictionary , :first_message => :Message}, :Space => {:classes => :Dictionary , :first_message => :Message},
:Frame => {:next_frame => :Frame, :indexed_length => :Integer}, :Frame => {:next_frame => :Frame, :indexed_length => :Integer},
:Layout => {:object_class => :Class, :instance_methods => :List , :indexed_length => :Integer} , :Layout => {:object_class => :Class, :instance_methods => :List , :indexed_length => :Integer} ,

View File

@ -12,7 +12,7 @@ module Positioned
raise "Setting of nil not allowed" if pos.nil? 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. # resetting of position used to be error, but since relink and dynamic instruction size it is ok.
# in measures (of 32) # 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}" raise "position set again #{pos}!=#{@position} for #{self}"
end end
@position = pos @position = pos

View File

@ -29,7 +29,7 @@ HERE
@interpreter.tick @interpreter.tick
end while( ! @interpreter.instruction.nil?) end while( ! @interpreter.instruction.nil?)
assert_equal @stdout , @interpreter.stdout assert_equal @stdout , @interpreter.stdout
# write_file if true write_file if true
end end
def write_file def write_file