rubyx/lib/risc/parfait_adapter.rb
Torsten bc558d1f0d do not copy name of method
so that the resolve can compare name identity
which is what is does, not equality
this (and some other bug) is crashing arm currently
2020-03-25 12:43:57 +02:00

152 lines
3.9 KiB
Ruby

require_relative "fake_memory"
module Parfait
class Object
# redefine the runtime version
def self.new( *args )
object = self.allocate
Parfait.set_type_for(object)
object.send :initialize , *args
object
end
# Setter fo the boot process, only at runtime.
# only one space exists and it is generated at compile time, not runtime
def self.set_object_space( space )
@object_space = space
end
end
def self.set_type_for(object)
return unless(Parfait.object_space)
return if(object.is_a?(Symbol))
return if(object.is_a?(::Integer))
name = object.class.name.split("::").last.to_sym
# have to grab the class, because we are in the ruby class not the parfait one
cl = Parfait.object_space.get_class_by_name( name )
# and have to set the type before we let the object do anything. otherwise boom
raise "No such class #{name} for #{object}" unless cl
object.set_type cl.instance_type
end
class Space < Object
# Space can only ever be creared at compile time, not runtime
def initialize( )
@classes = Dictionary.new
@types = Dictionary.new
@factories = Dictionary.new
@true_object = Parfait::TrueClass.new
@false_object = Parfait::FalseClass.new
@nil_object = Parfait::NilClass.new
end
def init_mem(pages)
[:Integer , :ReturnAddress , :Message].each do |fact_name|
for_type = @classes[fact_name].instance_type
page_size = pages[fact_name] || 1024
factory = Factory.new( for_type , page_size )
factory.get_more
@factories[ fact_name ] = factory
end
init_message_chain( factories[ :Message ].reserve )
init_message_chain( factories[ :Message ].next_object )
end
def init_message_chain( message )
prev = nil
while(message)
message.initialize
message._set_caller(prev) if prev
prev = message
message = message.next_message
end
end
end
class DataObject < Object
def self.allocate
r = super
r.instance_variable_set(:@memory , Risc::FakeMemory.new(r ,self.type_length , self.memory_size))
r
end
# 0 -based index
def get_internal_word(index)
return super(index) if index < self.class.type_length
@memory[ index ]
end
# 0 -based index
def set_internal_word(index , value)
return super(index,value) if index < self.class.type_length
@memory[ index ] = value
end
end
class Object
# 0 -based index
def get_internal_word(index)
return @type if index == Parfait::TYPE_INDEX
name = self.type.names[index]
return nil unless name
instance_eval("@#{name}")
end
# 0 -based index
def set_internal_word(index , value)
name = self.type.names[index] #unless name.is_a?(Symbol)
raise "not sym for #{index} in #{self}:#{self.type}:#{name.class}" unless name.is_a?(Symbol)
instance_eval("@#{name}=value" )
value
end
end
# new list from ruby array to be precise
def self.new_list array
list = Parfait::List.new
list.set_length array.length
index = 0
while index < array.length do
list.set(index , array[index])
index = index + 1
end
list
end
def self.new_word_max( string )
return self.new_word(string) if string.length < 20
self.new_word(string[0 ... 20])
end
# Word from string
def self.new_word( string )
# puts "NEW #{string.length}=#{string}"
string = string.to_s if string.is_a? Symbol
word = Word.new( string.length )
string.codepoints.each_with_index do |code , index |
word.set_char(index , code)
end
word
end
end
class Symbol
def has_type?
true
end
def get_type
l = Parfait.object_space.classes[:Word].instance_type
#puts "LL #{l.class}"
l
end
alias :ct_type :get_type
def value
self
end
def padded_length
Parfait::Object.padded( to_s.length + 4)
end
end