rubyx/lib/risc/position.rb
Torsten Ruger 37d62d298e assemble risc to it's position (not itself)
So in the next step the interpreter can use positions as program counter
and would be much more like the real thing
2018-05-17 09:49:01 +03:00

76 lines
2.3 KiB
Ruby

module Risc
# Positions are very different during compilation and run-time.
# At run-time they are inherrent to the object, and fixed.
# While during compilation we can move things about, and do not use the
# objects memory position at all.
#
# Furthermore, there are differnet kind of positions during compilation.
# Off course the object position as hinted above, but also instruction
# positions, that do not reflect the position of the object, but of the
# assembled instruction in the binary.
#
# The Position module keeps a hash of all compile time positions.
#
# While the (different)Position objects transmit the change that (re) positioning
# entails to affected objects.
module Position
@positions = {}
def self.positions
@positions
end
def self.set?(object)
self.positions.has_key?(object)
end
def self.get(object)
pos = self.positions[object]
if pos == nil
str = "position accessed but not set, "
str += "0x#{object.object_id.to_s(16)}\n"
str += "for #{object.class} byte_length #{object.byte_length if object.respond_to?(:byte_length)} for #{object.inspect[0...130]}"
raise str
end
pos
end
# set to the same position as before, thus triggering whatever code that propagates
# position _must have been set, otherwise raises
def self.reset(obj)
old = self.get(obj)
old.reset_to( old.at )
end
def self.set( object , pos , extra = nil)
# resetting of position used to be error, but since relink and dynamic instruction size it is ok.
# in measures (of 32)
#puts "Setting #{pos} for #{self.class}"
old = Position.positions[object]
if old != nil
old.reset_to(pos)
return old
end
position = for_at( object , pos , extra)
self.positions[object] = position
position.init(pos)
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(at,object)
end
end
end
end
require_relative "position/object_position"
require_relative "position/instruction_position"
require_relative "position/code_position"