2018-05-10 19:56:12 +02:00
|
|
|
module Risc
|
|
|
|
module Position
|
|
|
|
|
2018-05-11 17:36:45 +02:00
|
|
|
# BinaryCodes form a linked list
|
|
|
|
#
|
|
|
|
# We want to keep all code for a method continous, so we propagate Positions
|
|
|
|
#
|
2018-05-13 14:28:10 +02:00
|
|
|
# At the end of the list the propagation spills into the next methods
|
|
|
|
# binary and so on
|
|
|
|
#
|
2018-05-10 19:56:12 +02:00
|
|
|
class CodePosition < ObjectPosition
|
2018-05-11 17:36:45 +02:00
|
|
|
|
2018-05-10 19:56:12 +02:00
|
|
|
attr_reader :code , :method
|
2018-05-11 17:36:45 +02:00
|
|
|
|
2018-05-10 19:56:12 +02:00
|
|
|
def initialize(code, pos , method)
|
2018-05-23 20:34:49 +02:00
|
|
|
super(code,pos)
|
2018-05-10 19:56:12 +02:00
|
|
|
@code = code
|
|
|
|
@method = method
|
2018-05-13 14:28:10 +02:00
|
|
|
raise "Method nil" unless method
|
2018-05-10 19:56:12 +02:00
|
|
|
end
|
2018-05-25 18:03:46 +02:00
|
|
|
def init(at , method)
|
|
|
|
raise "No no" unless method.name == @method.name
|
2018-05-12 17:36:59 +02:00
|
|
|
next_pos = at + code.padded_length
|
|
|
|
if code.next
|
|
|
|
Position.set(code.next , next_pos, method)
|
2018-05-25 18:03:46 +02:00
|
|
|
set_jump(at)
|
2018-05-12 17:36:59 +02:00
|
|
|
else
|
2018-05-13 14:28:10 +02:00
|
|
|
next_meth = next_method
|
|
|
|
return unless next_meth
|
|
|
|
Position.set( next_meth.binary , next_pos , next_meth)
|
2018-05-23 20:34:49 +02:00
|
|
|
next_cpu_pos = next_pos + Parfait::BinaryCode.offset
|
|
|
|
Position.set( next_meth.cpu_instructions, next_cpu_pos , next_meth.binary)
|
2018-05-12 17:36:59 +02:00
|
|
|
end
|
2018-05-10 19:56:12 +02:00
|
|
|
end
|
2018-05-25 18:03:46 +02:00
|
|
|
def reset_to(pos , ignored)
|
|
|
|
init(pos , ignored)
|
2018-05-28 10:45:04 +02:00
|
|
|
super(pos, ignored)
|
2018-05-24 13:27:53 +02:00
|
|
|
Position.log.debug "ResetCode (#{pos.to_s(16)}) #{code}"
|
2018-05-10 19:56:12 +02:00
|
|
|
end
|
2018-05-25 18:03:46 +02:00
|
|
|
# insert a jump to the next instruction, at the last instruction
|
|
|
|
# thus hopping over the object header
|
|
|
|
def set_jump(at)
|
|
|
|
jump = Branch.new("BinaryCode #{at.to_s(16)}" , code.next)
|
|
|
|
translator = Risc.machine.platform.translator
|
|
|
|
cpu_jump = translator.translate(jump)
|
|
|
|
pos = at + code.padded_length - cpu_jump.byte_length
|
|
|
|
Position.set( cpu_jump , pos , code)
|
|
|
|
cpu_jump.assemble(JumpWriter.new(code))
|
|
|
|
end
|
|
|
|
|
2018-05-13 14:28:10 +02:00
|
|
|
def next_method
|
|
|
|
next_m = @method.next_method
|
|
|
|
return next_m if next_m
|
2018-05-23 20:34:49 +02:00
|
|
|
Position.log.debug "Type now #{@method.for_type.name}"
|
2018-05-13 14:28:10 +02:00
|
|
|
type = next_type(@method.for_type)
|
|
|
|
if type
|
2018-05-23 20:34:49 +02:00
|
|
|
Position.log.debug "Position for #{type.name}"
|
2018-05-13 14:28:10 +02:00
|
|
|
return type.methods
|
|
|
|
else
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
def next_type(type)
|
|
|
|
nekst = Parfait.object_space.types.next_value(type)
|
|
|
|
return nil unless nekst
|
|
|
|
return nekst if nekst.methods
|
|
|
|
return next_type(nekst)
|
|
|
|
end
|
2018-05-10 19:56:12 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|