Repository: dotnet/runtime
File: src/coreclr/vm/method.cpp (C++)

Code before:
        (pTargetMT->IsValueType()), /* get unboxing entry point if a struct*/
        pStaticMD->GetMethodInstantiation(),
        FALSE /* no allowInstParam */ ));
}

PCODE MethodDesc::GetSingleCallableAddrOfCode()
{
    WRAPPER_NO_CONTRACT;
    _ASSERTE(!IsGenericMethodDefinition());
    return GetMethodEntryPoint();
}

PCODE MethodDesc::GetSingleCallableAddrOfCodeForUnmanagedCallersOnly()
{
    CONTRACTL
    {
        THROWS;
        GC_NOTRIGGER;
        MODE_ANY;
    }
    CONTRACTL_END;

#ifdef FEATURE_PORTABLE_ENTRYPOINTS
    PCODE entryPoint = GetPortableEntryPoint();
    if (!PortableEntryPoint::ToPortableEntryPoint(entryPoint)->EnsureUnmanagedCallersOnlyAttribute())
        COMPlusThrow(kInvalidOperationException);
    return (PCODE)PortableEntryPoint::GetActualCode(entryPoint);

#else // !FEATURE_PORTABLE_ENTRYPOINTS
    // HasUnmanagedCallersOnlyAttribute() must be true for this API.
    // We only validate this on non portable entrypoints because HasUnmanagedCallersOnlyAttribute()
    // is an unnecessary cost, even in non-Release builds, on portable entrypoint platforms.
    _ASSERTE(HasUnmanagedCallersOnlyAttribute());
    return GetSingleCallableAddrOfCode();

#endif // FEATURE_PORTABLE_ENTRYPOINTS
}

//*******************************************************************************
PCODE MethodDesc::GetSingleCallableAddrOfVirtualizedCode(OBJECTREF *orThis, TypeHandle staticTH)
{
    WRAPPER_NO_CONTRACT;
    PRECONDITION(IsVtableMethod());

    MethodTable *pObjMT = (*orThis)->GetMethodTable();

    if (HasMethodInstantiation())
    {
        CheckRestore();
        MethodDesc *pResultMD = ResolveGenericVirtualMethod(orThis);


Review comment (bug):
I do not think we throw InvalidOperationException anywhere else for missing UnmanagedCallersOnly attribute.

Given that the only way you can hit is by having a bug in the runtime or corelib, should this be just an assert like on the !FEATURE_PORTABLE_ENTRYPOINTS path below?

Code after:
        (pTargetMT->IsValueType()), /* get unboxing entry point if a struct*/
        pStaticMD->GetMethodInstantiation(),
        FALSE /* no allowInstParam */ ));
}

PCODE MethodDesc::GetSingleCallableAddrOfCode()
{
    WRAPPER_NO_CONTRACT;
    _ASSERTE(!IsGenericMethodDefinition());
    return GetMethodEntryPoint();
}

PCODE MethodDesc::GetSingleCallableAddrOfCodeForUnmanagedCallersOnly()
{
    CONTRACTL
    {
        THROWS;
        GC_NOTRIGGER;
        MODE_ANY;
        PRECONDITION(HasUnmanagedCallersOnlyAttribute());
    }
    CONTRACTL_END;

    PCODE entryPoint;

#ifdef FEATURE_PORTABLE_ENTRYPOINTS
    entryPoint = GetPortableEntryPoint();
    (void)PortableEntryPoint::ToPortableEntryPoint(entryPoint)->EnsureCodeForUnmanagedCallersOnly();
    entryPoint = (PCODE)PortableEntryPoint::GetActualCode(entryPoint);
#else // !FEATURE_PORTABLE_ENTRYPOINTS
    entryPoint = GetSingleCallableAddrOfCode();
#endif // FEATURE_PORTABLE_ENTRYPOINTS

    return entryPoint;
}

//*******************************************************************************
PCODE MethodDesc::GetSingleCallableAddrOfVirtualizedCode(OBJECTREF *orThis, TypeHandle staticTH)
{
    WRAPPER_NO_CONTRACT;
    PRECONDITION(IsVtableMethod());

    MethodTable *pObjMT = (*orThis)->GetMethodTable();

    if (HasMethodInstantiation())
    {
        CheckRestore();
        MethodDesc *pResultMD = ResolveGenericVirtualMethod(orThis);

        // If we're remoting this call we can't call directly on the returned
        // method desc, we need to go through a stub that guarantees we end up