positioning wip
This commit is contained in:
@ -12,14 +12,13 @@ module Risc
|
||||
|
||||
attr_reader :code , :method
|
||||
|
||||
def initialize(code, pos , method)
|
||||
def initialize(code , method)
|
||||
super(code,pos)
|
||||
@code = code
|
||||
@method = method
|
||||
raise "Method nil" unless method
|
||||
end
|
||||
def init(at , method)
|
||||
raise "No no" unless method.name == @method.name
|
||||
def set(at )
|
||||
next_pos = at + code.padded_length
|
||||
if code.next
|
||||
Position.set(code.next , next_pos, method)
|
||||
@ -32,11 +31,7 @@ module Risc
|
||||
Position.set( next_meth.cpu_instructions, next_cpu_pos , next_meth.binary)
|
||||
end
|
||||
end
|
||||
def reset_to(pos , ignored)
|
||||
super(pos, ignored)
|
||||
init(pos , ignored)
|
||||
Position.log.debug "ResetCode (#{pos.to_s(16)}) #{code}"
|
||||
end
|
||||
|
||||
# insert a jump to the next instruction, at the last instruction
|
||||
# thus hopping over the object header
|
||||
def set_jump(at)
|
||||
|
@ -16,9 +16,9 @@ module Risc
|
||||
#
|
||||
class InstructionPosition < ObjectPosition
|
||||
attr_reader :instruction , :binary
|
||||
def initialize(instruction, pos , binary)
|
||||
raise "not set #{binary}" if pos != 0 and !binary.is_a?(Parfait::BinaryCode)
|
||||
super(instruction,pos)
|
||||
def initialize(instruction , binary)
|
||||
pos = 0
|
||||
super(instruction)
|
||||
@instruction = instruction
|
||||
@binary = binary
|
||||
end
|
||||
@ -47,6 +47,25 @@ module Risc
|
||||
init(pos , binary)
|
||||
Position.log.debug "ResetInstruction (#{pos.to_s(16)}) #{instruction}"
|
||||
end
|
||||
|
||||
# initialize the dependency graph for instructions
|
||||
#
|
||||
# starting from the given instruction, create InstructionPositions
|
||||
# for it and the whole chain
|
||||
#
|
||||
# Set the next created to be dependent on the previous
|
||||
def self.init( instruction , code)
|
||||
while(instruction)
|
||||
position = InstructionPosition.new(instruction , code)
|
||||
nekst = instruction.next
|
||||
if nekst
|
||||
listener = InstructionListener.new( nekst )
|
||||
position.register_event(:position_changed , listener)
|
||||
end
|
||||
instruction = nekst
|
||||
end
|
||||
position
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -7,11 +7,13 @@ module Risc
|
||||
|
||||
attr_reader :at , :object
|
||||
|
||||
def initialize( object, at)
|
||||
@at = at
|
||||
# initialize with a given object, first parameter
|
||||
# The object ill be the key in global position map
|
||||
# Give an integer as the actual position, where -1
|
||||
# which means no legal position known
|
||||
def initialize(object , pos )
|
||||
@at = 0
|
||||
@object = object
|
||||
@listeners = []
|
||||
raise "not int #{self}-#{at}" unless @at.is_a?(Integer)
|
||||
end
|
||||
|
||||
def +(offset)
|
||||
@ -31,13 +33,17 @@ 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
|
||||
@at = pos
|
||||
trigger(:position_changed , self)
|
||||
true
|
||||
end
|
||||
def self.init(object , at = -1)
|
||||
position = ObjectPosition.new(object , at)
|
||||
Position.set_to( position , at)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -56,52 +56,19 @@ module Risc
|
||||
old.reset_to( old.at )
|
||||
end
|
||||
|
||||
# resetting of position used to be error, but since relink and dynamic instruction size it is ok.
|
||||
# in measures
|
||||
#
|
||||
# reseting to the same position as before, triggers code that propagates
|
||||
def self.reset(position , to , extra)
|
||||
log.debug "ReSetting #{position}, to:#{to.to_s(16)}, for #{position.object.class}-#{position.object}"
|
||||
position.reset_to(to, extra)
|
||||
if testing = @reverse_cache[ to ]
|
||||
if testing.class != position.class
|
||||
raise "Mismatch (at #{to.to_s(16)}) new:#{position}:#{position.class} , was #{testing}:#{testing.class}"
|
||||
end
|
||||
end
|
||||
unless position.object.is_a? Label
|
||||
@reverse_cache.delete(to)
|
||||
@reverse_cache[position.at] = position
|
||||
end
|
||||
log.debug "Reset #{position} (#{to.to_s(16)}) for #{position.class}"
|
||||
return position
|
||||
end
|
||||
|
||||
def self.set( object , pos , extra = nil)
|
||||
old = Position.positions[object]
|
||||
return self.reset(old , pos , extra) if old
|
||||
log.debug "Setting #{pos.to_s(16)} for #{object.class}-#{object}"
|
||||
testing = self.at( pos )
|
||||
position = for_at( object , pos , extra)
|
||||
def self.set_to( position , to)
|
||||
postest = Position.positions[position.object]
|
||||
raise "Mismatch #{position}" if postest and postest != position
|
||||
@reverse_cache.delete(position.at) unless position.object.is_a? Label
|
||||
testing = self.at( position.at ) if position.at >= 0
|
||||
if testing and testing.class != position.class
|
||||
raise "Mismatch (at #{pos.to_s(16)}) was:#{position} #{position.class} #{position.object} , should #{testing}#{testing.class}"
|
||||
end
|
||||
self.positions[object] = position
|
||||
position.init(pos , extra)
|
||||
@reverse_cache[position.at] = position unless object.is_a? Label
|
||||
log.debug "Set #{position} (#{pos.to_s(16)}) for #{position.class}"
|
||||
self.positions[position.object] = position
|
||||
@reverse_cache[to] = position unless position.object.is_a? Label
|
||||
log.debug "Set #{position} (#{to.to_s(16)}) for #{position.class}"
|
||||
position
|
||||
end
|
||||
|
||||
def self.for_at(object , at , extra)
|
||||
case object
|
||||
when Parfait::BinaryCode
|
||||
CodePosition.new(object,at , extra)
|
||||
when Arm::Instruction , Risc::Instruction
|
||||
InstructionPosition.new(object,at , extra)
|
||||
else
|
||||
ObjectPosition.new(object,at)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
require_relative "object_position"
|
||||
|
Reference in New Issue
Block a user