rubyx/lib/register/parfait/layout.rb
Torsten Ruger 979660f282 move parfait into register
register layer uses parfait models to generate object space
so parfait  should be part of register (not above it)
2015-11-18 12:04:25 +02:00

106 lines
3.0 KiB
Ruby

# An Object is really a hash like structure. It is dynamic and
# you want to store values by name (instance variable names).
#
# One could (like mri), store the names in each object, but that is wasteful
# Instead we store only the values, and access them by index.
# The Layout allows the mapping of names to index.
# The Layout of an object describes the memory layout of the object
# The Layout is a simple list of the names of instance variables.
#
# As every object has a Layout to describe it, the name "layout" is the
# first name in the list for every Layout.
# But as we want every Object to have a class, the Layout carries that class.
# So the layout of layout has an entry "object_class"
# But Objects must also be able to carry methods themselves (ruby calls singleton_methods)
# and those too are stored in the Layout (both layout and class include behaviour)
# In other words, the Layout is a list of names that describe
# the values stored in an actual object.
# The object is an List of values of length n and
# the Layout is an List of names of length n , plus class reference and methods reference
# Together they turn the object into a hash like structure
module Parfait
class Layout < Object
attribute :object_class
include Behaviour
include Indexed
self.offset(3)
def initialize( object_class )
super()
add_instance_variable :layout ,:Layout
self.object_class = object_class
end
def == other
self.object_id == other.object_id
end
# add the name of an instance variable
# The index will be returned and can subsequently be searched with index_of
# The index of the name is the index of the data in the object
#
# TODO , later we would need to COPY the layout to keep the old constant
# but now we are concerned with booting, ie getting a working structure
def add_instance_variable name , type
raise "Name shouldn't be nil" unless name
raise "Type shouldn't be nil" unless type
self.push(name)
self.push(type)
self.get_length
end
def instance_names
names = List.new
name = true
each do |item|
names.push(item) if name
name = ! name
end
names
end
def instance_length
(self.get_length / 2).to_i # to_i for opal
end
alias :super_index :index_of
def index_of(name)
raise "Use variable_index instead"
end
# index of the variable when using get_internal
# (get_internal is 1 based and 1 is always the layout)
def variable_index name
has = super_index(name)
return nil unless has
raise "internal error #{name}:#{has}" if has < 1
(1 + has / 2).to_i # to_i for opal
end
def type_at index
type_index = index * 2
get(type_index)
end
def inspect
"Layout[#{super}]"
end
def sof_reference_name
"#{self.object_class.name}_Layout"
end
alias :name :sof_reference_name
def super_class_name
nil # stop resolve recursing up metaclasses
end
end
end