work on jump insertion continues
Now registering CodeListener instead of PositionListener Also instead of on the previous, in itself, which is simpler and allows to react to insertion at end
This commit is contained in:
parent
7fa8397b56
commit
2d218bbc48
@ -39,11 +39,7 @@ module Parfait
|
|||||||
|
|
||||||
def extend_one()
|
def extend_one()
|
||||||
@next = BinaryCode.new(1)
|
@next = BinaryCode.new(1)
|
||||||
if Risc::Position.set?(self)
|
Risc::Position.get(self).trigger_inserted if Risc::Position.set?(self)
|
||||||
Risc::Position.log.debug "extending one in #{self}"
|
|
||||||
my_pos = Risc::Position.get(self)
|
|
||||||
Risc::CodeListener.init( @next , my_pos + self.padded_length)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def ensure_next
|
def ensure_next
|
||||||
|
@ -121,7 +121,8 @@ module Risc
|
|||||||
Parfait.object_space.types.values.each do |type|
|
Parfait.object_space.types.values.each do |type|
|
||||||
next unless type.methods
|
next unless type.methods
|
||||||
type.methods.each_method do |method|
|
type.methods.each_method do |method|
|
||||||
last_code = CodeListener.init(method.binary , code_start)
|
last_code = CodeListener.init(method.binary)
|
||||||
|
last_code.set(code_start)
|
||||||
first_position = InstructionListener.init(method.cpu_instructions, method.binary)
|
first_position = InstructionListener.init(method.cpu_instructions, method.binary)
|
||||||
first_position.set( code_start + Parfait::BinaryCode.byte_offset)
|
first_position.set( code_start + Parfait::BinaryCode.byte_offset)
|
||||||
last_code.position_listener( prev_code.object) if prev_code
|
last_code.position_listener( prev_code.object) if prev_code
|
||||||
|
@ -9,15 +9,8 @@ module Risc
|
|||||||
#
|
#
|
||||||
class CodeListener
|
class CodeListener
|
||||||
|
|
||||||
attr_reader :code , :method
|
|
||||||
|
|
||||||
def initialize(code , method)
|
|
||||||
super(code,pos)
|
|
||||||
@code = code
|
|
||||||
@method = method
|
|
||||||
raise "Method nil" unless method
|
|
||||||
end
|
|
||||||
def set(at)
|
def set(at)
|
||||||
|
raise "Called"
|
||||||
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)
|
||||||
@ -33,7 +26,9 @@ module Risc
|
|||||||
|
|
||||||
# insert a jump to the next instruction, at the last instruction
|
# insert a jump to the next instruction, at the last instruction
|
||||||
# thus hopping over the object header
|
# thus hopping over the object header
|
||||||
def set_jump(at)
|
def set_jump_for(position)
|
||||||
|
at = position.at
|
||||||
|
code = position.object
|
||||||
jump = Branch.new("BinaryCode #{at.to_s(16)}" , code.next)
|
jump = Branch.new("BinaryCode #{at.to_s(16)}" , code.next)
|
||||||
translator = Risc.machine.platform.translator
|
translator = Risc.machine.platform.translator
|
||||||
cpu_jump = translator.translate(jump)
|
cpu_jump = translator.translate(jump)
|
||||||
@ -42,20 +37,31 @@ module Risc
|
|||||||
cpu_jump.assemble(JumpWriter.new(code))
|
cpu_jump.assemble(JumpWriter.new(code))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def position_inserted(position)
|
||||||
|
Position.log.debug "extending one in #{self}"
|
||||||
|
pos = CodeListener.init( position.object.next )
|
||||||
|
pos.set( position + position.object.padded_length)
|
||||||
|
return unless position.valid?
|
||||||
|
set_jump_for(position)
|
||||||
|
end
|
||||||
|
|
||||||
|
def position_changed(position)
|
||||||
|
return unless position.object.next
|
||||||
|
raise "Called"
|
||||||
|
end
|
||||||
|
|
||||||
# Create Position for the given BinaryCode object
|
# Create Position for the given BinaryCode object
|
||||||
# return the last position that was created, for chaining
|
# return the first position that was created, to set it
|
||||||
def self.init( code , at = -1)
|
def self.init( code )
|
||||||
|
first = nil
|
||||||
while code
|
while code
|
||||||
raise "Not Binary Code #{code.class}" unless code.is_a?(Parfait::BinaryCode)
|
raise "Not Binary Code #{code.class}" unless code.is_a?(Parfait::BinaryCode)
|
||||||
position = Position.new(code , at)
|
position = Position.new(code , -1)
|
||||||
if code.next
|
first = position unless first
|
||||||
listener = PositionListener.new(code.next)
|
position.position_listener(CodeListener.new)
|
||||||
position.position_listener( listener)
|
|
||||||
end
|
|
||||||
at += code.padded_length unless at < 0
|
|
||||||
code = code.next
|
code = code.next
|
||||||
end
|
end
|
||||||
position
|
first
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -20,16 +20,19 @@ module Risc
|
|||||||
def test_init_returns_position
|
def test_init_returns_position
|
||||||
assert_equal Position , CodeListener.init(@binary).class
|
assert_equal Position , CodeListener.init(@binary).class
|
||||||
end
|
end
|
||||||
|
def test_not_init_listner
|
||||||
|
pos = CodeListener.init(@binary)
|
||||||
|
assert CodeListener == pos.event_table[:position_changed].last.class
|
||||||
|
end
|
||||||
def test_init_listner
|
def test_init_listner
|
||||||
@binary.extend_one
|
@binary.extend_one
|
||||||
CodeListener.init(@binary)
|
CodeListener.init(@binary)
|
||||||
pos = Position.get(@binary)
|
pos = Position.get(@binary)
|
||||||
assert !pos.event_table[:position_changed].empty?
|
assert_equal CodeListener , pos.event_table[:position_changed].first.class
|
||||||
end
|
end
|
||||||
def test_not_init_listner
|
def test_extends_creates_jump
|
||||||
|
@binary.extend_one
|
||||||
CodeListener.init(@binary)
|
CodeListener.init(@binary)
|
||||||
pos = Position.get(@binary)
|
|
||||||
assert pos.event_table[:position_changed].empty?
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
26
test/risc/position/test_code_listener1.rb
Normal file
26
test/risc/position/test_code_listener1.rb
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
require_relative "helper"
|
||||||
|
|
||||||
|
module Risc
|
||||||
|
# tests that require a boot and test propagation
|
||||||
|
class TestCodeListenerFull < MiniTest::Test
|
||||||
|
def setup
|
||||||
|
Risc.machine.boot
|
||||||
|
@binary = Parfait::BinaryCode.new(1)
|
||||||
|
@method = Parfait.object_space.types.values.first.methods
|
||||||
|
@label = Risc.label("hi","ho")
|
||||||
|
@machine.translate(:arm)
|
||||||
|
@machine.position_all
|
||||||
|
end
|
||||||
|
def test_listener_after_extend
|
||||||
|
CodeListener.init(@binary).set(0)
|
||||||
|
@binary.extend_one
|
||||||
|
pos = Position.get(@binary.next)
|
||||||
|
assert_equal CodeListener , pos.event_table[:position_changed].first.class
|
||||||
|
end
|
||||||
|
def test_extend_sets_next_pos
|
||||||
|
CodeListener.init(@binary).set(0)
|
||||||
|
@binary.extend_one
|
||||||
|
assert Position.get(@binary.next)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user