private static PInvokeDelegateThunk AllocateThunk(Delegate del) { if (s_thunkPoolHeap == null) { // TODO: Free s_thunkPoolHeap if the thread lose the race Interlocked.CompareExchange( ref s_thunkPoolHeap, RuntimeAugments.CreateThunksHeap(RuntimeImports.GetInteropCommonStubAddress()), null ); Debug.Assert(s_thunkPoolHeap != null); } var delegateThunk = new PInvokeDelegateThunk(del); McgPInvokeDelegateData pinvokeDelegateData; if (!RuntimeAugments.InteropCallbacks.TryGetMarshallerDataForDelegate(del.GetTypeHandle(), out pinvokeDelegateData)) { Environment.FailFast("Couldn't find marshalling stubs for delegate."); } // // For open static delegates set target to ReverseOpenStaticDelegateStub which calls the static function pointer directly // IntPtr pTarget = del.GetRawFunctionPointerForOpenStaticDelegate() == IntPtr.Zero ? pinvokeDelegateData.ReverseStub : pinvokeDelegateData.ReverseOpenStaticDelegateStub; RuntimeAugments.SetThunkData(s_thunkPoolHeap, delegateThunk.Thunk, delegateThunk.ContextData, pTarget); return(delegateThunk); }
private static PInvokeDelegateThunk AllocateThunk(Delegate del) { if (s_thunkPoolHeap == null) { // TODO: Free s_thunkPoolHeap if the thread lose the race Interlocked.CompareExchange( ref s_thunkPoolHeap, RuntimeAugments.CreateThunksHeap(RuntimeImports.GetInteropCommonStubAddress()), null ); Debug.Assert(s_thunkPoolHeap != null); } var delegateThunk = new PInvokeDelegateThunk(del); // // For open static delegates set target to ReverseOpenStaticDelegateStub which calls the static function pointer directly // bool openStaticDelegate = del.GetRawFunctionPointerForOpenStaticDelegate() != IntPtr.Zero; IntPtr pTarget = RuntimeInteropData.GetDelegateMarshallingStub(del.GetTypeHandle(), openStaticDelegate); Debug.Assert(pTarget != IntPtr.Zero); RuntimeAugments.SetThunkData(s_thunkPoolHeap, delegateThunk.Thunk, delegateThunk.ContextData, pTarget); return(delegateThunk); }
private static IntPtr AllocateThunk(Delegate del) { //TODO: cache del->thunk here if (s_thunkPoolHeap == null) { s_thunkPoolHeap = RuntimeAugments.CreateThunksHeap(RuntimeImports.GetInteropCommonStubAddress()); Debug.Assert(s_thunkPoolHeap != null); } IntPtr pThunk = RuntimeAugments.AllocateThunk(s_thunkPoolHeap); Debug.Assert(pThunk != IntPtr.Zero); if (pThunk == IntPtr.Zero) { // We've either run out of memory, or failed to allocate a new thunk due to some other bug. Now we should fail fast Environment.FailFast("Insufficient number of thunks."); return(IntPtr.Zero); } else { McgPInvokeDelegateData pinvokeDelegateData; if (!RuntimeAugments.InteropCallbacks.TryGetMarshallerDataForDelegate(del.GetTypeHandle(), out pinvokeDelegateData)) { Environment.FailFast("Couldn't find marshalling stubs for delegate."); } IntPtr pContext; unsafe { // // Allocate unmanaged memory for GCHandle of delegate and function pointer of open static delegate // We will store this pointer on the context slot of thunk data // pContext = (IntPtr)CoTaskMemAllocAndZeroMemory((System.IntPtr)(2 * (IntPtr.Size))); ThunkContextData *thunkData = (ThunkContextData *)pContext; (*thunkData).Handle = GCHandle.Alloc(del, GCHandleType.Weak); (*thunkData).FunctionPtr = del.GetRawFunctionPointerForOpenStaticDelegate(); } // // For open static delegates set target to ReverseOpenStaticDelegateStub which calls the static function pointer directly // IntPtr pTarget = del.GetRawFunctionPointerForOpenStaticDelegate() == IntPtr.Zero ? pinvokeDelegateData.ReverseStub : pinvokeDelegateData.ReverseOpenStaticDelegateStub; RuntimeAugments.SetThunkData(s_thunkPoolHeap, pThunk, pContext, pTarget); return(pThunk); } }
private static IntPtr GetOrAllocateThunk(Delegate del) { ConditionalWeakTable <Delegate, PInvokeDelegateThunk> pinvokeDelegates = GetPInvokeDelegates(); PInvokeDelegateThunk delegateThunk; // if the delegate already exists in the table return the allocated thunk for it if (pinvokeDelegates.TryGetValue(del, out delegateThunk)) { return(delegateThunk.Thunk); } if (s_thunkPoolHeap == null) { s_thunkPoolHeap = RuntimeAugments.CreateThunksHeap(RuntimeImports.GetInteropCommonStubAddress()); Debug.Assert(s_thunkPoolHeap != null); } delegateThunk = new PInvokeDelegateThunk(del); McgPInvokeDelegateData pinvokeDelegateData; if (!RuntimeAugments.InteropCallbacks.TryGetMarshallerDataForDelegate(del.GetTypeHandle(), out pinvokeDelegateData)) { Environment.FailFast("Couldn't find marshalling stubs for delegate."); } // // For open static delegates set target to ReverseOpenStaticDelegateStub which calls the static function pointer directly // IntPtr pTarget = del.GetRawFunctionPointerForOpenStaticDelegate() == IntPtr.Zero ? pinvokeDelegateData.ReverseStub : pinvokeDelegateData.ReverseOpenStaticDelegateStub; RuntimeAugments.SetThunkData(s_thunkPoolHeap, delegateThunk.Thunk, delegateThunk.ContextData, pTarget); // Add the delegate to the dictionary if it doesn't already exists delegateThunk = pinvokeDelegates.GetOrAdd(del, delegateThunk); return(delegateThunk.Thunk); }