Skip to content

Commit 8eb0dbc

Browse files
committed
Handle (Enum)(object)int and (int)(object)enum
1 parent 59a3093 commit 8eb0dbc

File tree

18 files changed

+72
-43
lines changed

18 files changed

+72
-43
lines changed

src/coreclr/inc/corinfo.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2544,7 +2544,8 @@ class ICorStaticInfo
25442544
// equal, or the comparison needs to be resolved at runtime.
25452545
virtual TypeCompareState compareTypesForEquality(
25462546
CORINFO_CLASS_HANDLE cls1,
2547-
CORINFO_CLASS_HANDLE cls2
2547+
CORINFO_CLASS_HANDLE cls2,
2548+
bool exact = true
25482549
) = 0;
25492550

25502551
// Returns the intersection of cls1 and cls2.

src/coreclr/inc/icorjitinfoimpl_generated.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,8 @@ TypeCompareState compareTypesForCast(
322322

323323
TypeCompareState compareTypesForEquality(
324324
CORINFO_CLASS_HANDLE cls1,
325-
CORINFO_CLASS_HANDLE cls2) override;
325+
CORINFO_CLASS_HANDLE cls2,
326+
bool exact) override;
326327

327328
CORINFO_CLASS_HANDLE mergeClasses(
328329
CORINFO_CLASS_HANDLE cls1,

src/coreclr/inc/jiteeversionguid.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ typedef const GUID *LPCGUID;
4343
#define GUID_DEFINED
4444
#endif // !GUID_DEFINED
4545

46-
constexpr GUID JITEEVersionIdentifier = { /* f2a217c4-2a69-4308-99ce-8292c6763776 */
47-
0xf2a217c4,
48-
0x2a69,
49-
0x4308,
50-
{0x99, 0xce, 0x82, 0x92, 0xc6, 0x76, 0x37, 0x76}
46+
constexpr GUID JITEEVersionIdentifier = { /* 0f725067-bcb1-42bd-a145-bad968d89fa6 */
47+
0xf725067,
48+
0xbcb1,
49+
0x42bd,
50+
{0xa1, 0x45, 0xba, 0xd9, 0x68, 0xd8, 0x9f, 0xa6}
5151
};
5252

5353
//////////////////////////////////////////////////////////////////////////////////////////////////////////

src/coreclr/jit/ICorJitInfo_API_wrapper.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -753,10 +753,11 @@ TypeCompareState WrapICorJitInfo::compareTypesForCast(
753753

754754
TypeCompareState WrapICorJitInfo::compareTypesForEquality(
755755
CORINFO_CLASS_HANDLE cls1,
756-
CORINFO_CLASS_HANDLE cls2)
756+
CORINFO_CLASS_HANDLE cls2,
757+
bool exact)
757758
{
758759
API_ENTER(compareTypesForEquality);
759-
TypeCompareState temp = wrapHnd->compareTypesForEquality(cls1, cls2);
760+
TypeCompareState temp = wrapHnd->compareTypesForEquality(cls1, cls2, exact);
760761
API_LEAVE(compareTypesForEquality);
761762
return temp;
762763
}

src/coreclr/jit/importer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7455,7 +7455,7 @@ int Compiler::impBoxPatternMatch(CORINFO_RESOLVED_TOKEN* pResolvedToken,
74557455

74567456
// See if the resolved tokens describe types that are equal.
74577457
const TypeCompareState compare =
7458-
info.compCompHnd->compareTypesForEquality(unboxResolvedToken.hClass, pResolvedToken->hClass);
7458+
info.compCompHnd->compareTypesForEquality(unboxResolvedToken.hClass, pResolvedToken->hClass, false);
74597459

74607460
// If so, box/unbox.any is a nop.
74617461
if (compare == TypeCompareState::Must)

src/coreclr/tools/Common/JitInterface/CorInfoBase.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1137,12 +1137,12 @@ static TypeCompareState _compareTypesForCast(IntPtr thisHandle, IntPtr* ppExcept
11371137
}
11381138

11391139
[UnmanagedCallersOnly]
1140-
static TypeCompareState _compareTypesForEquality(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls1, CORINFO_CLASS_STRUCT_* cls2)
1140+
static TypeCompareState _compareTypesForEquality(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls1, CORINFO_CLASS_STRUCT_* cls2, byte exact)
11411141
{
11421142
var _this = GetThis(thisHandle);
11431143
try
11441144
{
1145-
return _this.compareTypesForEquality(cls1, cls2);
1145+
return _this.compareTypesForEquality(cls1, cls2, exact != 0);
11461146
}
11471147
catch (Exception ex)
11481148
{
@@ -2645,7 +2645,7 @@ static IntPtr GetUnmanagedCallbacks()
26452645
callbacks[73] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*, byte>)&_canCast;
26462646
callbacks[74] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*, byte>)&_areTypesEquivalent;
26472647
callbacks[75] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*, TypeCompareState>)&_compareTypesForCast;
2648-
callbacks[76] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*, TypeCompareState>)&_compareTypesForEquality;
2648+
callbacks[76] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*, byte, TypeCompareState>)&_compareTypesForEquality;
26492649
callbacks[77] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*>)&_mergeClasses;
26502650
callbacks[78] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*, byte>)&_isMoreSpecificType;
26512651
callbacks[79] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*>)&_getParentType;

