+ # 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;
+ `}
+