+
+ # This method is called when `current_class` class is moved in attribute table of `self`
+ # *`vm` Running instance of the virtual machine
+ # *`current_class` The class which was moved in `self` structures
+ # *`offset` The offset of block of attributes of `current_class` in `self`
+ fun moved_class_attributes(vm: VirtualMachine, current_class: MClass, offset: Int)
+ do
+ # `current_class` was moved in `self` attribute table
+ if not current_class.positions_attributes.has_key(current_class) then
+ # The invariant position is no longer satisfied
+ current_class.positions_attributes[current_class] = current_class.position_attributes
+ current_class.position_attributes = - current_class.position_attributes
+ else
+ # The class has already several positions and an update is needed
+ current_class.positions_attributes[current_class] = - current_class.positions_attributes[current_class]
+
+ for sub in ordering do
+ if sub == current_class then continue
+
+ var super_id = current_class.vtable.id
+ var mask = sub.vtable.mask
+ vm.load_class(sub)
+
+ if vm.inter_is_subtype_ph(super_id, mask, sub.vtable.internal_vtable) then
+ if not sub.positions_methods.has_key(current_class) then
+ sub.positions_attributes[current_class] = current_class.position_attributes
+ else
+ var old_position = sub.positions_attributes[current_class]
+ if old_position > 0 then
+ # Indicate this class can not used anymore single inheritance implementation
+ sub.positions_attributes[current_class] = - old_position
+ end
+ end
+ end
+ end
+ end
+
+ # Save the position of `current_class` in `self`
+ positions_attributes[current_class] = offset
+ end
+
+ # Return the position of the method's block of class `cl` in `self` if `cl` has an invariant position in self,
+ # Otherwise return a negative position
+ fun get_position_methods(cl: MClass): Int
+ do
+ # The class has an invariant position in all subclasses
+ if cl.position_methods > 0 then return cl.position_methods
+
+ # The position has an invariant position for this class and its subclasses only
+ if positions_methods.has_key(cl) then
+ var pos = positions_methods[cl]
+ if pos > 0 then return pos
+ return -1
+ end
+
+ # No invariant position at all, the caller must use a multiple inheritance implementation
+ return -1
+ end
+
+ # Return the position of the attribute's block of class `cl` in `self` if `cl` has an invariant position in self,
+ # Otherwise return a negative position
+ fun get_position_attributes(cl: MClass): Int
+ do
+ # The class has an invariant position in all subclasses
+ if cl.position_attributes > 0 then return cl.position_attributes
+
+ # The position has an invariant position for this class and its subclasses only
+ if positions_attributes.has_key(cl) then
+ var pos = positions_attributes[cl]
+ if pos > 0 then return pos
+ return -1
+ end
+
+ # No invariant position at all, the caller must use a multiple inheritance implementation
+ return -1
+ end
+end
+
+redef class MProperty
+ # Relative offset of this in the runtime instance
+ # (beginning of the block of its introducing class for attributes or methods)
+ var offset: Int