src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2627,7 +2627,7 @@ private TypeCompareState compareTypesForCast(CORINFO_CLASS_STRUCT_* fromClass, C
26272627
return result;
26282628
}
26292629

2630-
private TypeCompareState compareTypesForEquality(CORINFO_CLASS_STRUCT_* cls1, CORINFO_CLASS_STRUCT_* cls2)
2630+
private TypeCompareState compareTypesForEquality(CORINFO_CLASS_STRUCT_* cls1, CORINFO_CLASS_STRUCT_* cls2, bool exact)
26312631
{
26322632
TypeCompareState result = TypeCompareState.May;
26332633

@@ -2637,6 +2637,12 @@ private TypeCompareState compareTypesForEquality(CORINFO_CLASS_STRUCT_* cls1, CO
26372637
// If neither type is a canonical subtype, type handle comparison suffices
26382638
if (!type1.IsCanonicalSubtype(CanonicalFormKind.Any) && !type2.IsCanonicalSubtype(CanonicalFormKind.Any))
26392639
{
2640+
if (!exact)
2641+
{
2642+
// Compare with Enum's underlying primitive type
2643+
type1 = type1.IsEnum ? type1.UnderlyingType : type1;
2644+
type2 = type2.IsEnum ? type2.UnderlyingType : type2;
2645+
}
26402646
result = (type1 == type2 ? TypeCompareState.Must : TypeCompareState.MustNot);
26412647
}
26422648
// If either or both types are canonical subtypes, we can sometimes prove inequality.

src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ FUNCTIONS
229229
bool canCast(CORINFO_CLASS_HANDLE child, CORINFO_CLASS_HANDLE parent)
230230
bool areTypesEquivalent(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2)
231231
TypeCompareState compareTypesForCast(CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass)
232-
TypeCompareState compareTypesForEquality(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2)
232+
TypeCompareState compareTypesForEquality(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2, bool exact)
233233
CORINFO_CLASS_HANDLE mergeClasses(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2)
234234
bool isMoreSpecificType(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2)
235235
CORINFO_CLASS_HANDLE getParentType(CORINFO_CLASS_HANDLE cls)

src/coreclr/tools/aot/jitinterface/jitinterface.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ struct JitInterfaceCallbacks
8787
bool (* canCast)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE child, CORINFO_CLASS_HANDLE parent);
8888
bool (* areTypesEquivalent)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2);
8989
TypeCompareState (* compareTypesForCast)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass);
90-
TypeCompareState (* compareTypesForEquality)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2);
90+
TypeCompareState (* compareTypesForEquality)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2, bool exact);
9191
CORINFO_CLASS_HANDLE (* mergeClasses)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2);
9292
bool (* isMoreSpecificType)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2);
9393
CORINFO_CLASS_HANDLE (* getParentType)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls);
@@ -940,10 +940,11 @@ class JitInterfaceWrapper : public ICorJitInfo
940940

941941
virtual TypeCompareState compareTypesForEquality(
942942
CORINFO_CLASS_HANDLE cls1,
943-
CORINFO_CLASS_HANDLE cls2)
943+
CORINFO_CLASS_HANDLE cls2,
944+
bool exact)
944945
{
945946
CorInfoExceptionClass* pException = nullptr;
946-
TypeCompareState temp = _callbacks->compareTypesForEquality(_thisHandle, &pException, cls1, cls2);
947+
TypeCompareState temp = _callbacks->compareTypesForEquality(_thisHandle, &pException, cls1, cls2, exact);
947948
if (pException != nullptr) throw pException;
948949
return temp;
949950
}

src/coreclr/tools/superpmi/superpmi-shared/agnostic.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,13 @@ struct DLDL
6464
DWORDLONG B;
6565
};
6666

