// This function is known to the IL Transformer. protected void InitializeClosedInstanceSlow(object firstParameter, IntPtr functionPointer) { // This method is like InitializeClosedInstance, but it handles ALL cases. In particular, it handles generic method with fun function pointers. if (firstParameter == null) { throw new ArgumentException(SR.Arg_DlgtNullInst); } if (!FunctionPointerOps.IsGenericMethodPointer(functionPointer)) { m_functionPointer = functionPointer; m_firstParameter = firstParameter; } else { m_firstParameter = this; m_functionPointer = GetThunk(ClosedInstanceThunkOverGenericMethod); m_extraFunctionPointerOrData = functionPointer; m_helperObject = firstParameter; } }
private string GetTargetMethodsDescriptionForDebugger() { if (m_functionPointer == GetThunk(MulticastThunk)) { // Multi-cast delegates return the Target of the last delegate in the list Delegate[] invocationList = (Delegate[])m_helperObject; int invocationCount = (int)m_extraFunctionPointerOrData; StringBuilder builder = new StringBuilder(); for (int c = 0; c < invocationCount; c++) { if (c != 0) { builder.Append(", "); } builder.Append(invocationList[c].GetTargetMethodsDescriptionForDebugger()); } return(builder.ToString()); } else { RuntimeTypeHandle typeOfFirstParameterIfInstanceDelegate; bool isOpenThunk; IntPtr functionPointer = GetFunctionPointer(out typeOfFirstParameterIfInstanceDelegate, out isOpenThunk); if (!FunctionPointerOps.IsGenericMethodPointer(functionPointer)) { return(DebuggerFunctionPointerFormattingHook(functionPointer, typeOfFirstParameterIfInstanceDelegate)); } else { unsafe { GenericMethodDescriptor *pointerDef = FunctionPointerOps.ConvertToGenericDescriptor(functionPointer); return(DebuggerFunctionPointerFormattingHook(pointerDef->InstantiationArgument, typeOfFirstParameterIfInstanceDelegate)); } } } }
private static unsafe IntPtr ResolveCallOnReferenceType(ref object thisPtr, IntPtr callDescIntPtr) #endif { return(RuntimeAugments.RuntimeCacheLookup(thisPtr.GetType().TypeHandle.ToIntPtr(), callDescIntPtr, (IntPtr context, IntPtr callDescPtr, object contextObject, ref IntPtr auxResult) => { // Perform a normal GVM dispatch, then change the function pointer to dereference the this pointer. GenericConstrainedCallDesc *callDesc = (GenericConstrainedCallDesc *)callDescPtr; IntPtr target = RuntimeAugments.GVMLookupForSlot(contextObject.GetType().TypeHandle, callDesc->_constrainedMethod); if (FunctionPointerOps.IsGenericMethodPointer(target)) { GenericMethodDescriptor *genMethodDesc = FunctionPointerOps.ConvertToGenericDescriptor(target); IntPtr actualCodeTarget = GetThunkThatDereferencesThisPointerAndTailCallsTarget(genMethodDesc->MethodFunctionPointer); return FunctionPointerOps.GetGenericMethodFunctionPointer(actualCodeTarget, genMethodDesc->InstantiationArgument); } else { return GetThunkThatDereferencesThisPointerAndTailCallsTarget(target); } }, thisPtr, out _)); }