/// <summary> /// Build initial array of vtable thunks. These thunks are the ones directly embedded in /// the typeloader codebase instead of being dynamically generated out of the thunk pool. /// </summary> private static IntPtr[] InitialThunks() { IntPtr firstResolverThunk; int thunkCount; int thunkSize = VTableResolver_Init(out firstResolverThunk, Intrinsics.AddrOf(new Func <IntPtr, IntPtr, IntPtr>(VTableResolveThunk)), RuntimeAugments.GetUniversalTransitionThunk(), out thunkCount); IntPtr[] initialThunks = new IntPtr[thunkCount]; for (int i = 0; i < thunkCount; i++) { unsafe { initialThunks[i] = (IntPtr)(((byte *)firstResolverThunk) + (thunkSize * i)); } } return(initialThunks); }
private static IntPtr SetupMethodEntrypoints() { return(MethodEntrypointStubs_SetupPointers(RuntimeAugments.GetUniversalTransitionThunk(), Intrinsics.AddrOf <Func <IntPtr, IntPtr, IntPtr> >(EntrypointThunk))); }
public static unsafe IntPtr Get(RuntimeTypeHandle constraintType, RuntimeTypeHandle constrainedMethodType, int constrainedMethodSlot, bool directConstrainedCall = false) { lock (s_nonGenericConstrainedCallDescs) { // Get list of constrained call descs associated with a given type LowLevelList <IntPtr> associatedCallDescs; if (!s_nonGenericConstrainedCallDescs.TryGetValue(constraintType, out associatedCallDescs)) { associatedCallDescs = new LowLevelList <IntPtr>(); s_nonGenericConstrainedCallDescs.Add(constraintType, associatedCallDescs); } // Perform linear scan of associated call descs to see if one matches for (int i = 0; i < associatedCallDescs.Count; i++) { NonGenericConstrainedCallDesc *callDesc = (NonGenericConstrainedCallDesc *)associatedCallDescs[i]; Debug.Assert(constraintType.Equals(callDesc->_constraintType)); if (callDesc->_constrainedMethodSlot != constrainedMethodSlot) { continue; } if (!callDesc->_constrainedMethodType.Equals(constrainedMethodType)) { continue; } // Found matching entry. return(associatedCallDescs[i]); } // Did not find match, allocate a new one and add it to the lookup list IntPtr newCallDescPtr = MemoryHelpers.AllocateMemory(sizeof(NonGenericConstrainedCallDesc)); NonGenericConstrainedCallDesc *newCallDesc = (NonGenericConstrainedCallDesc *)newCallDescPtr; newCallDesc->_exactTarget = IntPtr.Zero; if (directConstrainedCall) { newCallDesc->_lookupFunc = RuntimeAugments.GetUniversalTransitionThunk(); } else { if (RuntimeAugments.IsValueType(constraintType)) { newCallDesc->_lookupFunc = s_resolveCallOnValueTypeFuncPtr; } else { newCallDesc->_lookupFunc = s_resolveCallOnReferenceTypeFuncPtr; } } newCallDesc->_constraintType = constraintType; newCallDesc->_constrainedMethodSlot = constrainedMethodSlot; newCallDesc->_constrainedMethodType = constrainedMethodType; associatedCallDescs.Add(newCallDescPtr); return(newCallDescPtr); } }