67+
struct Agnostic_CompareTypesForEquality
68+
{
69+
DWORDLONG cls1;
70+
DWORDLONG cls2;
71+
DWORD exact;
72+
};
73+
6774
struct Agnostic_CanInline
6875
{
6976
DWORD result;

src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ LWM(CanInlineTypeCheck, DLD, DWORD)
3131
LWM(CanTailCall, Agnostic_CanTailCall, DWORD)
3232
LWM(CheckMethodModifier, Agnostic_CheckMethodModifier, DWORD)
3333
LWM(CompareTypesForCast, DLDL, DWORD)
34-
LWM(CompareTypesForEquality, DLDL, DWORD)
34+
LWM(CompareTypesForEquality, Agnostic_CompareTypesForEquality, DWORD)
3535
LWM(CompileMethod, DWORD, Agnostic_CompileMethod)
3636
LWM(ConstructStringLiteral, DLD, DLD)
3737
LWM(ConvertPInvokeCalliToCall, DLD, DWORDLONG)

src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5980,32 +5980,35 @@ TypeCompareState MethodContext::repCompareTypesForCast(CORINFO_CLASS_HANDLE from
59805980

59815981
void MethodContext::recCompareTypesForEquality(CORINFO_CLASS_HANDLE cls1,
59825982
CORINFO_CLASS_HANDLE cls2,
5983+
bool exact,
59835984
TypeCompareState result)
59845985
{
59855986
if (CompareTypesForEquality == nullptr)
5986-
CompareTypesForEquality = new LightWeightMap<DLDL, DWORD>();
5987+
CompareTypesForEquality = new LightWeightMap<Agnostic_CompareTypesForEquality, DWORD>();
59875988

5988-
DLDL key;
5989+
Agnostic_CompareTypesForEquality key;
59895990
ZeroMemory(&key, sizeof(key)); // Zero key including any struct padding
5990-
key.A = CastHandle(cls1);
5991-
key.B = CastHandle(cls2);
5991+
key.cls1 = CastHandle(cls1);
5992+
key.cls2 = CastHandle(cls2);
5993+
key.exact = (DWORD)exact;
59925994

59935995
DWORD value = (DWORD)result;
59945996
CompareTypesForEquality->Add(key, value);
59955997
DEBUG_REC(dmpCompareTypesForEquality(key, value));
59965998
}
5997-
void MethodContext::dmpCompareTypesForEquality(DLDL key, DWORD value)
5999+
void MethodContext::dmpCompareTypesForEquality(Agnostic_CompareTypesForEquality key, DWORD value)
59986000
{
5999-
printf("CompareTypesForEquality key cls1=%016llX, cls2=%016llx, result=%d", key.A, key.B, value);
6001+
printf("CompareTypesForEquality key cls1=%016llX, cls2=%016llx, exact=%d result=%d", key.cls1, key.cls2, key.exact, value);
60006002
}
6001-
TypeCompareState MethodContext::repCompareTypesForEquality(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2)
6003+
TypeCompareState MethodContext::repCompareTypesForEquality(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2, bool exact)
60026004
{
6003-
DLDL key;
6005+
Agnostic_CompareTypesForEquality key;
60046006
ZeroMemory(&key, sizeof(key)); // Zero key including any struct padding
6005-
key.A = CastHandle(cls1);
6006-
key.B = CastHandle(cls2);
6007+
key.cls1 = CastHandle(cls1);
6008+
key.cls2 = CastHandle(cls2);
6009+
key.exact = (DWORD)exact;
60076010

6008-
AssertMapAndKeyExist(CompareTypesForEquality, key, ": key %016llX %016llX", key.A, key.B);
6011+
AssertMapAndKeyExist(CompareTypesForEquality, key, ": key %016llX %016llX %d", key.cls1, key.cls2, key.exact);
60096012

60106013
DWORD value = CompareTypesForEquality->Get(key);
60116014
DEBUG_REP(dmpCompareTypesForEquality(key, value));

src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -738,9 +738,9 @@ class MethodContext
738738
void dmpCompareTypesForCast(DLDL key, DWORD value);
739739
TypeCompareState repCompareTypesForCast(CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass);
740740

741-
void recCompareTypesForEquality(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2, TypeCompareState result);
742-
void dmpCompareTypesForEquality(DLDL key, DWORD value);
743-
TypeCompareState repCompareTypesForEquality(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2);
741+
void recCompareTypesForEquality(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2, bool exact, TypeCompareState result);
742+
void dmpCompareTypesForEquality(Agnostic_CompareTypesForEquality key, DWORD value);
743+
TypeCompareState repCompareTypesForEquality(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2, bool exact);
744744

745745
void recFindNameOfToken(
746746
CORINFO_MODULE_HANDLE module, mdToken metaTOK, char* szFQName, size_t FQNameCapacity, size_t result);

src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -897,11 +897,11 @@ TypeCompareState interceptor_ICJI::compareTypesForCast(CORINFO_CLASS_HANDLE from
897897

898898
// See if types represented by cls1 and cls2 compare equal, not
899899
// equal, or the comparison needs to be resolved at runtime.
900-
TypeCompareState interceptor_ICJI::compareTypesForEquality(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2)
900+
TypeCompareState interceptor_ICJI::compareTypesForEquality(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2, bool exact)
901901
{
902902
mc->cr->AddCall("compareTypesForEquality");
903-
TypeCompareState temp = original_ICorJitInfo->compareTypesForEquality(cls1, cls2);
904-
mc->recCompareTypesForEquality(cls1, cls2, temp);
903+
TypeCompareState temp = original_ICorJitInfo->compareTypesForEquality(cls1, cls2, exact);
904+
mc->recCompareTypesForEquality(cls1, cls2, exact, temp);
905905
return temp;
906906
}
907907

src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -617,10 +617,11 @@ TypeCompareState interceptor_ICJI::compareTypesForCast(
617617

618618
TypeCompareState interceptor_ICJI::compareTypesForEquality(
619619
CORINFO_CLASS_HANDLE cls1,
620-
CORINFO_CLASS_HANDLE cls2)
620+
CORINFO_CLASS_HANDLE cls2,
621+
bool exact)
621622
{
622623
mcs->AddCall("compareTypesForEquality");
623-
return original_ICorJitInfo->compareTypesForEquality(cls1, cls2);
624+
return original_ICorJitInfo->compareTypesForEquality(cls1, cls2, exact);
624625
}
625626

626627
CORINFO_CLASS_HANDLE interceptor_ICJI::mergeClasses(

src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -541,9 +541,10 @@ TypeCompareState interceptor_ICJI::compareTypesForCast(
541541

542542
TypeCompareState interceptor_ICJI::compareTypesForEquality(
543543
CORINFO_CLASS_HANDLE cls1,
544-
CORINFO_CLASS_HANDLE cls2)
544+
CORINFO_CLASS_HANDLE cls2,
545+
bool exact)
545546
{
546-
return original_ICorJitInfo->compareTypesForEquality(cls1, cls2);
547+
return original_ICorJitInfo->compareTypesForEquality(cls1, cls2, exact);
547548
}
548549

549550
CORINFO_CLASS_HANDLE interceptor_ICJI::mergeClasses(

src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -763,10 +763,10 @@ TypeCompareState MyICJI::compareTypesForCast(CORINFO_CLASS_HANDLE fromClass, COR
763763

764764
// See if types represented by cls1 and cls2 compare equal, not
765765
// equal, or the comparison needs to be resolved at runtime.
766-
TypeCompareState MyICJI::compareTypesForEquality(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2)
766+
TypeCompareState MyICJI::compareTypesForEquality(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2, bool exact)
767767
{
768768
jitInstance->mc->cr->AddCall("compareTypesForEquality");
769-
return jitInstance->mc->repCompareTypesForEquality(cls1, cls2);
769+
return jitInstance->mc->repCompareTypesForEquality(cls1, cls2, exact);
770770
}
771771

772772
// returns the intersection of cls1 and cls2.

src/coreclr/vm/jitinterface.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4276,7 +4276,8 @@ TypeCompareState CEEInfo::compareTypesForCast(
42764276
// equal, or the comparison needs to be resolved at runtime.
42774277
TypeCompareState CEEInfo::compareTypesForEquality(
42784278
CORINFO_CLASS_HANDLE cls1,
4279-
CORINFO_CLASS_HANDLE cls2)
4279+
CORINFO_CLASS_HANDLE cls2,
4280+
bool exact)
42804281
{
42814282
CONTRACTL {
42824283
THROWS;
@@ -4294,6 +4295,12 @@ TypeCompareState CEEInfo::compareTypesForEquality(
42944295
// If neither type is a canonical subtype, type handle comparison suffices
42954296
if (!hnd1.IsCanonicalSubtype() && !hnd2.IsCanonicalSubtype())
42964297
{
4298+
if (!exact)
4299+
{
4300+
// Compare with Enum's underlying primitive type
4301+
hnd1 = hnd1.IsEnum() ? CoreLibBinder::GetElementType(hnd1.GetVerifierCorElementType()) : hnd1;
4302+
hnd2 = hnd2.IsEnum() ? CoreLibBinder::GetElementType(hnd2.GetVerifierCorElementType()) : hnd2;
4303+
}
42974304
result = (hnd1 == hnd2 ? TypeCompareState::Must : TypeCompareState::MustNot);
42984305
}
42994306
// If either or both types are canonical subtypes, we can sometimes prove inequality.

0 commit comments

Comments
 (0)