+
+ # Return the value of the attribute `mproperty` for the object `recv`
+ redef fun read_attribute(mproperty: MAttribute, recv: Instance): Instance
+ do
+ assert recv isa MutableInstance
+
+ # Read the attribute value with perfect hashing
+ var id = mproperty.intro_mclassdef.mclass.vtable.id
+
+ var i = read_attribute_ph(recv.internal_attributes, recv.vtable.internal_vtable,
+ recv.vtable.mask, id, mproperty.offset)
+
+ # If we get a `MInit` value, throw an error
+ if i == initialization_value then
+ fatal("Uninitialized attribute {mproperty.name}")
+ abort
+ end
+
+ return i
+ end
+
+ # Return the attribute value in `instance` with a sequence of perfect_hashing
+ # `instance` is the attributes array of the receiver
+ # `vtable` is the pointer to the virtual table of the class (of the receiver)
+ # `mask` is the perfect hashing mask of the class
+ # `id` is the identifier of the class
+ # `offset` is the relative offset of this attribute
+ private fun read_attribute_ph(instance: Pointer, vtable: Pointer, mask: Int, id: Int, offset: Int): Instance `{
+ // Perfect hashing position
+ int hv = mask & id;
+ long unsigned int *pointer = (long unsigned int*)(((long int *)vtable)[-hv]);
+
+ // pointer+1 is the position where the delta of the class is
+ int absolute_offset = *(pointer + 1);
+
+ Instance res = ((Instance *)instance)[absolute_offset + offset];
+
+ return res;
+ `}
+
+ # Replace in `recv` the value of the attribute `mproperty` by `value`
+ redef fun write_attribute(mproperty: MAttribute, recv: Instance, value: Instance)
+ do
+ assert recv isa MutableInstance
+
+ var id = mproperty.intro_mclassdef.mclass.vtable.id
+
+ # Replace the old value of mproperty in recv
+ write_attribute_ph(recv.internal_attributes, recv.vtable.internal_vtable,
+ recv.vtable.mask, id, mproperty.offset, value)
+ end
+
+ # Replace the value of an attribute in an instance
+ # `instance` is the attributes array of the receiver
+ # `vtable` is the pointer to the virtual table of the class (of the receiver)
+ # `mask` is the perfect hashing mask of the class
+ # `id` is the identifier of the class
+ # `offset` is the relative offset of this attribute
+ # `value` is the new value for this attribute
+ private fun write_attribute_ph(instance: Pointer, vtable: Pointer, mask: Int, id: Int, offset: Int, value: Instance) `{
+ // Perfect hashing position
+ int hv = mask & id;
+ long unsigned int *pointer = (long unsigned int*)(((long int *)vtable)[-hv]);
+
+ // pointer+1 is the position where the delta of the class is
+ int absolute_offset = *(pointer + 1);
+
+ ((Instance *)instance)[absolute_offset + offset] = value;
+ Instance_incr_ref(value);
+ `}
+
+ # Is the attribute `mproperty` initialized in the instance `recv`?
+ redef fun isset_attribute(mproperty: MAttribute, recv: Instance): Bool
+ do
+ assert recv isa MutableInstance
+
+ # Read the attribute value with internal perfect hashing read
+ # because we do not want to throw an error if the value is `initialization_value`
+ var id = mproperty.intro_mclassdef.mclass.vtable.id
+
+ var i = read_attribute_ph(recv.internal_attributes, recv.vtable.internal_vtable,
+ recv.vtable.mask, id, mproperty.offset)
+
+ return i != initialization_value
+ end