private static IntPtr RhResolveDispatch(object pObject, EETypePtr interfaceType, ushort slot) { DispatchCellInfo cellInfo = new DispatchCellInfo(); cellInfo.CellType = DispatchCellType.InterfaceAndSlot; cellInfo.InterfaceType = interfaceType; cellInfo.InterfaceSlot = slot; return RhResolveDispatchWorker(pObject, null, ref cellInfo); }
private static IntPtr RhResolveDispatch(object pObject, EETypePtr interfaceType, ushort slot) { DispatchCellInfo cellInfo = new DispatchCellInfo(); cellInfo.CellType = DispatchCellType.InterfaceAndSlot; cellInfo.InterfaceType = interfaceType; cellInfo.InterfaceSlot = slot; return(RhResolveDispatchWorker(pObject, null, ref cellInfo)); }
public static DispatchCellInfo Create() { var stru = new DispatchCellInfo(); stru.CellType = DispatchCellType.InterfaceAndSlot; stru.InterfaceType = default(EETypePtr); stru.InterfaceSlot = 0; stru.HasCache = 0; stru.MetadataToken = 0; stru.VTableOffset = 0; return(stru); }
private static unsafe IntPtr RhResolveDispatchWorker(object pObject, void *cell, ref DispatchCellInfo cellInfo) { // Type of object we're dispatching on. EEType *pInstanceType = pObject.EEType; if (cellInfo.CellType == DispatchCellType.InterfaceAndSlot) { // Type whose DispatchMap is used. Usually the same as the above but for types which implement ICastable // we may repeat this process with an alternate type. EEType *pResolvingInstanceType = pInstanceType; IntPtr pTargetCode = DispatchResolve.FindInterfaceMethodImplementationTarget(pResolvingInstanceType, cellInfo.InterfaceType.ToPointer(), cellInfo.InterfaceSlot); if (pTargetCode == IntPtr.Zero && pInstanceType->IsICastable) { // TODO!! BEGIN REMOVE THIS CODE WHEN WE REMOVE ICASTABLE // Dispatch not resolved through normal dispatch map, try using the ICastable // Call the ICastable.IsInstanceOfInterface method directly rather than via an interface // dispatch since we know the method address statically. We ignore any cast error exception // object passed back on failure (result == false) since IsInstanceOfInterface never throws. IntPtr pfnIsInstanceOfInterface = pInstanceType->ICastableIsInstanceOfInterfaceMethod; Exception castError = null; if (CalliIntrinsics.Call <bool>(pfnIsInstanceOfInterface, pObject, cellInfo.InterfaceType.ToPointer(), out castError)) { IntPtr pfnGetImplTypeMethod = pInstanceType->ICastableGetImplTypeMethod; pResolvingInstanceType = (EEType *)CalliIntrinsics.Call <IntPtr>(pfnGetImplTypeMethod, pObject, new IntPtr(cellInfo.InterfaceType.ToPointer())); pTargetCode = DispatchResolve.FindInterfaceMethodImplementationTarget(pResolvingInstanceType, cellInfo.InterfaceType.ToPointer(), cellInfo.InterfaceSlot); } else // TODO!! END REMOVE THIS CODE WHEN WE REMOVE ICASTABLE { // Dispatch not resolved through normal dispatch map, using the CastableObject path pTargetCode = InternalCalls.RhpGetCastableObjectDispatchHelper(); } } return(pTargetCode); } else if (cellInfo.CellType == DispatchCellType.VTableOffset) { // Dereference VTable return(*(IntPtr *)(((byte *)pInstanceType) + cellInfo.VTableOffset)); } else { #if SUPPORTS_NATIVE_METADATA_TYPE_LOADING // Attempt to convert dispatch cell to non-metadata form if we haven't acquired a cache for this cell yet if (cellInfo.HasCache == 0) { cellInfo = InternalTypeLoaderCalls.ConvertMetadataTokenDispatch(InternalCalls.RhGetModuleFromPointer(cell), cellInfo); if (cellInfo.CellType != DispatchCellType.MetadataToken) { return(RhResolveDispatchWorker(pObject, cell, ref cellInfo)); } } // If that failed, go down the metadata resolution path return(InternalTypeLoaderCalls.ResolveMetadataTokenDispatch(InternalCalls.RhGetModuleFromPointer(cell), (int)cellInfo.MetadataToken, new IntPtr(pInstanceType))); #else EH.FallbackFailFast(RhFailFastReason.InternalError, null); return(IntPtr.Zero); #endif } }
private static unsafe IntPtr RhResolveDispatchWorker(object pObject, void *cell, ref DispatchCellInfo cellInfo) { // Type of object we're dispatching on. MethodTable *pInstanceType = pObject.GetMethodTable(); if (cellInfo.CellType == DispatchCellType.InterfaceAndSlot) { // Type whose DispatchMap is used. Usually the same as the above but for types which implement IDynamicInterfaceCastable // we may repeat this process with an alternate type. MethodTable *pResolvingInstanceType = pInstanceType; IntPtr pTargetCode = DispatchResolve.FindInterfaceMethodImplementationTarget(pResolvingInstanceType, cellInfo.InterfaceType.ToPointer(), cellInfo.InterfaceSlot); if (pTargetCode == IntPtr.Zero && pInstanceType->IsIDynamicInterfaceCastable) { // Dispatch not resolved through normal dispatch map, try using the IDynamicInterfaceCastable // This will either give us the appropriate result, or throw. var pfnGetInterfaceImplementation = (delegate * < object, MethodTable *, ushort, IntPtr >) pInstanceType->GetClasslibFunction(ClassLibFunctionId.IDynamicCastableGetInterfaceImplementation); pTargetCode = pfnGetInterfaceImplementation(pObject, cellInfo.InterfaceType.ToPointer(), cellInfo.InterfaceSlot); Diagnostics.Debug.Assert(pTargetCode != IntPtr.Zero); } return(pTargetCode); } else if (cellInfo.CellType == DispatchCellType.VTableOffset) { // Dereference VTable return(*(IntPtr *)(((byte *)pInstanceType) + cellInfo.VTableOffset)); } else { #if SUPPORTS_NATIVE_METADATA_TYPE_LOADING_AND_SUPPORTS_TOKEN_BASED_DISPATCH_CELLS // Attempt to convert dispatch cell to non-metadata form if we haven't acquired a cache for this cell yet if (cellInfo.HasCache == 0) { cellInfo = InternalTypeLoaderCalls.ConvertMetadataTokenDispatch(InternalCalls.RhGetModuleFromPointer(cell), cellInfo); if (cellInfo.CellType != DispatchCellType.MetadataToken) { return(RhResolveDispatchWorker(pObject, cell, ref cellInfo)); } } // If that failed, go down the metadata resolution path return(InternalTypeLoaderCalls.ResolveMetadataTokenDispatch(InternalCalls.RhGetModuleFromPointer(cell), (int)cellInfo.MetadataToken, new IntPtr(pInstanceType))); #else EH.FallbackFailFast(RhFailFastReason.InternalError, null); return(IntPtr.Zero); #endif } }
internal unsafe extern static IntPtr RhpUpdateDispatchCellCache(IntPtr pCell, IntPtr pTargetCode, EEType* pInstanceType, ref DispatchCellInfo newCellInfo);
internal unsafe extern static void RhpGetDispatchCellInfo(IntPtr pCell, out DispatchCellInfo newCellInfo);
internal extern static unsafe IntPtr RhpUpdateDispatchCellCache(IntPtr pCell, IntPtr pTargetCode, EEType *pInstanceType, ref DispatchCellInfo newCellInfo);
internal extern static unsafe void RhpGetDispatchCellInfo(IntPtr pCell, out DispatchCellInfo newCellInfo);
internal static extern unsafe IntPtr RhpUpdateDispatchCellCache(IntPtr pCell, IntPtr pTargetCode, MethodTable *pInstanceType, ref DispatchCellInfo newCellInfo);
internal static T Call <T>(IntPtr pfn, IntPtr arg0, DispatchCellInfo cellInfo) { throw new NotImplementedException(); }
private unsafe static IntPtr RhResolveDispatchWorker(object pObject, void* cell, ref DispatchCellInfo cellInfo) { // Type of object we're dispatching on. EEType* pInstanceType = pObject.EEType; if (cellInfo.CellType == DispatchCellType.InterfaceAndSlot) { // Type whose DispatchMap is used. Usually the same as the above but for types which implement ICastable // we may repeat this process with an alternate type. EEType* pResolvingInstanceType = pInstanceType; IntPtr pTargetCode = DispatchResolve.FindInterfaceMethodImplementationTarget(pResolvingInstanceType, cellInfo.InterfaceType.ToPointer(), cellInfo.InterfaceSlot); if (pTargetCode == IntPtr.Zero && pInstanceType->IsICastable) { // TODO!! BEGIN REMOVE THIS CODE WHEN WE REMOVE ICASTABLE // Dispatch not resolved through normal dispatch map, try using the ICastable // Call the ICastable.IsInstanceOfInterface method directly rather than via an interface // dispatch since we know the method address statically. We ignore any cast error exception // object passed back on failure (result == false) since IsInstanceOfInterface never throws. IntPtr pfnIsInstanceOfInterface = pInstanceType->ICastableIsInstanceOfInterfaceMethod; Exception castError = null; if (CalliIntrinsics.Call<bool>(pfnIsInstanceOfInterface, pObject, cellInfo.InterfaceType.ToPointer(), out castError)) { IntPtr pfnGetImplTypeMethod = pInstanceType->ICastableGetImplTypeMethod; pResolvingInstanceType = (EEType*)CalliIntrinsics.Call<IntPtr>(pfnGetImplTypeMethod, pObject, new IntPtr(cellInfo.InterfaceType.ToPointer())); pTargetCode = DispatchResolve.FindInterfaceMethodImplementationTarget(pResolvingInstanceType, cellInfo.InterfaceType.ToPointer(), cellInfo.InterfaceSlot); } else // TODO!! END REMOVE THIS CODE WHEN WE REMOVE ICASTABLE { // Dispatch not resolved through normal dispatch map, using the CastableObject path pTargetCode = InternalCalls.RhpGetCastableObjectDispatchHelper(); } } return pTargetCode; } else if (cellInfo.CellType == DispatchCellType.VTableOffset) { // Dereference VTable return *(IntPtr*)(((byte*)pInstanceType) + cellInfo.VTableOffset); } else { #if SUPPORTS_NATIVE_METADATA_TYPE_LOADING // Attempt to convert dispatch cell to non-metadata form if we haven't acquired a cache for this cell yet if (cellInfo.HasCache == 0) { cellInfo = InternalTypeLoaderCalls.ConvertMetadataTokenDispatch(InternalCalls.RhGetModuleFromPointer(cell), cellInfo); if (cellInfo.CellType != DispatchCellType.MetadataToken) { return RhResolveDispatchWorker(pObject, cell, ref cellInfo); } } // If that failed, go down the metadata resolution path return InternalTypeLoaderCalls.ResolveMetadataTokenDispatch(InternalCalls.RhGetModuleFromPointer(cell), (int)cellInfo.MetadataToken, new IntPtr(pInstanceType)); #else EH.FallbackFailFast(RhFailFastReason.InternalError, null); return IntPtr.Zero; #endif } }
private static unsafe IntPtr RhResolveDispatchWorker(object pObject, void *cell, ref DispatchCellInfo cellInfo) { // Type of object we're dispatching on. EEType *pInstanceType = pObject.EEType; if (cellInfo.CellType == DispatchCellType.InterfaceAndSlot) { // Type whose DispatchMap is used. EEType *pResolvingInstanceType = pInstanceType; IntPtr pTargetCode = DispatchResolve.FindInterfaceMethodImplementationTarget(pResolvingInstanceType, cellInfo.InterfaceType.ToPointer(), cellInfo.InterfaceSlot); return(pTargetCode); } else if (cellInfo.CellType == DispatchCellType.VTableOffset) { // Dereference VTable return(*(IntPtr *)(((byte *)pInstanceType) + cellInfo.VTableOffset)); } else { #if SUPPORTS_NATIVE_METADATA_TYPE_LOADING_AND_SUPPORTS_TOKEN_BASED_DISPATCH_CELLS // Attempt to convert dispatch cell to non-metadata form if we haven't acquired a cache for this cell yet if (cellInfo.HasCache == 0) { cellInfo = InternalTypeLoaderCalls.ConvertMetadataTokenDispatch(InternalCalls.RhGetModuleFromPointer(cell), cellInfo); if (cellInfo.CellType != DispatchCellType.MetadataToken) { return(RhResolveDispatchWorker(pObject, cell, ref cellInfo)); } } // If that failed, go down the metadata resolution path return(InternalTypeLoaderCalls.ResolveMetadataTokenDispatch(InternalCalls.RhGetModuleFromPointer(cell), (int)cellInfo.MetadataToken, new IntPtr(pInstanceType))); #else EH.FallbackFailFast(RhFailFastReason.InternalError, null); return(IntPtr.Zero); #endif } }