+
+ # Execute `mproperty` for a `args` (where `args[0]` is the receiver).
+ redef fun send(mproperty: MMethod, args: Array[Instance]): nullable Instance
+ do
+ var recv = args.first
+ var mtype = recv.mtype
+ var ret = send_commons(mproperty, args, mtype)
+ if ret != null then return ret
+
+ var propdef = method_dispatch(mproperty, recv.vtable.as(not null), recv)
+
+ return self.call(propdef, args)
+ end
+
+ # Method dispatch, for a given global method `mproperty`
+ # returns the most specific local method in the class corresponding to `vtable`
+ private fun method_dispatch(mproperty: MMethod, vtable: VTable, recv: Instance): MMethodDef
+ do
+ if mproperty.intro_mclassdef.mclass.positions_methods[recv.mtype.as(MClassType).mclass] != -1 then
+ return method_dispatch_sst(vtable.internal_vtable, mproperty.absolute_offset)
+ else
+ return method_dispatch_ph(vtable.internal_vtable, vtable.mask,
+ mproperty.intro_mclassdef.mclass.vtable.id, mproperty.offset)
+ end
+ end
+
+ # Execute a method dispatch with perfect hashing and return the appropriate `MMethodDef`
+ # * `vtable` Pointer to the internal virtual table of the class
+ # * `mask` Perfect hashing mask of the receiver class
+ # * `id` Identifier of the class which introduce the method
+ # * `offset` Relative offset of the method from the beginning of the block
+ fun method_dispatch_ph(vtable: Pointer, mask: Int, id: Int, offset: Int): MMethodDef `{
+ // Perfect hashing position
+ int hv = mask & id;
+ long unsigned int *pointer = (long unsigned int*)(((long int *)vtable)[-hv]);
+
+ // pointer+2 is the position where methods are
+ // Add the offset of property and get the method implementation
+ MMethodDef propdef = (MMethodDef)*(pointer + 2 + offset);
+
+ return propdef;
+ `}
+
+ # Execute a method dispatch with direct access and return the appropriate `MMethodDef`
+ # * `vtable` Pointer to the internal virtual table of the class
+ # * `absolute_offset` Absolute offset from the beginning of the virtual table
+ fun method_dispatch_sst(vtable: Pointer, absolute_offset: Int): MMethodDef `{
+ // pointer+2 is the position where methods are
+ // Add the offset of property and get the method implementation
+ MMethodDef propdef = (MMethodDef)((long int *)vtable)[absolute_offset];
+
+ return propdef;
+ `}
+
+ # 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
+
+ var i: Instance
+
+ if mproperty.intro_mclassdef.mclass.positions_attributes[recv.mtype.as(MClassType).mclass] != -1 then
+ # if this attribute class has an unique position for this receiver, then use direct access
+ i = read_attribute_sst(recv.internal_attributes, mproperty.absolute_offset)
+ else
+ # Otherwise, read the attribute value with perfect hashing
+ var id = mproperty.intro_mclassdef.mclass.vtable.id
+
+ i = read_attribute_ph(recv.internal_attributes, recv.vtable.internal_vtable,
+ recv.vtable.mask, id, mproperty.offset)
+ end
+
+ # 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
+ 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;
+ `}
+
+ # Return the attribute value in `instance` with a direct access (SST)
+ # * `instance` is the attributes array of the receiver
+ # * `offset` is the absolute offset of this attribute
+ fun read_attribute_sst(instance: Pointer, offset: Int): Instance `{
+ /* We can make a direct access to the attribute value
+ because this attribute is always at the same position
+ for the class of this receiver */
+ Instance res = ((Instance *)instance)[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
+
+ # Replace the old value of mproperty in recv
+ if mproperty.intro_mclassdef.mclass.positions_attributes[recv.mtype.as(MClassType).mclass] != -1 then
+ # if this attribute class has an unique position for this receiver, then use direct access
+ write_attribute_sst(recv.internal_attributes, mproperty.absolute_offset, value)
+ else
+ # Otherwise, use perfect hashing to replace the old value
+ var id = mproperty.intro_mclassdef.mclass.vtable.id
+
+ write_attribute_ph(recv.internal_attributes, recv.vtable.internal_vtable,
+ recv.vtable.mask, id, mproperty.offset, value)
+ end
+ 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
+ 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);
+ `}
+
+ # Replace the value of an attribute in an instance with direct access
+ # * `instance` is the attributes array of the receiver
+ # * `offset` is the absolute offset of this attribute
+ # * `value` is the new value for this attribute
+ fun write_attribute_sst(instance: Pointer, offset: Int, value: Instance) `{
+ // Direct access to the position with the absolute offset
+ ((Instance *)instance)[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