/// <summary> /// This function is called from the lazy vtable resolver thunks via the UniversalTransitionThunk to compute /// the correct resolution of a virtual dispatch. /// </summary> /// <param name="callerTransitionBlockParam">pointer to the arguments of the called function</param> /// <param name="eeTypePointerOffsetAsIntPtr">eeTypePointerOffsetAsIntPtr is the offset from the start of the EEType to the vtable slot</param> /// <returns>function pointer of correct override of virtual function</returns> unsafe private static IntPtr VTableResolveThunk(IntPtr callerTransitionBlockParam, IntPtr eeTypePointerOffsetAsIntPtr) { int eeTypePointerOffset = (int)eeTypePointerOffsetAsIntPtr; int vtableSlotIndex = EETypeVTableOffsetToSlotIndex(eeTypePointerOffset); Debug.Assert(eeTypePointerOffset == SlotIndexToEETypeVTableOffset(vtableSlotIndex)); // Assert that the round trip through the slot calculations is good EEType **thisPointer = *((EEType ***)(((byte *)callerTransitionBlockParam) + ArgIterator.GetThisOffset())); EEType * eeType = *thisPointer; RuntimeTypeHandle rth = eeType->ToRuntimeTypeHandle(); TypeSystemContext context = TypeSystemContextFactory.Create(); TypeDesc type = context.ResolveRuntimeTypeHandle(rth); IntPtr functionPointer = ResolveVirtualVTableFunction(type, vtableSlotIndex); eeType->GetVTableStartAddress()[vtableSlotIndex] = functionPointer; TypeSystemContextFactory.Recycle(context); return(functionPointer); }
internal unsafe extern static void RhpGetDispatchCellInfo(IntPtr pCell, EEType **pInterfaceType, ushort *slot);