From 4253d7a6b9850838afdabf85190d8a38b0f57246 Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Tue, 27 Mar 2018 18:47:39 +0300 Subject: [PATCH] move assembly from assembler to machine id now called position --- lib/risc/assembler.rb | 49 ------------------------------ lib/risc/instructions/label.rb | 2 +- lib/risc/machine.rb | 54 ++++++++++++++++++++++++++++++++-- test/risc/test_machine.rb | 11 ++++++- 4 files changed, 63 insertions(+), 53 deletions(-) diff --git a/lib/risc/assembler.rb b/lib/risc/assembler.rb index d1ce0969..aba515da 100644 --- a/lib/risc/assembler.rb +++ b/lib/risc/assembler.rb @@ -20,57 +20,8 @@ module Risc @load_at = 0x8054 # this is linux/arm end - def assemble - #need the initial jump at 0 and then functions - @machine.cpu_init.set_position( 0 ) - at = @machine.cpu_init.byte_length - at = position_objects( at ) - # and then everything code - position_code_from( at ) - end - - def position_objects( at ) - at += 8 # thats the padding - # want to have the objects first in the executable - @objects.each do | id , objekt| - case objekt - when Risc::Label # will get assembled as method.cpu_instructions - Positioned.set_position(objekt,at) - when Parfait::BinaryCode - else - Positioned.set_position(objekt,at) - at += objekt.padded_length - end - end - at - end - - def position_code_from( at ) - @objects.each do |id , method| - next unless method.is_a? Parfait::TypedMethod - log.debug "CODE1 #{method.name}" - # create binary for assembly - binary = method.binary - Positioned.set_position(binary,at) - method.cpu_instructions.set_position( at + 12) # BinaryCode header - len = 4 * 14 - at += binary.padded_length - nekst = binary.next - while(nekst) - Positioned.set_position(nekst , at) - at += binary.padded_length - nekst = nekst.next - len += 4 * 16 - #puts "LENGTH #{len}" - end - log.debug "CODE2 #{method.name} at #{Positioned.position(binary)} len: #{len}" - end - at - end - # objects must be written in same order as positioned / assembled def write_as_string - assemble write_debug write_create_binary write_objects diff --git a/lib/risc/instructions/label.rb b/lib/risc/instructions/label.rb index d1df49c2..625950d4 100644 --- a/lib/risc/instructions/label.rb +++ b/lib/risc/instructions/label.rb @@ -54,7 +54,7 @@ module Risc def byte_length 0 end - + alias :padded_length :byte_length end def self.label( source , name , nekst = nil) diff --git a/lib/risc/machine.rb b/lib/risc/machine.rb index 5cc2414d..220ab96a 100644 --- a/lib/risc/machine.rb +++ b/lib/risc/machine.rb @@ -12,7 +12,6 @@ module Risc # class Machine - include Collector include Logging log_level :info @@ -20,13 +19,15 @@ module Risc @booted = false @constants = [] end - attr_reader :constants , :risc_init , :cpu_init , :booted + attr_reader :constants , :risc_init , :cpu_init + attr_reader :booted , :translated # translate to arm, ie instantiate an arm translator and pass it to translate # # currently we have no machanism to translate to other cpu's (nor such translators) # but the mechanism is ready def translate_arm + @translated = true translate(Arm::Translator.new) end @@ -44,8 +45,57 @@ module Risc end end + # machine keeps a list of all objects. this is lazily created with a collector + def objects + @objects ||= Collector.collect_space + end + + def position_all + translate_arm unless @translated + #need the initial jump at 0 and then functions + cpu_init.set_position( 0 ) + at = cpu_init.byte_length + at = position_objects( at ) + # and then everything code + position_code_from( at ) + end + + def position_objects( at ) + at += 8 # thats the padding + # want to have the objects first in the executable + objects.each do | id , objekt| + case objekt + when Parfait::BinaryCode + when Risc::Label + else + Positioned.set_position(objekt,at) + at += objekt.padded_length + end + end + at + end + + def position_code_from( at ) + objects.each do |id , method| + next unless method.is_a? Parfait::TypedMethod + log.debug "CODE1 #{method.name}:#{at}" + method.cpu_instructions.set_position( at + 12) # BinaryCode header + before = at + nekst = method.binary + while(nekst) + Positioned.set_position(nekst , at) + at += nekst.padded_length + nekst = nekst.next + #puts "LENGTH #{len}" + end + log.debug "CODE2 #{method.name}:#{at} len: #{at - before}" + end + at + end + def boot initialize + @objects = nil boot_parfait! @risc_init = Branch.new( "__initial_branch__" , Parfait.object_space.get_init.risc_instructions ) @booted = true diff --git a/test/risc/test_machine.rb b/test/risc/test_machine.rb index e0f1cc1b..37ad8a65 100644 --- a/test/risc/test_machine.rb +++ b/test/risc/test_machine.rb @@ -7,8 +7,17 @@ module Risc @machine = Risc.machine.boot end - def test_co + def test_objects + objects = @machine.objects + assert_equal Hash , objects.class + assert 400 < objects.length + end + def test_position + @machine.position_all + objects = @machine.objects + assert_equal Hash , objects.class + assert 400 < objects.length end end end