From 7d196a32661b98fc37c72b26ad51c232f673320c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 00:21:43 +0000 Subject: [PATCH 01/63] Remove verifier element type API and rename primitive-value-type category to enum Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/5e928e4d-026c-49f8-a093-001b6bf1d69c Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- .../RuntimeHelpers.CoreCLR.cs | 4 +- src/coreclr/vm/arraynative.cpp | 2 +- src/coreclr/vm/callingconvention.h | 2 +- src/coreclr/vm/class.cpp | 2 +- src/coreclr/vm/comdelegate.cpp | 2 +- src/coreclr/vm/customattribute.cpp | 2 +- src/coreclr/vm/invokeutil.cpp | 4 +- src/coreclr/vm/jitinterface.cpp | 12 ++-- src/coreclr/vm/marshalnative.cpp | 2 +- src/coreclr/vm/methodtable.cpp | 55 ++----------------- src/coreclr/vm/methodtable.h | 16 ++---- src/coreclr/vm/proftoeeinterfaceimpl.cpp | 2 +- src/coreclr/vm/reflectioninvocation.cpp | 2 +- src/coreclr/vm/typedesc.cpp | 4 +- src/coreclr/vm/typehandle.cpp | 20 +------ src/coreclr/vm/typehandle.h | 17 +----- 16 files changed, 35 insertions(+), 113 deletions(-) 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..d6655cad15be91 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 @@ -850,7 +850,7 @@ internal unsafe struct MethodTable 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_Enum = 0x00060000; // sub-category of ValueType, Enum private const uint enum_flag_Category_TruePrimitive = 0x00070000; // sub-category of ValueType, Primitive (ELEMENT_TYPE_I, etc.) private const uint enum_flag_Category_Array = 0x00080000; private const uint enum_flag_Category_Array_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_IsPrimitiveMask) == enum_flag_Category_Enum; public bool IsTruePrimitive => (Flags & enum_flag_Category_Mask) is enum_flag_Category_TruePrimitive; 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 746464ca77f2c0..e618e9e432ca28 100644 --- a/src/coreclr/vm/callingconvention.h +++ b/src/coreclr/vm/callingconvention.h @@ -2435,7 +2435,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 1a37e2346b0dbe..d5cbd54c028dc4 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/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/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/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 cb30fa87c3aaec..d313373bcfbec1 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -4067,7 +4067,7 @@ CorInfoType CEEInfo::getTypeForPrimitiveValueClass( TypeHandle th(clsHnd); _ASSERTE (!th.IsGenericVariable()); - CorElementType elementType = th.GetVerifierCorElementType(); + CorElementType elementType = th.GetInternalCorElementType(); if (CorIsPrimitiveType(elementType)) { result = asCorInfoType(elementType); @@ -4445,7 +4445,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; } @@ -5052,7 +5052,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; @@ -7232,7 +7232,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) @@ -7401,7 +7401,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 || @@ -7430,7 +7430,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 5a5a714a360edf..3026707c1d2b61 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_Enum: + // This path should only be taken for enums and true primitive CoreLib types. 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_Enum: ret = ELEMENT_TYPE_VALUETYPE; break; @@ -5092,8 +5049,8 @@ void MethodTable::SetInternalCorElementType (CorElementType _NormType) _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(enum_flag_Category_Enum); + _ASSERTE(GetFlag(enum_flag_Category_Mask) == enum_flag_Category_Enum); break; } diff --git a/src/coreclr/vm/methodtable.h b/src/coreclr/vm/methodtable.h index 402b0cde9b15bd..b5106ab3321786 100644 --- a/src/coreclr/vm/methodtable.h +++ b/src/coreclr/vm/methodtable.h @@ -2769,28 +2769,22 @@ 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. For example, we treat 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(); - // 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. + // Note that GetInternalCorElementType might return these same values for enums. BOOL IsTruePrimitive(); void SetIsTruePrimitive(); @@ -3793,7 +3787,7 @@ 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_Enum = 0x00060000, // sub-category of ValueType, Enum. [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_Array = 0x00080000, // [cDAC] [RuntimeTypeSystem]: Contract depends on this value 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 37343b4fcb9cc2..ee1ed1ac38d4f8 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; 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 5dd7d4e85d468a..a1ddb5fca11010 100644 --- a/src/coreclr/vm/typehandle.cpp +++ b/src/coreclr/vm/typehandle.cpp @@ -592,7 +592,7 @@ BOOL TypeHandle::IsBoxedAndCanCastTo(TypeHandle type, TypeHandlePairList *pPairL CONTRACTL_END - CorElementType fromParamCorType = GetVerifierCorElementType(); + CorElementType fromParamCorType = GetInternalCorElementType(); if (CorTypeInfo::IsObjRef(fromParamCorType)) { @@ -1205,24 +1205,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 1fb2f944bb509d..42cd1b56d30159 100644 --- a/src/coreclr/vm/typehandle.h +++ b/src/coreclr/vm/typehandle.h @@ -200,26 +200,15 @@ 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 + // - Will return the primitive used by the calling convention // - // Internal representation is used among another things for the calling convention - // (jit benefits of primitive value types) or optimizing marshalling. + // Internal representation is used among other things for the calling convention + // and 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. CorElementType GetInternalCorElementType() const; - // This helper will return the same as GetSignatureCorElementType except: - // - Will return enums underlying type - CorElementType GetVerifierCorElementType() const; - //------------------------------------------------------------------- // CASTING // From 0af6cad736cac34c8be2159ae8da6a5d5e1cd187 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 00:32:41 +0000 Subject: [PATCH 02/63] Rename enum category in cDAC contracts/docs and clean related comments Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/5e928e4d-026c-49f8-a093-001b6bf1d69c Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- .../design/datacontracts/RuntimeTypeSystem.md | 8 +++---- .../Contracts/RuntimeTypeSystem_1.cs | 6 ++--- .../MethodTableFlags_1.cs | 2 +- .../managed/cdac/tests/MethodTableTests.cs | 22 +++++++++---------- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/docs/design/datacontracts/RuntimeTypeSystem.md b/docs/design/datacontracts/RuntimeTypeSystem.md index 28605efe3c70b3..4f19db53e998fe 100644 --- a/docs/design/datacontracts/RuntimeTypeSystem.md +++ b/docs/design/datacontracts/RuntimeTypeSystem.md @@ -294,7 +294,7 @@ internal partial struct RuntimeTypeSystem_1 Category_Array = 0x00080000, Category_ValueType = 0x00040000, Category_Nullable = 0x00050000, - Category_PrimitiveValueType = 0x00060000, + Category_Enum = 0x00060000, Category_TruePrimitive = 0x00070000, Category_Interface = 0x000C0000, Collectible = 0x00200000, @@ -813,7 +813,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_Enum: return CorElementType.ValueType; case WFLAGS_HIGH.Category_TruePrimitive: return (CorElementType)GetClassData(typeHandle).InternalCorElementType; @@ -835,9 +835,9 @@ Contracts used: // if typedesc: check for CorElementType.ValueType } - // Enums have Category_PrimitiveValueType in their MethodTable flags and their + // Enums have Category_Enum 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. IntPtr/UIntPtr continue to use Category_TruePrimitive. public bool IsEnum(TypeHandle typeHandle) { if (!typeHandle.IsMethodTable()) 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 26debd447f39ec..1e67e2d9adf726 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 @@ -848,7 +848,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_Enum: return CorElementType.ValueType; case MethodTableFlags_1.WFLAGS_HIGH.Category_TruePrimitive: return (CorElementType)GetClassData(typeHandle).InternalCorElementType; @@ -883,9 +883,9 @@ public bool IsValueType(TypeHandle typeHandle) public bool IsEnum(TypeHandle typeHandle) { - // Enums have Category_PrimitiveValueType in their MethodTable flags and their + // Enums have Category_Enum 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. IntPtr/UIntPtr continue to use Category_TruePrimitive. if (!typeHandle.IsMethodTable()) return false; 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..11076a8c73a8d4 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_Enum = 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 e8c15ad11f6734..0c5f9a5d4d4c9c 100644 --- a/src/native/managed/cdac/tests/MethodTableTests.cs +++ b/src/native/managed/cdac/tests/MethodTableTests.cs @@ -516,7 +516,7 @@ public void IsValueTypeReturnsTrueForValueTypeCategories(MockTarget.Architecture { TargetPointer valueTypeMTPtr = default; TargetPointer nullableMTPtr = default; - TargetPointer primitiveValueTypeMTPtr = default; + TargetPointer enumMTPtr = default; TargetPointer truePrimitiveMTPtr = default; TestPlaceholderTarget target = CreateTarget( @@ -545,15 +545,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_Enum; + 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"); @@ -570,7 +570,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))); } From fbca1de222d63e76ad5a7e630e3e77b0ddcedae5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 01:35:44 +0000 Subject: [PATCH 03/63] Address review feedback on enum/primitive category values and comments Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/a5ef9c79-9897-4019-af57-7543f1af7c54 Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- docs/design/datacontracts/RuntimeTypeSystem.md | 8 ++++---- .../Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs | 10 ++++++---- src/coreclr/vm/methodtable.cpp | 4 ++-- src/coreclr/vm/methodtable.h | 4 ++-- src/coreclr/vm/methodtable.inl | 5 +++-- .../Contracts/RuntimeTypeSystem_1.cs | 4 ++-- .../RuntimeTypeSystemHelpers/MethodTableFlags_1.cs | 4 ++-- src/native/managed/cdac/tests/MethodTableTests.cs | 2 +- 8 files changed, 22 insertions(+), 19 deletions(-) diff --git a/docs/design/datacontracts/RuntimeTypeSystem.md b/docs/design/datacontracts/RuntimeTypeSystem.md index 4f19db53e998fe..4935017c7a1b17 100644 --- a/docs/design/datacontracts/RuntimeTypeSystem.md +++ b/docs/design/datacontracts/RuntimeTypeSystem.md @@ -294,8 +294,8 @@ internal partial struct RuntimeTypeSystem_1 Category_Array = 0x00080000, Category_ValueType = 0x00040000, Category_Nullable = 0x00050000, - Category_Enum = 0x00060000, - Category_TruePrimitive = 0x00070000, + Category_Primitive = 0x00060000, + Category_Enum = 0x00070000, Category_Interface = 0x000C0000, Collectible = 0x00200000, RequiresAlign8 = 0x00800000, @@ -815,7 +815,7 @@ Contracts used: case WFLAGS_HIGH.Category_Nullable: case WFLAGS_HIGH.Category_Enum: return CorElementType.ValueType; - case WFLAGS_HIGH.Category_TruePrimitive: + case WFLAGS_HIGH.Category_Primitive: return (CorElementType)GetClassData(typeHandle).InternalCorElementType; default: return CorElementType.Class; @@ -837,7 +837,7 @@ Contracts used: // Enums have Category_Enum in their MethodTable flags and their // InternalCorElementType is a primitive type (I1, U1, I2, U2, I4, U4, I8, U8), - // not ValueType. IntPtr/UIntPtr continue to use Category_TruePrimitive. + // not ValueType. public bool IsEnum(TypeHandle typeHandle) { if (!typeHandle.IsMethodTable()) 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 d6655cad15be91..a86253dd0eaf13 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 @@ -850,8 +850,8 @@ internal unsafe struct MethodTable 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_Enum = 0x00060000; // sub-category of ValueType, Enum - private const uint enum_flag_Category_TruePrimitive = 0x00070000; // sub-category of ValueType, Primitive (ELEMENT_TYPE_I, etc.) + private const uint enum_flag_Category_Primitive = 0x00060000; // sub-category of ValueType, Primitive (ELEMENT_TYPE_I, etc.) + private const uint enum_flag_Category_Enum = 0x00070000; // sub-category of ValueType, Enum 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,9 +955,11 @@ 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_Enum; + public bool IsPrimitive => (Flags & enum_flag_Category_IsPrimitiveMask) == enum_flag_Category_Primitive; - public bool IsTruePrimitive => (Flags & enum_flag_Category_Mask) is enum_flag_Category_TruePrimitive; + public bool IsTruePrimitive => + (Flags & enum_flag_Category_IsPrimitiveMask) == enum_flag_Category_Primitive && + (Flags & enum_flag_Category_Mask) != enum_flag_Category_Enum; public bool IsArray => (Flags & enum_flag_Category_Array_Mask) == enum_flag_Category_Array; diff --git a/src/coreclr/vm/methodtable.cpp b/src/coreclr/vm/methodtable.cpp index 3026707c1d2b61..d3058add99c2e1 100644 --- a/src/coreclr/vm/methodtable.cpp +++ b/src/coreclr/vm/methodtable.cpp @@ -4969,7 +4969,7 @@ CorElementType MethodTable::GetInternalCorElementType() ret = ELEMENT_TYPE_VALUETYPE; break; - case enum_flag_Category_Enum: + case enum_flag_Category_Primitive: // This path should only be taken for enums and true primitive CoreLib types. ret = GetClass()->GetInternalCorElementType(); _ASSERTE((ret != ELEMENT_TYPE_CLASS) && @@ -5019,7 +5019,7 @@ CorElementType MethodTable::GetSignatureCorElementType() ret = ELEMENT_TYPE_VALUETYPE; break; - case enum_flag_Category_TruePrimitive: + case enum_flag_Category_Primitive: ret = GetClass()->GetInternalCorElementType(); break; diff --git a/src/coreclr/vm/methodtable.h b/src/coreclr/vm/methodtable.h index b5106ab3321786..a4ff1a900cd74d 100644 --- a/src/coreclr/vm/methodtable.h +++ b/src/coreclr/vm/methodtable.h @@ -3787,8 +3787,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_Enum = 0x00060000, // sub-category of ValueType, Enum. [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, Primitive (ELEMENT_TYPE_I, etc.). [cDAC] [RuntimeTypeSystem]: Contract depends on this value + enum_flag_Category_Enum = 0x00070000, // sub-category of ValueType, Enum. [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 d0b112d01d7526..9f4b41090319f1 100644 --- a/src/coreclr/vm/methodtable.inl +++ b/src/coreclr/vm/methodtable.inl @@ -327,14 +327,15 @@ inline DWORD MethodTable::GetRank() inline BOOL MethodTable::IsTruePrimitive() { LIMITED_METHOD_DAC_CONTRACT; - return GetFlag(enum_flag_Category_Mask) == enum_flag_Category_TruePrimitive; + return GetFlag(enum_flag_Category_Mask) == enum_flag_Category_Primitive; } //========================================================================================== inline void MethodTable::SetIsTruePrimitive() { LIMITED_METHOD_DAC_CONTRACT; - SetFlag(enum_flag_Category_TruePrimitive); + ClearFlag(enum_flag_Category_Mask); + SetFlag(enum_flag_Category_Primitive); } //========================================================================================== 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 1e67e2d9adf726..cb56858942dffa 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 @@ -850,7 +850,7 @@ public CorElementType GetSignatureCorElementType(TypeHandle typeHandle) case MethodTableFlags_1.WFLAGS_HIGH.Category_Nullable: case MethodTableFlags_1.WFLAGS_HIGH.Category_Enum: return CorElementType.ValueType; - case MethodTableFlags_1.WFLAGS_HIGH.Category_TruePrimitive: + case MethodTableFlags_1.WFLAGS_HIGH.Category_Primitive: return (CorElementType)GetClassData(typeHandle).InternalCorElementType; default: return CorElementType.Class; @@ -885,7 +885,7 @@ public bool IsEnum(TypeHandle typeHandle) { // Enums have Category_Enum in their MethodTable flags and their // InternalCorElementType is a primitive type (I1, U1, I2, U2, I4, U4, I8, U8), - // not ValueType. IntPtr/UIntPtr continue to use Category_TruePrimitive. + // not ValueType. if (!typeHandle.IsMethodTable()) return false; 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 11076a8c73a8d4..56975c1df16073 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,8 +42,8 @@ internal enum WFLAGS_HIGH : uint Category_ElementType_Mask = 0x000E0000, Category_ValueType = 0x00040000, Category_Nullable = 0x00050000, - Category_Enum = 0x00060000, - Category_TruePrimitive = 0x00070000, + Category_Primitive = 0x00060000, + Category_Enum = 0x00070000, Category_Interface = 0x000C0000, Collectible = 0x00200000, // GC depends on this bit. RequiresAlign8 = 0x00800000, diff --git a/src/native/managed/cdac/tests/MethodTableTests.cs b/src/native/managed/cdac/tests/MethodTableTests.cs index 0c5f9a5d4d4c9c..08a2f7542d3ac0 100644 --- a/src/native/managed/cdac/tests/MethodTableTests.cs +++ b/src/native/managed/cdac/tests/MethodTableTests.cs @@ -557,7 +557,7 @@ public void IsValueTypeReturnsTrueForValueTypeCategories(MockTarget.Architecture MockEEClass tpEEClass = rtsBuilder.AddEEClass("TruePrimitiveEEClass"); MockMethodTable tpMT = rtsBuilder.AddMethodTable("TruePrimitive"); - tpMT.MTFlags = (uint)MethodTableFlags_1.WFLAGS_HIGH.Category_TruePrimitive; + tpMT.MTFlags = (uint)MethodTableFlags_1.WFLAGS_HIGH.Category_Primitive; tpMT.BaseSize = rtsBuilder.Builder.TargetTestHelpers.ObjectBaseSize; tpMT.ParentMethodTable = systemObjectMethodTablePtr; tpMT.NumVirtuals = 3; From 2bdd2da43e19f99050deda423ef2a396ec6f6df4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 01:43:54 +0000 Subject: [PATCH 04/63] Refine RuntimeHelpers primitive checks after review tool feedback Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/a5ef9c79-9897-4019-af57-7543f1af7c54 Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- .../Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) 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 a86253dd0eaf13..9124a55a5f223b 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,7 +849,6 @@ 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_Primitive = 0x00060000; // sub-category of ValueType, Primitive (ELEMENT_TYPE_I, etc.) private const uint enum_flag_Category_Enum = 0x00070000; // sub-category of ValueType, Enum private const uint enum_flag_Category_Array = 0x00080000; @@ -955,11 +954,9 @@ 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_Primitive; + public bool IsPrimitive => (Flags & enum_flag_Category_Mask) is enum_flag_Category_Primitive or enum_flag_Category_Enum; - public bool IsTruePrimitive => - (Flags & enum_flag_Category_IsPrimitiveMask) == enum_flag_Category_Primitive && - (Flags & enum_flag_Category_Mask) != enum_flag_Category_Enum; + public bool IsTruePrimitive => (Flags & enum_flag_Category_Mask) is enum_flag_Category_Primitive; public bool IsArray => (Flags & enum_flag_Category_Array_Mask) == enum_flag_Category_Array; From 4a179b36b8fc7d9ddbae325a15058da683420521 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 01:46:08 +0000 Subject: [PATCH 05/63] Clarify primitive/enum mask behavior comment in MethodTable Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/a5ef9c79-9897-4019-af57-7543f1af7c54 Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- src/coreclr/vm/methodtable.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/vm/methodtable.cpp b/src/coreclr/vm/methodtable.cpp index d3058add99c2e1..35b287b995a8c0 100644 --- a/src/coreclr/vm/methodtable.cpp +++ b/src/coreclr/vm/methodtable.cpp @@ -4970,7 +4970,7 @@ CorElementType MethodTable::GetInternalCorElementType() break; case enum_flag_Category_Primitive: - // This path should only be taken for enums and true primitive CoreLib types. + // enum_flag_Category_ElementTypeMask maps both Category_Primitive and Category_Enum here. ret = GetClass()->GetInternalCorElementType(); _ASSERTE((ret != ELEMENT_TYPE_CLASS) && (ret != ELEMENT_TYPE_VALUETYPE)); From 53d2152c6addbdee2441137c0b69b3986c2558e5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 02:55:09 +0000 Subject: [PATCH 06/63] Apply latest enum/primitive review suggestions across runtime and cDAC Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/4ef6b0df-8fc1-41d6-afe1-1119ff0f3c32 Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- docs/design/datacontracts/RuntimeTypeSystem.md | 8 ++------ .../Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs | 7 +++++-- src/coreclr/vm/methodtable.h | 4 ++-- src/coreclr/vm/methodtable.inl | 3 +-- src/coreclr/vm/typehandle.h | 3 --- .../Contracts/RuntimeTypeSystem_1.cs | 8 ++------ 6 files changed, 12 insertions(+), 21 deletions(-) diff --git a/docs/design/datacontracts/RuntimeTypeSystem.md b/docs/design/datacontracts/RuntimeTypeSystem.md index 4935017c7a1b17..8a29098adfca42 100644 --- a/docs/design/datacontracts/RuntimeTypeSystem.md +++ b/docs/design/datacontracts/RuntimeTypeSystem.md @@ -843,12 +843,8 @@ Contracts used: 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_Enum; } // 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 9124a55a5f223b..a86253dd0eaf13 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,6 +849,7 @@ 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_Primitive = 0x00060000; // sub-category of ValueType, Primitive (ELEMENT_TYPE_I, etc.) private const uint enum_flag_Category_Enum = 0x00070000; // sub-category of ValueType, Enum private const uint enum_flag_Category_Array = 0x00080000; @@ -954,9 +955,11 @@ 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_Mask) is enum_flag_Category_Primitive or enum_flag_Category_Enum; + public bool IsPrimitive => (Flags & enum_flag_Category_IsPrimitiveMask) == enum_flag_Category_Primitive; - public bool IsTruePrimitive => (Flags & enum_flag_Category_Mask) is enum_flag_Category_Primitive; + public bool IsTruePrimitive => + (Flags & enum_flag_Category_IsPrimitiveMask) == enum_flag_Category_Primitive && + (Flags & enum_flag_Category_Mask) != enum_flag_Category_Enum; public bool IsArray => (Flags & enum_flag_Category_Array_Mask) == enum_flag_Category_Array; diff --git a/src/coreclr/vm/methodtable.h b/src/coreclr/vm/methodtable.h index a4ff1a900cd74d..37507bf3c0159c 100644 --- a/src/coreclr/vm/methodtable.h +++ b/src/coreclr/vm/methodtable.h @@ -2769,7 +2769,7 @@ 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. To get the signature + // 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() @@ -2784,7 +2784,7 @@ class MethodTable // ELEMENT_TYPE_I, // ELEMENT_TYPE_I4, // ELEMENT_TYPE_TYPEDBYREF etc. - // Note that GetInternalCorElementType might return these same values for enums. + // And not enum. BOOL IsTruePrimitive(); void SetIsTruePrimitive(); diff --git a/src/coreclr/vm/methodtable.inl b/src/coreclr/vm/methodtable.inl index 9f4b41090319f1..6d203304eb7915 100644 --- a/src/coreclr/vm/methodtable.inl +++ b/src/coreclr/vm/methodtable.inl @@ -334,8 +334,7 @@ inline BOOL MethodTable::IsTruePrimitive() inline void MethodTable::SetIsTruePrimitive() { LIMITED_METHOD_DAC_CONTRACT; - ClearFlag(enum_flag_Category_Mask); - SetFlag(enum_flag_Category_Primitive); + m_dwFlags = (m_dwFlags & ~(DWORD)enum_flag_Category_Mask) | (DWORD)enum_flag_Category_Primitive; } //========================================================================================== diff --git a/src/coreclr/vm/typehandle.h b/src/coreclr/vm/typehandle.h index 42cd1b56d30159..a8617851bc87bd 100644 --- a/src/coreclr/vm/typehandle.h +++ b/src/coreclr/vm/typehandle.h @@ -202,9 +202,6 @@ class TypeHandle // - Will return underlying primitive for System.Int32 etc... // - Will return the primitive used by the calling convention // - // Internal representation is used among other things for the calling convention - // and 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. CorElementType GetInternalCorElementType() const; 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 cb56858942dffa..41408991c2b95b 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 @@ -889,12 +889,8 @@ 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(MethodTableFlags_1.WFLAGS_HIGH.Category_Mask) == MethodTableFlags_1.WFLAGS_HIGH.Category_Enum; } // 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. From 6ce3aae1e0a266ae74fccf2a1ed46d94c0755524 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 03:00:37 +0000 Subject: [PATCH 07/63] Clarify IsTruePrimitive comment wording in MethodTable Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/4ef6b0df-8fc1-41d6-afe1-1119ff0f3c32 Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- src/coreclr/vm/methodtable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/vm/methodtable.h b/src/coreclr/vm/methodtable.h index 37507bf3c0159c..74441d230b584b 100644 --- a/src/coreclr/vm/methodtable.h +++ b/src/coreclr/vm/methodtable.h @@ -2784,7 +2784,7 @@ class MethodTable // ELEMENT_TYPE_I, // ELEMENT_TYPE_I4, // ELEMENT_TYPE_TYPEDBYREF etc. - // And not enum. + // Note that IsTruePrimitive returns false for enum types. BOOL IsTruePrimitive(); void SetIsTruePrimitive(); From 4ec08184818f5591aa52fb8c81a99cc3e7bfdc7f Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Wed, 6 May 2026 20:03:26 -0700 Subject: [PATCH 08/63] Update src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs --- .../System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) 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 a86253dd0eaf13..078150b541b153 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 @@ -957,9 +957,7 @@ public int MultiDimensionalArrayRank // 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_Primitive; - public bool IsTruePrimitive => - (Flags & enum_flag_Category_IsPrimitiveMask) == enum_flag_Category_Primitive && - (Flags & enum_flag_Category_Mask) != enum_flag_Category_Enum; + public bool IsTruePrimitive => (Flags & enum_flag_Category_Mask) == enum_flag_Category_Primitive; public bool IsArray => (Flags & enum_flag_Category_Array_Mask) == enum_flag_Category_Array; From f3b82386881e614840c3437081d1744ce73eba1e Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Wed, 6 May 2026 20:31:13 -0700 Subject: [PATCH 09/63] Update src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs --- .../System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 078150b541b153..06ecbe9bf62ec2 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 @@ -851,7 +851,7 @@ internal unsafe struct MethodTable private const uint enum_flag_Category_Nullable = 0x00050000; private const uint enum_flag_Category_IsPrimitiveMask = 0x000E0000; private const uint enum_flag_Category_Primitive = 0x00060000; // sub-category of ValueType, Primitive (ELEMENT_TYPE_I, etc.) - private const uint enum_flag_Category_Enum = 0x00070000; // sub-category of ValueType, Enum + // private const uint enum_flag_Category_Enum = 0x00070000; // sub-category of ValueType, Enum 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; From 257cd4353f1e64b7060dace857583229bcab1daa Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 03:55:10 +0000 Subject: [PATCH 10/63] Add IsPrimitive(), refactor SetInternalCorElementType, delete SetIsTruePrimitive, simplify jitinterface condition, delete handle ELEMENT_TYPE_I Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/d00ace36-750a-4a1e-8467-db312f324c69 Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- src/coreclr/vm/jitinterface.cpp | 9 +-------- src/coreclr/vm/methodtable.cpp | 6 +++--- src/coreclr/vm/methodtable.h | 8 +++++--- src/coreclr/vm/methodtable.inl | 4 ++-- src/coreclr/vm/methodtablebuilder.cpp | 15 +-------------- 5 files changed, 12 insertions(+), 30 deletions(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index d313373bcfbec1..1fb1ea6b39bd7b 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -338,14 +338,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(); } diff --git a/src/coreclr/vm/methodtable.cpp b/src/coreclr/vm/methodtable.cpp index 35b287b995a8c0..336ab5e55f1eed 100644 --- a/src/coreclr/vm/methodtable.cpp +++ b/src/coreclr/vm/methodtable.cpp @@ -5034,7 +5034,7 @@ CorElementType MethodTable::GetSignatureCorElementType() #ifndef DACCESS_COMPILE //========================================================================================== -void MethodTable::SetInternalCorElementType (CorElementType _NormType) +void MethodTable::SetInternalCorElementType (CorElementType _NormType, bool isTruePrimitive) { WRAPPER_NO_CONTRACT; @@ -5049,8 +5049,8 @@ void MethodTable::SetInternalCorElementType (CorElementType _NormType) _ASSERTE(GetFlag(enum_flag_Category_Mask) == enum_flag_Category_ValueType); break; default: - SetFlag(enum_flag_Category_Enum); - _ASSERTE(GetFlag(enum_flag_Category_Mask) == enum_flag_Category_Enum); + SetFlag(isTruePrimitive ? enum_flag_Category_Primitive : enum_flag_Category_Enum); + _ASSERTE(GetFlag(enum_flag_Category_Mask) == (isTruePrimitive ? enum_flag_Category_Primitive : enum_flag_Category_Enum)); break; } diff --git a/src/coreclr/vm/methodtable.h b/src/coreclr/vm/methodtable.h index 74441d230b584b..daa4f0c349d87b 100644 --- a/src/coreclr/vm/methodtable.h +++ b/src/coreclr/vm/methodtable.h @@ -2775,7 +2775,7 @@ class MethodTable // * code:TypeHandle.GetSignatureCorElementType() // * code:TypeHandle.GetInternalCorElementType() CorElementType GetInternalCorElementType(); - void SetInternalCorElementType(CorElementType _NormType); + void SetInternalCorElementType(CorElementType _NormType, bool isTruePrimitive = false); // See code:TypeHandle::GetSignatureCorElementType for description CorElementType GetSignatureCorElementType(); @@ -2784,9 +2784,11 @@ class MethodTable // ELEMENT_TYPE_I, // ELEMENT_TYPE_I4, // ELEMENT_TYPE_TYPEDBYREF etc. - // Note that IsTruePrimitive returns false for enum types. + // And not enum. BOOL IsTruePrimitive(); - void SetIsTruePrimitive(); + + // 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() diff --git a/src/coreclr/vm/methodtable.inl b/src/coreclr/vm/methodtable.inl index 6d203304eb7915..ab846eefefc4fa 100644 --- a/src/coreclr/vm/methodtable.inl +++ b/src/coreclr/vm/methodtable.inl @@ -331,10 +331,10 @@ inline BOOL MethodTable::IsTruePrimitive() } //========================================================================================== -inline void MethodTable::SetIsTruePrimitive() +inline BOOL MethodTable::IsPrimitive() { LIMITED_METHOD_DAC_CONTRACT; - m_dwFlags = (m_dwFlags & ~(DWORD)enum_flag_Category_Mask) | (DWORD)enum_flag_Category_Primitive; + 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..c37e930e31050c 100644 --- a/src/coreclr/vm/methodtablebuilder.cpp +++ b/src/coreclr/vm/methodtablebuilder.cpp @@ -10744,8 +10744,7 @@ void MethodTableBuilder::CheckForSystemTypes() CorElementType type = CorTypeInfo::FindPrimitiveType(name); if (type != ELEMENT_TYPE_END) { - 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(); From ceafd3dfce68ddca7e3a1d223bc9f0edefc94fc2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 03:57:36 +0000 Subject: [PATCH 11/63] Fix SetFlag type in SetInternalCorElementType default case Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/d00ace36-750a-4a1e-8467-db312f324c69 Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- src/coreclr/vm/methodtable.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/coreclr/vm/methodtable.cpp b/src/coreclr/vm/methodtable.cpp index 336ab5e55f1eed..3d44ca126fa64e 100644 --- a/src/coreclr/vm/methodtable.cpp +++ b/src/coreclr/vm/methodtable.cpp @@ -5049,10 +5049,13 @@ void MethodTable::SetInternalCorElementType (CorElementType _NormType, bool isTr _ASSERTE(GetFlag(enum_flag_Category_Mask) == enum_flag_Category_ValueType); break; default: - SetFlag(isTruePrimitive ? enum_flag_Category_Primitive : enum_flag_Category_Enum); - _ASSERTE(GetFlag(enum_flag_Category_Mask) == (isTruePrimitive ? enum_flag_Category_Primitive : enum_flag_Category_Enum)); + { + WFLAGS_HIGH_ENUM category = isTruePrimitive ? enum_flag_Category_Primitive : enum_flag_Category_Enum; + SetFlag(category); + _ASSERTE(GetFlag(enum_flag_Category_Mask) == category); break; } + } GetClass()->SetInternalCorElementType(_NormType); _ASSERTE(GetInternalCorElementType() == _NormType); From 1647dbe166065456b155866763b2b4a7a2d2c99f Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Wed, 6 May 2026 21:01:55 -0700 Subject: [PATCH 12/63] Apply suggestion from @jkotas --- src/coreclr/vm/methodtable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/vm/methodtable.h b/src/coreclr/vm/methodtable.h index daa4f0c349d87b..a30e8501c56adc 100644 --- a/src/coreclr/vm/methodtable.h +++ b/src/coreclr/vm/methodtable.h @@ -2784,7 +2784,7 @@ class MethodTable // ELEMENT_TYPE_I, // ELEMENT_TYPE_I4, // ELEMENT_TYPE_TYPEDBYREF etc. - // And not enum. + // Note that IsTruePrimitive returns false for enum types. BOOL IsTruePrimitive(); // Like IsTruePrimitive but also returns true for enum types. From 2a130cbef227a920da2c77ab40d72e7dec1ef550 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Wed, 6 May 2026 21:05:16 -0700 Subject: [PATCH 13/63] Apply suggestion from @jkotas --- src/coreclr/vm/typehandle.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/coreclr/vm/typehandle.h b/src/coreclr/vm/typehandle.h index a8617851bc87bd..8f1592d19219ff 100644 --- a/src/coreclr/vm/typehandle.h +++ b/src/coreclr/vm/typehandle.h @@ -200,7 +200,6 @@ class TypeHandle // This helper: // - Will return enums underlying type // - Will return underlying primitive for System.Int32 etc... - // - Will return the primitive used by the calling convention // // This will NOT convert E_T_ARRAY, E_T_SZARRAY etc. to E_T_CLASS (though it probably // should). Use CorTypeInfo::IsObjRef for that. From 8179e5f62955929517ec41420614f4bc48ddc460 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Wed, 6 May 2026 21:05:57 -0700 Subject: [PATCH 14/63] Apply suggestion from @jkotas --- src/coreclr/vm/typehandle.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/coreclr/vm/typehandle.h b/src/coreclr/vm/typehandle.h index 8f1592d19219ff..6c10b2d755704d 100644 --- a/src/coreclr/vm/typehandle.h +++ b/src/coreclr/vm/typehandle.h @@ -201,8 +201,7 @@ class TypeHandle // - Will return enums underlying type // - Will return underlying primitive for System.Int32 etc... // - // 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; //------------------------------------------------------------------- From 9bc8857f248a9cdd951d02fb921da5221f9f2b28 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 04:17:23 +0000 Subject: [PATCH 15/63] Change IsTruePrimitive and IsPrimitive return types from BOOL to bool Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/41f05a09-6124-4a52-a78d-8b1b82aa4f9c Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- src/coreclr/vm/methodtable.h | 4 ++-- src/coreclr/vm/methodtable.inl | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/coreclr/vm/methodtable.h b/src/coreclr/vm/methodtable.h index a30e8501c56adc..cbfd0079f8a977 100644 --- a/src/coreclr/vm/methodtable.h +++ b/src/coreclr/vm/methodtable.h @@ -2785,10 +2785,10 @@ class MethodTable // ELEMENT_TYPE_I4, // ELEMENT_TYPE_TYPEDBYREF etc. // Note that IsTruePrimitive returns false for enum types. - BOOL IsTruePrimitive(); + bool IsTruePrimitive(); // Like IsTruePrimitive but also returns true for enum types. - BOOL IsPrimitive(); + bool IsPrimitive(); // Is this delegate? Returns false for System.Delegate and System.MulticastDelegate. inline BOOL IsDelegate() diff --git a/src/coreclr/vm/methodtable.inl b/src/coreclr/vm/methodtable.inl index ab846eefefc4fa..2019c1ab8b2d1c 100644 --- a/src/coreclr/vm/methodtable.inl +++ b/src/coreclr/vm/methodtable.inl @@ -324,14 +324,14 @@ 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_Primitive; } //========================================================================================== -inline BOOL MethodTable::IsPrimitive() +inline bool MethodTable::IsPrimitive() { LIMITED_METHOD_DAC_CONTRACT; return GetFlag(enum_flag_Category_ElementTypeMask) == enum_flag_Category_Primitive; From 22fcaef0155336969c1d51f4d3e3b56f9762b806 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 04:23:22 +0000 Subject: [PATCH 16/63] Apply MethodTable bool signature and parameter naming suggestions Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/522a0066-595e-44f6-a1fa-d58b7ae4b085 Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- src/coreclr/vm/methodtable.cpp | 8 ++++---- src/coreclr/vm/methodtable.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/coreclr/vm/methodtable.cpp b/src/coreclr/vm/methodtable.cpp index 3d44ca126fa64e..430f7eaf11d530 100644 --- a/src/coreclr/vm/methodtable.cpp +++ b/src/coreclr/vm/methodtable.cpp @@ -5034,11 +5034,11 @@ CorElementType MethodTable::GetSignatureCorElementType() #ifndef DACCESS_COMPILE //========================================================================================== -void MethodTable::SetInternalCorElementType (CorElementType _NormType, bool isTruePrimitive) +void MethodTable::SetInternalCorElementType(CorElementType elemType, bool isTruePrimitive) { WRAPPER_NO_CONTRACT; - switch (_NormType) + switch (elemType) { case ELEMENT_TYPE_CLASS: _ASSERTE(!IsArray()); @@ -5057,8 +5057,8 @@ void MethodTable::SetInternalCorElementType (CorElementType _NormType, bool isTr } } - 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 cbfd0079f8a977..1544e77b11987b 100644 --- a/src/coreclr/vm/methodtable.h +++ b/src/coreclr/vm/methodtable.h @@ -2775,7 +2775,7 @@ class MethodTable // * code:TypeHandle.GetSignatureCorElementType() // * code:TypeHandle.GetInternalCorElementType() CorElementType GetInternalCorElementType(); - void SetInternalCorElementType(CorElementType _NormType, bool isTruePrimitive = false); + void SetInternalCorElementType(CorElementType elemType, bool isTruePrimitive = false); // See code:TypeHandle::GetSignatureCorElementType for description CorElementType GetSignatureCorElementType(); From 58de2510513f58f3b148de34b5d96df00a3e5c69 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 05:21:36 +0000 Subject: [PATCH 17/63] Revert category flag names to PrimitiveValueType/TruePrimitive and fix signed/unsigned mismatch Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/308624f3-4df4-4397-a474-cdbd40a15d4a Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- docs/design/datacontracts/RuntimeTypeSystem.md | 12 ++++++------ .../CompilerServices/RuntimeHelpers.CoreCLR.cs | 8 ++++---- src/coreclr/vm/methodtable.cpp | 12 ++++++------ src/coreclr/vm/methodtable.h | 4 ++-- src/coreclr/vm/methodtable.inl | 4 ++-- .../Contracts/RuntimeTypeSystem_1.cs | 8 ++++---- .../RuntimeTypeSystemHelpers/MethodTableFlags_1.cs | 4 ++-- src/native/managed/cdac/tests/MethodTableTests.cs | 4 ++-- 8 files changed, 28 insertions(+), 28 deletions(-) diff --git a/docs/design/datacontracts/RuntimeTypeSystem.md b/docs/design/datacontracts/RuntimeTypeSystem.md index 8a29098adfca42..bb92fa93681839 100644 --- a/docs/design/datacontracts/RuntimeTypeSystem.md +++ b/docs/design/datacontracts/RuntimeTypeSystem.md @@ -294,8 +294,8 @@ internal partial struct RuntimeTypeSystem_1 Category_Array = 0x00080000, Category_ValueType = 0x00040000, Category_Nullable = 0x00050000, - Category_Primitive = 0x00060000, - Category_Enum = 0x00070000, + Category_PrimitiveValueType = 0x00060000, + Category_TruePrimitive = 0x00070000, Category_Interface = 0x000C0000, Collectible = 0x00200000, RequiresAlign8 = 0x00800000, @@ -813,9 +813,9 @@ Contracts used: return CorElementType.SzArray; case WFLAGS_HIGH.Category_ValueType: case WFLAGS_HIGH.Category_Nullable: - case WFLAGS_HIGH.Category_Enum: + case WFLAGS_HIGH.Category_PrimitiveValueType: return CorElementType.ValueType; - case WFLAGS_HIGH.Category_Primitive: + case WFLAGS_HIGH.Category_TruePrimitive: return (CorElementType)GetClassData(typeHandle).InternalCorElementType; default: return CorElementType.Class; @@ -835,7 +835,7 @@ Contracts used: // if typedesc: check for CorElementType.ValueType } - // Enums have Category_Enum in their MethodTable flags and their + // Enums have Category_PrimitiveValueType in their MethodTable flags and their // InternalCorElementType is a primitive type (I1, U1, I2, U2, I4, U4, I8, U8), // not ValueType. public bool IsEnum(TypeHandle typeHandle) @@ -844,7 +844,7 @@ Contracts used: return false; MethodTable methodTable = _methodTables[typeHandle.Address]; - return methodTable.Flags.GetFlag(WFLAGS_HIGH.Category_Mask) == WFLAGS_HIGH.Category_Enum; + return methodTable.Flags.GetFlag(WFLAGS_HIGH.Category_Mask) == WFLAGS_HIGH.Category_PrimitiveValueType; } // 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 06ecbe9bf62ec2..5a976b2d8f54d3 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 @@ -850,8 +850,8 @@ internal unsafe struct MethodTable 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_Primitive = 0x00060000; // sub-category of ValueType, Primitive (ELEMENT_TYPE_I, etc.) - // private const uint enum_flag_Category_Enum = 0x00070000; // sub-category of ValueType, Enum + 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_Array = 0x00080000; private const uint enum_flag_Category_Array_Mask = 0x000C0000; private const uint enum_flag_Category_ValueType_Mask = 0x000C0000; @@ -955,9 +955,9 @@ 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_Primitive; + public bool IsPrimitive => (Flags & enum_flag_Category_IsPrimitiveMask) == enum_flag_Category_TruePrimitive; - public bool IsTruePrimitive => (Flags & enum_flag_Category_Mask) == enum_flag_Category_Primitive; + public bool IsTruePrimitive => (Flags & enum_flag_Category_Mask) == enum_flag_Category_TruePrimitive; public bool IsArray => (Flags & enum_flag_Category_Array_Mask) == enum_flag_Category_Array; diff --git a/src/coreclr/vm/methodtable.cpp b/src/coreclr/vm/methodtable.cpp index 430f7eaf11d530..c7224f3c0f5946 100644 --- a/src/coreclr/vm/methodtable.cpp +++ b/src/coreclr/vm/methodtable.cpp @@ -4969,8 +4969,8 @@ CorElementType MethodTable::GetInternalCorElementType() ret = ELEMENT_TYPE_VALUETYPE; break; - case enum_flag_Category_Primitive: - // enum_flag_Category_ElementTypeMask maps both Category_Primitive and Category_Enum here. + case enum_flag_Category_TruePrimitive: + // enum_flag_Category_ElementTypeMask maps both Category_TruePrimitive and Category_PrimitiveValueType here. ret = GetClass()->GetInternalCorElementType(); _ASSERTE((ret != ELEMENT_TYPE_CLASS) && (ret != ELEMENT_TYPE_VALUETYPE)); @@ -5015,11 +5015,11 @@ CorElementType MethodTable::GetSignatureCorElementType() case enum_flag_Category_ValueType: case enum_flag_Category_Nullable: - case enum_flag_Category_Enum: + case enum_flag_Category_PrimitiveValueType: ret = ELEMENT_TYPE_VALUETYPE; break; - case enum_flag_Category_Primitive: + case enum_flag_Category_TruePrimitive: ret = GetClass()->GetInternalCorElementType(); break; @@ -5050,9 +5050,9 @@ void MethodTable::SetInternalCorElementType(CorElementType elemType, bool isTrue break; default: { - WFLAGS_HIGH_ENUM category = isTruePrimitive ? enum_flag_Category_Primitive : enum_flag_Category_Enum; + WFLAGS_HIGH_ENUM category = isTruePrimitive ? enum_flag_Category_TruePrimitive : enum_flag_Category_PrimitiveValueType; SetFlag(category); - _ASSERTE(GetFlag(enum_flag_Category_Mask) == category); + _ASSERTE(GetFlag(enum_flag_Category_Mask) == static_cast(category)); break; } } diff --git a/src/coreclr/vm/methodtable.h b/src/coreclr/vm/methodtable.h index 1544e77b11987b..2de0a7ab49eed4 100644 --- a/src/coreclr/vm/methodtable.h +++ b/src/coreclr/vm/methodtable.h @@ -3789,8 +3789,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_Primitive = 0x00060000, // sub-category of ValueType, Primitive (ELEMENT_TYPE_I, etc.). [cDAC] [RuntimeTypeSystem]: Contract depends on this value - enum_flag_Category_Enum = 0x00070000, // sub-category of ValueType, Enum. [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_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 2019c1ab8b2d1c..60c4c1bde2f89f 100644 --- a/src/coreclr/vm/methodtable.inl +++ b/src/coreclr/vm/methodtable.inl @@ -327,14 +327,14 @@ inline DWORD MethodTable::GetRank() inline bool MethodTable::IsTruePrimitive() { LIMITED_METHOD_DAC_CONTRACT; - return GetFlag(enum_flag_Category_Mask) == enum_flag_Category_Primitive; + return GetFlag(enum_flag_Category_Mask) == enum_flag_Category_TruePrimitive; } //========================================================================================== inline bool MethodTable::IsPrimitive() { LIMITED_METHOD_DAC_CONTRACT; - return GetFlag(enum_flag_Category_ElementTypeMask) == enum_flag_Category_Primitive; + return GetFlag(enum_flag_Category_ElementTypeMask) == enum_flag_Category_TruePrimitive; } //========================================================================================== 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 41408991c2b95b..837cbf00224371 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 @@ -848,9 +848,9 @@ 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_Enum: + case MethodTableFlags_1.WFLAGS_HIGH.Category_PrimitiveValueType: return CorElementType.ValueType; - case MethodTableFlags_1.WFLAGS_HIGH.Category_Primitive: + case MethodTableFlags_1.WFLAGS_HIGH.Category_TruePrimitive: return (CorElementType)GetClassData(typeHandle).InternalCorElementType; default: return CorElementType.Class; @@ -883,14 +883,14 @@ public bool IsValueType(TypeHandle typeHandle) public bool IsEnum(TypeHandle typeHandle) { - // Enums have Category_Enum in their MethodTable flags and their + // Enums have Category_PrimitiveValueType in their MethodTable flags and their // InternalCorElementType is a primitive type (I1, U1, I2, U2, I4, U4, I8, U8), // not ValueType. if (!typeHandle.IsMethodTable()) return false; MethodTable methodTable = _methodTables[typeHandle.Address]; - return methodTable.Flags.GetFlag(MethodTableFlags_1.WFLAGS_HIGH.Category_Mask) == MethodTableFlags_1.WFLAGS_HIGH.Category_Enum; + return methodTable.Flags.GetFlag(MethodTableFlags_1.WFLAGS_HIGH.Category_Mask) == MethodTableFlags_1.WFLAGS_HIGH.Category_PrimitiveValueType; } // 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 56975c1df16073..466d45a4ee4975 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,8 +42,8 @@ internal enum WFLAGS_HIGH : uint Category_ElementType_Mask = 0x000E0000, Category_ValueType = 0x00040000, Category_Nullable = 0x00050000, - Category_Primitive = 0x00060000, - Category_Enum = 0x00070000, + Category_PrimitiveValueType = 0x00060000, + Category_TruePrimitive = 0x00070000, Category_Interface = 0x000C0000, Collectible = 0x00200000, // GC depends on this bit. RequiresAlign8 = 0x00800000, diff --git a/src/native/managed/cdac/tests/MethodTableTests.cs b/src/native/managed/cdac/tests/MethodTableTests.cs index 08a2f7542d3ac0..05ebd34cd4604c 100644 --- a/src/native/managed/cdac/tests/MethodTableTests.cs +++ b/src/native/managed/cdac/tests/MethodTableTests.cs @@ -547,7 +547,7 @@ public void IsValueTypeReturnsTrueForValueTypeCategories(MockTarget.Architecture MockEEClass enumEEClass = rtsBuilder.AddEEClass("EnumEEClass"); MockMethodTable enumMT = rtsBuilder.AddMethodTable("Enum"); - enumMT.MTFlags = (uint)MethodTableFlags_1.WFLAGS_HIGH.Category_Enum; + enumMT.MTFlags = (uint)MethodTableFlags_1.WFLAGS_HIGH.Category_PrimitiveValueType; enumMT.BaseSize = rtsBuilder.Builder.TargetTestHelpers.ObjectBaseSize; enumMT.ParentMethodTable = systemObjectMethodTablePtr; enumMT.NumVirtuals = 3; @@ -557,7 +557,7 @@ public void IsValueTypeReturnsTrueForValueTypeCategories(MockTarget.Architecture MockEEClass tpEEClass = rtsBuilder.AddEEClass("TruePrimitiveEEClass"); MockMethodTable tpMT = rtsBuilder.AddMethodTable("TruePrimitive"); - tpMT.MTFlags = (uint)MethodTableFlags_1.WFLAGS_HIGH.Category_Primitive; + tpMT.MTFlags = (uint)MethodTableFlags_1.WFLAGS_HIGH.Category_TruePrimitive; tpMT.BaseSize = rtsBuilder.Builder.TargetTestHelpers.ObjectBaseSize; tpMT.ParentMethodTable = systemObjectMethodTablePtr; tpMT.NumVirtuals = 3; From 492ea1eda1ffa10027264094c487d02b57b91560 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Wed, 6 May 2026 22:37:08 -0700 Subject: [PATCH 18/63] Apply suggestion from @jkotas --- .../System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 5a976b2d8f54d3..668e6663cc506e 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 @@ -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_TruePrimitive; + public bool IsPrimitive => (Flags & enum_flag_Category_IsPrimitiveMask) == enum_flag_Category_PrimitiveValueType; public bool IsTruePrimitive => (Flags & enum_flag_Category_Mask) == enum_flag_Category_TruePrimitive; From 4b6ba08cc7c412c1891616a0765a6ec7284bbffb Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Wed, 6 May 2026 22:38:43 -0700 Subject: [PATCH 19/63] Apply suggestion from @jkotas --- src/coreclr/vm/methodtable.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/vm/methodtable.cpp b/src/coreclr/vm/methodtable.cpp index c7224f3c0f5946..9f3a30d675ca1a 100644 --- a/src/coreclr/vm/methodtable.cpp +++ b/src/coreclr/vm/methodtable.cpp @@ -4969,7 +4969,7 @@ CorElementType MethodTable::GetInternalCorElementType() ret = ELEMENT_TYPE_VALUETYPE; break; - case enum_flag_Category_TruePrimitive: + case enum_flag_Category_PrimitiveValueType: // enum_flag_Category_ElementTypeMask maps both Category_TruePrimitive and Category_PrimitiveValueType here. ret = GetClass()->GetInternalCorElementType(); _ASSERTE((ret != ELEMENT_TYPE_CLASS) && From 1e0c51023037a0999c11e430963ca3738e152808 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Wed, 6 May 2026 22:39:06 -0700 Subject: [PATCH 20/63] Apply suggestion from @jkotas --- .../System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 668e6663cc506e..935ae133272fe7 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 @@ -957,7 +957,7 @@ public int MultiDimensionalArrayRank // 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 IsTruePrimitive => (Flags & enum_flag_Category_Mask) == enum_flag_Category_TruePrimitive; + public bool IsTruePrimitive => (Flags & enum_flag_Category_Mask) is enum_flag_Category_TruePrimitive; public bool IsArray => (Flags & enum_flag_Category_Array_Mask) == enum_flag_Category_Array; From 64a71ba0242df571e6bf8ad0cd2a4b043b85587b Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Wed, 6 May 2026 22:40:38 -0700 Subject: [PATCH 21/63] Apply suggestion from @jkotas --- src/coreclr/vm/methodtable.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/vm/methodtable.inl b/src/coreclr/vm/methodtable.inl index 60c4c1bde2f89f..0b534584a55845 100644 --- a/src/coreclr/vm/methodtable.inl +++ b/src/coreclr/vm/methodtable.inl @@ -334,7 +334,7 @@ inline bool MethodTable::IsTruePrimitive() inline bool MethodTable::IsPrimitive() { LIMITED_METHOD_DAC_CONTRACT; - return GetFlag(enum_flag_Category_ElementTypeMask) == enum_flag_Category_TruePrimitive; + return GetFlag(enum_flag_Category_ElementTypeMask) == enum_flag_Category_PrimitiveValueType; } //========================================================================================== From e7ac939f90ee550e042669ca92c475e71c04452b Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Wed, 6 May 2026 22:44:03 -0700 Subject: [PATCH 22/63] Apply suggestions from code review Co-authored-by: Jan Kotas --- src/coreclr/vm/methodtable.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/coreclr/vm/methodtable.cpp b/src/coreclr/vm/methodtable.cpp index 9f3a30d675ca1a..cc9932333764c4 100644 --- a/src/coreclr/vm/methodtable.cpp +++ b/src/coreclr/vm/methodtable.cpp @@ -5046,13 +5046,9 @@ void MethodTable::SetInternalCorElementType(CorElementType elemType, bool isTrue break; case ELEMENT_TYPE_VALUETYPE: SetFlag(enum_flag_Category_ValueType); - _ASSERTE(GetFlag(enum_flag_Category_Mask) == enum_flag_Category_ValueType); break; default: - { - WFLAGS_HIGH_ENUM category = isTruePrimitive ? enum_flag_Category_TruePrimitive : enum_flag_Category_PrimitiveValueType; - SetFlag(category); - _ASSERTE(GetFlag(enum_flag_Category_Mask) == static_cast(category)); + SetFlag(isTruePrimitive ? enum_flag_Category_TruePrimitive : enum_flag_Category_PrimitiveValueType); break; } } From 8d0b204afffd1ce9c0b1e9f234c8a238f7e363aa Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Wed, 6 May 2026 22:51:23 -0700 Subject: [PATCH 23/63] Apply suggestion from @jkotas --- docs/design/datacontracts/RuntimeTypeSystem.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/design/datacontracts/RuntimeTypeSystem.md b/docs/design/datacontracts/RuntimeTypeSystem.md index bb92fa93681839..a56d7889561529 100644 --- a/docs/design/datacontracts/RuntimeTypeSystem.md +++ b/docs/design/datacontracts/RuntimeTypeSystem.md @@ -837,7 +837,7 @@ Contracts used: // Enums have Category_PrimitiveValueType in their MethodTable flags and their // InternalCorElementType is a primitive type (I1, U1, I2, U2, I4, U4, I8, U8), - // not ValueType. + // not ValueType. Regular primitive value types (Int32, etc.) have Category_TruePrimitive. public bool IsEnum(TypeHandle typeHandle) { if (!typeHandle.IsMethodTable()) From eba9e493d2ea5080a588f6f7ecdfd0159ec70778 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Wed, 6 May 2026 23:00:38 -0700 Subject: [PATCH 24/63] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- src/coreclr/vm/methodtable.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/coreclr/vm/methodtable.cpp b/src/coreclr/vm/methodtable.cpp index cc9932333764c4..db587a1c764345 100644 --- a/src/coreclr/vm/methodtable.cpp +++ b/src/coreclr/vm/methodtable.cpp @@ -5051,7 +5051,6 @@ void MethodTable::SetInternalCorElementType(CorElementType elemType, bool isTrue SetFlag(isTruePrimitive ? enum_flag_Category_TruePrimitive : enum_flag_Category_PrimitiveValueType); break; } - } GetClass()->SetInternalCorElementType(elemType); _ASSERTE(GetInternalCorElementType() == elemType); From 53ca4a8ec200187fae2888328ac3d42ce5564010 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Wed, 6 May 2026 23:02:44 -0700 Subject: [PATCH 25/63] Apply suggestion from @jkotas --- src/coreclr/vm/methodtable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/vm/methodtable.h b/src/coreclr/vm/methodtable.h index 2de0a7ab49eed4..6283c4001362b7 100644 --- a/src/coreclr/vm/methodtable.h +++ b/src/coreclr/vm/methodtable.h @@ -3789,7 +3789,7 @@ 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_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_Array = 0x00080000, // [cDAC] [RuntimeTypeSystem]: Contract depends on this value From 6e6336ac9fd70207aa3e19a34d1d1266c627ae62 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Wed, 6 May 2026 23:03:16 -0700 Subject: [PATCH 26/63] Apply suggestion from @jkotas --- src/coreclr/vm/methodtable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/vm/methodtable.h b/src/coreclr/vm/methodtable.h index 6283c4001362b7..584b14b311089b 100644 --- a/src/coreclr/vm/methodtable.h +++ b/src/coreclr/vm/methodtable.h @@ -3790,7 +3790,7 @@ public : 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_TruePrimitive = 0x00070000, // sub-category of PrimitiveValueType. (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 From 5f72765a2c00c13c88de5125fa7ac36c45500492 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Wed, 6 May 2026 23:05:34 -0700 Subject: [PATCH 27/63] Apply suggestion from @jkotas --- src/coreclr/vm/methodtable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/vm/methodtable.h b/src/coreclr/vm/methodtable.h index 584b14b311089b..3a36da70642967 100644 --- a/src/coreclr/vm/methodtable.h +++ b/src/coreclr/vm/methodtable.h @@ -3790,7 +3790,7 @@ public : 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 PrimitiveValueType. (Int32, etc.). [cDAC] [RuntimeTypeSystem]: Contract depends on this value + enum_flag_Category_TruePrimitive = 0x00070000, // sub-category of PrimitiveValueType. Regular primitive value types (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 From 12c52810e3b75c1b1042caa50d78a4c59bc49bcd Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Wed, 6 May 2026 23:06:21 -0700 Subject: [PATCH 28/63] Apply suggestion from @jkotas --- src/coreclr/vm/methodtable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/vm/methodtable.h b/src/coreclr/vm/methodtable.h index 3a36da70642967..7fed86f2196770 100644 --- a/src/coreclr/vm/methodtable.h +++ b/src/coreclr/vm/methodtable.h @@ -3789,7 +3789,7 @@ 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_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 PrimitiveValueType. Regular primitive value types (Int32, etc.). [cDAC] [RuntimeTypeSystem]: Contract depends on this value enum_flag_Category_Array = 0x00080000, // [cDAC] [RuntimeTypeSystem]: Contract depends on this value From b7b9de796f5fefd17310e50e04170f7555bbafe3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 06:13:35 +0000 Subject: [PATCH 29/63] Update enum_flag_Category_PrimitiveValueType comment to 'Enum or true primitive' Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/9263f39d-624e-4ab2-aec8-3250d36f4d9a Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- .../System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs | 2 +- src/coreclr/vm/methodtable.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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..64f2b6bc84b596 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 @@ -850,7 +850,7 @@ internal unsafe struct MethodTable 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_PrimitiveValueType = 0x00060000; // sub-category of ValueType, Enum or true primitive private const uint enum_flag_Category_TruePrimitive = 0x00070000; // sub-category of ValueType, Primitive (ELEMENT_TYPE_I, etc.) private const uint enum_flag_Category_Array = 0x00080000; private const uint enum_flag_Category_Array_Mask = 0x000C0000; diff --git a/src/coreclr/vm/methodtable.h b/src/coreclr/vm/methodtable.h index 7fed86f2196770..7a3626fba6a25f 100644 --- a/src/coreclr/vm/methodtable.h +++ b/src/coreclr/vm/methodtable.h @@ -3789,7 +3789,7 @@ 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_PrimitiveValueType=0x00060000, // sub-category of ValueType, Enum or true primitive. [cDAC] [RuntimeTypeSystem]: Contract depends on this value enum_flag_Category_TruePrimitive = 0x00070000, // sub-category of PrimitiveValueType. Regular primitive value types (Int32, etc.). [cDAC] [RuntimeTypeSystem]: Contract depends on this value enum_flag_Category_Array = 0x00080000, // [cDAC] [RuntimeTypeSystem]: Contract depends on this value From cf223a585a1237ec57ee78c78183ca7808d32fac Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 06:23:58 +0000 Subject: [PATCH 30/63] Update primitive category comments Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/17782ce4-6976-4012-a337-8003bc624549 Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- .../System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs | 2 +- src/coreclr/vm/methodtable.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) 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 64f2b6bc84b596..cfa30b2573944f 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 @@ -851,7 +851,7 @@ internal unsafe struct MethodTable 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 true primitive - private const uint enum_flag_Category_TruePrimitive = 0x00070000; // sub-category of ValueType, Primitive (ELEMENT_TYPE_I, etc.) + private const uint enum_flag_Category_TruePrimitive = 0x00070000; // sub-category of PrimitiveValueType. (Int32, etc.) 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; diff --git a/src/coreclr/vm/methodtable.h b/src/coreclr/vm/methodtable.h index 7a3626fba6a25f..c3aabdbc84ce64 100644 --- a/src/coreclr/vm/methodtable.h +++ b/src/coreclr/vm/methodtable.h @@ -3789,8 +3789,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 true primitive. [cDAC] [RuntimeTypeSystem]: Contract depends on this value - enum_flag_Category_TruePrimitive = 0x00070000, // sub-category of PrimitiveValueType. Regular primitive value types (Int32, etc.). [cDAC] [RuntimeTypeSystem]: Contract depends on this value + enum_flag_Category_PrimitiveValueType= 0x00060000, // sub-category of ValueType, Enum or true primitive. [cDAC] [RuntimeTypeSystem]: Contract depends on this value + enum_flag_Category_TruePrimitive = 0x00070000, // sub-category of PrimitiveValueType. (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 From fe05de31bc7ff348781648f5be4c7d1ab1de7895 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 06:43:55 +0000 Subject: [PATCH 31/63] Rename enum_flag_Category_PrimitiveValueType to enum_flag_Category_Enum throughout Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/104333fd-5bb4-4e6c-9d53-1cc01c62e143 Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- docs/design/datacontracts/RuntimeTypeSystem.md | 4 ++-- .../Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs | 6 +++--- src/coreclr/vm/methodtable.cpp | 8 ++++---- src/coreclr/vm/methodtable.h | 4 ++-- src/coreclr/vm/methodtable.inl | 2 +- .../Contracts/RuntimeTypeSystem_1.cs | 6 +++--- .../RuntimeTypeSystemHelpers/MethodTableFlags_1.cs | 2 +- src/native/managed/cdac/tests/MethodTableTests.cs | 2 +- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/docs/design/datacontracts/RuntimeTypeSystem.md b/docs/design/datacontracts/RuntimeTypeSystem.md index a56d7889561529..b31f32f9d65ccd 100644 --- a/docs/design/datacontracts/RuntimeTypeSystem.md +++ b/docs/design/datacontracts/RuntimeTypeSystem.md @@ -835,7 +835,7 @@ Contracts used: // if typedesc: check for CorElementType.ValueType } - // Enums have Category_PrimitiveValueType in their MethodTable flags and their + // Enums have Category_Enum 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 (Int32, etc.) have Category_TruePrimitive. public bool IsEnum(TypeHandle typeHandle) @@ -844,7 +844,7 @@ Contracts used: return false; MethodTable methodTable = _methodTables[typeHandle.Address]; - return methodTable.Flags.GetFlag(WFLAGS_HIGH.Category_Mask) == WFLAGS_HIGH.Category_PrimitiveValueType; + return methodTable.Flags.GetFlag(WFLAGS_HIGH.Category_Mask) == WFLAGS_HIGH.Category_Enum; } // 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 cfa30b2573944f..c037c95e9f3fce 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 @@ -850,8 +850,8 @@ internal unsafe struct MethodTable 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 true primitive - private const uint enum_flag_Category_TruePrimitive = 0x00070000; // sub-category of PrimitiveValueType. (Int32, etc.) + private const uint enum_flag_Category_Enum = 0x00060000; // sub-category of ValueType + private const uint enum_flag_Category_TruePrimitive = 0x00070000; // sub-category of ValueType. (Int32, etc.) 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_IsPrimitiveMask) == enum_flag_Category_Enum; public bool IsTruePrimitive => (Flags & enum_flag_Category_Mask) is enum_flag_Category_TruePrimitive; diff --git a/src/coreclr/vm/methodtable.cpp b/src/coreclr/vm/methodtable.cpp index db587a1c764345..21aa442bdbfcf8 100644 --- a/src/coreclr/vm/methodtable.cpp +++ b/src/coreclr/vm/methodtable.cpp @@ -4969,8 +4969,8 @@ CorElementType MethodTable::GetInternalCorElementType() ret = ELEMENT_TYPE_VALUETYPE; break; - case enum_flag_Category_PrimitiveValueType: - // enum_flag_Category_ElementTypeMask maps both Category_TruePrimitive and Category_PrimitiveValueType here. + case enum_flag_Category_Enum: + // enum_flag_Category_ElementTypeMask maps both Category_TruePrimitive and Category_Enum here. ret = GetClass()->GetInternalCorElementType(); _ASSERTE((ret != ELEMENT_TYPE_CLASS) && (ret != ELEMENT_TYPE_VALUETYPE)); @@ -5015,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_Enum: ret = ELEMENT_TYPE_VALUETYPE; break; @@ -5048,7 +5048,7 @@ void MethodTable::SetInternalCorElementType(CorElementType elemType, bool isTrue SetFlag(enum_flag_Category_ValueType); break; default: - SetFlag(isTruePrimitive ? enum_flag_Category_TruePrimitive : enum_flag_Category_PrimitiveValueType); + SetFlag(isTruePrimitive ? enum_flag_Category_TruePrimitive : enum_flag_Category_Enum); break; } diff --git a/src/coreclr/vm/methodtable.h b/src/coreclr/vm/methodtable.h index c3aabdbc84ce64..9542f0aa251f2c 100644 --- a/src/coreclr/vm/methodtable.h +++ b/src/coreclr/vm/methodtable.h @@ -3789,8 +3789,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 true primitive. [cDAC] [RuntimeTypeSystem]: Contract depends on this value - enum_flag_Category_TruePrimitive = 0x00070000, // sub-category of PrimitiveValueType. (Int32, etc.). [cDAC] [RuntimeTypeSystem]: Contract depends on this value + enum_flag_Category_Enum = 0x00060000, // sub-category of ValueType. [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 0b534584a55845..058d1e3349a5b9 100644 --- a/src/coreclr/vm/methodtable.inl +++ b/src/coreclr/vm/methodtable.inl @@ -334,7 +334,7 @@ inline bool MethodTable::IsTruePrimitive() inline bool MethodTable::IsPrimitive() { LIMITED_METHOD_DAC_CONTRACT; - return GetFlag(enum_flag_Category_ElementTypeMask) == enum_flag_Category_PrimitiveValueType; + return GetFlag(enum_flag_Category_ElementTypeMask) == enum_flag_Category_Enum; } //========================================================================================== 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 837cbf00224371..2bbd4a11a7c9de 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 @@ -848,7 +848,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_Enum: return CorElementType.ValueType; case MethodTableFlags_1.WFLAGS_HIGH.Category_TruePrimitive: return (CorElementType)GetClassData(typeHandle).InternalCorElementType; @@ -883,14 +883,14 @@ public bool IsValueType(TypeHandle typeHandle) public bool IsEnum(TypeHandle typeHandle) { - // Enums have Category_PrimitiveValueType in their MethodTable flags and their + // Enums have Category_Enum in their MethodTable flags and their // InternalCorElementType is a primitive type (I1, U1, I2, U2, I4, U4, I8, U8), // not ValueType. if (!typeHandle.IsMethodTable()) return false; MethodTable methodTable = _methodTables[typeHandle.Address]; - return methodTable.Flags.GetFlag(MethodTableFlags_1.WFLAGS_HIGH.Category_Mask) == MethodTableFlags_1.WFLAGS_HIGH.Category_PrimitiveValueType; + return methodTable.Flags.GetFlag(MethodTableFlags_1.WFLAGS_HIGH.Category_Mask) == MethodTableFlags_1.WFLAGS_HIGH.Category_Enum; } // 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..11076a8c73a8d4 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_Enum = 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 05ebd34cd4604c..0c5f9a5d4d4c9c 100644 --- a/src/native/managed/cdac/tests/MethodTableTests.cs +++ b/src/native/managed/cdac/tests/MethodTableTests.cs @@ -547,7 +547,7 @@ public void IsValueTypeReturnsTrueForValueTypeCategories(MockTarget.Architecture MockEEClass enumEEClass = rtsBuilder.AddEEClass("EnumEEClass"); MockMethodTable enumMT = rtsBuilder.AddMethodTable("Enum"); - enumMT.MTFlags = (uint)MethodTableFlags_1.WFLAGS_HIGH.Category_PrimitiveValueType; + enumMT.MTFlags = (uint)MethodTableFlags_1.WFLAGS_HIGH.Category_Enum; enumMT.BaseSize = rtsBuilder.Builder.TargetTestHelpers.ObjectBaseSize; enumMT.ParentMethodTable = systemObjectMethodTablePtr; enumMT.NumVirtuals = 3; From 99c07d85ac6ddcc495fb7e1bf6b90767197e6b44 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 06:54:09 +0000 Subject: [PATCH 32/63] Add explanatory comment to IsPrimitive() about ElementTypeMask behavior Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/77f3ecf4-b37d-4e90-860a-e73634f54ac6 Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- src/coreclr/vm/methodtable.inl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/coreclr/vm/methodtable.inl b/src/coreclr/vm/methodtable.inl index 058d1e3349a5b9..ec821ac7962ce4 100644 --- a/src/coreclr/vm/methodtable.inl +++ b/src/coreclr/vm/methodtable.inl @@ -334,6 +334,7 @@ inline bool MethodTable::IsTruePrimitive() inline bool MethodTable::IsPrimitive() { LIMITED_METHOD_DAC_CONTRACT; + // enum_flag_Category_ElementTypeMask maps both Category_TruePrimitive and Category_Enum here. return GetFlag(enum_flag_Category_ElementTypeMask) == enum_flag_Category_Enum; } From 8739054ea9e0cf56b16e6a75edc91e78fa09b1c1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 13:58:19 +0000 Subject: [PATCH 33/63] Restore ELEMENT_TYPE_I for runtime handle types without setting category flags Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/475ee8bc-54b9-4ace-b1d4-dc7da359a9b4 Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- src/coreclr/vm/methodtablebuilder.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/coreclr/vm/methodtablebuilder.cpp b/src/coreclr/vm/methodtablebuilder.cpp index c37e930e31050c..bc7f59a7524c26 100644 --- a/src/coreclr/vm/methodtablebuilder.cpp +++ b/src/coreclr/vm/methodtablebuilder.cpp @@ -10777,6 +10777,18 @@ void MethodTableBuilder::CheckForSystemTypes() { pMT->SetIsNullable(); } + else if (strcmp(name, g_RuntimeArgumentHandleName) == 0) + { + GetHalfBakedClass()->SetInternalCorElementType(ELEMENT_TYPE_I); + } + else if (strcmp(name, g_RuntimeMethodHandleInternalName) == 0) + { + GetHalfBakedClass()->SetInternalCorElementType(ELEMENT_TYPE_I); + } + else if (strcmp(name, g_RuntimeFieldHandleInternalName) == 0) + { + GetHalfBakedClass()->SetInternalCorElementType(ELEMENT_TYPE_I); + } else if ((strcmp(name, g_Int128Name) == 0) || (strcmp(name, g_UInt128Name) == 0)) { EEClassLayoutInfo* pLayout = pClass->GetLayoutInfo(); From 4688e6d3bcc327079967ca8d9f1781611b068fdb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 14:17:05 +0000 Subject: [PATCH 34/63] Revert "Restore ELEMENT_TYPE_I for runtime handle types without setting category flags" This reverts commit 8739054ea9e0cf56b16e6a75edc91e78fa09b1c1. Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- src/coreclr/vm/methodtablebuilder.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/coreclr/vm/methodtablebuilder.cpp b/src/coreclr/vm/methodtablebuilder.cpp index bc7f59a7524c26..c37e930e31050c 100644 --- a/src/coreclr/vm/methodtablebuilder.cpp +++ b/src/coreclr/vm/methodtablebuilder.cpp @@ -10777,18 +10777,6 @@ void MethodTableBuilder::CheckForSystemTypes() { pMT->SetIsNullable(); } - else if (strcmp(name, g_RuntimeArgumentHandleName) == 0) - { - GetHalfBakedClass()->SetInternalCorElementType(ELEMENT_TYPE_I); - } - else if (strcmp(name, g_RuntimeMethodHandleInternalName) == 0) - { - GetHalfBakedClass()->SetInternalCorElementType(ELEMENT_TYPE_I); - } - else if (strcmp(name, g_RuntimeFieldHandleInternalName) == 0) - { - GetHalfBakedClass()->SetInternalCorElementType(ELEMENT_TYPE_I); - } else if ((strcmp(name, g_Int128Name) == 0) || (strcmp(name, g_UInt128Name) == 0)) { EEClassLayoutInfo* pLayout = pClass->GetLayoutInfo(); From 25a34203dfe6041d293f495a9453e5ef20d0a824 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 14:25:36 +0000 Subject: [PATCH 35/63] Fix runtime handle types by setting ELEMENT_TYPE_I with Category_Enum and validating enum underlying types in IsEnum() Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/3ee6d5ff-6d86-4a80-9113-7a4bb37a39cd Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- .../design/datacontracts/RuntimeTypeSystem.md | 19 ++++++++++++++++--- src/coreclr/vm/methodtablebuilder.cpp | 12 ++++++++++++ .../Contracts/RuntimeTypeSystem_1.cs | 18 +++++++++++++++--- 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/docs/design/datacontracts/RuntimeTypeSystem.md b/docs/design/datacontracts/RuntimeTypeSystem.md index b31f32f9d65ccd..15933dac446a04 100644 --- a/docs/design/datacontracts/RuntimeTypeSystem.md +++ b/docs/design/datacontracts/RuntimeTypeSystem.md @@ -836,15 +836,28 @@ Contracts used: } // Enums have Category_Enum 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 (Int32, etc.) have Category_TruePrimitive. + // InternalCorElementType is a valid enum underlying type (I1, U1, I2, U2, I4, U4, I8, U8), + // not ELEMENT_TYPE_I (which is used for runtime handle types). + // Regular primitive value types (Int32, etc.) have Category_TruePrimitive. public bool IsEnum(TypeHandle typeHandle) { if (!typeHandle.IsMethodTable()) return false; MethodTable methodTable = _methodTables[typeHandle.Address]; - return methodTable.Flags.GetFlag(WFLAGS_HIGH.Category_Mask) == WFLAGS_HIGH.Category_Enum; + if (methodTable.Flags.GetFlag(WFLAGS_HIGH.Category_Mask) != WFLAGS_HIGH.Category_Enum) + return false; + + // Check that the internal element type is a valid enum underlying type + CorElementType elementType = (CorElementType)GetClassData(typeHandle).InternalCorElementType; + return elementType == CorElementType.I1 || + elementType == CorElementType.U1 || + elementType == CorElementType.I2 || + elementType == CorElementType.U2 || + elementType == CorElementType.I4 || + elementType == CorElementType.U4 || + elementType == CorElementType.I8 || + elementType == CorElementType.U8; } // 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/vm/methodtablebuilder.cpp b/src/coreclr/vm/methodtablebuilder.cpp index c37e930e31050c..05af0d7acf1b00 100644 --- a/src/coreclr/vm/methodtablebuilder.cpp +++ b/src/coreclr/vm/methodtablebuilder.cpp @@ -10777,6 +10777,18 @@ void MethodTableBuilder::CheckForSystemTypes() { pMT->SetIsNullable(); } + else if (strcmp(name, g_RuntimeArgumentHandleName) == 0) + { + pMT->SetInternalCorElementType(ELEMENT_TYPE_I, false); + } + else if (strcmp(name, g_RuntimeMethodHandleInternalName) == 0) + { + pMT->SetInternalCorElementType(ELEMENT_TYPE_I, false); + } + else if (strcmp(name, g_RuntimeFieldHandleInternalName) == 0) + { + pMT->SetInternalCorElementType(ELEMENT_TYPE_I, false); + } else if ((strcmp(name, g_Int128Name) == 0) || (strcmp(name, g_UInt128Name) == 0)) { EEClassLayoutInfo* pLayout = pClass->GetLayoutInfo(); 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 2bbd4a11a7c9de..84002fc829b794 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 @@ -884,13 +884,25 @@ public bool IsValueType(TypeHandle typeHandle) public bool IsEnum(TypeHandle typeHandle) { // Enums have Category_Enum in their MethodTable flags and their - // InternalCorElementType is a primitive type (I1, U1, I2, U2, I4, U4, I8, U8), - // not ValueType. + // InternalCorElementType is a valid enum underlying type (I1, U1, I2, U2, I4, U4, I8, U8), + // not ELEMENT_TYPE_I (which is used for runtime handle types). if (!typeHandle.IsMethodTable()) return false; MethodTable methodTable = _methodTables[typeHandle.Address]; - return methodTable.Flags.GetFlag(MethodTableFlags_1.WFLAGS_HIGH.Category_Mask) == MethodTableFlags_1.WFLAGS_HIGH.Category_Enum; + if (methodTable.Flags.GetFlag(MethodTableFlags_1.WFLAGS_HIGH.Category_Mask) != MethodTableFlags_1.WFLAGS_HIGH.Category_Enum) + return false; + + // Check that the internal element type is a valid enum underlying type + CorElementType elementType = (CorElementType)GetClassData(typeHandle).InternalCorElementType; + return elementType == CorElementType.I1 || + elementType == CorElementType.U1 || + elementType == CorElementType.I2 || + elementType == CorElementType.U2 || + elementType == CorElementType.I4 || + elementType == CorElementType.U4 || + elementType == CorElementType.I8 || + elementType == CorElementType.U8; } // 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. From ac9f6f6817ca5b97be3684115cac574b3c6dc900 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 14:47:21 +0000 Subject: [PATCH 36/63] Revert "Fix runtime handle types by setting ELEMENT_TYPE_I with Category_Enum and validating enum underlying types in IsEnum()" This reverts commit 25a34203dfe6041d293f495a9453e5ef20d0a824. Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- .../design/datacontracts/RuntimeTypeSystem.md | 19 +++---------------- src/coreclr/vm/methodtablebuilder.cpp | 12 ------------ .../Contracts/RuntimeTypeSystem_1.cs | 18 +++--------------- 3 files changed, 6 insertions(+), 43 deletions(-) diff --git a/docs/design/datacontracts/RuntimeTypeSystem.md b/docs/design/datacontracts/RuntimeTypeSystem.md index 15933dac446a04..b31f32f9d65ccd 100644 --- a/docs/design/datacontracts/RuntimeTypeSystem.md +++ b/docs/design/datacontracts/RuntimeTypeSystem.md @@ -836,28 +836,15 @@ Contracts used: } // Enums have Category_Enum in their MethodTable flags and their - // InternalCorElementType is a valid enum underlying type (I1, U1, I2, U2, I4, U4, I8, U8), - // not ELEMENT_TYPE_I (which is used for runtime handle types). - // Regular primitive value types (Int32, etc.) have Category_TruePrimitive. + // InternalCorElementType is a primitive type (I1, U1, I2, U2, I4, U4, I8, U8), + // not ValueType. Regular primitive value types (Int32, etc.) have Category_TruePrimitive. public bool IsEnum(TypeHandle typeHandle) { if (!typeHandle.IsMethodTable()) return false; MethodTable methodTable = _methodTables[typeHandle.Address]; - if (methodTable.Flags.GetFlag(WFLAGS_HIGH.Category_Mask) != WFLAGS_HIGH.Category_Enum) - return false; - - // Check that the internal element type is a valid enum underlying type - CorElementType elementType = (CorElementType)GetClassData(typeHandle).InternalCorElementType; - return elementType == CorElementType.I1 || - elementType == CorElementType.U1 || - elementType == CorElementType.I2 || - elementType == CorElementType.U2 || - elementType == CorElementType.I4 || - elementType == CorElementType.U4 || - elementType == CorElementType.I8 || - elementType == CorElementType.U8; + return methodTable.Flags.GetFlag(WFLAGS_HIGH.Category_Mask) == WFLAGS_HIGH.Category_Enum; } // 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/vm/methodtablebuilder.cpp b/src/coreclr/vm/methodtablebuilder.cpp index 05af0d7acf1b00..c37e930e31050c 100644 --- a/src/coreclr/vm/methodtablebuilder.cpp +++ b/src/coreclr/vm/methodtablebuilder.cpp @@ -10777,18 +10777,6 @@ void MethodTableBuilder::CheckForSystemTypes() { pMT->SetIsNullable(); } - else if (strcmp(name, g_RuntimeArgumentHandleName) == 0) - { - pMT->SetInternalCorElementType(ELEMENT_TYPE_I, false); - } - else if (strcmp(name, g_RuntimeMethodHandleInternalName) == 0) - { - pMT->SetInternalCorElementType(ELEMENT_TYPE_I, false); - } - else if (strcmp(name, g_RuntimeFieldHandleInternalName) == 0) - { - pMT->SetInternalCorElementType(ELEMENT_TYPE_I, false); - } else if ((strcmp(name, g_Int128Name) == 0) || (strcmp(name, g_UInt128Name) == 0)) { EEClassLayoutInfo* pLayout = pClass->GetLayoutInfo(); 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 84002fc829b794..2bbd4a11a7c9de 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 @@ -884,25 +884,13 @@ public bool IsValueType(TypeHandle typeHandle) public bool IsEnum(TypeHandle typeHandle) { // Enums have Category_Enum in their MethodTable flags and their - // InternalCorElementType is a valid enum underlying type (I1, U1, I2, U2, I4, U4, I8, U8), - // not ELEMENT_TYPE_I (which is used for runtime handle types). + // InternalCorElementType is a primitive type (I1, U1, I2, U2, I4, U4, I8, U8), + // not ValueType. if (!typeHandle.IsMethodTable()) return false; MethodTable methodTable = _methodTables[typeHandle.Address]; - if (methodTable.Flags.GetFlag(MethodTableFlags_1.WFLAGS_HIGH.Category_Mask) != MethodTableFlags_1.WFLAGS_HIGH.Category_Enum) - return false; - - // Check that the internal element type is a valid enum underlying type - CorElementType elementType = (CorElementType)GetClassData(typeHandle).InternalCorElementType; - return elementType == CorElementType.I1 || - elementType == CorElementType.U1 || - elementType == CorElementType.I2 || - elementType == CorElementType.U2 || - elementType == CorElementType.I4 || - elementType == CorElementType.U4 || - elementType == CorElementType.I8 || - elementType == CorElementType.U8; + return methodTable.Flags.GetFlag(MethodTableFlags_1.WFLAGS_HIGH.Category_Mask) == MethodTableFlags_1.WFLAGS_HIGH.Category_Enum; } // 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. From d0a71b83ce3e8e2f46d6acae7ce9865502a657da Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 14:51:33 +0000 Subject: [PATCH 37/63] Fix JIT assertion for runtime handle types by allowing pointer-sized struct assignment to TYP_I_IMPL locals Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- src/coreclr/jit/importer.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 84749718f92d18..8508eca8b0f252 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -6814,7 +6814,9 @@ void Compiler::impImportBlockCode(BasicBlock* block) (genActualType(lclTyp) == TYP_I_IMPL && (op1->TypeIs(TYP_BYREF) || op1->TypeIs(TYP_REF))) || (genActualType(op1->gtType) == TYP_I_IMPL && lclTyp == TYP_BYREF) || (varTypeIsFloating(lclTyp) && varTypeIsFloating(op1->TypeGet())) || - ((genActualType(lclTyp) == TYP_BYREF) && genActualType(op1->TypeGet()) == TYP_REF)); + ((genActualType(lclTyp) == TYP_BYREF) && genActualType(op1->TypeGet()) == TYP_REF) || + (genActualType(lclTyp) == TYP_I_IMPL && op1->TypeIs(TYP_STRUCT) && + info.compCompHnd->getClassSize(op1->GetLayout(this)->GetClassHandle()) == TARGET_POINTER_SIZE)); // If op1 is "&var" then its type is the transient "*" and it can // be used either as BYREF or TYP_I_IMPL. From 51d25a5754e418f7ec34cdadebf227157bce4a87 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 17:54:49 +0000 Subject: [PATCH 38/63] Fix runtime handle types by setting ELEMENT_TYPE_VALUETYPE for non-primitive value types Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/d189165d-e317-4787-aa73-4aca2aac012e Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- src/coreclr/jit/importer.cpp | 4 +--- src/coreclr/vm/methodtablebuilder.cpp | 6 ++++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 8508eca8b0f252..84749718f92d18 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -6814,9 +6814,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) (genActualType(lclTyp) == TYP_I_IMPL && (op1->TypeIs(TYP_BYREF) || op1->TypeIs(TYP_REF))) || (genActualType(op1->gtType) == TYP_I_IMPL && lclTyp == TYP_BYREF) || (varTypeIsFloating(lclTyp) && varTypeIsFloating(op1->TypeGet())) || - ((genActualType(lclTyp) == TYP_BYREF) && genActualType(op1->TypeGet()) == TYP_REF) || - (genActualType(lclTyp) == TYP_I_IMPL && op1->TypeIs(TYP_STRUCT) && - info.compCompHnd->getClassSize(op1->GetLayout(this)->GetClassHandle()) == TARGET_POINTER_SIZE)); + ((genActualType(lclTyp) == TYP_BYREF) && genActualType(op1->TypeGet()) == TYP_REF)); // If op1 is "&var" then its type is the transient "*" and it can // be used either as BYREF or TYP_I_IMPL. diff --git a/src/coreclr/vm/methodtablebuilder.cpp b/src/coreclr/vm/methodtablebuilder.cpp index c37e930e31050c..7d1590de5b6154 100644 --- a/src/coreclr/vm/methodtablebuilder.cpp +++ b/src/coreclr/vm/methodtablebuilder.cpp @@ -10803,6 +10803,12 @@ void MethodTableBuilder::CheckForSystemTypes() #error Unknown architecture #endif // TARGET_64BIT } + else + { + // For all other value types (including runtime handle types), set ELEMENT_TYPE_VALUETYPE + // to ensure they are correctly categorized as value types rather than reference types. + pMT->SetInternalCorElementType(ELEMENT_TYPE_VALUETYPE, false); + } } else { From 1e2f63b00b023e45daad654f99836a9fe6b4a8d9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 18:03:06 +0000 Subject: [PATCH 39/63] Fix runtime handle types by returning CORINFO_TYPE_VALUECLASS from getTypeForPrimitiveValueClass for non-primitive value types Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- src/coreclr/jit/importer.cpp | 4 +++- src/coreclr/vm/jitinterface.cpp | 6 ++++++ src/coreclr/vm/methodtablebuilder.cpp | 6 ------ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 84749718f92d18..8508eca8b0f252 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -6814,7 +6814,9 @@ void Compiler::impImportBlockCode(BasicBlock* block) (genActualType(lclTyp) == TYP_I_IMPL && (op1->TypeIs(TYP_BYREF) || op1->TypeIs(TYP_REF))) || (genActualType(op1->gtType) == TYP_I_IMPL && lclTyp == TYP_BYREF) || (varTypeIsFloating(lclTyp) && varTypeIsFloating(op1->TypeGet())) || - ((genActualType(lclTyp) == TYP_BYREF) && genActualType(op1->TypeGet()) == TYP_REF)); + ((genActualType(lclTyp) == TYP_BYREF) && genActualType(op1->TypeGet()) == TYP_REF) || + (genActualType(lclTyp) == TYP_I_IMPL && op1->TypeIs(TYP_STRUCT) && + info.compCompHnd->getClassSize(op1->GetLayout(this)->GetClassHandle()) == TARGET_POINTER_SIZE)); // If op1 is "&var" then its type is the transient "*" and it can // be used either as BYREF or TYP_I_IMPL. diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 1fb1ea6b39bd7b..1f2db8f5c03daa 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -4065,6 +4065,12 @@ CorInfoType CEEInfo::getTypeForPrimitiveValueClass( { result = asCorInfoType(elementType); } + else if (!th.IsTypeDesc() && th.AsMethodTable()->IsValueType() && !th.AsMethodTable()->IsTruePrimitive()) + { + // For non-primitive value types (e.g., runtime handle types), return CORINFO_TYPE_VALUECLASS + // so the JIT correctly types them as TYP_STRUCT instead of falling back to TYP_I_IMPL + result = CORINFO_TYPE_VALUECLASS; + } EE_TO_JIT_TRANSITION(); return result; diff --git a/src/coreclr/vm/methodtablebuilder.cpp b/src/coreclr/vm/methodtablebuilder.cpp index 7d1590de5b6154..c37e930e31050c 100644 --- a/src/coreclr/vm/methodtablebuilder.cpp +++ b/src/coreclr/vm/methodtablebuilder.cpp @@ -10803,12 +10803,6 @@ void MethodTableBuilder::CheckForSystemTypes() #error Unknown architecture #endif // TARGET_64BIT } - else - { - // For all other value types (including runtime handle types), set ELEMENT_TYPE_VALUETYPE - // to ensure they are correctly categorized as value types rather than reference types. - pMT->SetInternalCorElementType(ELEMENT_TYPE_VALUETYPE, false); - } } else { From 256d4253ec8f90fbbf54c5fb2419e577db75201e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 18:49:33 +0000 Subject: [PATCH 40/63] Revert assertion relaxation in importer.cpp as the fix in getTypeForPrimitiveValueClass makes it unnecessary Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/cb9f901c-1f24-4b03-b4ca-6dc67f6387ca Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- src/coreclr/jit/importer.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 8508eca8b0f252..84749718f92d18 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -6814,9 +6814,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) (genActualType(lclTyp) == TYP_I_IMPL && (op1->TypeIs(TYP_BYREF) || op1->TypeIs(TYP_REF))) || (genActualType(op1->gtType) == TYP_I_IMPL && lclTyp == TYP_BYREF) || (varTypeIsFloating(lclTyp) && varTypeIsFloating(op1->TypeGet())) || - ((genActualType(lclTyp) == TYP_BYREF) && genActualType(op1->TypeGet()) == TYP_REF) || - (genActualType(lclTyp) == TYP_I_IMPL && op1->TypeIs(TYP_STRUCT) && - info.compCompHnd->getClassSize(op1->GetLayout(this)->GetClassHandle()) == TARGET_POINTER_SIZE)); + ((genActualType(lclTyp) == TYP_BYREF) && genActualType(op1->TypeGet()) == TYP_REF)); // If op1 is "&var" then its type is the transient "*" and it can // be used either as BYREF or TYP_I_IMPL. From 7c775d2d1fcae2b47d85e50d953f11ba4dd0fdcd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 20:01:43 +0000 Subject: [PATCH 41/63] Revert getTypeForPrimitiveValueClass change as it causes test failures Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- src/coreclr/vm/jitinterface.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 1f2db8f5c03daa..1fb1ea6b39bd7b 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -4065,12 +4065,6 @@ CorInfoType CEEInfo::getTypeForPrimitiveValueClass( { result = asCorInfoType(elementType); } - else if (!th.IsTypeDesc() && th.AsMethodTable()->IsValueType() && !th.AsMethodTable()->IsTruePrimitive()) - { - // For non-primitive value types (e.g., runtime handle types), return CORINFO_TYPE_VALUECLASS - // so the JIT correctly types them as TYP_STRUCT instead of falling back to TYP_I_IMPL - result = CORINFO_TYPE_VALUECLASS; - } EE_TO_JIT_TRANSITION(); return result; From 8cd4494cb6305940e5d76035fa09acb68e07cc73 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 10 May 2026 00:28:07 +0000 Subject: [PATCH 42/63] Handle runtime handle internal types as TYP_I_IMPL in JIT lvaInitVarDsc RuntimeArgumentHandle, RuntimeMethodHandleInternal, and RuntimeFieldHandleInternal are pointer-sized value types that should be treated as native ints (TYP_I_IMPL) rather than structs for JIT purposes. This fix identifies these types by name and treats them specially without calling GetClass() or other struct-specific operations that would fail. Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- src/coreclr/jit/lclvars.cpp | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index 34ad714fc1d2c0..754c5e2ff89002 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -889,7 +889,34 @@ void Compiler::lvaInitVarDsc(LclVarDsc* varDsc, // Set the lvType (before this point it is TYP_UNDEF). if ((varTypeIsStruct(type))) { - lvaSetStruct(varNum, typeHnd, typeHnd != NO_CLASS_HANDLE); + // Special case: Runtime handle internal types (RuntimeArgumentHandle, RuntimeMethodHandleInternal, + // RuntimeFieldHandleInternal) are pointer-sized value types that should be treated as + // native ints (TYP_I_IMPL) rather than structs for JIT purposes. + bool isRuntimeHandleInternalType = false; + if ((typeHnd != NO_CLASS_HANDLE) && (info.compCompHnd->getClassSize(typeHnd) == TARGET_POINTER_SIZE)) + { + const char* namespaceName = nullptr; + const char* className = info.compCompHnd->getClassNameFromMetadata(typeHnd, &namespaceName); + if ((className != nullptr) && (namespaceName != nullptr) && (strcmp(namespaceName, "System") == 0)) + { + if ((strcmp(className, "RuntimeMethodHandleInternal") == 0) || + (strcmp(className, "RuntimeArgumentHandle") == 0) || + (strcmp(className, "RuntimeFieldHandleInternal") == 0)) + { + isRuntimeHandleInternalType = true; + } + } + } + + if (isRuntimeHandleInternalType) + { + // Treat runtime handle internal types as native ints + varDsc->lvType = TYP_I_IMPL; + } + else + { + lvaSetStruct(varNum, typeHnd, typeHnd != NO_CLASS_HANDLE); + } } else { From 09d49781984bd07154979512b5f41d3189e620b8 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Sun, 10 May 2026 21:33:59 -0700 Subject: [PATCH 43/63] Revert "Handle runtime handle internal types as TYP_I_IMPL in JIT lvaInitVarDsc" This reverts commit 8cd4494cb6305940e5d76035fa09acb68e07cc73. --- src/coreclr/jit/lclvars.cpp | 29 +---------------------------- 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index 754c5e2ff89002..34ad714fc1d2c0 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -889,34 +889,7 @@ void Compiler::lvaInitVarDsc(LclVarDsc* varDsc, // Set the lvType (before this point it is TYP_UNDEF). if ((varTypeIsStruct(type))) { - // Special case: Runtime handle internal types (RuntimeArgumentHandle, RuntimeMethodHandleInternal, - // RuntimeFieldHandleInternal) are pointer-sized value types that should be treated as - // native ints (TYP_I_IMPL) rather than structs for JIT purposes. - bool isRuntimeHandleInternalType = false; - if ((typeHnd != NO_CLASS_HANDLE) && (info.compCompHnd->getClassSize(typeHnd) == TARGET_POINTER_SIZE)) - { - const char* namespaceName = nullptr; - const char* className = info.compCompHnd->getClassNameFromMetadata(typeHnd, &namespaceName); - if ((className != nullptr) && (namespaceName != nullptr) && (strcmp(namespaceName, "System") == 0)) - { - if ((strcmp(className, "RuntimeMethodHandleInternal") == 0) || - (strcmp(className, "RuntimeArgumentHandle") == 0) || - (strcmp(className, "RuntimeFieldHandleInternal") == 0)) - { - isRuntimeHandleInternalType = true; - } - } - } - - if (isRuntimeHandleInternalType) - { - // Treat runtime handle internal types as native ints - varDsc->lvType = TYP_I_IMPL; - } - else - { - lvaSetStruct(varNum, typeHnd, typeHnd != NO_CLASS_HANDLE); - } + lvaSetStruct(varNum, typeHnd, typeHnd != NO_CLASS_HANDLE); } else { From a5c7ff8cf5802d528fd35d1b0e5a99fb2a012aa3 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Thu, 14 May 2026 20:32:26 -0700 Subject: [PATCH 44/63] More --- src/coreclr/vm/jitinterface.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 9e055f6c21e258..bbe830f214e7da 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -370,10 +370,10 @@ CorInfoType CEEInfo::asCorInfoType(CorElementType eeType, CORINFO_TYPE_BYREF, CORINFO_TYPE_VALUECLASS, CORINFO_TYPE_CLASS, - CORINFO_TYPE_VAR, // VAR (type variable) + CORINFO_TYPE_VAR, // VAR CORINFO_TYPE_CLASS, // ARRAY - CORINFO_TYPE_CLASS, // WITH - CORINFO_TYPE_REFANY, + CORINFO_TYPE_CLASS, // GENERICINST + CORINFO_TYPE_VALUECLASS, // TypedReference CORINFO_TYPE_UNDEF, // VALUEARRAY_UNSUPPORTED CORINFO_TYPE_NATIVEINT, // I CORINFO_TYPE_NATIVEUINT, // U @@ -396,7 +396,7 @@ CorInfoType CEEInfo::asCorInfoType(CorElementType eeType, // spot check of the map _ASSERTE((CorInfoType) map[ELEMENT_TYPE_I4] == CORINFO_TYPE_INT); _ASSERTE((CorInfoType) map[ELEMENT_TYPE_PTR] == CORINFO_TYPE_PTR); - _ASSERTE((CorInfoType) map[ELEMENT_TYPE_TYPEDBYREF] == CORINFO_TYPE_REFANY); + _ASSERTE((CorInfoType) map[ELEMENT_TYPE_TYPEDBYREF] == CORINFO_TYPE_VALUECLASS); CorInfoType res = ((unsigned)eeType < ELEMENT_TYPE_MAX) ? ((CorInfoType) map[(unsigned)eeType]) : CORINFO_TYPE_UNDEF; From ffdefa1815af90322fc69cbb24fabcd0534456da Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Thu, 14 May 2026 21:15:07 -0700 Subject: [PATCH 45/63] More --- src/coreclr/vm/jitinterface.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index bbe830f214e7da..e4f7d21fb3a5ff 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -343,7 +343,9 @@ CorInfoType CEEInfo::asCorInfoType(CorElementType eeType, // Enums are exactly like primitives, even from a verification standpoint, // so we zap the type handle in this case. // - if (!typeHnd.IsTypeDesc() && typeHnd.AsMethodTable()->IsPrimitive()) + // To make things stranger, TypedReference returns true for "IsPrimitive". + // However the JIT likes us to report the type handle in that case. + if (!typeHnd.IsTypeDesc() && typeHnd.AsMethodTable()->IsPrimitive() && typeHnd != TypeHandle(g_TypedReferenceMT)) { typeHndUpdated = TypeHandle(); } From 2cd4088451966732494cb09a75bc4712f958f6d2 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Thu, 14 May 2026 21:29:35 -0700 Subject: [PATCH 46/63] More --- src/coreclr/vm/comutilnative.cpp | 2 +- src/coreclr/vm/ilmarshalers.cpp | 4 +--- src/coreclr/vm/jitinterface.cpp | 4 +--- src/coreclr/vm/methodtable.h | 2 +- src/coreclr/vm/methodtablebuilder.cpp | 6 +++--- src/coreclr/vm/reflectioninvocation.cpp | 2 +- src/coreclr/vm/zapsig.cpp | 2 ++ 7 files changed, 10 insertions(+), 12 deletions(-) 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/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/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index e4f7d21fb3a5ff..bbe830f214e7da 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -343,9 +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. // - // To make things stranger, TypedReference returns true for "IsPrimitive". - // However the JIT likes us to report the type handle in that case. - if (!typeHnd.IsTypeDesc() && typeHnd.AsMethodTable()->IsPrimitive() && typeHnd != TypeHandle(g_TypedReferenceMT)) + if (!typeHnd.IsTypeDesc() && typeHnd.AsMethodTable()->IsPrimitive()) { typeHndUpdated = TypeHandle(); } diff --git a/src/coreclr/vm/methodtable.h b/src/coreclr/vm/methodtable.h index 9542f0aa251f2c..f4e8cf76174c98 100644 --- a/src/coreclr/vm/methodtable.h +++ b/src/coreclr/vm/methodtable.h @@ -2783,7 +2783,7 @@ class MethodTable // A true primitive is one whose GetInternalCorElementType() == // ELEMENT_TYPE_I, // ELEMENT_TYPE_I4, - // ELEMENT_TYPE_TYPEDBYREF etc. + // ELEMENT_TYPE_R8, etc. // Note that IsTruePrimitive returns false for enum types. bool IsTruePrimitive(); diff --git a/src/coreclr/vm/methodtablebuilder.cpp b/src/coreclr/vm/methodtablebuilder.cpp index c37e930e31050c..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,7 +10742,7 @@ 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, true); @@ -12018,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/reflectioninvocation.cpp b/src/coreclr/vm/reflectioninvocation.cpp index ee1ed1ac38d4f8..781b39252c72ba 100644 --- a/src/coreclr/vm/reflectioninvocation.cpp +++ b/src/coreclr/vm/reflectioninvocation.cpp @@ -1989,7 +1989,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/zapsig.cpp b/src/coreclr/vm/zapsig.cpp index d73e609a01936d..216bd28e360dcb 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()) From 29930e81d130b838175282c24ba97cb495d9b3ac Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 15 May 2026 04:36:10 +0000 Subject: [PATCH 47/63] Update RuntimeTypeSystem docs to use Category_Enum naming Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/2acd0c3a-e4f9-4316-bc72-a1462ef61397 Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- docs/design/datacontracts/RuntimeTypeSystem.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/design/datacontracts/RuntimeTypeSystem.md b/docs/design/datacontracts/RuntimeTypeSystem.md index 3a5155289520ab..d3089670f4b48c 100644 --- a/docs/design/datacontracts/RuntimeTypeSystem.md +++ b/docs/design/datacontracts/RuntimeTypeSystem.md @@ -301,7 +301,7 @@ internal partial struct RuntimeTypeSystem_1 Category_Array = 0x00080000, Category_ValueType = 0x00040000, Category_Nullable = 0x00050000, - Category_PrimitiveValueType = 0x00060000, + Category_Enum = 0x00060000, Category_TruePrimitive = 0x00070000, Category_Interface = 0x000C0000, Collectible = 0x00200000, @@ -822,7 +822,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_Enum: return CorElementType.ValueType; case WFLAGS_HIGH.Category_TruePrimitive: return (CorElementType)GetClassData(typeHandle).InternalCorElementType; From 18c574c694f94a533e13e31b1c0f83b7372b36d7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 15 May 2026 04:55:32 +0000 Subject: [PATCH 48/63] Rename RuntimeTypeSystem doc flag to Category_Primitive Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/b25dfaef-9df2-4161-8c86-129dd0b25ea8 Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- docs/design/datacontracts/RuntimeTypeSystem.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/design/datacontracts/RuntimeTypeSystem.md b/docs/design/datacontracts/RuntimeTypeSystem.md index d3089670f4b48c..d79e13ccb4da56 100644 --- a/docs/design/datacontracts/RuntimeTypeSystem.md +++ b/docs/design/datacontracts/RuntimeTypeSystem.md @@ -301,7 +301,7 @@ internal partial struct RuntimeTypeSystem_1 Category_Array = 0x00080000, Category_ValueType = 0x00040000, Category_Nullable = 0x00050000, - Category_Enum = 0x00060000, + Category_Primitive = 0x00060000, Category_TruePrimitive = 0x00070000, Category_Interface = 0x000C0000, Collectible = 0x00200000, @@ -822,7 +822,7 @@ Contracts used: return CorElementType.SzArray; case WFLAGS_HIGH.Category_ValueType: case WFLAGS_HIGH.Category_Nullable: - case WFLAGS_HIGH.Category_Enum: + case WFLAGS_HIGH.Category_Primitive: return CorElementType.ValueType; case WFLAGS_HIGH.Category_TruePrimitive: return (CorElementType)GetClassData(typeHandle).InternalCorElementType; @@ -857,7 +857,7 @@ Contracts used: // if typedesc: check for CorElementType.ValueType } - // Enums have Category_Enum 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 (Int32, etc.) have Category_TruePrimitive. public bool IsEnum(TypeHandle typeHandle) @@ -866,7 +866,7 @@ Contracts used: return false; MethodTable methodTable = _methodTables[typeHandle.Address]; - return methodTable.Flags.GetFlag(WFLAGS_HIGH.Category_Mask) == WFLAGS_HIGH.Category_Enum; + 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. From 4cc66e20d3df488cb2e4db903d40e7f88cd74a07 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 15 May 2026 05:25:02 +0000 Subject: [PATCH 49/63] Rename IsPrimitiveMask constant to ElementTypeMask in RuntimeHelpers Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/43600cbc-8cd7-4f70-aa1d-a272a469e4ad Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- .../System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 c037c95e9f3fce..5bd7c66b5c041d 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,7 +849,7 @@ 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_ElementTypeMask = 0x000E0000; private const uint enum_flag_Category_Enum = 0x00060000; // sub-category of ValueType private const uint enum_flag_Category_TruePrimitive = 0x00070000; // sub-category of ValueType. (Int32, etc.) private const uint enum_flag_Category_Array = 0x00080000; @@ -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_Enum; + public bool IsPrimitive => (Flags & enum_flag_Category_ElementTypeMask) == enum_flag_Category_Enum; public bool IsTruePrimitive => (Flags & enum_flag_Category_Mask) is enum_flag_Category_TruePrimitive; From 2491a2343fb9230076d3c23d3324fe613d72da2a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 15 May 2026 06:04:55 +0000 Subject: [PATCH 50/63] Rename Category_Enum to Category_Primitive across runtime flags Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/23221766-5057-454a-b53d-f8904a0ae9eb Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- .../Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs | 4 ++-- src/coreclr/vm/methodtable.cpp | 8 ++++---- src/coreclr/vm/methodtable.h | 2 +- src/coreclr/vm/methodtable.inl | 4 ++-- .../Contracts/RuntimeTypeSystem_1.cs | 6 +++--- .../RuntimeTypeSystemHelpers/MethodTableFlags_1.cs | 2 +- src/native/managed/cdac/tests/MethodTableTests.cs | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) 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 5bd7c66b5c041d..aad80e74c3826b 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 @@ -850,7 +850,7 @@ internal unsafe struct MethodTable private const uint enum_flag_Category_ValueType = 0x00040000; private const uint enum_flag_Category_Nullable = 0x00050000; private const uint enum_flag_Category_ElementTypeMask = 0x000E0000; - private const uint enum_flag_Category_Enum = 0x00060000; // sub-category of ValueType + private const uint enum_flag_Category_Primitive = 0x00060000; // sub-category of ValueType private const uint enum_flag_Category_TruePrimitive = 0x00070000; // sub-category of ValueType. (Int32, etc.) private const uint enum_flag_Category_Array = 0x00080000; private const uint enum_flag_Category_Array_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_ElementTypeMask) == enum_flag_Category_Enum; + 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/vm/methodtable.cpp b/src/coreclr/vm/methodtable.cpp index 21aa442bdbfcf8..06150b6a7eb2fe 100644 --- a/src/coreclr/vm/methodtable.cpp +++ b/src/coreclr/vm/methodtable.cpp @@ -4969,8 +4969,8 @@ CorElementType MethodTable::GetInternalCorElementType() ret = ELEMENT_TYPE_VALUETYPE; break; - case enum_flag_Category_Enum: - // enum_flag_Category_ElementTypeMask maps both Category_TruePrimitive and Category_Enum here. + 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)); @@ -5015,7 +5015,7 @@ CorElementType MethodTable::GetSignatureCorElementType() case enum_flag_Category_ValueType: case enum_flag_Category_Nullable: - case enum_flag_Category_Enum: + case enum_flag_Category_Primitive: ret = ELEMENT_TYPE_VALUETYPE; break; @@ -5048,7 +5048,7 @@ void MethodTable::SetInternalCorElementType(CorElementType elemType, bool isTrue SetFlag(enum_flag_Category_ValueType); break; default: - SetFlag(isTruePrimitive ? enum_flag_Category_TruePrimitive : enum_flag_Category_Enum); + SetFlag(isTruePrimitive ? enum_flag_Category_TruePrimitive : enum_flag_Category_Primitive); break; } diff --git a/src/coreclr/vm/methodtable.h b/src/coreclr/vm/methodtable.h index f4e8cf76174c98..11155d324399b1 100644 --- a/src/coreclr/vm/methodtable.h +++ b/src/coreclr/vm/methodtable.h @@ -3789,7 +3789,7 @@ 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_Enum = 0x00060000, // sub-category of ValueType. [cDAC] [RuntimeTypeSystem]: Contract depends on this value + enum_flag_Category_Primitive = 0x00060000, // sub-category of ValueType. [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 diff --git a/src/coreclr/vm/methodtable.inl b/src/coreclr/vm/methodtable.inl index ec821ac7962ce4..09b02ecde8e5f9 100644 --- a/src/coreclr/vm/methodtable.inl +++ b/src/coreclr/vm/methodtable.inl @@ -334,8 +334,8 @@ inline bool MethodTable::IsTruePrimitive() inline bool MethodTable::IsPrimitive() { LIMITED_METHOD_DAC_CONTRACT; - // enum_flag_Category_ElementTypeMask maps both Category_TruePrimitive and Category_Enum here. - return GetFlag(enum_flag_Category_ElementTypeMask) == enum_flag_Category_Enum; + // 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/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 18212c630216fb..b20b66f1df0416 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 @@ -854,7 +854,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_Enum: + case MethodTableFlags_1.WFLAGS_HIGH.Category_Primitive: return CorElementType.ValueType; case MethodTableFlags_1.WFLAGS_HIGH.Category_TruePrimitive: return (CorElementType)GetClassData(typeHandle).InternalCorElementType; @@ -902,14 +902,14 @@ public bool IsValueType(TypeHandle typeHandle) public bool IsEnum(TypeHandle typeHandle) { - // Enums have Category_Enum 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. if (!typeHandle.IsMethodTable()) return false; MethodTable methodTable = _methodTables[typeHandle.Address]; - return methodTable.Flags.GetFlag(MethodTableFlags_1.WFLAGS_HIGH.Category_Mask) == MethodTableFlags_1.WFLAGS_HIGH.Category_Enum; + 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 11076a8c73a8d4..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_Enum = 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 607332412efa83..c4413799fdc286 100644 --- a/src/native/managed/cdac/tests/MethodTableTests.cs +++ b/src/native/managed/cdac/tests/MethodTableTests.cs @@ -602,7 +602,7 @@ public void IsValueTypeReturnsTrueForValueTypeCategories(MockTarget.Architecture MockEEClass enumEEClass = rtsBuilder.AddEEClass("EnumEEClass"); MockMethodTable enumMT = rtsBuilder.AddMethodTable("Enum"); - enumMT.MTFlags = (uint)MethodTableFlags_1.WFLAGS_HIGH.Category_Enum; + enumMT.MTFlags = (uint)MethodTableFlags_1.WFLAGS_HIGH.Category_Primitive; enumMT.BaseSize = rtsBuilder.Builder.TargetTestHelpers.ObjectBaseSize; enumMT.ParentMethodTable = systemObjectMethodTablePtr; enumMT.NumVirtuals = 3; From 2f33264a548624d235dce9e4cb9298790851e78f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 19 May 2026 01:03:56 +0000 Subject: [PATCH 51/63] Handle TypedReference explicitly in ZapSig type comparison Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/0b309854-d541-4fd7-9c78-ad6d8929f887 Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- src/coreclr/vm/zapsig.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/coreclr/vm/zapsig.cpp b/src/coreclr/vm/zapsig.cpp index 216bd28e360dcb..1e9ad5ab145454 100644 --- a/src/coreclr/vm/zapsig.cpp +++ b/src/coreclr/vm/zapsig.cpp @@ -351,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)); From a92c664932f39e3f7e86969c08911a3a9e02a2de Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 19 May 2026 22:55:57 +0000 Subject: [PATCH 52/63] Fix CEE_ARGLIST import to produce RuntimeArgumentHandle struct Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/08b6be3c-8c9c-43f7-ab97-d7afaddd88ba Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- src/coreclr/jit/importer.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 55a04cbc635ac0..51ddf1b0bb5dd6 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -7002,7 +7002,10 @@ 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(); + op1 = gtNewLclVarAddrNode(lvaVarargsHandleArg, TYP_BYREF); + op1 = gtNewLoadValueNode(TYP_STRUCT, typGetObjLayout(clsHnd), op1); + tiRetVal = makeTypeInfo(clsHnd); impPushOnStack(op1, tiRetVal); break; From 77b73d1402a1738cf1e5a4ee3cc35bb7022e2d4a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 20 May 2026 04:47:00 +0000 Subject: [PATCH 53/63] Fix CEE_ARGLIST to initialize RuntimeArgumentHandle with varargs-handle address Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/2ea2be50-1517-4821-8941-ff6d58f7f869 Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- src/coreclr/jit/importer.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 51ddf1b0bb5dd6..5a08e3b71b177d 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,12 +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); - clsHnd = impGetRuntimeArgumentHandle(); - op1 = gtNewLclVarAddrNode(lvaVarargsHandleArg, TYP_BYREF); - op1 = gtNewLoadValueNode(TYP_STRUCT, typGetObjLayout(clsHnd), op1); + clsHnd = impGetRuntimeArgumentHandle(); + + unsigned argListTmp = lvaGrabTemp(false DEBUGARG("arglist tmp")); + lvaSetStruct(argListTmp, clsHnd, false); + + op1 = gtNewLclVarAddrNode(lvaVarargsHandleArg, TYP_BYREF); + 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: From 75590e34f3ccd06905466a6b3c7638a295fa20cf Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Tue, 19 May 2026 22:25:13 -0700 Subject: [PATCH 54/63] Fixes --- .../src/System/RuntimeHandles.cs | 15 +++--- src/coreclr/vm/classnames.h | 48 +------------------ src/coreclr/vm/corelib.h | 11 +++-- src/coreclr/vm/ilmarshalers.h | 2 +- 4 files changed, 16 insertions(+), 60 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index baee8db37dd8a0..abfa615f81547f 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -942,7 +942,7 @@ 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; @@ -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] @@ -1417,22 +1417,23 @@ 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 + 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 - RuntimeFieldHandleInternal IRuntimeFieldInfo.Value => m_fieldHandle; + private IntPtr m_fieldHandle; + + RuntimeFieldHandleInternal IRuntimeFieldInfo.Value => new RuntimeFieldHandleInternal(m_fieldHandle); // implementation of CORINFO_HELP_FIELDDESC_TO_STUBRUNTIMEFIELD [StackTraceHidden] 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/corelib.h b/src/coreclr/vm/corelib.h index 4a36a6518a0446..47bd21db9a42ab 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -206,7 +206,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 +364,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 +566,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/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; } }; From b7a65ff65221cd3cdc75cdf126d751f68450a7c6 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Tue, 19 May 2026 22:28:50 -0700 Subject: [PATCH 55/63] Apply suggestion from @jkotas --- src/coreclr/jit/importer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 5a08e3b71b177d..04b2addadce82d 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -7007,7 +7007,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) unsigned argListTmp = lvaGrabTemp(false DEBUGARG("arglist tmp")); lvaSetStruct(argListTmp, clsHnd, false); - op1 = gtNewLclVarAddrNode(lvaVarargsHandleArg, TYP_BYREF); + op1 = gtNewLclVarAddrNode(lvaVarargsHandleArg, TYP_I_IMPL); impAppendTree(gtNewStoreLclFldNode(argListTmp, TYP_I_IMPL, 0, op1), CHECK_SPILL_ALL, impCurStmtDI); op1 = gtNewLclVarNode(argListTmp, TYP_STRUCT); From 826c476438c939a020db3d35ce94b80e2dc3a719 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Tue, 19 May 2026 22:57:52 -0700 Subject: [PATCH 56/63] Nit --- src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index abfa615f81547f..85fc73d47262e2 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -1411,7 +1411,6 @@ RuntimeFieldHandleInternal Value } } - [StructLayout(LayoutKind.Sequential)] internal sealed class RuntimeFieldInfoStub : IRuntimeFieldInfo { public RuntimeFieldInfoStub(RuntimeFieldHandleInternal fieldHandle, object keepalive) From 091d2bedc0590f8e201af7da8ed0cfc86638d2d2 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Wed, 20 May 2026 06:37:14 -0700 Subject: [PATCH 57/63] Fix build break --- .../System.Private.CoreLib/src/System/RuntimeHandles.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index 85fc73d47262e2..7fc5dc96f17b0f 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -947,7 +947,7 @@ public RuntimeMethodInfoStub(RuntimeMethodHandleInternal methodHandleValue, obje 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; @@ -1421,14 +1421,14 @@ public RuntimeFieldInfoStub(RuntimeFieldHandleInternal fieldHandle, object keepa 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 object? m_e; private object? m_f; -#pragma warning restore 414, 169, IDE0044 +#pragma warning restore CA1823, 414, 169, IDE0044 private IntPtr m_fieldHandle; From 8c618c75646c403ed588a43b23d545c4d40c5ffc Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Wed, 20 May 2026 07:10:39 -0700 Subject: [PATCH 58/63] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- src/coreclr/vm/methodtable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/vm/methodtable.h b/src/coreclr/vm/methodtable.h index 1efda84ca67f74..ef2b5a2951c2a8 100644 --- a/src/coreclr/vm/methodtable.h +++ b/src/coreclr/vm/methodtable.h @@ -3789,7 +3789,7 @@ 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_Primitive = 0x00060000, // sub-category of ValueType. [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 From 6003adb963c7d2c0d6c3d98a9450049e264f6c73 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Wed, 20 May 2026 07:11:40 -0700 Subject: [PATCH 59/63] Apply suggestion from @jkotas --- .../System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 aad80e74c3826b..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 @@ -850,8 +850,8 @@ internal unsafe struct MethodTable private const uint enum_flag_Category_ValueType = 0x00040000; private const uint enum_flag_Category_Nullable = 0x00050000; private const uint enum_flag_Category_ElementTypeMask = 0x000E0000; - private const uint enum_flag_Category_Primitive = 0x00060000; // sub-category of ValueType - private const uint enum_flag_Category_TruePrimitive = 0x00070000; // sub-category of ValueType. (Int32, etc.) + 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; From 732d054eaa1450220059c8def1bc769c629898bb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 21 May 2026 00:42:14 +0000 Subject: [PATCH 60/63] Delete dead EmitArgIteratorCreateAndLoad helper Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/18226290-9256-4617-8724-756a9b93ec39 Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- src/coreclr/vm/stubgen.cpp | 26 -------------------------- src/coreclr/vm/stubgen.h | 1 - 2 files changed, 27 deletions(-) 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(); From b45f4131c59feca78e06aee11c0e014fc95031fb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 21 May 2026 01:08:44 +0000 Subject: [PATCH 61/63] Add arglist RuntimeArgumentHandle regression test Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/3093cf8e-f9ea-474c-86ee-68898f201c85 Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- src/tests/JIT/Directed/arglist/vararg.cs | 29 +++++++++++++++++++ .../JIT/Directed/arglist/varargmanaged.cs | 28 ++++++++++++++++++ 2 files changed, 57 insertions(+) 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) { From bb9fd608aa5ac7b583508155433cd099af6cb945 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 21 May 2026 01:34:08 +0000 Subject: [PATCH 62/63] Remove stale ArgIterator CTOR2 corelib entry Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/40431d8a-04a1-4e7d-8bb8-69b9c65cdf35 Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- src/coreclr/vm/corelib.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index 47bd21db9a42ab..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) From fadeaed88e32e20a152fde6f635d7e920600cffa Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 21 May 2026 07:51:48 +0000 Subject: [PATCH 63/63] Delete invalid PREFIX arglist tests Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/69b984b8-312c-4a70-b684-cacff512abe8 Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com> --- .../Directed/PREFIX/unaligned/1/arglist.il | 120 ---------------- .../Directed/PREFIX/unaligned/1/arglist64.il | 130 ------------------ .../1/arglist_Target_32BIT_unaligned_1.ilproj | 13 -- .../1/arglist_Target_64BIT_unaligned_1.ilproj | 13 -- .../Directed/PREFIX/unaligned/2/arglist.il | 121 ---------------- .../Directed/PREFIX/unaligned/2/arglist64.il | 130 ------------------ .../2/arglist_Target_32BIT_unaligned_2.ilproj | 13 -- .../2/arglist_Target_64BIT_unaligned_2.ilproj | 13 -- .../Directed/PREFIX/unaligned/4/arglist.il | 120 ---------------- .../Directed/PREFIX/unaligned/4/arglist64.il | 130 ------------------ .../4/arglist_Target_32BIT_unaligned_4.ilproj | 13 -- .../4/arglist_Target_64BIT_unaligned_4.ilproj | 13 -- .../JIT/Directed/PREFIX/volatile/1/arglist.il | 122 ---------------- .../Directed/PREFIX/volatile/1/arglist64.il | 130 ------------------ .../1/arglist_Target_32BIT_volatile.ilproj | 13 -- .../1/arglist_Target_64BIT_volatile.ilproj | 13 -- 16 files changed, 1107 deletions(-) delete mode 100644 src/tests/JIT/Directed/PREFIX/unaligned/1/arglist.il delete mode 100644 src/tests/JIT/Directed/PREFIX/unaligned/1/arglist64.il delete mode 100644 src/tests/JIT/Directed/PREFIX/unaligned/1/arglist_Target_32BIT_unaligned_1.ilproj delete mode 100644 src/tests/JIT/Directed/PREFIX/unaligned/1/arglist_Target_64BIT_unaligned_1.ilproj delete mode 100644 src/tests/JIT/Directed/PREFIX/unaligned/2/arglist.il delete mode 100644 src/tests/JIT/Directed/PREFIX/unaligned/2/arglist64.il delete mode 100644 src/tests/JIT/Directed/PREFIX/unaligned/2/arglist_Target_32BIT_unaligned_2.ilproj delete mode 100644 src/tests/JIT/Directed/PREFIX/unaligned/2/arglist_Target_64BIT_unaligned_2.ilproj delete mode 100644 src/tests/JIT/Directed/PREFIX/unaligned/4/arglist.il delete mode 100644 src/tests/JIT/Directed/PREFIX/unaligned/4/arglist64.il delete mode 100644 src/tests/JIT/Directed/PREFIX/unaligned/4/arglist_Target_32BIT_unaligned_4.ilproj delete mode 100644 src/tests/JIT/Directed/PREFIX/unaligned/4/arglist_Target_64BIT_unaligned_4.ilproj delete mode 100644 src/tests/JIT/Directed/PREFIX/volatile/1/arglist.il delete mode 100644 src/tests/JIT/Directed/PREFIX/volatile/1/arglist64.il delete mode 100644 src/tests/JIT/Directed/PREFIX/volatile/1/arglist_Target_32BIT_volatile.ilproj delete mode 100644 src/tests/JIT/Directed/PREFIX/volatile/1/arglist_Target_64BIT_volatile.ilproj 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 - - - - - - - -