Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewrite Enum.HasFlags and Enum.Equals in C# #59514

Merged
merged 2 commits into from
Sep 24, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions src/coreclr/System.Private.CoreLib/src/System/Enum.CoreCLR.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ public abstract partial class Enum
[DllImport(RuntimeHelpers.QCall, CharSet = CharSet.Unicode)]
private static extern void GetEnumValuesAndNames(QCallTypeHandle enumType, ObjectHandleOnStack values, ObjectHandleOnStack names, Interop.BOOL getNames);

[MethodImpl(MethodImplOptions.InternalCall)]
public extern override bool Equals([NotNullWhen(true)] object? obj);

[MethodImpl(MethodImplOptions.InternalCall)]
private static extern object InternalBoxEnum(RuntimeType enumType, long value);

Expand All @@ -25,9 +22,6 @@ public abstract partial class Enum
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern RuntimeType InternalGetUnderlyingType(RuntimeType enumType);

[MethodImpl(MethodImplOptions.InternalCall)]
private extern bool InternalHasFlag(Enum flags);

private static EnumInfo GetEnumInfo(RuntimeType enumType, bool getNames = true)
{
EnumInfo? entry = enumType.GenericCache as EnumInfo;
Expand Down
35 changes: 0 additions & 35 deletions src/coreclr/vm/commodule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -902,38 +902,3 @@ FCIMPL1(FC_BOOL_RET, COMModule::IsResource, ReflectModuleBaseObject* pModuleUNSA
FC_RETURN_BOOL(pModuleUNSAFE->GetModule()->IsResource());
}
FCIMPLEND


//---------------------------------------------------------------------
// Helper code for PunkSafeHandle class. This does the Release in the
// safehandle's critical finalizer.
//---------------------------------------------------------------------
static VOID __stdcall DReleaseTarget(IUnknown *punk)
{
CONTRACTL
{
NOTHROW;
GC_TRIGGERS;
MODE_PREEMPTIVE;
}
CONTRACTL_END;

if (punk)
{
punk->Release();
}
}


//---------------------------------------------------------------------
// Helper code for PunkSafeHandle class. This returns the function that performs
// the Release() for the safehandle's critical finalizer.
//---------------------------------------------------------------------
FCIMPL0(void*, COMPunkSafeHandle::nGetDReleaseTarget)
{
FCALL_CONTRACT;

return (void*)DReleaseTarget;
}
FCIMPLEND

6 changes: 0 additions & 6 deletions src/coreclr/vm/commodule.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,4 @@ class COMModule

};

class COMPunkSafeHandle
{
public:
static FCDECL0(void*, nGetDReleaseTarget);
};

#endif
9 changes: 0 additions & 9 deletions src/coreclr/vm/ecalllist.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,16 +79,8 @@ FCFuncStart(gEnumFuncs)
FCFuncElement("InternalGetCorElementType", ReflectionEnum::InternalGetCorElementType)
QCFuncElement("GetEnumValuesAndNames", ReflectionEnum::GetEnumValuesAndNames)
FCFuncElement("InternalBoxEnum", ReflectionEnum::InternalBoxEnum)
FCFuncElement("Equals", ReflectionEnum::InternalEquals)
FCFuncElement("InternalHasFlag", ReflectionEnum::InternalHasFlag)
FCFuncEnd()


FCFuncStart(gSymWrapperCodePunkSafeHandleFuncs)
FCFuncElement("nGetDReleaseTarget", COMPunkSafeHandle::nGetDReleaseTarget)
FCFuncEnd()


