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
|
||||
#need the initial jump at 0 and then functions
|
||||
Position.set(cpu_init , 0 , nil)
|
||||
@code_start = position_objects( @platform.padding )
|
||||
code_start = position_objects( @platform.padding )
|
||||
# and then everything code
|
||||
position_code
|
||||
position_code(code_start)
|
||||
end
|
||||
|
||||
# go through everything that is not code (BinaryCode) and set position
|
||||
@ -97,10 +97,13 @@ module Risc
|
||||
def position_objects(at)
|
||||
# want to have the objects first in the executable
|
||||
sorted = objects.values.sort{|left,right| left.class.name <=> right.class.name}
|
||||
previous = nil
|
||||
sorted.each do | objekt|
|
||||
next if objekt.is_a?( Parfait::BinaryCode) or objekt.is_a?( Risc::Label )
|
||||
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
|
||||
log.debug "Object #{objekt.class}:#{before.to_s(16)} len: #{(at - before).to_s(16)}"
|
||||
end
|
||||
@ -112,17 +115,14 @@ module Risc
|
||||
# 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
|
||||
#
|
||||
# start at @code_start. The method is called until
|
||||
# assembly stops throwing errors
|
||||
def position_code
|
||||
at = @code_start
|
||||
# start at code_start.
|
||||
def position_code(code_start)
|
||||
first_method = Parfait.object_space.types.values.first.methods
|
||||
before = at
|
||||
Position.set( first_method.binary , at , first_method)
|
||||
Position.set( first_method.cpu_instructions, at + Parfait::BinaryCode.byte_offset , first_method.binary)
|
||||
log.debug "Method #{first_method.name}:#{before.to_s(16)} len: #{(at - before).to_s(16)}"
|
||||
before = code_start
|
||||
Position.set( first_method.binary , code_start , first_method)
|
||||
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: #{(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)}"
|
||||
at
|
||||
end
|
||||
|
||||
# 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
|
||||
def reset_to(pos , guaranteed_nil )
|
||||
return false if pos == at
|
||||
trigger(:position_changed , self)
|
||||
if((at - pos).abs > 1000)
|
||||
raise "position set too far off #{pos}!=#{at} for #{object}:#{object.class}"
|
||||
end
|
||||
|
@ -105,5 +105,6 @@ module Risc
|
||||
end
|
||||
end
|
||||
require_relative "object_position"
|
||||
require_relative "object_listener"
|
||||
require_relative "instruction_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…
Reference in New Issue
Block a user