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
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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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} ,

View File

@ -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

View File

@ -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