FCFuncStart(gObjectFuncs)
FCIntrinsic("GetType", ObjectNative::GetClass, CORINFO_INTRINSIC_Object_GetType)
FCFuncEnd()
Expand Down Expand Up @@ -1199,7 +1191,6 @@ FCClassElement("ObjectiveCMarshal", "System.Runtime.InteropServices.ObjectiveC",
FCClassElement("OverlappedData", "System.Threading", gOverlappedFuncs)


FCClassElement("PunkSafeHandle", "System.Reflection.Emit", gSymWrapperCodePunkSafeHandleFuncs)
FCClassElement("RegisteredWaitHandle", "System.Threading", gRegisteredWaitHandleFuncs)

FCClassElement("RuntimeAssembly", "System.Reflection", gRuntimeAssemblyFuncs)
Expand Down
97 changes: 0 additions & 97 deletions src/coreclr/vm/reflectioninvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2492,100 +2492,3 @@ FCIMPL2_IV(Object*, ReflectionEnum::InternalBoxEnum, ReflectClassBaseObject* tar
return OBJECTREFToObject(ret);
}
FCIMPLEND

//*************************************************************************************************
//*************************************************************************************************
//*************************************************************************************************
// ReflectionEnum
//*************************************************************************************************
//*************************************************************************************************
//*************************************************************************************************

FCIMPL2(FC_BOOL_RET, ReflectionEnum::InternalEquals, Object *pRefThis, Object* pRefTarget)
{
FCALL_CONTRACT;

VALIDATEOBJECT(pRefThis);
BOOL ret = false;
if (pRefTarget == NULL) {
FC_RETURN_BOOL(ret);
}

if( pRefThis == pRefTarget)
FC_RETURN_BOOL(true);

//Make sure we are comparing same type.
MethodTable* pMTThis = pRefThis->GetMethodTable();
_ASSERTE(!pMTThis->IsArray()); // bunch of assumptions about arrays wrong.
if ( pMTThis != pRefTarget->GetMethodTable()) {
FC_RETURN_BOOL(ret);
}

void * pThis = pRefThis->UnBox();
void * pTarget = pRefTarget->UnBox();
switch (pMTThis->GetNumInstanceFieldBytes()) {
case 1:
ret = (*(UINT8*)pThis == *(UINT8*)pTarget);
break;
case 2:
ret = (*(UINT16*)pThis == *(UINT16*)pTarget);
break;
case 4:
ret = (*(UINT32*)pThis == *(UINT32*)pTarget);
break;
case 8:
ret = (*(UINT64*)pThis == *(UINT64*)pTarget);
break;
default:
// should not reach here.
UNREACHABLE_MSG("Incorrect Enum Type size!");
break;
}

FC_RETURN_BOOL(ret);
}
FCIMPLEND

// perform (this & flags) == flags
FCIMPL2(FC_BOOL_RET, ReflectionEnum::InternalHasFlag, Object *pRefThis, Object* pRefFlags)
{
FCALL_CONTRACT;

VALIDATEOBJECT(pRefThis);

BOOL cmp = false;

_ASSERTE(pRefFlags != NULL); // Enum.cs would have thrown ArgumentNullException before calling into InternalHasFlag

VALIDATEOBJECT(pRefFlags);

void * pThis = pRefThis->UnBox();
void * pFlags = pRefFlags->UnBox();

MethodTable* pMTThis = pRefThis->GetMethodTable();

_ASSERTE(!pMTThis->IsArray()); // bunch of assumptions about arrays wrong.
_ASSERTE(pMTThis->GetNumInstanceFieldBytes() == pRefFlags->GetMethodTable()->GetNumInstanceFieldBytes()); // Enum.cs verifies that the types are Equivalent

switch (pMTThis->GetNumInstanceFieldBytes()) {
case 1:
cmp = ((*(UINT8*)pThis & *(UINT8*)pFlags) == *(UINT8*)pFlags);
break;
case 2:
cmp = ((*(UINT16*)pThis & *(UINT16*)pFlags) == *(UINT16*)pFlags);
break;
case 4:
cmp = ((*(UINT32*)pThis & *(UINT32*)pFlags) == *(UINT32*)pFlags);
break;
case 8:
cmp = ((*(UINT64*)pThis & *(UINT64*)pFlags) == *(UINT64*)pFlags);
break;
default:
// should not reach here.
UNREACHABLE_MSG("Incorrect Enum Type size!");
break;
}

FC_RETURN_BOOL(cmp);
}
FCIMPLEND
2 changes: 0 additions & 2 deletions src/coreclr/vm/reflectioninvocation.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,6 @@ class ReflectionEnum {
void QCALLTYPE GetEnumValuesAndNames(QCall::TypeHandle pEnumType, QCall::ObjectHandleOnStack pReturnValues, QCall::ObjectHandleOnStack pReturnNames, BOOL fGetNames);

static FCDECL2_IV(Object*, InternalBoxEnum, ReflectClassBaseObject* pEnumType, INT64 value);
static FCDECL2(FC_BOOL_RET, InternalEquals, Object *pRefThis, Object* pRefTarget);
static FCDECL2(FC_BOOL_RET, InternalHasFlag, Object *pRefThis, Object* pRefFlags);
};

#endif // _REFLECTIONINVOCATION_H_
Loading