public static unsafe IntPtr MakeThunk(ThunkKind thunkKind, IntPtr targetPointer, IntPtr instantiatingArg, bool hasThis, RuntimeTypeHandle[] parameters, bool[] byRefParameters, bool[] paramsByRefForced) { // Build thunk data TypeHandle thReturnType = new TypeHandle(GetByRefIndicatorAtIndex(0, byRefParameters), parameters[0]); TypeHandle[] thParameters = null; if (parameters.Length > 1) { thParameters = new TypeHandle[parameters.Length - 1]; for (int i = 1; i < parameters.Length; i++) { thParameters[i - 1] = new TypeHandle(GetByRefIndicatorAtIndex(i, byRefParameters), parameters[i]); } } int callConversionInfo = CallConversionInfo.RegisterCallConversionInfo(thunkKind, targetPointer, instantiatingArg, hasThis, thReturnType, thParameters, paramsByRefForced); return FindExistingOrAllocateThunk(callConversionInfo); }
// Note that this overload does not handle varargs private static bool IsArgPassedByRef(TypeHandle th) { // LIMITED_METHOD_CONTRACT; Debug.Assert(!th.IsNull()); // This method only works for valuetypes. It includes true value types, // primitives, enums and TypedReference. Debug.Assert(th.IsValueType()); uint size = th.GetSize(); #if _TARGET_AMD64_ return IsArgPassedByRef((int)size); #elif _TARGET_ARM64_ // Composites greater than 16 bytes are passed by reference return ((size > ArchitectureConstants.ENREGISTERED_PARAMTYPE_MAXSIZE) && !th.IsHFA()); #else #error ArgIterator::IsArgPassedByRef #endif }
public bool Equals(TypeHandle other) { return _isByRef == other._isByRef && _eeType == other._eeType; }
public CorElementType GetReturnType(out TypeHandle thValueType, out bool forceByRefReturn) { if (_forcedByRefParams != null && _forcedByRefParams.Length > 0) forceByRefReturn = _forcedByRefParams[0]; else forceByRefReturn = false; return _argData.GetReturnType(out thValueType); }
//========================================================================= // Indicates whether an argument is to be put in a register using the // default IL calling convention. This should be called on each parameter // in the order it appears in the call signature. For a non-static meethod, // this function should also be called once for the "this" argument, prior // to calling it for the "real" arguments. Pass in a typ of ELEMENT_TYPE_CLASS. // // *pNumRegistersUsed: [in,out]: keeps track of the number of argument // registers assigned previously. The caller should // initialize this variable to 0 - then each call // will update it. // // typ: the signature type //========================================================================= private static bool IsArgumentInRegister(ref int pNumRegistersUsed, CorElementType typ, TypeHandle thValueType) { // LIMITED_METHOD_CONTRACT; if ((pNumRegistersUsed) < ArchitectureConstants.NUM_ARGUMENT_REGISTERS) { switch (typ) { case CorElementType.ELEMENT_TYPE_BOOLEAN: case CorElementType.ELEMENT_TYPE_CHAR: case CorElementType.ELEMENT_TYPE_I1: case CorElementType.ELEMENT_TYPE_U1: case CorElementType.ELEMENT_TYPE_I2: case CorElementType.ELEMENT_TYPE_U2: case CorElementType.ELEMENT_TYPE_I4: case CorElementType.ELEMENT_TYPE_U4: case CorElementType.ELEMENT_TYPE_STRING: case CorElementType.ELEMENT_TYPE_PTR: case CorElementType.ELEMENT_TYPE_BYREF: case CorElementType.ELEMENT_TYPE_CLASS: case CorElementType.ELEMENT_TYPE_ARRAY: case CorElementType.ELEMENT_TYPE_I: case CorElementType.ELEMENT_TYPE_U: case CorElementType.ELEMENT_TYPE_FNPTR: case CorElementType.ELEMENT_TYPE_OBJECT: case CorElementType.ELEMENT_TYPE_SZARRAY: pNumRegistersUsed++; return true; case CorElementType.ELEMENT_TYPE_VALUETYPE: { // On ProjectN valuetypes of integral size are passed enregistered int structSize = TypeHandle.GetElemSize(typ, thValueType); switch (structSize) { case 1: case 2: case 4: pNumRegistersUsed++; return true; } break; } } } return (false); }
public CorElementType GetReturnType(out TypeHandle thValueType) { thValueType = _returnType; CorElementType returnValue = thValueType.GetCorElementType(); if (!thValueType.IsValueType()) { thValueType = default(TypeHandle); } return returnValue; }
// Argument iteration. public CorElementType GetArgumentType(int argNum, out TypeHandle thValueType, out bool forceByRefReturn) { forceByRefReturn = false; if (_extraObjectFirstArg && argNum == 0) { thValueType = default(TypeHandle); return CorElementType.ELEMENT_TYPE_CLASS; } argNum = _extraObjectFirstArg ? argNum - 1 : argNum; Debug.Assert(argNum >= 0); if (_forcedByRefParams != null && (argNum + 1) < _forcedByRefParams.Length) forceByRefReturn = _forcedByRefParams[argNum + 1]; if (_extraFunctionPointerArg && argNum == _argData.NumFixedArgs()) { thValueType = default(TypeHandle); return CorElementType.ELEMENT_TYPE_I; } return _argData.GetArgumentType(argNum, out thValueType); }
// Argument iteration. public CorElementType GetArgumentType(int argNum, out TypeHandle thValueType) { thValueType = _parameterTypes[argNum]; CorElementType returnValue = thValueType.GetCorElementType(); if (!thValueType.IsValueType()) { thValueType = default(TypeHandle); } return returnValue; }
public ArgIteratorData(bool hasThis, bool isVarArg, TypeHandle[] parameterTypes, TypeHandle returnType) { _hasThis = hasThis; _isVarArg = isVarArg; _parameterTypes = parameterTypes; _returnType = returnType; }
unsafe public static int GetElemSize(CorElementType t, TypeHandle thValueType) { if (((int)t) <= 0x1d) { int elemSize = s_elemSizes[(int)t]; if (elemSize == -1) { return (int)thValueType.GetSize(); } if (elemSize == -2) { return IntPtr.Size; } return elemSize; } return 0; }
public CorElementType GetByRefArgType(out TypeHandle pByRefArgTypeHandle) { // LIMITED_METHOD_CONTRACT; pByRefArgTypeHandle = _argTypeHandleOfByRefParam; return _argType; }
public CorElementType GetArgType(out TypeHandle pTypeHandle) { // LIMITED_METHOD_CONTRACT; pTypeHandle = _argTypeHandle; return _argType; }