Skip to content

Commit

Permalink
Remove FCThrows from Reflection APIs. (dotnet#110766)
Browse files Browse the repository at this point in the history
Co-authored-by: Jan Kotas <[email protected]>
  • Loading branch information
AaronRobinsonMSFT and jkotas authored Dec 18, 2024
1 parent e654570 commit 8edcc31
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 195 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,16 @@ static RuntimeModule GetManifestModuleWorker(RuntimeAssembly assembly)
private static partial void GetManifestModuleSlow(ObjectHandleOnStack assembly, ObjectHandleOnStack module);

[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern int GetToken(RuntimeAssembly assembly);
private static extern int GetTokenInternal(RuntimeAssembly assembly);

internal static int GetToken(RuntimeAssembly assembly)
{
int tokenMaybe = GetTokenInternal(assembly);
// If the result is negative, it is an error code.
if (tokenMaybe < 0)
Marshal.ThrowExceptionForHR(tokenMaybe, new IntPtr(-1));
return tokenMaybe;
}

[RequiresUnreferencedCode("Types might be removed")]
public sealed override Type[] GetForwardedTypes()
Expand Down
11 changes: 9 additions & 2 deletions src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1258,7 +1258,7 @@ internal static bool IsGenericMethodDefinition(IRuntimeMethodInfo method)
}

[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern bool IsTypicalMethodDefinition(IRuntimeMethodInfo method);
private static extern bool IsTypicalMethodDefinition(IRuntimeMethodInfo method);

[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeMethodHandle_GetTypicalMethodDefinition")]
private static partial void GetTypicalMethodDefinition(RuntimeMethodHandleInternal method, ObjectHandleOnStack outMethod);
Expand Down Expand Up @@ -1626,7 +1626,14 @@ internal static void SetValueDirect(RtFieldInfo field, RuntimeType fieldType, Ty
}

[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern RuntimeFieldHandleInternal GetStaticFieldForGenericType(RuntimeFieldHandleInternal field, RuntimeType declaringType);
private static extern unsafe RuntimeFieldHandleInternal GetStaticFieldForGenericType(RuntimeFieldHandleInternal field, MethodTable* pMT);

internal static RuntimeFieldHandleInternal GetStaticFieldForGenericType(RuntimeFieldHandleInternal field, RuntimeType declaringType)
{
TypeHandle th = declaringType.GetNativeTypeHandle();
Debug.Assert(!th.IsTypeDesc);
return GetStaticFieldForGenericType(field, th.AsMethodTable());
}

[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern bool AcquiresContextFromThis(RuntimeFieldHandleInternal field);
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/vm/ecalllist.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ FCFuncEnd()
FCFuncStart(gRuntimeAssemblyFuncs)
FCFuncElement("GetIsDynamic", AssemblyNative::GetIsDynamic)
FCFuncElement("GetManifestModule", AssemblyHandle::GetManifestModule)
FCFuncElement("GetToken", AssemblyHandle::GetToken)
FCFuncElement("GetTokenInternal", AssemblyHandle::GetTokenInternal)
FCFuncEnd()

FCFuncStart(gAssemblyLoadContextFuncs)
Expand Down
47 changes: 0 additions & 47 deletions src/coreclr/vm/fcall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,53 +65,6 @@ NOINLINE LPVOID __FCThrow(LPVOID __me, RuntimeExceptionKind reKind, UINT resID,
return NULL;
}

NOINLINE LPVOID __FCThrowArgument(LPVOID __me, RuntimeExceptionKind reKind, LPCWSTR argName, LPCWSTR resourceName)
{
STATIC_CONTRACT_THROWS;
// This isn't strictly true... But the guarantee that we make here is
// that we won't trigger without having setup a frame.
// STATIC_CONTRACT_TRIGGER
STATIC_CONTRACT_GC_NOTRIGGER;

// side effect the compiler can't remove
if (FC_NO_TAILCALL != 1)
return (LPVOID)(SIZE_T)(FC_NO_TAILCALL + 1);

FC_CAN_TRIGGER_GC();
INCONTRACT(FCallCheck __fCallCheck(__FILE__, __LINE__));
FC_GC_POLL_NOT_NEEDED(); // throws always open up for GC

HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_NOPOLL(Frame::FRAME_ATTR_CAPTURE_DEPTH_2);

switch (reKind) {
case kArgumentNullException:
if (resourceName) {
COMPlusThrowArgumentNull(argName, resourceName);
} else {
COMPlusThrowArgumentNull(argName);
}
break;

case kArgumentOutOfRangeException:
COMPlusThrowArgumentOutOfRange(argName, resourceName);
break;

case kArgumentException:
COMPlusThrowArgumentException(argName, resourceName);
break;

default:
// If you see this assert, add a case for your exception kind above.
_ASSERTE(argName == NULL);
COMPlusThrow(reKind, resourceName);
}

HELPER_METHOD_FRAME_END();
FC_CAN_TRIGGER_GC_END();
_ASSERTE(!"Throw returned");
return NULL;
}

/**************************************************************************************/
/* erect a frame in the FCALL and then poll the GC, objToProtect will be protected
during the poll and the updated object returned. */
Expand Down
13 changes: 1 addition & 12 deletions src/coreclr/vm/fcall.h
Original file line number Diff line number Diff line change
Expand Up @@ -362,11 +362,9 @@ class CompletedFCallTransitionState

//==============================================================================================
// This is where FCThrow ultimately ends up. Never call this directly.
// Use the FCThrow() macros. __FCThrowArgument is the helper to throw ArgumentExceptions
// with a resource taken from the managed resource manager.
// Use the FCThrow() macro.
//==============================================================================================
LPVOID __FCThrow(LPVOID me, enum RuntimeExceptionKind reKind, UINT resID, LPCWSTR arg1, LPCWSTR arg2, LPCWSTR arg3);
LPVOID __FCThrowArgument(LPVOID me, enum RuntimeExceptionKind reKind, LPCWSTR argumentName, LPCWSTR resourceName);

//==============================================================================================
// FDECLn: A set of macros for generating header declarations for FC targets.
Expand Down Expand Up @@ -1236,15 +1234,6 @@ struct FCSigCheck {
return 0; \
}

// Use FCThrowRes to throw an exception with a localized error message from the
// ResourceManager in managed code.
#define FCThrowRes(reKind, resourceName) \
{ \
while (NULL == \
__FCThrowArgument(__me, reKind, NULL, resourceName)) {}; \
return 0; \
}

// The managed calling convention expects returned small types (e.g. bool) to be
// widened to 32-bit on return. The C/C++ calling convention does not guarantee returned
// small types to be widened on most platforms. The small types have to be artificially
Expand Down
Loading

0 comments on commit 8edcc31

Please sign in to comment.