From 6be28e7f558124c9a9459c75a504d1a28d90a086 Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Tue, 1 May 2018 19:48:11 +0300 Subject: [PATCH] fix (re)positioning when link exceptions are thrown slow design, but sort of works --- lib/risc/binary_writer.rb | 19 +------------------ lib/risc/machine.rb | 39 ++++++++++++++++++++++++++++++--------- lib/risc/text_writer.rb | 4 ++-- 3 files changed, 33 insertions(+), 29 deletions(-) diff --git a/lib/risc/binary_writer.rb b/lib/risc/binary_writer.rb index d1eb9ab3..b3ebd82e 100644 --- a/lib/risc/binary_writer.rb +++ b/lib/risc/binary_writer.rb @@ -11,26 +11,9 @@ module Risc @code = code end - # write into the given BinaryCode instance - # LinkException may be thrown, possibly several times - # So repeat until it works - def assemble( instruction ) - not_ok = 1 - while(not_ok) - begin - #puts "Not ok #{not_ok}" - #FIXME really need to reposition here, so jumps go right - assemble_all(instruction) - not_ok = false - rescue LinkException - not_ok += 1 - end - end - end - # Go through and assemble all instructions. # Assembly may cause LinkException, which is caught by caller - def assemble_all( instruction ) + def assemble( instruction ) @index = 1 while(instruction) instruction.assemble(self) diff --git a/lib/risc/machine.rb b/lib/risc/machine.rb index 87949b78..6237e1a8 100644 --- a/lib/risc/machine.rb +++ b/lib/risc/machine.rb @@ -79,14 +79,15 @@ module Risc cpu_init.set_position( 0 ) #Positioned.set_position(cpu_init.first , 0) Positioned.set_position(binary_init,0) - at = position_objects( binary_init.padded_length ) + @code_start = position_objects( binary_init.padded_length ) # and then everything code - position_code_from( at ) + position_code end # go through everything that is not code (BinaryCode) and set position # padded_length is what determines an objects (byte) length - def position_objects( at ) + # return final position that is stored in code_start + def position_objects(at) # want to have the objects first in the executable objects.each do | id , objekt| next if objekt.is_a?( Parfait::BinaryCode) or objekt.is_a?( Risc::Label ) @@ -98,9 +99,13 @@ module Risc # Position all BinaryCode. # - # So that all code from one method is layed out linearly (for debuggin) + # So that all code from one method is layed out linearly (for debugging) # we go through methods, and then through all codes from the method - def position_code_from( at ) + # + # start at @code_start. The method is called until + # assembly stops throwing errors + def position_code + at = @code_start objects.each do |id , method| next unless method.is_a? Parfait::TypedMethod log.debug "POS1 #{method.name}:#{at.to_s(16)}" @@ -119,16 +124,32 @@ module Risc # Create Binary code for all methods and the initial jump # BinaryWriter handles the writing from instructions into BinaryCode objects + # + # current (poor) design throws an exception when the assembly can't fit + # constant loads into one instruction. + # def create_binary + not_ok = 1 + while(not_ok) + begin + return do_create_binary + rescue LinkException + not_ok += 1 + puts "relink no #{not_ok}" + position_code + end + end + end + + # have to retry until it works. Unfortunately (FIXME) jumps can go be both + # directions, and so already assembled codes get wrong by moving/ inserting + # instructions. And we end up assmebling all code again :-( + def do_create_binary objects.each do |id , method| next unless method.is_a? Parfait::TypedMethod writer = BinaryWriter.new(method.binary) writer.assemble(method.cpu_instructions) end - puts "CPU init" - puts cpu_init.first.inspect[0...130] - puts Parfait.object_space.get_init.risc_instructions.inspect[0...130] - puts Parfait.object_space.get_init.cpu_instructions.inspect[0...130] BinaryWriter.new(binary_init).assemble(cpu_init) end diff --git a/lib/risc/text_writer.rb b/lib/risc/text_writer.rb index a6e8167d..c5f8fe69 100644 --- a/lib/risc/text_writer.rb +++ b/lib/risc/text_writer.rb @@ -9,7 +9,7 @@ module Risc class TextWriter include Logging - log_level :debug + log_level :info MARKER = 0xBAD4C0DE @@ -109,7 +109,7 @@ module Risc def write_object_check(object) log.debug "Write object #{object.class} #{object.inspect[0..100]}" #Only initially created codes are collected. Binary_init and method "tails" not - if !@objects.has_key?(object.object_id) and !object.is_a?(Parfait::BinaryCode) + if !@machine.objects.has_key?(object.object_id) and !object.is_a?(Parfait::BinaryCode) log.debug "Object at 0x#{Positioned.position(object).to_s(16)}:#{object.get_type()}" raise "Object(0x#{object.object_id.to_s(16)}) not linked #{object.inspect}" end