diff --git a/docs/design/datacontracts/RuntimeTypeSystem.md b/docs/design/datacontracts/RuntimeTypeSystem.md index 24d03fb28acf6a..9fbbf9a791aa80 100644 --- a/docs/design/datacontracts/RuntimeTypeSystem.md +++ b/docs/design/datacontracts/RuntimeTypeSystem.md @@ -312,7 +312,7 @@ internal partial struct RuntimeTypeSystem_1 Category_Array = 0x00080000, Category_ValueType = 0x00040000, Category_Nullable = 0x00050000, - Category_PrimitiveValueType = 0x00060000, + Category_Primitive = 0x00060000, Category_TruePrimitive = 0x00070000, Category_Interface = 0x000C0000, Collectible = 0x00200000, @@ -837,7 +837,7 @@ Contracts used: return CorElementType.SzArray; case WFLAGS_HIGH.Category_ValueType: case WFLAGS_HIGH.Category_Nullable: - case WFLAGS_HIGH.Category_PrimitiveValueType: + case WFLAGS_HIGH.Category_Primitive: return CorElementType.ValueType; case WFLAGS_HIGH.Category_TruePrimitive: return (CorElementType)GetClassData(typeHandle).InternalCorElementType; @@ -872,20 +872,16 @@ Contracts used: // if typedesc: check for CorElementType.ValueType } - // Enums have Category_PrimitiveValueType in their MethodTable flags and their + // Enums have Category_Primitive in their MethodTable flags and their // InternalCorElementType is a primitive type (I1, U1, I2, U2, I4, U4, I8, U8), - // not ValueType. Regular primitive value types (IntPtr/UIntPtr) have Category_TruePrimitive. + // not ValueType. Regular primitive value types (Int32, etc.) have Category_TruePrimitive. public bool IsEnum(TypeHandle typeHandle) { if (!typeHandle.IsMethodTable()) return false; - CorElementType sigType = GetSignatureCorElementType(typeHandle); - if (sigType != CorElementType.ValueType) - return false; - - CorElementType internalType = (CorElementType)GetClassData(typeHandle).InternalCorElementType; - return internalType != CorElementType.ValueType; + MethodTable methodTable = _methodTables[typeHandle.Address]; + return methodTable.Flags.GetFlag(WFLAGS_HIGH.Category_Mask) == WFLAGS_HIGH.Category_Primitive; } // return true if the TypeHandle represents an array, and set the rank to either 0 (if the type is not an array), or the rank number if it is. diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs index 935ae133272fe7..bc87d4fdd3d62f 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs @@ -849,9 +849,9 @@ internal unsafe struct MethodTable private const uint enum_flag_Category_Mask = 0x000F0000; private const uint enum_flag_Category_ValueType = 0x00040000; private const uint enum_flag_Category_Nullable = 0x00050000; - private const uint enum_flag_Category_IsPrimitiveMask = 0x000E0000; - private const uint enum_flag_Category_PrimitiveValueType = 0x00060000; // sub-category of ValueType, Enum or primitive value type - private const uint enum_flag_Category_TruePrimitive = 0x00070000; // sub-category of ValueType, Primitive (ELEMENT_TYPE_I, etc.) + private const uint enum_flag_Category_ElementTypeMask = 0x000E0000; + private const uint enum_flag_Category_Primitive = 0x00060000; + private const uint enum_flag_Category_TruePrimitive = 0x00070000; private const uint enum_flag_Category_Array = 0x00080000; private const uint enum_flag_Category_Array_Mask = 0x000C0000; private const uint enum_flag_Category_ValueType_Mask = 0x000C0000; @@ -955,7 +955,7 @@ public int MultiDimensionalArrayRank public bool IsByRefLike => (Flags & (enum_flag_HasComponentSize | enum_flag_IsByRefLike)) == enum_flag_IsByRefLike; // Warning! UNLIKE the similarly named Reflection api, this method also returns "true" for Enums. - public bool IsPrimitive => (Flags & enum_flag_Category_IsPrimitiveMask) == enum_flag_Category_PrimitiveValueType; + public bool IsPrimitive => (Flags & enum_flag_Category_ElementTypeMask) == enum_flag_Category_Primitive; public bool IsTruePrimitive => (Flags & enum_flag_Category_Mask) is enum_flag_Category_TruePrimitive; diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index baee8db37dd8a0..7fc5dc96f17b0f 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -942,12 +942,12 @@ internal sealed class RuntimeMethodInfoStub : IRuntimeMethodInfo public RuntimeMethodInfoStub(RuntimeMethodHandleInternal methodHandleValue, object keepalive) { m_keepalive = keepalive; - m_value = methodHandleValue; + m_value = methodHandleValue.Value; } private readonly object m_keepalive; - // These unused variables are used to ensure that this class has the same layout as RuntimeMethodInfo + // These unused variables are used to ensure that m_value has same offset as RuntimeMethodInfo.m_handle #pragma warning disable CA1823, 414, 169, IDE0044 private object? m_a; private object? m_b; @@ -959,9 +959,9 @@ public RuntimeMethodInfoStub(RuntimeMethodHandleInternal methodHandleValue, obje private object? m_h; #pragma warning restore CA1823, 414, 169, IDE0044 - public RuntimeMethodHandleInternal m_value; + private IntPtr m_value; - RuntimeMethodHandleInternal IRuntimeMethodInfo.Value => m_value; + RuntimeMethodHandleInternal IRuntimeMethodInfo.Value => new RuntimeMethodHandleInternal(m_value); // implementation of CORINFO_HELP_METHODDESC_TO_STUBRUNTIMEMETHOD [StackTraceHidden] @@ -1411,28 +1411,28 @@ RuntimeFieldHandleInternal Value } } - [StructLayout(LayoutKind.Sequential)] internal sealed class RuntimeFieldInfoStub : IRuntimeFieldInfo { public RuntimeFieldInfoStub(RuntimeFieldHandleInternal fieldHandle, object keepalive) { m_keepalive = keepalive; - m_fieldHandle = fieldHandle; + m_fieldHandle = fieldHandle.Value; } private readonly object m_keepalive; - // These unused variables are used to ensure that this class has the same layout as RuntimeFieldInfo -#pragma warning disable 414, 169, IDE0044 + // These unused variables are used to ensure that m_fieldHandle has same offset as RtFieldInfo.m_fieldHandle +#pragma warning disable CA1823, 414, 169, IDE0044 + private IntPtr m_b; private object? m_c; private object? m_d; - private int m_b; private object? m_e; private object? m_f; - private RuntimeFieldHandleInternal m_fieldHandle; -#pragma warning restore 414, 169, IDE0044 +#pragma warning restore CA1823, 414, 169, IDE0044 + + private IntPtr m_fieldHandle; - RuntimeFieldHandleInternal IRuntimeFieldInfo.Value => m_fieldHandle; + RuntimeFieldHandleInternal IRuntimeFieldInfo.Value => new RuntimeFieldHandleInternal(m_fieldHandle); // implementation of CORINFO_HELP_FIELDDESC_TO_STUBRUNTIMEFIELD [StackTraceHidden] diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 55a04cbc635ac0..04b2addadce82d 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -6991,7 +6991,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) break; case CEE_ARGLIST: - + { if (!info.compIsVarArgs) { BADCODE("arglist in non-vararg method"); @@ -7002,9 +7002,19 @@ void Compiler::impImportBlockCode(BasicBlock* block) // The ARGLIST cookie is a hidden 'last' parameter, we have already // adjusted the arg count cos this is like fetching the last param. assertImp(numArgs > 0); - op1 = gtNewLclVarAddrNode(lvaVarargsHandleArg, TYP_BYREF); + clsHnd = impGetRuntimeArgumentHandle(); + + unsigned argListTmp = lvaGrabTemp(false DEBUGARG("arglist tmp")); + lvaSetStruct(argListTmp, clsHnd, false); + + op1 = gtNewLclVarAddrNode(lvaVarargsHandleArg, TYP_I_IMPL); + impAppendTree(gtNewStoreLclFldNode(argListTmp, TYP_I_IMPL, 0, op1), CHECK_SPILL_ALL, impCurStmtDI); + + op1 = gtNewLclVarNode(argListTmp, TYP_STRUCT); + tiRetVal = makeTypeInfo(clsHnd); impPushOnStack(op1, tiRetVal); break; + } case CEE_ENDFINALLY: diff --git a/src/coreclr/vm/arraynative.cpp b/src/coreclr/vm/arraynative.cpp index c076c42ffa02c7..be42a36c0b764d 100644 --- a/src/coreclr/vm/arraynative.cpp +++ b/src/coreclr/vm/arraynative.cpp @@ -24,7 +24,7 @@ FCIMPL1(INT32, ArrayNative::GetCorElementTypeOfElementType, ArrayBase* arrayUNSA _ASSERTE(arrayUNSAFE != NULL); - return arrayUNSAFE->GetArrayElementTypeHandle().GetVerifierCorElementType(); + return arrayUNSAFE->GetArrayElementTypeHandle().GetInternalCorElementType(); } FCIMPLEND diff --git a/src/coreclr/vm/callingconvention.h b/src/coreclr/vm/callingconvention.h index 5bf44181f2a41c..3fcdaf0835f61b 100644 --- a/src/coreclr/vm/callingconvention.h +++ b/src/coreclr/vm/callingconvention.h @@ -2447,7 +2447,7 @@ inline BOOL HasRetBuffArgUnmanagedFixup(MetaSig * pSig) { WRAPPER_NO_CONTRACT; // We cannot just pSig->GetReturnType() here since it will return ELEMENT_TYPE_VALUETYPE for enums - CorElementType type = pSig->GetRetTypeHandleThrowing().GetVerifierCorElementType(); + CorElementType type = pSig->GetRetTypeHandleThrowing().GetInternalCorElementType(); return type == ELEMENT_TYPE_VALUETYPE; } #endif diff --git a/src/coreclr/vm/class.cpp b/src/coreclr/vm/class.cpp index 19424b88d49569..551c456691954b 100644 --- a/src/coreclr/vm/class.cpp +++ b/src/coreclr/vm/class.cpp @@ -1318,7 +1318,7 @@ void ClassLoader::LoadExactParents(MethodTable* pMT) /*static*/ CorElementType ClassLoader::GetReducedTypeElementType(TypeHandle hType) { - CorElementType elemType = hType.GetVerifierCorElementType(); + CorElementType elemType = hType.GetInternalCorElementType(); switch (elemType) { case ELEMENT_TYPE_U1: diff --git a/src/coreclr/vm/classnames.h b/src/coreclr/vm/classnames.h index 81160ea4ff683e..f56068039ef462 100644 --- a/src/coreclr/vm/classnames.h +++ b/src/coreclr/vm/classnames.h @@ -11,25 +11,14 @@ // These system class names are not assembly qualified. #define g_AppDomainClassName "System.AppDomain" -#define g_ArgIteratorName "ArgIterator" #define g_ArrayClassName "System.Array" #define g_NullableName "Nullable`1" -#define g_CollectionsEnumerableItfName "System.Collections.IEnumerable" #define g_CollectionsEnumeratorClassName "System.Collections.IEnumerator" -#define g_CollectionsCollectionItfName "System.Collections.ICollection" -#define g_CollectionsGenericCollectionItfName "System.Collections.Generic.ICollection`1" -#define g_CollectionsGenericReadOnlyCollectionItfName "System.Collections.Generic.IReadOnlyCollection`1" #ifdef FEATURE_COMINTEROP -#define g_CorelibAsmName "System.Private.CoreLib" -#define g_SystemAsmName "System" -#define g_SystemRuntimeAsmName "System.Runtime" -#define g_DrawingAsmName "System.Drawing" -#define g_ObjectModelAsmName "System.ObjectModel" #define g_ColorClassName "System.Drawing.Color" -#define g_ColorTranslatorClassName "System.Drawing.ColorTranslator" #define g_ComObjectName "__ComObject" #endif // FEATURE_COMINTEROP @@ -55,51 +44,16 @@ #define g_Vector512ClassName "System.Runtime.Intrinsics.Vector512`1" #define g_Vector512Name "Vector512`1" -#define g_EnumeratorToEnumClassName "System.Runtime.InteropServices.CustomMarshalers.EnumeratorToEnumVariantMarshaler" -#define g_ExceptionClassName "System.Exception" -#define g_ExecutionEngineExceptionClassName "System.ExecutionEngineException" - -#define g_ThreadStaticAttributeClassName "System.ThreadStaticAttribute" -#define g_TypeIdentifierAttributeClassName "System.Runtime.InteropServices.TypeIdentifierAttribute" - #define g_ObjectClassName "System.Object" -#define g_ObjectName "Object" -#define g_OutOfMemoryExceptionClassName "System.OutOfMemoryException" - -#define g_ReflectionClassName "System.RuntimeType" -#define g_ReflectionConstructorName "System.Reflection.RuntimeConstructorInfo" -#define g_ReflectionEventInfoName "System.Reflection.EventInfo" -#define g_ReflectionEventName "System.Reflection.RuntimeEventInfo" -#define g_ReflectionFieldName "System.Reflection.RuntimeFieldInfo" -#define g_ReflectionMemberInfoName "System.Reflection.MemberInfo" -#define g_MethodBaseName "System.Reflection.MethodBase" -#define g_ReflectionFieldInfoName "System.Reflection.FieldInfo" -#define g_ReflectionPropertyInfoName "System.Reflection.PropertyInfo" -#define g_ReflectionConstructorInfoName "System.Reflection.ConstructorInfo" -#define g_ReflectionMethodInfoName "System.Reflection.MethodInfo" -#define g_ReflectionMethodName "System.Reflection.RuntimeMethodInfo" -#define g_ReflectionMethodInterfaceName "System.IRuntimeMethodInfo" -#define g_ReflectionAssemblyName "System.Reflection.RuntimeAssembly" -#define g_ReflectionModuleName "System.Reflection.RuntimeModule" -#define g_ReflectionParamInfoName "System.Reflection.ParameterInfo" -#define g_ReflectionParamName "System.Reflection.RuntimeParameterInfo" -#define g_ReflectionPropInfoName "System.Reflection.RuntimePropertyInfo" -#define g_RuntimeArgumentHandleName "RuntimeArgumentHandle" + #define g_RuntimeFieldHandleClassName "System.RuntimeFieldHandle" -#define g_RuntimeFieldHandleInternalName "RuntimeFieldHandleInternal" #define g_RuntimeMethodHandleClassName "System.RuntimeMethodHandle" -#define g_RuntimeMethodHandleInternalName "RuntimeMethodHandleInternal" #define g_RuntimeTypeHandleClassName "System.RuntimeTypeHandle" -#define g_StackOverflowExceptionClassName "System.StackOverflowException" #define g_StringBufferClassName "System.Text.StringBuilder" -#define g_StringBufferName "StringBuilder" #define g_StringClassName "System.String" #define g_StringName "String" -#define g_ThreadClassName "System.Threading.Thread" -#define g_TypeClassName "System.Type" - #define g_VariantClassName "System.Variant" #define g_GuidClassName "System.Guid" diff --git a/src/coreclr/vm/comdelegate.cpp b/src/coreclr/vm/comdelegate.cpp index a4eb59dd72f4a0..24d4bf7140fb95 100644 --- a/src/coreclr/vm/comdelegate.cpp +++ b/src/coreclr/vm/comdelegate.cpp @@ -2511,7 +2511,7 @@ static bool IsLocationAssignable(TypeHandle fromHandle, TypeHandle toHandle, boo else { // they are not compatible yet enums can go into each other if their underlying element type is the same - if (toHandle.GetVerifierCorElementType() == fromHandle.GetVerifierCorElementType() + if (toHandle.GetInternalCorElementType() == fromHandle.GetInternalCorElementType() && (toHandle.IsEnum() || fromHandle.IsEnum())) return true; diff --git a/src/coreclr/vm/comutilnative.cpp b/src/coreclr/vm/comutilnative.cpp index bcbb0c6d8bfd9c..8db3217f1cb855 100644 --- a/src/coreclr/vm/comutilnative.cpp +++ b/src/coreclr/vm/comutilnative.cpp @@ -1977,7 +1977,7 @@ FCIMPL1(CorElementType, MethodTableNative::GetPrimitiveCorElementType, MethodTab { FCALL_CONTRACT; - _ASSERTE(mt->IsTruePrimitive() || mt->IsEnum()); + _ASSERTE(mt->IsPrimitive()); // MethodTable::GetInternalCorElementType has unnecessary overhead for primitives and enums // Call EEClass::GetInternalCorElementType directly to avoid it diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index 4a36a6518a0446..476878a901f333 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -104,7 +104,6 @@ DEFINE_METHOD(APPCONTEXT, ON_FIRST_CHANCE_EXCEPTION, OnFirstChanceException, DEFINE_CLASS(ARG_ITERATOR, System, ArgIterator) DEFINE_CLASS_U(System, ArgIterator, VARARGS) // Includes a SigPointer. -DEFINE_METHOD(ARG_ITERATOR, CTOR2, .ctor, IM_RuntimeArgumentHandle_PtrVoid_RetVoid) DEFINE_CLASS(ARGUMENT_HANDLE, System, RuntimeArgumentHandle) @@ -206,7 +205,10 @@ DEFINE_CLASS_U(System, RuntimeMethodInfoStub, ReflectMethodO DEFINE_FIELD_U(m_value, ReflectMethodObject, m_pMD) DEFINE_CLASS(STUBMETHODINFO, System, RuntimeMethodInfoStub) DEFINE_FIELD(STUBMETHODINFO, HANDLE, m_value) -DEFINE_METHOD(STUBMETHODINFO, FROMPTR, FromPtr, SM_IntPtr_RetObj) +DEFINE_METHOD(STUBMETHODINFO, FROMPTR, FromPtr, SM_IntPtr_RetObj) +#ifdef FOR_ILLINK +DEFINE_METHOD(STUBMETHODINFO, CTOR, .ctor, IM_RetVoid) +#endif // FOR_ILLINK DEFINE_CLASS(CONSTRUCTOR_INFO, Reflection, ConstructorInfo) @@ -361,12 +363,12 @@ DEFINE_METHOD(TYPE_NAME_RESOLVER, GET_TYPE_HELPER, GetTypeHelper, DEFINE_CLASS_U(Reflection, RtFieldInfo, NoClass) DEFINE_FIELD_U(m_fieldHandle, ReflectFieldObject, m_pFD) DEFINE_CLASS(RT_FIELD_INFO, Reflection, RtFieldInfo) -DEFINE_FIELD(RT_FIELD_INFO, HANDLE, m_fieldHandle) DEFINE_CLASS_U(System, RuntimeFieldInfoStub, ReflectFieldObject) DEFINE_FIELD_U(m_fieldHandle, ReflectFieldObject, m_pFD) DEFINE_CLASS(STUBFIELDINFO, System, RuntimeFieldInfoStub) -DEFINE_METHOD(STUBFIELDINFO, FROMPTR, FromPtr, SM_IntPtr_RetObj) +DEFINE_FIELD(STUBFIELDINFO, HANDLE, m_fieldHandle) +DEFINE_METHOD(STUBFIELDINFO, FROMPTR, FromPtr, SM_IntPtr_RetObj) #ifdef FOR_ILLINK DEFINE_METHOD(STUBFIELDINFO, CTOR, .ctor, IM_RetVoid) #endif // FOR_ILLINK @@ -563,8 +565,6 @@ DEFINE_METHOD(RUNTIME_METHOD_BODY, CTOR, .ctor, IM_RetVoid) DEFINE_CLASS(METHOD_INFO, Reflection, MethodInfo) -DEFINE_CLASS(METHOD_HANDLE_INTERNAL,System, RuntimeMethodHandleInternal) - DEFINE_CLASS(METHOD_HANDLE, System, RuntimeMethodHandle) DEFINE_FIELD(METHOD_HANDLE, METHOD, m_value) DEFINE_METHOD(METHOD_HANDLE, TO_INTPTR, ToIntPtr, SM_RuntimeMethodHandle_RetIntPtr) diff --git a/src/coreclr/vm/customattribute.cpp b/src/coreclr/vm/customattribute.cpp index caf204b84cee19..59c3d87f73b3d2 100644 --- a/src/coreclr/vm/customattribute.cpp +++ b/src/coreclr/vm/customattribute.cpp @@ -52,7 +52,7 @@ static HRESULT ParseCaType( if (!th.IsNull() && th.IsEnum()) { - pCaType->enumType = (CorSerializationType)th.GetVerifierCorElementType(); + pCaType->enumType = (CorSerializationType)th.GetInternalCorElementType(); // The assembly qualified name of th might not equal pCaType->szEnumName. // e.g. th could be "MyEnum, MyAssembly, Version=4.0.0.0" while diff --git a/src/coreclr/vm/ilmarshalers.cpp b/src/coreclr/vm/ilmarshalers.cpp index 110245fecc59a9..3c3b5d84a42b0d 100644 --- a/src/coreclr/vm/ilmarshalers.cpp +++ b/src/coreclr/vm/ilmarshalers.cpp @@ -3868,9 +3868,7 @@ bool ILNativeArrayMarshaler::CanMarshalViaPinning() TypeHandle elementTypeHandle = m_pargs->na.m_pArrayMT->GetArrayElementTypeHandle(); - return elementTypeHandle.IsBlittable() - && (elementTypeHandle.GetMethodTable()->IsValueType() - || elementTypeHandle.GetMethodTable()->IsTruePrimitive()); + return elementTypeHandle.IsBlittable() && elementTypeHandle.GetMethodTable()->IsValueType(); } void ILNativeArrayMarshaler::EmitMarshalViaPinning(ILCodeStream* pslILEmit) diff --git a/src/coreclr/vm/ilmarshalers.h b/src/coreclr/vm/ilmarshalers.h index e8e0fe0e2896a7..fd42e348875c34 100644 --- a/src/coreclr/vm/ilmarshalers.h +++ b/src/coreclr/vm/ilmarshalers.h @@ -1975,7 +1975,7 @@ class ILRuntimeFieldHandleMarshaler : public ILReflectionObjectMarshaler { protected: BinderFieldID GetStructureFieldID() override { LIMITED_METHOD_CONTRACT; return FIELD__FIELD_HANDLE__M_FIELD; } - BinderFieldID GetObjectFieldID() override { LIMITED_METHOD_CONTRACT; return FIELD__RT_FIELD_INFO__HANDLE; } + BinderFieldID GetObjectFieldID() override { LIMITED_METHOD_CONTRACT; return FIELD__STUBFIELDINFO__HANDLE; } BinderClassID GetManagedTypeBinderID() override { LIMITED_METHOD_CONTRACT; return CLASS__FIELD_HANDLE; } }; diff --git a/src/coreclr/vm/invokeutil.cpp b/src/coreclr/vm/invokeutil.cpp index ea289619bcf902..49186d28afc058 100644 --- a/src/coreclr/vm/invokeutil.cpp +++ b/src/coreclr/vm/invokeutil.cpp @@ -135,7 +135,7 @@ void InvokeUtil::CopyArg(TypeHandle th, PVOID argRef, ArgDestination *argDest) { CONTRACTL_END; void *pArgDst = argDest->GetDestinationAddress(); - CorElementType type = th.GetVerifierCorElementType(); + CorElementType type = th.GetInternalCorElementType(); switch (type) { #ifdef TARGET_RISCV64 @@ -500,7 +500,7 @@ void InvokeUtil::ValidField(TypeHandle th, OBJECTREF* value) if (th.IsEnum()) COMPlusThrow(kArgumentException,W("Arg_ObjObj")); - type = th.GetVerifierCorElementType(); + type = th.GetInternalCorElementType(); if (IsPrimitiveType(type)) { if (CanPrimitiveWiden(type, oType)) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 0a0afe526e29ae..cecb1d57a062e7 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -343,14 +343,7 @@ CorInfoType CEEInfo::asCorInfoType(CorElementType eeType, // Enums are exactly like primitives, even from a verification standpoint, // so we zap the type handle in this case. // - // However RuntimeTypeHandle etc. are reported as E_T_INT (or something like that) - // but don't count as primitives as far as verification is concerned... - // - // To make things stranger, TypedReference returns true for "IsTruePrimitive". - // However the JIT likes us to report the type handle in that case. - if (!typeHnd.IsTypeDesc() && ( - (typeHnd.AsMethodTable()->IsTruePrimitive() && typeHnd != TypeHandle(g_TypedReferenceMT)) - || typeHnd.AsMethodTable()->IsEnum()) ) + if (!typeHnd.IsTypeDesc() && typeHnd.AsMethodTable()->IsPrimitive()) { typeHndUpdated = TypeHandle(); } @@ -380,7 +373,7 @@ CorInfoType CEEInfo::asCorInfoType(CorElementType eeType, CORINFO_TYPE_UNDEF, // VAR (type variable) CORINFO_TYPE_CLASS, // ARRAY CORINFO_TYPE_UNDEF, // GENERICINST - CORINFO_TYPE_VALUECLASS, // TYPEDBYREF + CORINFO_TYPE_VALUECLASS, // TYPEDBYREF CORINFO_TYPE_UNDEF, // VALUEARRAY_UNSUPPORTED CORINFO_TYPE_NATIVEINT, // I CORINFO_TYPE_NATIVEUINT, // U @@ -4072,7 +4065,7 @@ CorInfoType CEEInfo::getTypeForPrimitiveValueClass( TypeHandle th(clsHnd); _ASSERTE (!th.IsGenericVariable()); - CorElementType elementType = th.GetVerifierCorElementType(); + CorElementType elementType = th.GetInternalCorElementType(); if (CorIsPrimitiveType(elementType)) { result = asCorInfoType(elementType); @@ -4450,7 +4443,7 @@ static bool isExactTypeHelper(TypeHandle th) th = pMT->GetArrayElementTypeHandle(); // Arrays of primitives are interchangeable with arrays of enums of the same underlying type. - if (CorTypeInfo::IsPrimitiveType(th.GetVerifierCorElementType())) + if (CorTypeInfo::IsPrimitiveType(th.GetInternalCorElementType())) return false; } @@ -5057,7 +5050,7 @@ void CEEInfo::getCallInfo( if (pMD->GetSlot() == CoreLibBinder::GetMethod(METHOD__OBJECT__GET_HASH_CODE)->GetSlot()) { // Pretend this was a "constrained. UnderlyingType" instruction prefix - constrainedType = TypeHandle(CoreLibBinder::GetElementType(constrainedType.GetVerifierCorElementType())); + constrainedType = TypeHandle(CoreLibBinder::GetElementType(constrainedType.GetInternalCorElementType())); constrainedResolvedTokenCopy = *pConstrainedResolvedToken; pConstrainedResolvedToken = &constrainedResolvedTokenCopy; @@ -7237,7 +7230,7 @@ static bool getILIntrinsicImplementationForInterlocked(MethodDesc * ftn, } else { - CorElementType elementType = typeHandle.GetVerifierCorElementType(); + CorElementType elementType = typeHandle.GetInternalCorElementType(); if (!CorTypeInfo::IsPrimitiveType(elementType) || elementType == ELEMENT_TYPE_R4 || elementType == ELEMENT_TYPE_R8) @@ -7406,7 +7399,7 @@ static bool getILIntrinsicImplementationForRuntimeHelpers( Instantiation inst = ftn->GetMethodInstantiation(); _ASSERTE(inst.GetNumArgs() == 1); - CorElementType et = inst[0].GetVerifierCorElementType(); + CorElementType et = inst[0].GetInternalCorElementType(); if (et == ELEMENT_TYPE_I4 || et == ELEMENT_TYPE_U4 || et == ELEMENT_TYPE_I2 || @@ -7435,7 +7428,7 @@ static bool getILIntrinsicImplementationForRuntimeHelpers( Instantiation inst = ftn->GetMethodInstantiation(); _ASSERTE(inst.GetNumArgs() == 1); - CorElementType et = inst[0].GetVerifierCorElementType(); + CorElementType et = inst[0].GetInternalCorElementType(); if (et == ELEMENT_TYPE_I4 || et == ELEMENT_TYPE_U4 || et == ELEMENT_TYPE_I2 || diff --git a/src/coreclr/vm/marshalnative.cpp b/src/coreclr/vm/marshalnative.cpp index b9163b700bad00..b63144baf8f916 100644 --- a/src/coreclr/vm/marshalnative.cpp +++ b/src/coreclr/vm/marshalnative.cpp @@ -110,7 +110,7 @@ extern "C" BOOL QCALLTYPE MarshalNative_HasLayout(QCall::TypeHandle t, BOOL* pIs { // Enums don't have native layout info, but they marshal identically // to their underlying primitive type. - th = CoreLibBinder::GetElementType(th.GetVerifierCorElementType()); + th = CoreLibBinder::GetElementType(th.GetInternalCorElementType()); } if (th.HasLayout()) diff --git a/src/coreclr/vm/methodtable.cpp b/src/coreclr/vm/methodtable.cpp index cdf596f6c91c5f..50e628b85b0cec 100644 --- a/src/coreclr/vm/methodtable.cpp +++ b/src/coreclr/vm/methodtable.cpp @@ -3087,7 +3087,7 @@ namespace STANDARD_VM_CONTRACT; PTR_MethodTable fieldType = pFieldDesc->GetFieldTypeHandleThrowing().GetMethodTable(); - CorElementType corType = fieldType->GetVerifierCorElementType(); + CorElementType corType = fieldType->GetInternalCorElementType(); if (corType == ELEMENT_TYPE_VALUETYPE) { @@ -4969,9 +4969,8 @@ CorElementType MethodTable::GetInternalCorElementType() ret = ELEMENT_TYPE_VALUETYPE; break; - case enum_flag_Category_PrimitiveValueType: - // This path should only be taken for the builtin CoreLib types - // and primitive valuetypes + case enum_flag_Category_Primitive: + // enum_flag_Category_ElementTypeMask maps both Category_TruePrimitive and Category_Primitive here. ret = GetClass()->GetInternalCorElementType(); _ASSERTE((ret != ELEMENT_TYPE_CLASS) && (ret != ELEMENT_TYPE_VALUETYPE)); @@ -4994,48 +4993,6 @@ CorElementType MethodTable::GetInternalCorElementType() return ret; } -//========================================================================================== -CorElementType MethodTable::GetVerifierCorElementType() -{ - LIMITED_METHOD_CONTRACT; - SUPPORTS_DAC; - - // This should not touch the EEClass, at least not in the - // common cases of ELEMENT_TYPE_CLASS and ELEMENT_TYPE_VALUETYPE. - CorElementType ret; - - switch (GetFlag(enum_flag_Category_ElementTypeMask)) - { - case enum_flag_Category_Array: - ret = ELEMENT_TYPE_ARRAY; - break; - - case enum_flag_Category_Array | enum_flag_Category_IfArrayThenSzArray: - ret = ELEMENT_TYPE_SZARRAY; - break; - - case enum_flag_Category_ValueType: - ret = ELEMENT_TYPE_VALUETYPE; - break; - - case enum_flag_Category_PrimitiveValueType: - // - // This is the only difference from MethodTable::GetInternalCorElementType() - // - if (IsTruePrimitive() || IsEnum()) - ret = GetClass()->GetInternalCorElementType(); - else - ret = ELEMENT_TYPE_VALUETYPE; - break; - - default: - ret = ELEMENT_TYPE_CLASS; - break; - } - - return ret; -} - //========================================================================================== CorElementType MethodTable::GetSignatureCorElementType() { @@ -5058,7 +5015,7 @@ CorElementType MethodTable::GetSignatureCorElementType() case enum_flag_Category_ValueType: case enum_flag_Category_Nullable: - case enum_flag_Category_PrimitiveValueType: + case enum_flag_Category_Primitive: ret = ELEMENT_TYPE_VALUETYPE; break; @@ -5077,11 +5034,11 @@ CorElementType MethodTable::GetSignatureCorElementType() #ifndef DACCESS_COMPILE //========================================================================================== -void MethodTable::SetInternalCorElementType (CorElementType _NormType) +void MethodTable::SetInternalCorElementType(CorElementType elemType, bool isTruePrimitive) { WRAPPER_NO_CONTRACT; - switch (_NormType) + switch (elemType) { case ELEMENT_TYPE_CLASS: _ASSERTE(!IsArray()); @@ -5089,16 +5046,14 @@ void MethodTable::SetInternalCorElementType (CorElementType _NormType) break; case ELEMENT_TYPE_VALUETYPE: SetFlag(enum_flag_Category_ValueType); - _ASSERTE(GetFlag(enum_flag_Category_Mask) == enum_flag_Category_ValueType); break; default: - SetFlag(enum_flag_Category_PrimitiveValueType); - _ASSERTE(GetFlag(enum_flag_Category_Mask) == enum_flag_Category_PrimitiveValueType); + SetFlag(isTruePrimitive ? enum_flag_Category_TruePrimitive : enum_flag_Category_Primitive); break; } - GetClass()->SetInternalCorElementType(_NormType); - _ASSERTE(GetInternalCorElementType() == _NormType); + GetClass()->SetInternalCorElementType(elemType); + _ASSERTE(GetInternalCorElementType() == elemType); } #endif // !DACCESS_COMPILE diff --git a/src/coreclr/vm/methodtable.h b/src/coreclr/vm/methodtable.h index 3943e8ea8e0ae8..3a7c7e0cf2b2f7 100644 --- a/src/coreclr/vm/methodtable.h +++ b/src/coreclr/vm/methodtable.h @@ -2771,30 +2771,26 @@ class MethodTable // // #KindsOfElementTypes // GetInternalCorElementType() retrieves the internal representation of the type. It's not always - // appropriate to use this. For example, we treat enums as their underlying type or some structs are - // optimized to be ints. To get the signature type or the verifier type (same as signature except for - // enums are normalized to the primitive type that underlies them), use the APIs in Typehandle.h + // appropriate to use this. It treats enums as their underlying type. To get the signature + // type, use the APIs in Typehandle.h. // // * code:TypeHandle.GetSignatureCorElementType() - // * code:TypeHandle.GetVerifierCorElementType() // * code:TypeHandle.GetInternalCorElementType() CorElementType GetInternalCorElementType(); - void SetInternalCorElementType(CorElementType _NormType); - - // See code:TypeHandle::GetVerifierCorElementType for description - CorElementType GetVerifierCorElementType(); + void SetInternalCorElementType(CorElementType elemType, bool isTruePrimitive = false); // See code:TypeHandle::GetSignatureCorElementType for description CorElementType GetSignatureCorElementType(); - // A true primitive is one who's GetVerifierCorElementType() == + // A true primitive is one whose GetInternalCorElementType() == // ELEMENT_TYPE_I, // ELEMENT_TYPE_I4, - // ELEMENT_TYPE_TYPEDBYREF etc. - // Note that GetIntenalCorElementType might return these same values for some additional - // types such as Enums and some structs. - BOOL IsTruePrimitive(); - void SetIsTruePrimitive(); + // ELEMENT_TYPE_R8, etc. + // Note that IsTruePrimitive returns false for enum types. + bool IsTruePrimitive(); + + // Like IsTruePrimitive but also returns true for enum types. + bool IsPrimitive(); // Is this delegate? Returns false for System.Delegate and System.MulticastDelegate. inline BOOL IsDelegate() @@ -3795,8 +3791,8 @@ public : enum_flag_Category_ValueType = 0x00040000, // [cDAC] [RuntimeTypeSystem]: Contract depends on this value enum_flag_Category_ValueType_Mask = 0x000C0000, enum_flag_Category_Nullable = 0x00050000, // sub-category of ValueType. [cDAC] [RuntimeTypeSystem]: Contract depends on this value - enum_flag_Category_PrimitiveValueType=0x00060000, // sub-category of ValueType, Enum or primitive value type. [cDAC] [RuntimeTypeSystem]: Contract depends on this value - enum_flag_Category_TruePrimitive = 0x00070000, // sub-category of ValueType, Primitive (ELEMENT_TYPE_I, etc.). [cDAC] [RuntimeTypeSystem]: Contract depends on this value + enum_flag_Category_Primitive = 0x00060000, // sub-category of ValueType; used for enum types. [cDAC] [RuntimeTypeSystem]: Contract depends on this value + enum_flag_Category_TruePrimitive = 0x00070000, // sub-category of ValueType. (Int32, etc.). [cDAC] [RuntimeTypeSystem]: Contract depends on this value enum_flag_Category_Array = 0x00080000, // [cDAC] [RuntimeTypeSystem]: Contract depends on this value enum_flag_Category_Array_Mask = 0x000C0000, // [cDAC] [RuntimeTypeSystem]: Contract depends on this value diff --git a/src/coreclr/vm/methodtable.inl b/src/coreclr/vm/methodtable.inl index 261ef7969eaebc..5bd6ddf711b680 100644 --- a/src/coreclr/vm/methodtable.inl +++ b/src/coreclr/vm/methodtable.inl @@ -316,17 +316,18 @@ inline DWORD MethodTable::GetRank() } //========================================================================================== -inline BOOL MethodTable::IsTruePrimitive() +inline bool MethodTable::IsTruePrimitive() { LIMITED_METHOD_DAC_CONTRACT; return GetFlag(enum_flag_Category_Mask) == enum_flag_Category_TruePrimitive; } //========================================================================================== -inline void MethodTable::SetIsTruePrimitive() +inline bool MethodTable::IsPrimitive() { LIMITED_METHOD_DAC_CONTRACT; - SetFlag(enum_flag_Category_TruePrimitive); + // enum_flag_Category_ElementTypeMask maps both Category_TruePrimitive and Category_Primitive here. + return GetFlag(enum_flag_Category_ElementTypeMask) == enum_flag_Category_Primitive; } //========================================================================================== diff --git a/src/coreclr/vm/methodtablebuilder.cpp b/src/coreclr/vm/methodtablebuilder.cpp index 038fa7a8d61417..fb16290b29e561 100644 --- a/src/coreclr/vm/methodtablebuilder.cpp +++ b/src/coreclr/vm/methodtablebuilder.cpp @@ -4450,7 +4450,7 @@ VOID MethodTableBuilder::InitializeFieldDescs(FieldDesc *pFieldDescList, SetHasFieldsWhichMustBeInited(); #ifdef FEATURE_READYTORUN - if (!(pByValueClass->IsTruePrimitive() || pByValueClass->IsEnum())) + if (!pByValueClass->IsPrimitive()) { CheckLayoutDependsOnOtherModules(pByValueClass); } @@ -10742,10 +10742,9 @@ void MethodTableBuilder::CheckForSystemTypes() // Check if it is a primitive type CorElementType type = CorTypeInfo::FindPrimitiveType(name); - if (type != ELEMENT_TYPE_END) + if (type != ELEMENT_TYPE_END && CorTypeInfo::IsPrimitiveType(type)) { - pMT->SetInternalCorElementType(type); - pMT->SetIsTruePrimitive(); + pMT->SetInternalCorElementType(type, true); #if defined(TARGET_X86) && defined(UNIX_X86_ABI) switch (type) @@ -10778,18 +10777,6 @@ void MethodTableBuilder::CheckForSystemTypes() { pMT->SetIsNullable(); } - else if (strcmp(name, g_RuntimeArgumentHandleName) == 0) - { - pMT->SetInternalCorElementType (ELEMENT_TYPE_I); - } - else if (strcmp(name, g_RuntimeMethodHandleInternalName) == 0) - { - pMT->SetInternalCorElementType (ELEMENT_TYPE_I); - } - else if (strcmp(name, g_RuntimeFieldHandleInternalName) == 0) - { - pMT->SetInternalCorElementType (ELEMENT_TYPE_I); - } else if ((strcmp(name, g_Int128Name) == 0) || (strcmp(name, g_UInt128Name) == 0)) { EEClassLayoutInfo* pLayout = pClass->GetLayoutInfo(); @@ -12031,7 +12018,7 @@ VOID MethodTableBuilder::CheckLayoutDependsOnOtherModules(MethodTable * pDepende STANDARD_VM_CONTRACT; // These cases are expected to be handled by the caller - _ASSERTE(!(pDependencyMT == g_pObjectClass || pDependencyMT->IsTruePrimitive() || ((g_pEnumClass != NULL) && pDependencyMT->IsEnum()))); + _ASSERTE(!(pDependencyMT == g_pObjectClass || pDependencyMT->IsPrimitive())); // // WARNING: Changes in this algorithm are potential ReadyToRun breaking changes !!! diff --git a/src/coreclr/vm/proftoeeinterfaceimpl.cpp b/src/coreclr/vm/proftoeeinterfaceimpl.cpp index 8869fd4f0397a4..9a88fbfe9380ce 100644 --- a/src/coreclr/vm/proftoeeinterfaceimpl.cpp +++ b/src/coreclr/vm/proftoeeinterfaceimpl.cpp @@ -1777,7 +1777,7 @@ HRESULT ProfToEEInterfaceImpl::IsArrayClass( // Fill in the type if they want it if (pBaseElemType != NULL) { - *pBaseElemType = th.GetArrayElementTypeHandle().GetVerifierCorElementType(); + *pBaseElemType = th.GetArrayElementTypeHandle().GetInternalCorElementType(); } // If this is an array of classes and they wish to have the base type diff --git a/src/coreclr/vm/reflectioninvocation.cpp b/src/coreclr/vm/reflectioninvocation.cpp index e48b733634a60d..3b0b32dd32ec20 100644 --- a/src/coreclr/vm/reflectioninvocation.cpp +++ b/src/coreclr/vm/reflectioninvocation.cpp @@ -63,7 +63,7 @@ extern "C" void QCALLTYPE RuntimeFieldHandle_SetValue(FieldDesc* fieldDesc, QCal GCPROTECT_BEGIN(gc); TypeHandle fieldTypeHandle = fieldType.AsTypeHandle(); - InvokeUtil::SetValidField(fieldTypeHandle.GetVerifierCorElementType(), fieldTypeHandle, fieldDesc, &gc.target, &gc.value, declaringType.AsTypeHandle(), pIsClassInitialized); + InvokeUtil::SetValidField(fieldTypeHandle.GetInternalCorElementType(), fieldTypeHandle, fieldDesc, &gc.target, &gc.value, declaringType.AsTypeHandle(), pIsClassInitialized); GCPROTECT_END(); END_QCALL; @@ -2012,7 +2012,7 @@ extern "C" void QCALLTYPE ReflectionInvocation_GetBoxInfo( MethodTable* pMT = type.AsMethodTable(); - _ASSERTE(pMT->IsValueType() || pMT->IsNullable() || pMT->IsEnum() || pMT->IsTruePrimitive()); + _ASSERTE(pMT->IsValueType()); *pValueOffset = 0; diff --git a/src/coreclr/vm/stubgen.cpp b/src/coreclr/vm/stubgen.cpp index 5edddb6afae093..622a5b987a98ed 100644 --- a/src/coreclr/vm/stubgen.cpp +++ b/src/coreclr/vm/stubgen.cpp @@ -1988,32 +1988,6 @@ void ILCodeStream::EmitLoadNullPtr() EmitCONV_I(); } -void ILCodeStream::EmitArgIteratorCreateAndLoad() -{ - STANDARD_VM_CONTRACT; - - // - // we insert the ArgIterator in the same spot that the VASigCookie will go for sanity - // - LocalDesc aiLoc(CoreLibBinder::GetClass(CLASS__ARG_ITERATOR)); - int aiLocNum; - - aiLocNum = NewLocal(aiLoc); - - EmitLDLOCA(aiLocNum); - EmitDUP(); - EmitARGLIST(); - EmitLoadNullPtr(); - EmitCALL(METHOD__ARG_ITERATOR__CTOR2, 2, 0); - - aiLoc.ElementType[0] = ELEMENT_TYPE_BYREF; - aiLoc.ElementType[1] = ELEMENT_TYPE_INTERNAL; - aiLoc.cbType = 2; - aiLoc.InternalToken = CoreLibBinder::GetClass(CLASS__ARG_ITERATOR); - - SetStubTargetArgType(&aiLoc, false); -} - DWORD ILStubLinker::NewLocal(CorElementType typ) { CONTRACTL diff --git a/src/coreclr/vm/stubgen.h b/src/coreclr/vm/stubgen.h index 783be59ccd2a85..59b0020ca75393 100644 --- a/src/coreclr/vm/stubgen.h +++ b/src/coreclr/vm/stubgen.h @@ -1075,7 +1075,6 @@ class ILCodeStream void EmitLabel(ILCodeLabel* pLabel); void EmitLoadThis (); void EmitLoadNullPtr(); - void EmitArgIteratorCreateAndLoad(); ILCodeLabel* NewCodeLabel(); diff --git a/src/coreclr/vm/typedesc.cpp b/src/coreclr/vm/typedesc.cpp index 09598f362c7452..5b5c6f807c9c2c 100644 --- a/src/coreclr/vm/typedesc.cpp +++ b/src/coreclr/vm/typedesc.cpp @@ -401,7 +401,7 @@ BOOL TypeDesc::CanCastParam(TypeHandle fromParam, TypeHandle toParam, TypeHandle return TRUE; // Object parameters dont need an exact match but only inheritance, check for that - CorElementType fromParamCorType = fromParam.GetVerifierCorElementType(); + CorElementType fromParamCorType = fromParam.GetInternalCorElementType(); if (CorTypeInfo::IsObjRef(fromParamCorType)) { return fromParam.CanCastTo(toParam, pVisited); @@ -420,7 +420,7 @@ BOOL TypeDesc::CanCastParam(TypeHandle fromParam, TypeHandle toParam, TypeHandle } else if(CorTypeInfo::IsPrimitiveType(fromParamCorType)) { - CorElementType toParamCorType = toParam.GetVerifierCorElementType(); + CorElementType toParamCorType = toParam.GetInternalCorElementType(); if(CorTypeInfo::IsPrimitiveType(toParamCorType)) { if (GetNormalizedIntegralArrayElementType(toParamCorType) == GetNormalizedIntegralArrayElementType(fromParamCorType)) diff --git a/src/coreclr/vm/typehandle.cpp b/src/coreclr/vm/typehandle.cpp index aba22ce2da4ab1..9c5cb10f2ca9cf 100644 --- a/src/coreclr/vm/typehandle.cpp +++ b/src/coreclr/vm/typehandle.cpp @@ -599,7 +599,7 @@ BOOL TypeHandle::IsBoxedAndCanCastTo(TypeHandle type, TypeHandlePairList *pPairL CONTRACTL_END - CorElementType fromParamCorType = GetVerifierCorElementType(); + CorElementType fromParamCorType = GetInternalCorElementType(); if (CorTypeInfo::IsObjRef(fromParamCorType)) { @@ -1212,24 +1212,6 @@ CorElementType TypeHandle::GetSignatureCorElementType() const } } -// As its name suggests, this returns the type used by the IL verifier. The basic difference between this -// type and the type in the meta-data is that enumerations have been normalized to their underlieing -// primitive type. see code:MethodTable#KindsOfElementTypes for more -CorElementType TypeHandle::GetVerifierCorElementType() const -{ - LIMITED_METHOD_CONTRACT; - - if (IsTypeDesc()) - { - return AsTypeDesc()->GetInternalCorElementType(); - } - else - { - return AsMethodTable()->GetVerifierCorElementType(); - } -} - - #ifdef DACCESS_COMPILE void diff --git a/src/coreclr/vm/typehandle.h b/src/coreclr/vm/typehandle.h index fcd8f3f35ac700..4dd6c48d28fa20 100644 --- a/src/coreclr/vm/typehandle.h +++ b/src/coreclr/vm/typehandle.h @@ -200,26 +200,10 @@ class TypeHandle // This helper: // - Will return enums underlying type // - Will return underlying primitive for System.Int32 etc... - // - Will return underlying primitive as will be used in the calling convention - // For example - // struct t - // { - // public int i; - // } - // will return ELEMENT_TYPE_I4 in x86 instead of ELEMENT_TYPE_VALUETYPE. We - // call this type of value type a primitive value type // - // Internal representation is used among another things for the calling convention - // (jit benefits of primitive value types) or optimizing marshalling. - // - // This will NOT convert E_T_ARRAY, E_T_SZARRAY etc. to E_T_CLASS (though it probably - // should). Use CorTypeInfo::IsObjRef for that. + // This will NOT convert E_T_ARRAY, E_T_SZARRAY etc. to E_T_CLASS. Use CorTypeInfo::IsObjRef for that. CorElementType GetInternalCorElementType() const; - // This helper will return the same as GetSignatureCorElementType except: - // - Will return enums underlying type - CorElementType GetVerifierCorElementType() const; - //------------------------------------------------------------------- // CASTING // diff --git a/src/coreclr/vm/zapsig.cpp b/src/coreclr/vm/zapsig.cpp index d73e609a01936d..1e9ad5ab145454 100644 --- a/src/coreclr/vm/zapsig.cpp +++ b/src/coreclr/vm/zapsig.cpp @@ -270,6 +270,8 @@ BOOL ZapSig::GetSignatureForTypeHandle(TypeHandle handle, elemType = ELEMENT_TYPE_OBJECT; else if (pMT == g_pStringClass) elemType = ELEMENT_TYPE_STRING; + else if (pMT == g_TypedReferenceMT) + elemType = ELEMENT_TYPE_TYPEDBYREF; else if (pMT == g_pCanonMethodTableClass) elemType = (CorElementType) ELEMENT_TYPE_CANON_ZAPSIG; else if (pMT->IsArray()) @@ -349,9 +351,11 @@ BOOL ZapSig::GetSignatureForTypeHandle(TypeHandle handle, case ELEMENT_TYPE_R8: case ELEMENT_TYPE_BOOLEAN: case ELEMENT_TYPE_CHAR: - case ELEMENT_TYPE_TYPEDBYREF: RETURN(sigType == handleType); + case ELEMENT_TYPE_TYPEDBYREF: + RETURN(handle == TypeHandle(g_TypedReferenceMT)); + case ELEMENT_TYPE_STRING: RETURN(handle == TypeHandle(g_pStringClass)); diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystem_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystem_1.cs index 08a724b7b05a53..e09129f2d1b38b 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystem_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystem_1.cs @@ -860,7 +860,7 @@ public CorElementType GetSignatureCorElementType(TypeHandle typeHandle) return CorElementType.SzArray; case MethodTableFlags_1.WFLAGS_HIGH.Category_ValueType: case MethodTableFlags_1.WFLAGS_HIGH.Category_Nullable: - case MethodTableFlags_1.WFLAGS_HIGH.Category_PrimitiveValueType: + case MethodTableFlags_1.WFLAGS_HIGH.Category_Primitive: return CorElementType.ValueType; case MethodTableFlags_1.WFLAGS_HIGH.Category_TruePrimitive: return (CorElementType)GetClassData(typeHandle).InternalCorElementType; @@ -908,18 +908,14 @@ public bool IsValueType(TypeHandle typeHandle) public bool IsEnum(TypeHandle typeHandle) { - // Enums have Category_PrimitiveValueType in their MethodTable flags and their + // Enums have Category_Primitive in their MethodTable flags and their // InternalCorElementType is a primitive type (I1, U1, I2, U2, I4, U4, I8, U8), - // not ValueType. Regular primitive value types (IntPtr/UIntPtr) have Category_TruePrimitive. + // not ValueType. if (!typeHandle.IsMethodTable()) return false; - CorElementType sigType = GetSignatureCorElementType(typeHandle); - if (sigType != CorElementType.ValueType) - return false; - - CorElementType internalType = (CorElementType)GetClassData(typeHandle).InternalCorElementType; - return internalType != CorElementType.ValueType; + MethodTable methodTable = _methodTables[typeHandle.Address]; + return methodTable.Flags.GetFlag(MethodTableFlags_1.WFLAGS_HIGH.Category_Mask) == MethodTableFlags_1.WFLAGS_HIGH.Category_Primitive; } // return true if the TypeHandle represents an array, and set the rank to either 0 (if the type is not an array), or the rank number if it is. diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/RuntimeTypeSystemHelpers/MethodTableFlags_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/RuntimeTypeSystemHelpers/MethodTableFlags_1.cs index 466d45a4ee4975..e82522b79c672e 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/RuntimeTypeSystemHelpers/MethodTableFlags_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/RuntimeTypeSystemHelpers/MethodTableFlags_1.cs @@ -42,7 +42,7 @@ internal enum WFLAGS_HIGH : uint Category_ElementType_Mask = 0x000E0000, Category_ValueType = 0x00040000, Category_Nullable = 0x00050000, - Category_PrimitiveValueType = 0x00060000, + Category_Primitive = 0x00060000, Category_TruePrimitive = 0x00070000, Category_Interface = 0x000C0000, Collectible = 0x00200000, // GC depends on this bit. diff --git a/src/native/managed/cdac/tests/MethodTableTests.cs b/src/native/managed/cdac/tests/MethodTableTests.cs index 6206d761650ffa..7bbe2743700689 100644 --- a/src/native/managed/cdac/tests/MethodTableTests.cs +++ b/src/native/managed/cdac/tests/MethodTableTests.cs @@ -574,7 +574,7 @@ public void IsValueTypeReturnsTrueForValueTypeCategories(MockTarget.Architecture { TargetPointer valueTypeMTPtr = default; TargetPointer nullableMTPtr = default; - TargetPointer primitiveValueTypeMTPtr = default; + TargetPointer enumMTPtr = default; TargetPointer truePrimitiveMTPtr = default; TestPlaceholderTarget target = CreateTarget( @@ -603,15 +603,15 @@ public void IsValueTypeReturnsTrueForValueTypeCategories(MockTarget.Architecture nullableMT.EEClassOrCanonMT = nullableEEClass.Address; nullableMTPtr = nullableMT.Address; - MockEEClass pvtEEClass = rtsBuilder.AddEEClass("PrimitiveValueTypeEEClass"); - MockMethodTable pvtMT = rtsBuilder.AddMethodTable("PrimitiveValueType"); - pvtMT.MTFlags = (uint)MethodTableFlags_1.WFLAGS_HIGH.Category_PrimitiveValueType; - pvtMT.BaseSize = rtsBuilder.Builder.TargetTestHelpers.ObjectBaseSize; - pvtMT.ParentMethodTable = systemObjectMethodTablePtr; - pvtMT.NumVirtuals = 3; - pvtEEClass.MethodTable = pvtMT.Address; - pvtMT.EEClassOrCanonMT = pvtEEClass.Address; - primitiveValueTypeMTPtr = pvtMT.Address; + MockEEClass enumEEClass = rtsBuilder.AddEEClass("EnumEEClass"); + MockMethodTable enumMT = rtsBuilder.AddMethodTable("Enum"); + enumMT.MTFlags = (uint)MethodTableFlags_1.WFLAGS_HIGH.Category_Primitive; + enumMT.BaseSize = rtsBuilder.Builder.TargetTestHelpers.ObjectBaseSize; + enumMT.ParentMethodTable = systemObjectMethodTablePtr; + enumMT.NumVirtuals = 3; + enumEEClass.MethodTable = enumMT.Address; + enumMT.EEClassOrCanonMT = enumEEClass.Address; + enumMTPtr = enumMT.Address; MockEEClass tpEEClass = rtsBuilder.AddEEClass("TruePrimitiveEEClass"); MockMethodTable tpMT = rtsBuilder.AddMethodTable("TruePrimitive"); @@ -628,7 +628,7 @@ public void IsValueTypeReturnsTrueForValueTypeCategories(MockTarget.Architecture Assert.True(contract.IsValueType(contract.GetTypeHandle(valueTypeMTPtr))); Assert.True(contract.IsValueType(contract.GetTypeHandle(nullableMTPtr))); - Assert.True(contract.IsValueType(contract.GetTypeHandle(primitiveValueTypeMTPtr))); + Assert.True(contract.IsValueType(contract.GetTypeHandle(enumMTPtr))); Assert.True(contract.IsValueType(contract.GetTypeHandle(truePrimitiveMTPtr))); } diff --git a/src/tests/JIT/Directed/PREFIX/unaligned/1/arglist.il b/src/tests/JIT/Directed/PREFIX/unaligned/1/arglist.il deleted file mode 100644 index 0532685d0d29bf..00000000000000 --- a/src/tests/JIT/Directed/PREFIX/unaligned/1/arglist.il +++ /dev/null @@ -1,120 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - - -/* -CompareArgs() works as such: - -CompareArgs(3,1,2,3,1,2,3) -Where arg0 is 1/2 the number of the -remaining arguments. - -And the arguments 1,2,3 and 1,2,3 are -treated as two separate lists of size -arg0 whose elements are compared to one -another. - -ie. in this case CompareArgs checks that -arg1==arg4, arg2==arg5, arg3==arg6. -*/ - -.assembly extern legacy library mscorlib {} -.assembly extern System.Runtime { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) } -.assembly extern xunit.core {} -.assembly extern Microsoft.DotNet.XUnitExtensions { .publickeytoken = (31 BF 38 56 AD 36 4E 35 ) } -.assembly extern TestLibrary { .ver 0:0:0:0 } -.assembly 'arglist_Target_32BIT_unaligned_1'{ //This byte field requests that this assembly not be verified at run time and corresponds to this C# declaration: - //[assembly:System.Security.Permissions.SecurityPermissionAttribute( [mscorlib]System.Security.Permissions.SecurityAction.RequestMinimum, Flags=System.Security.Permissions.SecurityPermissionFlag.SkipVerification )] - } - -.method static vararg int32 CompareArgs(int32){ -.locals(int32 currentindex, int32 loopconstant) -.maxstack 10 -.try{ - ldc.i4 1 - stloc currentindex - ldarg 0 - stloc loopconstant -LOOP: ldloc currentindex - ldc.i4 4 - mul - arglist - add - unaligned. 0x1 - ldind.i4 - ldloc currentindex - ldloc loopconstant - add - ldc.i4 4 - mul - arglist - add - unaligned. 0x1 - ldind.i4 - ceq - brfalse EXITWITHFAIL - ldloc currentindex - ldloc loopconstant - beq EXITWITHPASS - ldc.i4 1 - ldloc currentindex - add - stloc currentindex - br LOOP - EXITWITHPASS: - leave SUCCESS - EXITWITHFAIL: - leave FAIL -}catch [mscorlib]System.NullReferenceException{ - pop - leave FAIL -} -SUCCESS: - ldc.i4 0x64 - ret -FAIL: - ldc.i4 0x0 -REALLYDONE: - ret -} - -//------------------------- -// Entry point - Main - -//------------------------- -.class public auto ansi arglist_ { -.method public static int32 main() { -.custom instance void [Microsoft.DotNet.XUnitExtensions]Xunit.ConditionalFactAttribute::.ctor(class [System.Runtime]System.Type, string[]) = { - type([TestLibrary]TestLibrary.PlatformDetection) - string[2] ('IsVarArgSupported' 'Is32BitProcess') -} -.entrypoint -.locals () -.maxstack 10 - - ldc.i4 1 - ldc.i4 1 - ldc.i4 1 - call vararg int32 CompareArgs(int32,...,int32,int32) - brfalse FAIL - - ldc.i4 4 - ldc.i4 2 - ldc.i4 3 - ldc.i4 4 - ldc.i4 5 - ldc.i4 2 - ldc.i4 3 - ldc.i4 4 - ldc.i4 5 - call vararg int32 CompareArgs(int32,...,int32,int32,int32,int32,int32,int32,int32,int32) - brfalse FAIL - - -PASS: - ldc.i4 0x64 - ret -FAIL: - ldc.i4 0x0 - ret -} -} diff --git a/src/tests/JIT/Directed/PREFIX/unaligned/1/arglist64.il b/src/tests/JIT/Directed/PREFIX/unaligned/1/arglist64.il deleted file mode 100644 index 6f1fa83cf64b85..00000000000000 --- a/src/tests/JIT/Directed/PREFIX/unaligned/1/arglist64.il +++ /dev/null @@ -1,130 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - - -/* -CompareArgs() works as such: - -CompareArgs(3,1,2,3,1,2,3) -Where arg0 is 1/2 the number of the -remaining arguments. - -And the arguments 1,2,3 and 1,2,3 are -treated as two separate lists of size -arg0 whose elements are compared to one -another. - -ie. in this case CompareArgs checks that -arg1==arg4, arg2==arg5, arg3==arg6. -*/ - -.assembly extern legacy library mscorlib {} -.assembly extern System.Runtime { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) } -.assembly extern xunit.core {} -.assembly extern Microsoft.DotNet.XUnitExtensions { .publickeytoken = (31 BF 38 56 AD 36 4E 35 ) } -.assembly extern TestLibrary { .ver 0:0:0:0 } -.assembly 'arglist_Target_64BIT_unaligned_1'{ //This byte field requests that this assembly not be verified at run time and corresponds to this C# declaration: - //[assembly:System.Security.Permissions.SecurityPermissionAttribute( [mscorlib]System.Security.Permissions.SecurityAction.RequestMinimum, Flags=System.Security.Permissions.SecurityPermissionFlag.SkipVerification )] - } - -/* -CompareArgs(5,1,2,3,4,5,1,2,3,4,5) -arglist on x86: 5,4,3,2,1,5,4,3,2,1,5 - ^ index 1 -arglist on ia64: 5,1,2,3,4,5,1,2,3,4,5 - ^ index 1 -*/ - -.method static vararg int32 CompareArgs(int32){ -.locals(int32 currentindex, int32 loopconstant) -.maxstack 10 -.try{ - ldc.i4 2 - stloc currentindex - ldarg 0 - stloc loopconstant -LOOP: ldloc currentindex - ldc.i4 8 - mul - arglist - add - unaligned. 0x1 - ldind.i4 - ldloc currentindex - ldloc loopconstant - add - ldc.i4 8 - mul - arglist - add - unaligned. 0x1 - ldind.i4 - ceq - brfalse EXITWITHFAIL - ldloc currentindex - ldloc loopconstant - ldc.i4 1 - add - beq EXITWITHPASS - ldc.i4 1 - ldloc currentindex - add - stloc currentindex - br LOOP - EXITWITHPASS: - leave SUCCESS - EXITWITHFAIL: - leave FAIL -}catch [mscorlib]System.NullReferenceException{ - pop - leave FAIL -} -SUCCESS: - ldc.i4 0x64 - ret -FAIL: - ldc.i4 0x0 -REALLYDONE: - ret -} - -//------------------------- -// Entry point - Main - -//------------------------- -.class public auto ansi arglist64 { -.method public static int32 main() { -.custom instance void [Microsoft.DotNet.XUnitExtensions]Xunit.ConditionalFactAttribute::.ctor(class [System.Runtime]System.Type, string[]) = { - type([TestLibrary]TestLibrary.PlatformDetection) - string[2] ('IsVarArgSupported' 'Is64BitProcess') -} -.entrypoint -.locals () -.maxstack 10 - - ldc.i4 1 - ldc.i4 1 - ldc.i4 1 - call vararg int32 CompareArgs(int32,...,int32,int32) - brfalse FAIL - - ldc.i4 4 - ldc.i4 2 - ldc.i4 3 - ldc.i4 4 - ldc.i4 5 - ldc.i4 2 - ldc.i4 3 - ldc.i4 4 - ldc.i4 5 - call vararg int32 CompareArgs(int32,...,int32,int32,int32,int32,int32,int32,int32,int32) - brfalse FAIL - - -PASS: - ldc.i4 0x64 - ret -FAIL: - ldc.i4 0x0 - ret -} -} diff --git a/src/tests/JIT/Directed/PREFIX/unaligned/1/arglist_Target_32BIT_unaligned_1.ilproj b/src/tests/JIT/Directed/PREFIX/unaligned/1/arglist_Target_32BIT_unaligned_1.ilproj deleted file mode 100644 index 3234fb9c227478..00000000000000 --- a/src/tests/JIT/Directed/PREFIX/unaligned/1/arglist_Target_32BIT_unaligned_1.ilproj +++ /dev/null @@ -1,13 +0,0 @@ - - - 1 - PdbOnly - True - - - - - - - - diff --git a/src/tests/JIT/Directed/PREFIX/unaligned/1/arglist_Target_64BIT_unaligned_1.ilproj b/src/tests/JIT/Directed/PREFIX/unaligned/1/arglist_Target_64BIT_unaligned_1.ilproj deleted file mode 100644 index 055cae36837025..00000000000000 --- a/src/tests/JIT/Directed/PREFIX/unaligned/1/arglist_Target_64BIT_unaligned_1.ilproj +++ /dev/null @@ -1,13 +0,0 @@ - - - 1 - PdbOnly - True - - - - - - - - diff --git a/src/tests/JIT/Directed/PREFIX/unaligned/2/arglist.il b/src/tests/JIT/Directed/PREFIX/unaligned/2/arglist.il deleted file mode 100644 index 5bf6173d595516..00000000000000 --- a/src/tests/JIT/Directed/PREFIX/unaligned/2/arglist.il +++ /dev/null @@ -1,121 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - - -/* -CompareArgs() works as such: - -CompareArgs(3,1,2,3,1,2,3) -Where arg0 is 1/2 the number of the -remaining arguments. - -And the arguments 1,2,3 and 1,2,3 are -treated as two separate lists of size -arg0 whose elements are compared to one -another. - -ie. in this case CompareArgs checks that -arg1==arg4, arg2==arg5, arg3==arg6. -*/ - -.assembly extern legacy library mscorlib {} -.assembly extern System.Runtime { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) } -.assembly extern xunit.core {} -.assembly extern Microsoft.DotNet.XUnitExtensions { .publickeytoken = (31 BF 38 56 AD 36 4E 35 ) } -.assembly extern TestLibrary { .ver 0:0:0:0 } -.assembly 'arglist_Target_32BIT_unaligned_2'{ //This byte field requests that this assembly not be verified at run time and corresponds to this C# declaration: - //[assembly:System.Security.Permissions.SecurityPermissionAttribute( [mscorlib]System.Security.Permissions.SecurityAction.RequestMinimum, Flags=System.Security.Permissions.SecurityPermissionFlag.SkipVerification )] - } - -.method static vararg int32 CompareArgs(int32){ -.locals(int32 currentindex, int32 loopconstant) -.maxstack 10 -.try{ - ldc.i4 1 - stloc currentindex - ldarg 0 - stloc loopconstant -LOOP: ldloc currentindex - ldc.i4 4 - mul - arglist - add - unaligned. 0x2 - ldind.i4 - ldloc currentindex - ldloc loopconstant - add - ldc.i4 4 - mul - arglist - add - unaligned. 0x2 - ldind.i4 - ceq - brfalse EXITWITHFAIL - ldloc currentindex - ldloc loopconstant - beq EXITWITHPASS - ldc.i4 1 - ldloc currentindex - add - stloc currentindex - br LOOP - EXITWITHPASS: - leave SUCCESS - EXITWITHFAIL: - leave FAIL -}catch [mscorlib]System.NullReferenceException{ - pop - leave FAIL - -} -SUCCESS: - ldc.i4 0x64 - ret -FAIL: - ldc.i4 0x0 -REALLYDONE: - ret -} - -//------------------------- -// Entry point - Main - -//------------------------- -.class public auto ansi arglist_ { -.method public static int32 main() { -.custom instance void [Microsoft.DotNet.XUnitExtensions]Xunit.ConditionalFactAttribute::.ctor(class [System.Runtime]System.Type, string[]) = { - type([TestLibrary]TestLibrary.PlatformDetection) - string[2] ('IsVarArgSupported' 'Is32BitProcess') -} -.entrypoint -.locals () -.maxstack 10 - - ldc.i4 1 - ldc.i4 1 - ldc.i4 1 - call vararg int32 CompareArgs(int32,...,int32,int32) - brfalse FAIL - - ldc.i4 4 - ldc.i4 2 - ldc.i4 3 - ldc.i4 4 - ldc.i4 5 - ldc.i4 2 - ldc.i4 3 - ldc.i4 4 - ldc.i4 5 - call vararg int32 CompareArgs(int32,...,int32,int32,int32,int32,int32,int32,int32,int32) - brfalse FAIL - - -PASS: - ldc.i4 0x64 - ret -FAIL: - ldc.i4 0x0 - ret -} -} diff --git a/src/tests/JIT/Directed/PREFIX/unaligned/2/arglist64.il b/src/tests/JIT/Directed/PREFIX/unaligned/2/arglist64.il deleted file mode 100644 index 8a9e5da878b4ac..00000000000000 --- a/src/tests/JIT/Directed/PREFIX/unaligned/2/arglist64.il +++ /dev/null @@ -1,130 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - - -/* -CompareArgs() works as such: - -CompareArgs(3,1,2,3,1,2,3) -Where arg0 is 1/2 the number of the -remaining arguments. - -And the arguments 1,2,3 and 1,2,3 are -treated as two separate lists of size -arg0 whose elements are compared to one -another. - -ie. in this case CompareArgs checks that -arg1==arg4, arg2==arg5, arg3==arg6. -*/ - -.assembly extern legacy library mscorlib {} -.assembly extern System.Runtime { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) } -.assembly extern xunit.core {} -.assembly extern Microsoft.DotNet.XUnitExtensions { .publickeytoken = (31 BF 38 56 AD 36 4E 35 ) } -.assembly extern TestLibrary { .ver 0:0:0:0 } -.assembly 'arglist_Target_64BIT_unaligned_2'{ //This byte field requests that this assembly not be verified at run time and corresponds to this C# declaration: - //[assembly:System.Security.Permissions.SecurityPermissionAttribute( [mscorlib]System.Security.Permissions.SecurityAction.RequestMinimum, Flags=System.Security.Permissions.SecurityPermissionFlag.SkipVerification )] - } - -/* -CompareArgs(5,1,2,3,4,5,1,2,3,4,5) -arglist on x86: 5,4,3,2,1,5,4,3,2,1,5 - ^ index 1 -arglist on ia64: 5,1,2,3,4,5,1,2,3,4,5 - ^ index 1 -*/ - -.method static vararg int32 CompareArgs(int32){ -.locals(int32 currentindex, int32 loopconstant) -.maxstack 10 -.try{ - ldc.i4 2 - stloc currentindex - ldarg 0 - stloc loopconstant -LOOP: ldloc currentindex - ldc.i4 8 - mul - arglist - add - unaligned. 0x2 - ldind.i4 - ldloc currentindex - ldloc loopconstant - add - ldc.i4 8 - mul - arglist - add - unaligned. 0x2 - ldind.i4 - ceq - brfalse EXITWITHFAIL - ldloc currentindex - ldloc loopconstant - ldc.i4 1 - add - beq EXITWITHPASS - ldc.i4 1 - ldloc currentindex - add - stloc currentindex - br LOOP - EXITWITHPASS: - leave SUCCESS - EXITWITHFAIL: - leave FAIL -}catch [mscorlib]System.NullReferenceException{ - pop - leave FAIL -} -SUCCESS: - ldc.i4 0x64 - ret -FAIL: - ldc.i4 0x0 -REALLYDONE: - ret -} - -//------------------------- -// Entry point - Main - -//------------------------- -.class public auto ansi arglist64 { -.method public static int32 main() { -.custom instance void [Microsoft.DotNet.XUnitExtensions]Xunit.ConditionalFactAttribute::.ctor(class [System.Runtime]System.Type, string[]) = { - type([TestLibrary]TestLibrary.PlatformDetection) - string[2] ('IsVarArgSupported' 'Is64BitProcess') -} -.entrypoint -.locals () -.maxstack 10 - - ldc.i4 1 - ldc.i4 1 - ldc.i4 1 - call vararg int32 CompareArgs(int32,...,int32,int32) - brfalse FAIL - - ldc.i4 4 - ldc.i4 2 - ldc.i4 3 - ldc.i4 4 - ldc.i4 5 - ldc.i4 2 - ldc.i4 3 - ldc.i4 4 - ldc.i4 5 - call vararg int32 CompareArgs(int32,...,int32,int32,int32,int32,int32,int32,int32,int32) - brfalse FAIL - - -PASS: - ldc.i4 0x64 - ret -FAIL: - ldc.i4 0x0 - ret -} -} diff --git a/src/tests/JIT/Directed/PREFIX/unaligned/2/arglist_Target_32BIT_unaligned_2.ilproj b/src/tests/JIT/Directed/PREFIX/unaligned/2/arglist_Target_32BIT_unaligned_2.ilproj deleted file mode 100644 index 3234fb9c227478..00000000000000 --- a/src/tests/JIT/Directed/PREFIX/unaligned/2/arglist_Target_32BIT_unaligned_2.ilproj +++ /dev/null @@ -1,13 +0,0 @@ - - - 1 - PdbOnly - True - - - - - - - - diff --git a/src/tests/JIT/Directed/PREFIX/unaligned/2/arglist_Target_64BIT_unaligned_2.ilproj b/src/tests/JIT/Directed/PREFIX/unaligned/2/arglist_Target_64BIT_unaligned_2.ilproj deleted file mode 100644 index 055cae36837025..00000000000000 --- a/src/tests/JIT/Directed/PREFIX/unaligned/2/arglist_Target_64BIT_unaligned_2.ilproj +++ /dev/null @@ -1,13 +0,0 @@ - - - 1 - PdbOnly - True - - - - - - - - diff --git a/src/tests/JIT/Directed/PREFIX/unaligned/4/arglist.il b/src/tests/JIT/Directed/PREFIX/unaligned/4/arglist.il deleted file mode 100644 index 72759c71d8f357..00000000000000 --- a/src/tests/JIT/Directed/PREFIX/unaligned/4/arglist.il +++ /dev/null @@ -1,120 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - - -/* -CompareArgs() works as such: - -CompareArgs(3,1,2,3,1,2,3) -Where arg0 is 1/2 the number of the -remaining arguments. - -And the arguments 1,2,3 and 1,2,3 are -treated as two separate lists of size -arg0 whose elements are compared to one -another. - -ie. in this case CompareArgs checks that -arg1==arg4, arg2==arg5, arg3==arg6. -*/ - -.assembly extern legacy library mscorlib {} -.assembly extern System.Runtime { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) } -.assembly extern xunit.core {} -.assembly extern Microsoft.DotNet.XUnitExtensions { .publickeytoken = (31 BF 38 56 AD 36 4E 35 ) } -.assembly extern TestLibrary { .ver 0:0:0:0 } -.assembly 'arglist_Target_32BIT_unaligned_4'{ //This byte field requests that this assembly not be verified at run time and corresponds to this C# declaration: - //[assembly:System.Security.Permissions.SecurityPermissionAttribute( [mscorlib]System.Security.Permissions.SecurityAction.RequestMinimum, Flags=System.Security.Permissions.SecurityPermissionFlag.SkipVerification )] - } - -.method static vararg int32 CompareArgs(int32){ -.locals(int32 currentindex, int32 loopconstant) -.maxstack 10 -.try{ - ldc.i4 1 - stloc currentindex - ldarg 0 - stloc loopconstant -LOOP: ldloc currentindex - ldc.i4 4 - mul - arglist - add - unaligned. 0x4 - ldind.i4 - ldloc currentindex - ldloc loopconstant - add - ldc.i4 4 - mul - arglist - add - unaligned. 0x4 - ldind.i4 - ceq - brfalse EXITWITHFAIL - ldloc currentindex - ldloc loopconstant - beq EXITWITHPASS - ldc.i4 1 - ldloc currentindex - add - stloc currentindex - br LOOP - EXITWITHPASS: - leave SUCCESS - EXITWITHFAIL: - leave FAIL -}catch [mscorlib]System.NullReferenceException{ - pop - leave FAIL -} -SUCCESS: - ldc.i4 0x64 - ret -FAIL: - ldc.i4 0x0 -REALLYDONE: - ret -} - -//------------------------- -// Entry point - Main - -//------------------------- -.class public auto ansi arglist_ { -.method public static int32 main() { -.custom instance void [Microsoft.DotNet.XUnitExtensions]Xunit.ConditionalFactAttribute::.ctor(class [System.Runtime]System.Type, string[]) = { - type([TestLibrary]TestLibrary.PlatformDetection) - string[2] ('IsVarArgSupported' 'Is32BitProcess') -} -.entrypoint -.locals () -.maxstack 10 - - ldc.i4 1 - ldc.i4 1 - ldc.i4 1 - call vararg int32 CompareArgs(int32,...,int32,int32) - brfalse FAIL - - ldc.i4 4 - ldc.i4 2 - ldc.i4 3 - ldc.i4 4 - ldc.i4 5 - ldc.i4 2 - ldc.i4 3 - ldc.i4 4 - ldc.i4 5 - call vararg int32 CompareArgs(int32,...,int32,int32,int32,int32,int32,int32,int32,int32) - brfalse FAIL - - -PASS: - ldc.i4 0x64 - ret -FAIL: - ldc.i4 0x0 - ret -} -} diff --git a/src/tests/JIT/Directed/PREFIX/unaligned/4/arglist64.il b/src/tests/JIT/Directed/PREFIX/unaligned/4/arglist64.il deleted file mode 100644 index bf03122112a91c..00000000000000 --- a/src/tests/JIT/Directed/PREFIX/unaligned/4/arglist64.il +++ /dev/null @@ -1,130 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - - -/* -CompareArgs() works as such: - -CompareArgs(3,1,2,3,1,2,3) -Where arg0 is 1/2 the number of the -remaining arguments. - -And the arguments 1,2,3 and 1,2,3 are -treated as two separate lists of size -arg0 whose elements are compared to one -another. - -ie. in this case CompareArgs checks that -arg1==arg4, arg2==arg5, arg3==arg6. -*/ - -.assembly extern legacy library mscorlib {} -.assembly extern System.Runtime { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) } -.assembly extern xunit.core {} -.assembly extern Microsoft.DotNet.XUnitExtensions { .publickeytoken = (31 BF 38 56 AD 36 4E 35 ) } -.assembly extern TestLibrary { .ver 0:0:0:0 } -.assembly 'arglist_Target_64BIT_unaligned_4'{ //This byte field requests that this assembly not be verified at run time and corresponds to this C# declaration: - //[assembly:System.Security.Permissions.SecurityPermissionAttribute( [mscorlib]System.Security.Permissions.SecurityAction.RequestMinimum, Flags=System.Security.Permissions.SecurityPermissionFlag.SkipVerification )] - } - -/* -CompareArgs(5,1,2,3,4,5,1,2,3,4,5) -arglist on x86: 5,4,3,2,1,5,4,3,2,1,5 - ^ index 1 -arglist on ia64: 5,1,2,3,4,5,1,2,3,4,5 - ^ index 1 -*/ - -.method static vararg int32 CompareArgs(int32){ -.locals(int32 currentindex, int32 loopconstant) -.maxstack 10 -.try{ - ldc.i4 2 - stloc currentindex - ldarg 0 - stloc loopconstant -LOOP: ldloc currentindex - ldc.i4 8 - mul - arglist - add - unaligned. 0x4 - ldind.i4 - ldloc currentindex - ldloc loopconstant - add - ldc.i4 8 - mul - arglist - add - unaligned. 0x4 - ldind.i4 - ceq - brfalse EXITWITHFAIL - ldloc currentindex - ldloc loopconstant - ldc.i4 1 - add - beq EXITWITHPASS - ldc.i4 1 - ldloc currentindex - add - stloc currentindex - br LOOP - EXITWITHPASS: - leave SUCCESS - EXITWITHFAIL: - leave FAIL -}catch [mscorlib]System.NullReferenceException{ - pop - leave FAIL -} -SUCCESS: - ldc.i4 0x64 - ret -FAIL: - ldc.i4 0x0 -REALLYDONE: - ret -} - -//------------------------- -// Entry point - Main - -//------------------------- -.class public auto ansi arglist64 { -.method public static int32 main() { -.custom instance void [Microsoft.DotNet.XUnitExtensions]Xunit.ConditionalFactAttribute::.ctor(class [System.Runtime]System.Type, string[]) = { - type([TestLibrary]TestLibrary.PlatformDetection) - string[2] ('IsVarArgSupported' 'Is64BitProcess') -} -.entrypoint -.locals () -.maxstack 10 - - ldc.i4 1 - ldc.i4 1 - ldc.i4 1 - call vararg int32 CompareArgs(int32,...,int32,int32) - brfalse FAIL - - ldc.i4 4 - ldc.i4 2 - ldc.i4 3 - ldc.i4 4 - ldc.i4 5 - ldc.i4 2 - ldc.i4 3 - ldc.i4 4 - ldc.i4 5 - call vararg int32 CompareArgs(int32,...,int32,int32,int32,int32,int32,int32,int32,int32) - brfalse FAIL - - -PASS: - ldc.i4 0x64 - ret -FAIL: - ldc.i4 0x0 - ret -} -} diff --git a/src/tests/JIT/Directed/PREFIX/unaligned/4/arglist_Target_32BIT_unaligned_4.ilproj b/src/tests/JIT/Directed/PREFIX/unaligned/4/arglist_Target_32BIT_unaligned_4.ilproj deleted file mode 100644 index 3234fb9c227478..00000000000000 --- a/src/tests/JIT/Directed/PREFIX/unaligned/4/arglist_Target_32BIT_unaligned_4.ilproj +++ /dev/null @@ -1,13 +0,0 @@ - - - 1 - PdbOnly - True - - - - - - - - diff --git a/src/tests/JIT/Directed/PREFIX/unaligned/4/arglist_Target_64BIT_unaligned_4.ilproj b/src/tests/JIT/Directed/PREFIX/unaligned/4/arglist_Target_64BIT_unaligned_4.ilproj deleted file mode 100644 index 055cae36837025..00000000000000 --- a/src/tests/JIT/Directed/PREFIX/unaligned/4/arglist_Target_64BIT_unaligned_4.ilproj +++ /dev/null @@ -1,13 +0,0 @@ - - - 1 - PdbOnly - True - - - - - - - - diff --git a/src/tests/JIT/Directed/PREFIX/volatile/1/arglist.il b/src/tests/JIT/Directed/PREFIX/volatile/1/arglist.il deleted file mode 100644 index 4698f52c0d4528..00000000000000 --- a/src/tests/JIT/Directed/PREFIX/volatile/1/arglist.il +++ /dev/null @@ -1,122 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - - -/* -CompareArgs() works as such: - -CompareArgs(3,1,2,3,1,2,3) -Where arg0 is 1/2 the number of the -remaining arguments. - -And the arguments 1,2,3 and 1,2,3 are -treated as two separate lists of size -arg0 whose elements are compared to one -another. - -ie. in this case CompareArgs checks that -arg1==arg4, arg2==arg5, arg3==arg6. -*/ - -.assembly extern legacy library mscorlib {} -.assembly extern System.Runtime { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) } -.assembly extern xunit.core {} -.assembly extern Microsoft.DotNet.XUnitExtensions { .publickeytoken = (31 BF 38 56 AD 36 4E 35 ) } -.assembly extern TestLibrary { .ver 0:0:0:0 } -.assembly 'arglist_Target_32BIT_volatile'{ //This byte field requests that this assembly not be verified at run time and corresponds to this C# declaration: - //[assembly:System.Security.Permissions.SecurityPermissionAttribute( [mscorlib]System.Security.Permissions.SecurityAction.RequestMinimum, Flags=System.Security.Permissions.SecurityPermissionFlag.SkipVerification )] - } - -.method static vararg int32 CompareArgs(int32){ -.locals(int32 currentindex, int32 loopconstant) -.maxstack 10 -.try{ - ldc.i4 1 - stloc currentindex - ldarg 0 - stloc loopconstant -LOOP: ldloc currentindex - ldc.i4 4 - mul - arglist - add - volatile. - unaligned. 0x1 - ldind.i4 - ldloc currentindex - ldloc loopconstant - add - ldc.i4 4 - mul - arglist - add - volatile. - unaligned. 0x1 - ldind.i4 - ceq - brfalse EXITWITHFAIL - ldloc currentindex - ldloc loopconstant - beq EXITWITHPASS - ldc.i4 1 - ldloc currentindex - add - stloc currentindex - br LOOP - EXITWITHPASS: - leave SUCCESS - EXITWITHFAIL: - leave FAIL -}catch [mscorlib]System.NullReferenceException{ - pop - leave FAIL -} -SUCCESS: - ldc.i4 0x64 - ret -FAIL: - ldc.i4 0x0 -REALLYDONE: - ret -} - -//------------------------- -// Entry point - Main - -//------------------------- -.class public auto ansi arglist_ { -.method public static int32 main() { -.custom instance void [Microsoft.DotNet.XUnitExtensions]Xunit.ConditionalFactAttribute::.ctor(class [System.Runtime]System.Type, string[]) = { - type([TestLibrary]TestLibrary.PlatformDetection) - string[2] ('IsVarArgSupported' 'Is32BitProcess') -} -.entrypoint -.locals () -.maxstack 10 - - ldc.i4 1 - ldc.i4 1 - ldc.i4 1 - call vararg int32 CompareArgs(int32,...,int32,int32) - brfalse FAIL - - ldc.i4 4 - ldc.i4 2 - ldc.i4 3 - ldc.i4 4 - ldc.i4 5 - ldc.i4 2 - ldc.i4 3 - ldc.i4 4 - ldc.i4 5 - call vararg int32 CompareArgs(int32,...,int32,int32,int32,int32,int32,int32,int32,int32) - brfalse FAIL - - -PASS: - ldc.i4 0x64 - ret -FAIL: - ldc.i4 0x0 - ret -} -} diff --git a/src/tests/JIT/Directed/PREFIX/volatile/1/arglist64.il b/src/tests/JIT/Directed/PREFIX/volatile/1/arglist64.il deleted file mode 100644 index 393704f1fb28a2..00000000000000 --- a/src/tests/JIT/Directed/PREFIX/volatile/1/arglist64.il +++ /dev/null @@ -1,130 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - - -/* -CompareArgs() works as such: - -CompareArgs(3,1,2,3,1,2,3) -Where arg0 is 1/2 the number of the -remaining arguments. - -And the arguments 1,2,3 and 1,2,3 are -treated as two separate lists of size -arg0 whose elements are compared to one -another. - -ie. in this case CompareArgs checks that -arg1==arg4, arg2==arg5, arg3==arg6. -*/ - -.assembly extern legacy library mscorlib {} -.assembly extern System.Runtime { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) } -.assembly extern xunit.core {} -.assembly extern Microsoft.DotNet.XUnitExtensions { .publickeytoken = (31 BF 38 56 AD 36 4E 35 ) } -.assembly extern TestLibrary { .ver 0:0:0:0 } -.assembly 'arglist_Target_64BIT_volatile'{ //This byte field requests that this assembly not be verified at run time and corresponds to this C# declaration: - //[assembly:System.Security.Permissions.SecurityPermissionAttribute( [mscorlib]System.Security.Permissions.SecurityAction.RequestMinimum, Flags=System.Security.Permissions.SecurityPermissionFlag.SkipVerification )] - } - -/* -CompareArgs(5,1,2,3,4,5,1,2,3,4,5) -arglist on x86: 5,4,3,2,1,5,4,3,2,1,5 - ^ index 1 -arglist on ia64: 5,1,2,3,4,5,1,2,3,4,5 - ^ index 1 -*/ - -.method static vararg int32 CompareArgs(int32){ -.locals(int32 currentindex, int32 loopconstant) -.maxstack 10 -.try{ - ldc.i4 2 - stloc currentindex - ldarg 0 - stloc loopconstant -LOOP: ldloc currentindex - ldc.i4 8 - mul - arglist - add - volatile. - ldind.i4 - ldloc currentindex - ldloc loopconstant - add - ldc.i4 8 - mul - arglist - add - volatile. - ldind.i4 - ceq - brfalse EXITWITHFAIL - ldloc currentindex - ldloc loopconstant - ldc.i4 1 - add - beq EXITWITHPASS - ldc.i4 1 - ldloc currentindex - add - stloc currentindex - br LOOP - EXITWITHPASS: - leave SUCCESS - EXITWITHFAIL: - leave FAIL -}catch [mscorlib]System.NullReferenceException{ - pop - leave FAIL -} -SUCCESS: - ldc.i4 0x64 - ret -FAIL: - ldc.i4 0x0 -REALLYDONE: - ret -} - -//------------------------- -// Entry point - Main - -//------------------------- -.class public auto ansi arglist64 { -.method public static int32 main() { -.custom instance void [Microsoft.DotNet.XUnitExtensions]Xunit.ConditionalFactAttribute::.ctor(class [System.Runtime]System.Type, string[]) = { - type([TestLibrary]TestLibrary.PlatformDetection) - string[2] ('IsVarArgSupported' 'Is64BitProcess') -} -.entrypoint -.locals () -.maxstack 10 - - ldc.i4 1 - ldc.i4 1 - ldc.i4 1 - call vararg int32 CompareArgs(int32,...,int32,int32) - brfalse FAIL - - ldc.i4 4 - ldc.i4 2 - ldc.i4 3 - ldc.i4 4 - ldc.i4 5 - ldc.i4 2 - ldc.i4 3 - ldc.i4 4 - ldc.i4 5 - call vararg int32 CompareArgs(int32,...,int32,int32,int32,int32,int32,int32,int32,int32) - brfalse FAIL - - -PASS: - ldc.i4 0x64 - ret -FAIL: - ldc.i4 0x0 - ret -} -} diff --git a/src/tests/JIT/Directed/PREFIX/volatile/1/arglist_Target_32BIT_volatile.ilproj b/src/tests/JIT/Directed/PREFIX/volatile/1/arglist_Target_32BIT_volatile.ilproj deleted file mode 100644 index 3234fb9c227478..00000000000000 --- a/src/tests/JIT/Directed/PREFIX/volatile/1/arglist_Target_32BIT_volatile.ilproj +++ /dev/null @@ -1,13 +0,0 @@ - - - 1 - PdbOnly - True - - - - - - - - diff --git a/src/tests/JIT/Directed/PREFIX/volatile/1/arglist_Target_64BIT_volatile.ilproj b/src/tests/JIT/Directed/PREFIX/volatile/1/arglist_Target_64BIT_volatile.ilproj deleted file mode 100644 index 055cae36837025..00000000000000 --- a/src/tests/JIT/Directed/PREFIX/volatile/1/arglist_Target_64BIT_volatile.ilproj +++ /dev/null @@ -1,13 +0,0 @@ - - - 1 - PdbOnly - True - - - - - - - - diff --git a/src/tests/JIT/Directed/arglist/vararg.cs b/src/tests/JIT/Directed/arglist/vararg.cs index 311279dc339e50..f9a8937bd72f0f 100644 --- a/src/tests/JIT/Directed/arglist/vararg.cs +++ b/src/tests/JIT/Directed/arglist/vararg.cs @@ -1067,6 +1067,34 @@ static bool TestPassingIntsManaged(int[] expectedValues) return sum == expectedSum; } + /// + /// Given an input set create an arglist to pass to a vararg callee. + /// + /// The callee will pass the RuntimeArgumentHandle to another method, + /// which will then loop over the arguments, compute the sum and + /// return the value. + /// + /// Do a quick check on the value returned, and return whether they + /// are equal. + /// + /// + /// + /// bool + [MethodImpl(MethodImplOptions.NoInlining)] + static bool TestPassingRuntimeArgumentHandleManaged(int[] expectedValues) + { + Debug.Assert(expectedValues.Length == 4); + int expectedSum = ManagedNativeVarargTests.TestPassingRuntimeArgumentHandle(expectedValues.Length, __arglist(expectedValues[0], expectedValues[1], expectedValues[2], expectedValues[3])); + + int sum = 0; + for (int i = 0; i < expectedValues.Length; ++i) + { + sum += expectedValues[i]; + } + + return sum == expectedSum; + } + /// /// Given an input set create an arglist to pass to a vararg callee. /// @@ -4558,6 +4586,7 @@ public static int TestEntryPoint() m_testCount = 0; success = ReportFailure(TestPassingIntsManaged(new int[] { 100, 299, -100, 50 }), "TestPassingIntsManaged(new int[] { 100, 299, -100, 50 })", success, 30); + success = ReportFailure(TestPassingRuntimeArgumentHandleManaged(new int[] { 100, 299, -100, 50 }), "TestPassingRuntimeArgumentHandleManaged(new int[] { 100, 299, -100, 50 })", success, 157); TestFour16ByteStructs(); diff --git a/src/tests/JIT/Directed/arglist/varargmanaged.cs b/src/tests/JIT/Directed/arglist/varargmanaged.cs index 1b94046a11f520..1ef7c58b57c7b2 100644 --- a/src/tests/JIT/Directed/arglist/varargmanaged.cs +++ b/src/tests/JIT/Directed/arglist/varargmanaged.cs @@ -764,6 +764,34 @@ public static int TestPassingInts(int count, __arglist) return sum; } + [MethodImpl(MethodImplOptions.NoInlining)] + public static int TestPassingRuntimeArgumentHandle(int count, __arglist) + { + RuntimeArgumentHandle handle = __arglist; + return TestPassingRuntimeArgumentHandleWorker(count, handle); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static int TestPassingRuntimeArgumentHandleWorker(int count, RuntimeArgumentHandle handle) + { + int calculatedCount = 0; + ArgIterator it = new ArgIterator(handle); + + int sum = 0; + while (it.GetRemainingCount() != 0) + { + int arg = __refvalue(it.GetNextArg(), int); + + sum += arg; + + ++calculatedCount; + } + + if (calculatedCount != count) return -1; + + return sum; + } + [MethodImpl(MethodImplOptions.NoInlining)] public static long TestPassingLongs(int count, __arglist) {