start on insertion events and handling
This commit is contained in:
parent
4789b63fcb
commit
c22aff4c4f
@ -22,10 +22,9 @@ module Arm
|
|||||||
end
|
end
|
||||||
|
|
||||||
def insert(instruction)
|
def insert(instruction)
|
||||||
super
|
ret = super
|
||||||
my_pos = Risc::Position.get(self)
|
Risc::Position.get(self).trigger_inserted if Risc::Position.set?(self)
|
||||||
listener = Risc::InstructionListener.new( instruction , my_pos.get_code )
|
ret
|
||||||
my_pos.position_listener(listener)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -19,6 +19,10 @@ module Risc
|
|||||||
@binary = binary
|
@binary = binary
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# if the position of the instruction before us changes, we need to
|
||||||
|
# adjust the position of this instruction accordingly
|
||||||
|
# Taking into account that BinaryCodes only take 13 instructions,
|
||||||
|
# meaning that chain may have to be extended
|
||||||
def position_changed(position)
|
def position_changed(position)
|
||||||
fix_binary
|
fix_binary
|
||||||
my_pos = Position.get(@instruction)
|
my_pos = Position.get(@instruction)
|
||||||
@ -34,6 +38,32 @@ module Risc
|
|||||||
my_pos.set(next_pos)
|
my_pos.set(next_pos)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# When this is called, only the actual insert has happened (keeping the
|
||||||
|
# position logic out of the instruction assembly).
|
||||||
|
#
|
||||||
|
# This event happens at the listener that was dependent on the position
|
||||||
|
# before the insert, ie:
|
||||||
|
# position : the arg is the first instruction in the chain where insert happened
|
||||||
|
# position.object.next : is the newly inserted instruction we need to setup
|
||||||
|
# @instruction : previously dependent on position, now on .next's position
|
||||||
|
#
|
||||||
|
# So we need to :
|
||||||
|
# - move the listener of @instruction to listen to the inserted instruction
|
||||||
|
# - add a listener for the new instruction (to listen to the arg)
|
||||||
|
# - set the new position (moving the chain along)
|
||||||
|
def position_inserted(position)
|
||||||
|
inserted = position.object.next
|
||||||
|
raise "uups" unless inserted ## TODO: remove
|
||||||
|
position.remove_position_listener(InstructionListener)
|
||||||
|
new_pos = Position.get(inserted)
|
||||||
|
new_pos.position_listener(old_listener)
|
||||||
|
|
||||||
|
my_pos = Position.get(@instruction)
|
||||||
|
listen = InstructionListener.new(position.object , @binary)
|
||||||
|
my_pos.position_listener(listen)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
# check that the binary we use is the one where the current position falls
|
# check that the binary we use is the one where the current position falls
|
||||||
# if not move up and register/unregister (soon)
|
# if not move up and register/unregister (soon)
|
||||||
def fix_binary
|
def fix_binary
|
||||||
|
@ -43,6 +43,11 @@ module Risc
|
|||||||
register_event(:position_changed , listener)
|
register_event(:position_changed , listener)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# When instruction get inserted, we have to move listeners around, remove given
|
||||||
|
def remove_position_listener(list)
|
||||||
|
unregister_event(:position_changed, list)
|
||||||
|
end
|
||||||
|
|
||||||
# utility to get all registered listeners to the :position_changed event
|
# utility to get all registered listeners to the :position_changed event
|
||||||
# returns an array
|
# returns an array
|
||||||
def position_listeners
|
def position_listeners
|
||||||
@ -68,6 +73,10 @@ module Risc
|
|||||||
int
|
int
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def trigger_inserted
|
||||||
|
event_table[:position_changed].each { |handler| handler.position_inserted( self) }
|
||||||
|
end
|
||||||
|
|
||||||
def +(offset)
|
def +(offset)
|
||||||
offset = offset.at if offset.is_a?(Position)
|
offset = offset.at if offset.is_a?(Position)
|
||||||
@at + offset
|
@at + offset
|
||||||
|
@ -14,5 +14,10 @@ module Risc
|
|||||||
def initialize(nekst = nil)
|
def initialize(nekst = nil)
|
||||||
@next = nekst
|
@next = nekst
|
||||||
end
|
end
|
||||||
|
def insert(instruction)
|
||||||
|
ret = super
|
||||||
|
Position.get(self).trigger_inserted if Position.set?(self)
|
||||||
|
ret
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -53,24 +53,4 @@ module Risc
|
|||||||
assert_equal Branch , at_8.object.class
|
assert_equal Branch , at_8.object.class
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
class TestInstructionListenerBig < MiniTest::Test
|
|
||||||
def setup
|
|
||||||
Risc.machine.boot
|
|
||||||
@binary = Parfait::BinaryCode.new(1)
|
|
||||||
@bin_pos = Position.new(@binary,0)
|
|
||||||
@instruction = DummyInstruction.new
|
|
||||||
13.times {@instruction.last.insert(DummyInstruction.new) }
|
|
||||||
@position = InstructionListener.init(@instruction , @binary)
|
|
||||||
@position.set(8)
|
|
||||||
end
|
|
||||||
def test_padding
|
|
||||||
assert_equal 64 , @binary.padded_length
|
|
||||||
end
|
|
||||||
def test_last
|
|
||||||
assert_equal 72 , Position.get(@instruction.last).at
|
|
||||||
end
|
|
||||||
def test_next
|
|
||||||
assert @binary.next
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
32
test/risc/position/test_instruction_listener1.rb
Normal file
32
test/risc/position/test_instruction_listener1.rb
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
require_relative "helper"
|
||||||
|
|
||||||
|
module Risc
|
||||||
|
class TestInstructionListenerBig < MiniTest::Test
|
||||||
|
def setup
|
||||||
|
Risc.machine.boot
|
||||||
|
@binary = Parfait::BinaryCode.new(1)
|
||||||
|
@bin_pos = Position.new(@binary,0)
|
||||||
|
@instruction = DummyInstruction.new
|
||||||
|
13.times {@instruction.last.insert(DummyInstruction.new) }
|
||||||
|
@position = InstructionListener.init(@instruction , @binary)
|
||||||
|
@position.set(8)
|
||||||
|
end
|
||||||
|
def test_padding
|
||||||
|
assert_equal 64 , @binary.padded_length
|
||||||
|
end
|
||||||
|
def test_last
|
||||||
|
assert_equal 72 , Position.get(@instruction.last).at
|
||||||
|
end
|
||||||
|
def test_next
|
||||||
|
assert @binary.next
|
||||||
|
end
|
||||||
|
def test_insert_initializes
|
||||||
|
@instruction.insert DummyInstruction.new
|
||||||
|
assert Position.get(@instruction.next)
|
||||||
|
end
|
||||||
|
def pest_insert_pushes
|
||||||
|
@instruction.insert DummyInstruction.new
|
||||||
|
assert_equal 76 , Position.get(@instruction.last).at
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -24,6 +24,9 @@ module Risc
|
|||||||
def test_has_listeners_helper
|
def test_has_listeners_helper
|
||||||
assert_equal Array , @pos.position_listeners.class
|
assert_equal Array , @pos.position_listeners.class
|
||||||
end
|
end
|
||||||
|
def test_has_trigger_inserted
|
||||||
|
assert_equal [] , @pos.trigger_inserted
|
||||||
|
end
|
||||||
def test_listeners_empty
|
def test_listeners_empty
|
||||||
assert @pos.position_listeners.empty?
|
assert @pos.position_listeners.empty?
|
||||||
end
|
end
|
||||||
@ -80,7 +83,7 @@ module Risc
|
|||||||
def test_can_unregister
|
def test_can_unregister
|
||||||
listener = PositionListener.new(self)
|
listener = PositionListener.new(self)
|
||||||
assert @position.position_listener(listener)
|
assert @position.position_listener(listener)
|
||||||
assert @position.unregister_event(:position_changed ,listener)
|
assert @position.remove_position_listener(listener)
|
||||||
end
|
end
|
||||||
def test_fires
|
def test_fires
|
||||||
@object = @instruction
|
@object = @instruction
|
||||||
@ -92,13 +95,22 @@ module Risc
|
|||||||
@object = @instruction
|
@object = @instruction
|
||||||
Position.new(self, 10)
|
Position.new(self, 10)
|
||||||
assert @position.register_event(:position_changed , self)
|
assert @position.register_event(:position_changed , self)
|
||||||
assert @position.unregister_event(:position_changed ,self)
|
assert @position.remove_position_listener(self)
|
||||||
@position.trigger(:position_changed , @position)
|
@position.trigger(:position_changed , @position)
|
||||||
assert_nil @trigger
|
assert_nil @trigger
|
||||||
end
|
end
|
||||||
|
def test_can_trigger_inserted
|
||||||
|
@object = @instruction
|
||||||
|
@position.register_event(:position_changed , self)
|
||||||
|
@position.trigger_inserted
|
||||||
|
assert_equal @position , @trigger
|
||||||
|
end
|
||||||
def position_changed(pos)
|
def position_changed(pos)
|
||||||
@trigger = pos
|
@trigger = pos
|
||||||
end
|
end
|
||||||
|
def position_inserted(pos)
|
||||||
|
@trigger = pos
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user