adds the simple object dependency
where the next object is dependent on the previous one and just behind it, the padded_length away
This commit is contained in:
parent
21a9c56ba9
commit
46fbfb7101
@ -86,9 +86,9 @@ module Risc
|
|||||||
raise "Not translated " unless @translated
|
raise "Not translated " unless @translated
|
||||||
#need the initial jump at 0 and then functions
|
#need the initial jump at 0 and then functions
|
||||||
Position.set(cpu_init , 0 , nil)
|
Position.set(cpu_init , 0 , nil)
|
||||||
@code_start = position_objects( @platform.padding )
|
code_start = position_objects( @platform.padding )
|
||||||
# and then everything code
|
# and then everything code
|
||||||
position_code
|
position_code(code_start)
|
||||||
end
|
end
|
||||||
|
|
||||||
# go through everything that is not code (BinaryCode) and set position
|
# go through everything that is not code (BinaryCode) and set position
|
||||||
@ -97,10 +97,13 @@ module Risc
|
|||||||
def position_objects(at)
|
def position_objects(at)
|
||||||
# want to have the objects first in the executable
|
# want to have the objects first in the executable
|
||||||
sorted = objects.values.sort{|left,right| left.class.name <=> right.class.name}
|
sorted = objects.values.sort{|left,right| left.class.name <=> right.class.name}
|
||||||
|
previous = nil
|
||||||
sorted.each do | objekt|
|
sorted.each do | 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 )
|
||||||
before = at
|
before = at
|
||||||
Position.set(objekt,at)
|
position = Position.set(objekt,at)
|
||||||
|
previous.register_event(:position_changed , Position::ObjectListener.new(objekt)) if previous
|
||||||
|
previous = position
|
||||||
at += objekt.padded_length
|
at += objekt.padded_length
|
||||||
log.debug "Object #{objekt.class}:#{before.to_s(16)} len: #{(at - before).to_s(16)}"
|
log.debug "Object #{objekt.class}:#{before.to_s(16)} len: #{(at - before).to_s(16)}"
|
||||||
end
|
end
|
||||||
@ -112,17 +115,14 @@ module Risc
|
|||||||
# So that all code from one method is layed out linearly (for debugging)
|
# 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
|
# we go through methods, and then through all codes from the method
|
||||||
#
|
#
|
||||||
# start at @code_start. The method is called until
|
# start at code_start.
|
||||||
# assembly stops throwing errors
|
def position_code(code_start)
|
||||||
def position_code
|
|
||||||
at = @code_start
|
|
||||||
first_method = Parfait.object_space.types.values.first.methods
|
first_method = Parfait.object_space.types.values.first.methods
|
||||||
before = at
|
before = code_start
|
||||||
Position.set( first_method.binary , at , first_method)
|
Position.set( first_method.binary , code_start , first_method)
|
||||||
Position.set( first_method.cpu_instructions, at + Parfait::BinaryCode.byte_offset , first_method.binary)
|
Position.set( first_method.cpu_instructions, code_start + Parfait::BinaryCode.byte_offset , first_method.binary)
|
||||||
log.debug "Method #{first_method.name}:#{before.to_s(16)} len: #{(at - before).to_s(16)}"
|
log.debug "Method #{first_method.name}:#{before.to_s(16)} len: #{(code_start - before).to_s(16)}"
|
||||||
log.debug "Instructions #{first_method.cpu_instructions.object_id.to_s(16)}:#{(before+Parfait::BinaryCode.byte_offset).to_s(16)}"
|
log.debug "Instructions #{first_method.cpu_instructions.object_id.to_s(16)}:#{(before+Parfait::BinaryCode.byte_offset).to_s(16)}"
|
||||||
at
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Create Binary code for all methods and the initial jump
|
# Create Binary code for all methods and the initial jump
|
||||||
|
31
lib/risc/position/object_listener.rb
Normal file
31
lib/risc/position/object_listener.rb
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
module Risc
|
||||||
|
module Position
|
||||||
|
|
||||||
|
# Listeners localise the changes that need to happen.
|
||||||
|
#
|
||||||
|
# An object listener assmes it is set up to the previous object.
|
||||||
|
# so when position changes, it places itself just behind the previous object
|
||||||
|
#
|
||||||
|
# This is handy, since the "normal" chaining of object is forward
|
||||||
|
# But the dependencies are backwards. This way we don't clutter the
|
||||||
|
# actual object (or even the position), but keep the logic seperate.
|
||||||
|
class ObjectListener
|
||||||
|
|
||||||
|
# initialize with the object that needs to react to change
|
||||||
|
def initialize(object)
|
||||||
|
@object = object
|
||||||
|
end
|
||||||
|
|
||||||
|
# when the argument changes position, we update the objects
|
||||||
|
# position to reflect that change
|
||||||
|
#
|
||||||
|
def position_changed(previous)
|
||||||
|
me = previous.at + previous.object.padded_length
|
||||||
|
object_pos = Position.get(@object)
|
||||||
|
return if me == object_pos.at
|
||||||
|
Position.set(@object , me)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -31,6 +31,7 @@ module Risc
|
|||||||
end
|
end
|
||||||
def reset_to(pos , guaranteed_nil )
|
def reset_to(pos , guaranteed_nil )
|
||||||
return false if pos == at
|
return false if pos == at
|
||||||
|
trigger(:position_changed , self)
|
||||||
if((at - pos).abs > 1000)
|
if((at - pos).abs > 1000)
|
||||||
raise "position set too far off #{pos}!=#{at} for #{object}:#{object.class}"
|
raise "position set too far off #{pos}!=#{at} for #{object}:#{object.class}"
|
||||||
end
|
end
|
||||||
|
@ -105,5 +105,6 @@ module Risc
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
require_relative "object_position"
|
require_relative "object_position"
|
||||||
|
require_relative "object_listener"
|
||||||
require_relative "instruction_position"
|
require_relative "instruction_position"
|
||||||
require_relative "code_position"
|
require_relative "code_position"
|
||||||
|
34
test/risc/position/test_object_listener.rb
Normal file
34
test/risc/position/test_object_listener.rb
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
require_relative "../helper"
|
||||||
|
|
||||||
|
module Risc
|
||||||
|
module Position
|
||||||
|
class Dummy
|
||||||
|
def padded_length
|
||||||
|
4
|
||||||
|
end
|
||||||
|
end
|
||||||
|
class TestObjectListener < MiniTest::Test
|
||||||
|
|
||||||
|
def setup
|
||||||
|
@object = Dummy.new
|
||||||
|
@dependent = Dummy.new
|
||||||
|
@pos = Position.set(@object,0)
|
||||||
|
Position.set(@dependent,0)
|
||||||
|
@listener = ObjectListener.new(@dependent)
|
||||||
|
end
|
||||||
|
def test_register
|
||||||
|
assert @pos.register_event(:position_changed , @listener)
|
||||||
|
end
|
||||||
|
def test_no_fire
|
||||||
|
@pos.register_event(:position_changed , self)
|
||||||
|
@pos = Position.set(@object,0)
|
||||||
|
assert_equal 0 , Position.get(@dependent).at
|
||||||
|
end
|
||||||
|
def test_reset
|
||||||
|
@pos.register_event(:position_changed , @listener)
|
||||||
|
@pos = Position.set(@object,4)
|
||||||
|
assert_equal 4 , Position.get(@dependent).at
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
x
Reference in New Issue
Block a user