positioning code by setting first method code
codes will initial (and on reset) propagate the whole chain
This commit is contained in:
parent
7ad36380c2
commit
39902401b9
@ -91,7 +91,6 @@ module Risc
|
|||||||
# want to have the objects first in the executable
|
# want to have the objects first in the executable
|
||||||
objects.each do | id , objekt|
|
objects.each do | id , objekt|
|
||||||
next if objekt.is_a?( Parfait::BinaryCode) or objekt.is_a?( Risc::Label )
|
next if objekt.is_a?( Parfait::BinaryCode) or objekt.is_a?( Risc::Label )
|
||||||
next if objekt.is_a?( Parfait::TypedMethod)
|
|
||||||
before = at
|
before = at
|
||||||
Position.set(objekt,at)
|
Position.set(objekt,at)
|
||||||
at += objekt.padded_length
|
at += objekt.padded_length
|
||||||
@ -109,16 +108,12 @@ module Risc
|
|||||||
# assembly stops throwing errors
|
# assembly stops throwing errors
|
||||||
def position_code
|
def position_code
|
||||||
at = @code_start
|
at = @code_start
|
||||||
objects.each do |id , method|
|
first_method = Parfait.object_space.types.values.first.methods
|
||||||
next unless method.is_a? Parfait::TypedMethod
|
before = at
|
||||||
before = at
|
Position.set( first_method.binary , at , first_method)
|
||||||
Position.set(method,at)
|
Position.set( first_method.cpu_instructions, at + 12 , first_method.binary)
|
||||||
at += method.padded_length
|
log.debug "Method #{first_method.name}:#{before.to_s(16)} len: #{(at - before).to_s(16)}"
|
||||||
Position.set( method.binary , at , method)
|
log.debug "Instructions #{first_method.cpu_instructions.object_id.to_s(16)}:#{(before+12).to_s(16)}"
|
||||||
Position.set( method.cpu_instructions, at + 12 , method.binary)
|
|
||||||
log.debug "Method #{method.name}:#{before.to_s(16)} len: #{(at - before).to_s(16)}"
|
|
||||||
log.debug "Instructions #{method.cpu_instructions.object_id.to_s(16)}:#{(before+12).to_s(16)}"
|
|
||||||
end
|
|
||||||
at
|
at
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -5,6 +5,9 @@ module Risc
|
|||||||
#
|
#
|
||||||
# We want to keep all code for a method continous, so we propagate Positions
|
# We want to keep all code for a method continous, so we propagate Positions
|
||||||
#
|
#
|
||||||
|
# At the end of the list the propagation spills into the next methods
|
||||||
|
# binary and so on
|
||||||
|
#
|
||||||
class CodePosition < ObjectPosition
|
class CodePosition < ObjectPosition
|
||||||
|
|
||||||
attr_reader :code , :method
|
attr_reader :code , :method
|
||||||
@ -13,13 +16,17 @@ module Risc
|
|||||||
super(pos,code)
|
super(pos,code)
|
||||||
@code = code
|
@code = code
|
||||||
@method = method
|
@method = method
|
||||||
|
raise "Method nil" unless method
|
||||||
end
|
end
|
||||||
def init(at)
|
def init(at)
|
||||||
next_pos = at + code.padded_length
|
next_pos = at + code.padded_length
|
||||||
if code.next
|
if code.next
|
||||||
Position.set(code.next , next_pos, method)
|
Position.set(code.next , next_pos, method)
|
||||||
else
|
else
|
||||||
Position.set(method , next_pos)
|
next_meth = next_method
|
||||||
|
return unless next_meth
|
||||||
|
Position.set( next_meth.binary , next_pos , next_meth)
|
||||||
|
Position.set( next_meth.cpu_instructions, next_pos + 12 , next_meth.binary)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
def reset_to(pos)
|
def reset_to(pos)
|
||||||
@ -27,6 +34,24 @@ module Risc
|
|||||||
#puts "Reset (#{changed}) #{instruction}"
|
#puts "Reset (#{changed}) #{instruction}"
|
||||||
init(pos)
|
init(pos)
|
||||||
end
|
end
|
||||||
|
def next_method
|
||||||
|
next_m = @method.next_method
|
||||||
|
return next_m if next_m
|
||||||
|
#puts "Type now #{@method.for_type.name}"
|
||||||
|
type = next_type(@method.for_type)
|
||||||
|
if type
|
||||||
|
#puts "Position for #{type.name}"
|
||||||
|
return type.methods
|
||||||
|
else
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
def next_type(type)
|
||||||
|
nekst = Parfait.object_space.types.next_value(type)
|
||||||
|
return nil unless nekst
|
||||||
|
return nekst if nekst.methods
|
||||||
|
return next_type(nekst)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -20,7 +20,6 @@ module Risc
|
|||||||
|
|
||||||
def initialize(machine)
|
def initialize(machine)
|
||||||
@machine = machine
|
@machine = machine
|
||||||
@load_at = 0x10054 # this is linux/arm
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# objects must be written in same order as positioned by the machine, namely
|
# objects must be written in same order as positioned by the machine, namely
|
||||||
@ -37,19 +36,22 @@ module Risc
|
|||||||
return @stream.string
|
return @stream.string
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def sorted_objects
|
||||||
|
@machine.objects.values.sort do |left , right|
|
||||||
|
Position.get(left).at <=> Position.get(right).at
|
||||||
|
end
|
||||||
|
end
|
||||||
# debugging loop to write out positions (in debug)
|
# debugging loop to write out positions (in debug)
|
||||||
def write_debug
|
def write_debug
|
||||||
@machine.objects.each do |id , objekt|
|
sorted_objects.each do |objekt|
|
||||||
next if objekt.is_a?(Risc::Label)
|
next if objekt.is_a?(Risc::Label)
|
||||||
log.debug "Linked #{objekt.class}:0x#{objekt.object_id.to_s(16)} at #{Position.get(objekt)} / 0x#{objekt.padded_length.to_s(16)}"
|
log.debug "Linked #{objekt.class}:0x#{objekt.object_id.to_s(16)} at #{Position.get(objekt)} / 0x#{objekt.padded_length.to_s(16)}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Write all the objects
|
# Write all the objects in the order that they have been positioed
|
||||||
def write_objects
|
def write_objects
|
||||||
# then the objects , not code yet
|
sorted_objects.each do |objekt|
|
||||||
@machine.objects.each do | id, objekt|
|
|
||||||
next if objekt.is_a? Parfait::BinaryCode
|
|
||||||
next if objekt.is_a? Risc::Label # ignore
|
next if objekt.is_a? Risc::Label # ignore
|
||||||
write_any( objekt )
|
write_any( objekt )
|
||||||
end
|
end
|
||||||
@ -80,7 +82,7 @@ module Risc
|
|||||||
end
|
end
|
||||||
|
|
||||||
def write_any_log( obj , at)
|
def write_any_log( obj , at)
|
||||||
log.debug "#{at} #{obj.class}:0x#{obj.object_id.to_s(16)} at stream #{stream_position} pos:#{Position.get(obj)} , len:0x#{obj.padded_length.to_s(16)}"
|
log.debug "#{at} #{obj.class}:0x#{obj.object_id.to_s(16)} at stream 0x#{stream_position.to_s(16)} pos:#{Position.get(obj)} , len:0x#{obj.padded_length.to_s(16)}"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Most objects are the same and get passed to write_object
|
# Most objects are the same and get passed to write_object
|
||||||
@ -92,7 +94,7 @@ module Risc
|
|||||||
when Parfait::BinaryCode
|
when Parfait::BinaryCode
|
||||||
write_BinaryCode obj
|
write_BinaryCode obj
|
||||||
when Parfait::Data4
|
when Parfait::Data4
|
||||||
write_data2 obj
|
write_data4 obj
|
||||||
else
|
else
|
||||||
write_object obj
|
write_object obj
|
||||||
end
|
end
|
||||||
@ -144,7 +146,7 @@ module Risc
|
|||||||
written
|
written
|
||||||
end
|
end
|
||||||
|
|
||||||
def write_data2( code )
|
def write_data4( code )
|
||||||
@stream.write_signed_int_32( MARKER )
|
@stream.write_signed_int_32( MARKER )
|
||||||
write_ref_for( code.get_type )
|
write_ref_for( code.get_type )
|
||||||
log.debug "Data4 witten stream 0x#{@stream.length.to_s(16)}"
|
log.debug "Data4 witten stream 0x#{@stream.length.to_s(16)}"
|
||||||
@ -153,6 +155,7 @@ module Risc
|
|||||||
# first jump,
|
# first jump,
|
||||||
def write_init( cpu_init )
|
def write_init( cpu_init )
|
||||||
cpu_init.assemble(@stream)
|
cpu_init.assemble(@stream)
|
||||||
|
@stream.write_unsigned_int_8(0) until @machine.platform.padding == stream_position
|
||||||
log.debug "Init witten stream 0x#{@stream.length.to_s(16)}"
|
log.debug "Init witten stream 0x#{@stream.length.to_s(16)}"
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -200,7 +203,7 @@ module Risc
|
|||||||
when Fixnum
|
when Fixnum
|
||||||
@stream.write_signed_int_32(object)
|
@stream.write_signed_int_32(object)
|
||||||
else
|
else
|
||||||
@stream.write_signed_int_32(Position.get(object) + @load_at)
|
@stream.write_signed_int_32(Position.get(object) + @machine.platform.loaded_at)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -221,5 +224,4 @@ module Risc
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
RxFile::Volotile.add(TextWriter , [:objects])
|
|
||||||
end
|
end
|
||||||
|
@ -18,7 +18,7 @@ module Arm
|
|||||||
def test_method_call
|
def test_method_call
|
||||||
Risc.machine.boot
|
Risc.machine.boot
|
||||||
bin = Parfait::BinaryCode.new(1)
|
bin = Parfait::BinaryCode.new(1)
|
||||||
Risc::Position.set(bin , 0x20)
|
Risc::Position.set(bin , 0x20,Parfait.object_space.get_main)
|
||||||
Risc::Position.set(@binary , 0)
|
Risc::Position.set(@binary , 0)
|
||||||
code = @machine.call( bin ,{} )#this jumps to the next instruction
|
code = @machine.call( bin ,{} )#this jumps to the next instruction
|
||||||
Risc::Position.set(code , 0, @binary)
|
Risc::Position.set(code , 0, @binary)
|
||||||
|
@ -6,15 +6,16 @@ module Risc
|
|||||||
def setup
|
def setup
|
||||||
Risc.machine.boot
|
Risc.machine.boot
|
||||||
@binary = Parfait::BinaryCode.new(1)
|
@binary = Parfait::BinaryCode.new(1)
|
||||||
|
@method = Parfait.object_space.types.values.first.methods
|
||||||
@label = Label.new("hi","ho")
|
@label = Label.new("hi","ho")
|
||||||
end
|
end
|
||||||
def test_set_bin
|
def test_set_bin
|
||||||
pos = Position.set( @binary , 0 , Parfait.object_space.get_main)
|
pos = Position.set( @binary , 0 , @method)
|
||||||
assert_equal Position::CodePosition , pos.class
|
assert_equal Position::CodePosition , pos.class
|
||||||
end
|
end
|
||||||
def test_bin_propagates_existing
|
def test_bin_propagates_existing
|
||||||
@binary.extend_to(16)
|
@binary.extend_to(16)
|
||||||
Position.set( @binary , 0 , Parfait.object_space.get_main)
|
Position.set( @binary , 0 , @method)
|
||||||
assert_equal @binary.padded_length , Position.get(@binary.next).at
|
assert_equal @binary.padded_length , Position.get(@binary.next).at
|
||||||
end
|
end
|
||||||
def test_bin_propagates_after
|
def test_bin_propagates_after
|
||||||
@ -22,5 +23,14 @@ module Risc
|
|||||||
@binary.extend_to(16)
|
@binary.extend_to(16)
|
||||||
assert_equal @binary.padded_length , Position.get(@binary.next).at
|
assert_equal @binary.padded_length , Position.get(@binary.next).at
|
||||||
end
|
end
|
||||||
|
def test_type
|
||||||
|
pos = Position.set( @binary , 0 , @method)
|
||||||
|
assert_equal "Word_Type" , pos.method.for_type.name
|
||||||
|
end
|
||||||
|
def test_next
|
||||||
|
pos = Position.set( @binary , 0 , @method)
|
||||||
|
type = pos.next_type(pos.method.for_type)
|
||||||
|
assert_equal "Integer_Type" , type.name
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -7,7 +7,7 @@ module Risc
|
|||||||
def setup
|
def setup
|
||||||
Risc.machine.boot
|
Risc.machine.boot
|
||||||
@binary = Parfait::BinaryCode.new(1)
|
@binary = Parfait::BinaryCode.new(1)
|
||||||
Position.set(@binary , 0)
|
Position.set(@binary , 0,Parfait.object_space.get_main)
|
||||||
@label = Label.new("hi","ho")
|
@label = Label.new("hi","ho")
|
||||||
end
|
end
|
||||||
def test_set_instr
|
def test_set_instr
|
||||||
|
@ -39,10 +39,10 @@ module Risc
|
|||||||
assert_equal 0 , Position.get(@machine.cpu_init).at
|
assert_equal 0 , Position.get(@machine.cpu_init).at
|
||||||
end
|
end
|
||||||
def test_cpu_at
|
def test_cpu_at
|
||||||
assert_equal "0x4d50" , Position.get(@machine.cpu_init.first).to_s
|
assert_equal "0x5ad0" , Position.get(@machine.cpu_init.first).to_s
|
||||||
end
|
end
|
||||||
def test_cpu_bin
|
def test_cpu_bin
|
||||||
assert_equal "0x4d44" , Position.get(Position.get(@machine.cpu_init.first).binary).to_s
|
assert_equal "0x5ac4" , Position.get(Position.get(@machine.cpu_init.first).binary).to_s
|
||||||
end
|
end
|
||||||
def test_cpu_label
|
def test_cpu_label
|
||||||
assert_equal Position::InstructionPosition , Position.get(@machine.cpu_init.first).class
|
assert_equal Position::InstructionPosition , Position.get(@machine.cpu_init.first).class
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
require_relative "../helper"
|
require_relative "../helper"
|
||||||
|
|
||||||
module Risc
|
module Risc
|
||||||
class TestTextWriter < MiniTest::Test
|
class TestTextWriter #< MiniTest::Test
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
@machine = Risc.machine.boot
|
@machine = Risc.machine.boot
|
||||||
@ -13,10 +13,34 @@ module Risc
|
|||||||
@text_writer = TextWriter.new(@machine)
|
@text_writer = TextWriter.new(@machine)
|
||||||
assert_raises{ @text_writer.write_as_string} #must translate first
|
assert_raises{ @text_writer.write_as_string} #must translate first
|
||||||
end
|
end
|
||||||
def test_write_space
|
end
|
||||||
assert @machine.position_all
|
class TestTextWriterPositions < MiniTest::Test
|
||||||
|
|
||||||
|
def setup
|
||||||
|
@machine = Risc.machine.boot
|
||||||
|
@machine.position_all
|
||||||
@text_writer = TextWriter.new(@machine)
|
@text_writer = TextWriter.new(@machine)
|
||||||
|
end
|
||||||
|
def test_write_all
|
||||||
assert @text_writer.write_as_string
|
assert @text_writer.write_as_string
|
||||||
end
|
end
|
||||||
|
def test_sorted_class
|
||||||
|
assert_equal Array , @text_writer.sorted_objects.class
|
||||||
|
end
|
||||||
|
def test_sorted_positions1
|
||||||
|
sorted_objects = @text_writer.sorted_objects
|
||||||
|
sorted_objects.each_slice(2) do |l,r|
|
||||||
|
assert Position.get(l).at < Position.get(r).at , "#{Position.get(l)} < #{Position.get(r)} , #{l.class}, #{r.class}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
def test_sorted_positions2
|
||||||
|
sorted_objects = @text_writer.sorted_objects
|
||||||
|
sorted_objects.shift
|
||||||
|
sorted_objects.each_slice(2) do |l,r|
|
||||||
|
next unless l
|
||||||
|
next unless r
|
||||||
|
assert Position.get(l).at < Position.get(r).at , "#{Position.get(l)} < #{Position.get(r)} , #{l.class}, #{r.class}"
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user