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

Make NativeCallableAttribute public. #33005

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
7831946
Avoid creating a COM Delegate when calling NativeCallableWrapper.
AaronRobinsonMSFT Feb 29, 2020
ddbfbeb
Create fast P/Invoke frame.
AaronRobinsonMSFT Feb 29, 2020
2b0d128
Properly handle Preemptive thread in PreStubWorker.
AaronRobinsonMSFT Feb 29, 2020
669fb47
Block fast NativeCallableAttribute on the X86 platform.
AaronRobinsonMSFT Feb 29, 2020
3db83bf
Limit the exclusion for fast NativeCallable to only Win-x86.
AaronRobinsonMSFT Feb 29, 2020
ee166b2
Add Reverse P/Invoke JIT helpers to CrossGen2.
AaronRobinsonMSFT Feb 29, 2020
7a97eba
Missing comma.
AaronRobinsonMSFT Feb 29, 2020
5b38870
Remove duplicate entries in ReadyToRunHelper enum.
AaronRobinsonMSFT Feb 29, 2020
1dbc940
Validate instantiated generic methods for ldftn.
AaronRobinsonMSFT Mar 2, 2020
391960f
Add test cases for instantiated generic methods and call from unknown…
AaronRobinsonMSFT Mar 2, 2020
ae3b190
Disallow non-generic methods from a generic class to be NativeCallable
AaronRobinsonMSFT Mar 2, 2020
e42c27b
Add test for generic class with NativeCallable static method.
AaronRobinsonMSFT Mar 2, 2020
7fdc950
Remove SAL annocations from NativeCallableAttribute test assets.
AaronRobinsonMSFT Mar 2, 2020
6e01d22
Move NativeCallableAttribute check to getCallInfo() in JIT interface.
AaronRobinsonMSFT Mar 2, 2020
5525aeb
Add test for non static methods for NativeCallableAttribute
AaronRobinsonMSFT Mar 2, 2020
2faea22
[WIP] Check in CrossGen2 for NativeCallableAttribute usage.
AaronRobinsonMSFT Mar 2, 2020
028ef61
Publicly expose NativeCallableAttribute.
AaronRobinsonMSFT Mar 3, 2020
4eba3e0
Add testing for exceptions on Windows.
AaronRobinsonMSFT Mar 3, 2020
88a2548
Add validation to CrossGen2.
AaronRobinsonMSFT Mar 3, 2020
ff0a8f8
Implement Unix EH change for NativeCallable methods
janvorli Mar 3, 2020
61e4a01
Update test.
AaronRobinsonMSFT Mar 3, 2020
b1d6f1f
Update src/libraries/System.Private.CoreLib/src/System/Runtime/Intero…
AaronRobinsonMSFT Mar 3, 2020
832f551
Update src/libraries/System.Private.CoreLib/src/System/Runtime/Intero…
AaronRobinsonMSFT Mar 3, 2020
ba22026
Error cases for NativeCallableAttribute should be InvalidProgramExcep…
AaronRobinsonMSFT Mar 7, 2020
f0b71de
Create ReadyToRun constant for Reverse PInvoke frame.
AaronRobinsonMSFT Mar 7, 2020
4f842f0
Documentation update related to future C# language feature.
AaronRobinsonMSFT Mar 7, 2020
f194c60
Revert "Implement Unix EH change for NativeCallable methods"
AaronRobinsonMSFT Mar 7, 2020
f9acf93
Implement Unix EH change for NativeCallable methods
janvorli Mar 3, 2020
fefa431
Clean up tests
AaronRobinsonMSFT Mar 7, 2020
807f162
Create a JIT_ReversePInvokeEnterRare() implementation for the slower …
AaronRobinsonMSFT Mar 7, 2020
b24d91c
Move exception testing to Windows only since non-Windows will failfast.
AaronRobinsonMSFT Mar 7, 2020
3a38cfd
Mark rare path as NOINLINE.
AaronRobinsonMSFT Mar 7, 2020
8d6b8c7
Add support to CallCountingManager for Preemptive threads.
AaronRobinsonMSFT Mar 7, 2020
edf0b61
Revert "Add support to CallCountingManager for Preemptive threads."
AaronRobinsonMSFT Mar 9, 2020
d8cb051
Disable NativeCallableAttribute for TieredCompilation consideration.
AaronRobinsonMSFT Mar 9, 2020
8567207
Handle the failure to create Thread in the reverse P/Invoke case.
AaronRobinsonMSFT Mar 9, 2020
a2bff26
Use EEPOLICY_HANDLE_FATAL_ERROR_WITH_MESSAGE() for failfast.
AaronRobinsonMSFT Mar 9, 2020
4369904
Revert "Disable NativeCallableAttribute for TieredCompilation conside…
AaronRobinsonMSFT Mar 9, 2020
c132966
Disable Tiered Compilation for NativeCallableAttribute methods.
AaronRobinsonMSFT Mar 10, 2020
2f8b28b
Change name of new reverse P/Invoke frame to match CoreRT.
AaronRobinsonMSFT Mar 10, 2020
04cee50
Manually inline enable preemptive.
AaronRobinsonMSFT Mar 10, 2020
c78f4a4
Handle issues for Tiered Compilation with NativeCallable in ReadyToRu…
AaronRobinsonMSFT Mar 11, 2020
898db75
Add test for code path involving RuntimeHelpers.PrepareMethod().
AaronRobinsonMSFT Mar 11, 2020
105d53f
Handle additional locations for R2R scenarios.
AaronRobinsonMSFT Mar 12, 2020
1091bfa
Review feedback on crossgen.
AaronRobinsonMSFT Mar 12, 2020
6a3e11a
Update CrossGen2 to match CrossGen semantics with respect to NativeCa…
AaronRobinsonMSFT Mar 12, 2020
cd421ac
Propagate the CallerGCMode in additional scenarios.
AaronRobinsonMSFT Mar 12, 2020
2578835
Feedback about local variable.
AaronRobinsonMSFT Mar 12, 2020
32981bc
Style fixes in CrossGen2
AaronRobinsonMSFT Mar 12, 2020
76442ce
Update error message for FailFast during reverse P/Invoke.
AaronRobinsonMSFT Mar 12, 2020
1449088
Change CrossGen2 exception type to NotImplementedException.
AaronRobinsonMSFT Mar 13, 2020
0a89a24
Block R2R compilation of NativeCallableAttribute methods for crossgen…
AaronRobinsonMSFT Mar 13, 2020
48758d4
Throw RequiresRuntimeJitException instead of NotImplementedException …
AaronRobinsonMSFT Mar 13, 2020
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
1 change: 0 additions & 1 deletion src/coreclr/src/inc/corcompile.h
Original file line number Diff line number Diff line change
Expand Up @@ -702,7 +702,6 @@ enum CORCOMPILE_FIXUP_BLOB_KIND
ENCODE_VARARGS_METHODREF,
ENCODE_VARARGS_SIG,
ENCODE_ACTIVE_DEPENDENCY, /* Conditional active dependency */
ENCODE_METHOD_NATIVE_ENTRY, /* NativeCallable method token */
};

enum EncodeMethodSigFlags
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/src/inc/jithelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -346,8 +346,8 @@
JITHELPER(CORINFO_HELP_JIT_PINVOKE_BEGIN, JIT_PInvokeBegin, CORINFO_HELP_SIG_REG_ONLY)
JITHELPER(CORINFO_HELP_JIT_PINVOKE_END, JIT_PInvokeEnd, CORINFO_HELP_SIG_REG_ONLY)

JITHELPER(CORINFO_HELP_JIT_REVERSE_PINVOKE_ENTER, NULL, CORINFO_HELP_SIG_UNDEF)
JITHELPER(CORINFO_HELP_JIT_REVERSE_PINVOKE_EXIT, NULL, CORINFO_HELP_SIG_UNDEF)
JITHELPER(CORINFO_HELP_JIT_REVERSE_PINVOKE_ENTER, JIT_ReversePInvokeEnter, CORINFO_HELP_SIG_REG_ONLY)
JITHELPER(CORINFO_HELP_JIT_REVERSE_PINVOKE_EXIT, JIT_ReversePInvokeExit, CORINFO_HELP_SIG_REG_ONLY)

JITHELPER(CORINFO_HELP_GVMLOOKUP_FOR_SLOT, NULL, CORINFO_HELP_SIG_NO_ALIGN_STUB)

Expand Down
5 changes: 4 additions & 1 deletion src/coreclr/src/inc/readytorun.h
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,8 @@ enum ReadyToRunHelper
READYTORUN_HELPER_PInvokeBegin = 0x42,
READYTORUN_HELPER_PInvokeEnd = 0x43,
READYTORUN_HELPER_GCPoll = 0x44,
READYTORUN_HELPER_ReversePInvokeEnter = 0x45,
READYTORUN_HELPER_ReversePInvokeExit = 0x46,

// Get string handle lazily
READYTORUN_HELPER_GetString = 0x50,
Expand Down Expand Up @@ -382,7 +384,8 @@ struct READYTORUN_EXCEPTION_CLAUSE

enum ReadyToRunRuntimeConstants : DWORD
{
READYTORUN_PInvokeTransitionFrameSizeInPointerUnits = 11
READYTORUN_PInvokeTransitionFrameSizeInPointerUnits = 11,
READYTORUN_ReversePInvokeTransitionFrameSizeInPointerUnits = 2
};

#endif // __READYTORUN_H__
2 changes: 2 additions & 0 deletions src/coreclr/src/inc/readytorunhelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ HELPER(READYTORUN_HELPER_EndCatch, CORINFO_HELP_ENDCATCH,
HELPER(READYTORUN_HELPER_PInvokeBegin, CORINFO_HELP_JIT_PINVOKE_BEGIN, )
HELPER(READYTORUN_HELPER_PInvokeEnd, CORINFO_HELP_JIT_PINVOKE_END, )
HELPER(READYTORUN_HELPER_GCPoll, CORINFO_HELP_POLL_GC, )
HELPER(READYTORUN_HELPER_ReversePInvokeEnter, CORINFO_HELP_JIT_REVERSE_PINVOKE_ENTER, )
HELPER(READYTORUN_HELPER_ReversePInvokeExit, CORINFO_HELP_JIT_REVERSE_PINVOKE_EXIT, )

HELPER(READYTORUN_HELPER_MonitorEnter, CORINFO_HELP_MON_ENTER, )
HELPER(READYTORUN_HELPER_MonitorExit, CORINFO_HELP_MON_EXIT, )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ public enum ReadyToRunHelper
PInvokeBegin = 0x42,
PInvokeEnd = 0x43,
GCPoll = 0x44,
ReversePInvokeEnter = 0x45,
ReversePInvokeExit = 0x46,

// Get string handle lazily
GetString = 0x50,
Expand Down Expand Up @@ -295,10 +297,6 @@ public enum ReadyToRunHelper
CheckCastInterface,
CheckInstanceInterface,

// P/Invoke support
ReversePInvokeEnter,
ReversePInvokeExit,

MonitorEnterStatic,
MonitorExitStatic,

Expand All @@ -314,5 +312,6 @@ public enum ReadyToRunHelper
public static class ReadyToRunRuntimeConstants
{
public const int READYTORUN_PInvokeTransitionFrameSizeInPointerUnits = 11;
public const int READYTORUN_ReversePInvokeTransitionFrameSizeInPointerUnits = 2;
}
}
12 changes: 11 additions & 1 deletion src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2220,7 +2220,7 @@ private void getEEInfo(ref CORINFO_EE_INFO pEEInfoOut)
pEEInfoOut.offsetOfDelegateInstance = (uint)pointerSize; // Delegate::m_firstParameter
pEEInfoOut.offsetOfDelegateFirstTarget = OffsetOfDelegateFirstTarget;

pEEInfoOut.sizeOfReversePInvokeFrame = (uint)(2 * pointerSize);
pEEInfoOut.sizeOfReversePInvokeFrame = (uint)SizeOfReversePInvokeTransitionFrame;

pEEInfoOut.osPageSize = new UIntPtr(0x1000);

Expand Down Expand Up @@ -2882,7 +2882,17 @@ private uint getJitFlags(ref CORJIT_FLAGS flags, uint sizeInBytes)
}

if (this.MethodBeingCompiled.IsNativeCallable)
{
#if READYTORUN
if (targetArchitecture == TargetArchitecture.X86
&& _compilation.TypeSystemContext.Target.OperatingSystem == TargetOS.Windows)
{
AaronRobinsonMSFT marked this conversation as resolved.
Show resolved Hide resolved
throw new RequiresRuntimeJitException("ReadyToRun: Methods with NativeCallableAttribute not implemented");
}
#endif

flags.Set(CorJitFlag.CORJIT_FLAG_REVERSE_PINVOKE);
}

if (this.MethodBeingCompiled.IsPInvoke)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ public enum ExceptionStringID
InvalidProgramNativeCallable,
InvalidProgramCallAbstractMethod,
InvalidProgramCallVirtStatic,
InvalidProgramNonStaticMethod,
InvalidProgramGenericMethod,
InvalidProgramNonBlittableTypes,

// BadImageFormatException
BadImageFormatGeneric,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,14 @@ private ISymbolNode GetHelperFtnUncached(CorInfoHelpFunc ftnNum)
id = ReadyToRunHelper.GCPoll;
break;

case CorInfoHelpFunc.CORINFO_HELP_JIT_REVERSE_PINVOKE_ENTER:
id = ReadyToRunHelper.ReversePInvokeEnter;
break;

case CorInfoHelpFunc.CORINFO_HELP_JIT_REVERSE_PINVOKE_EXIT:
id = ReadyToRunHelper.ReversePInvokeExit;
break;

case CorInfoHelpFunc.CORINFO_HELP_INITCLASS:
case CorInfoHelpFunc.CORINFO_HELP_INITINSTCLASS:
case CorInfoHelpFunc.CORINFO_HELP_THROW_ARGUMENTEXCEPTION:
Expand All @@ -616,8 +624,6 @@ private ISymbolNode GetHelperFtnUncached(CorInfoHelpFunc ftnNum)
case CorInfoHelpFunc.CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE_MAYBENULL:
case CorInfoHelpFunc.CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE_MAYBENULL:
case CorInfoHelpFunc.CORINFO_HELP_GETREFANY:
case CorInfoHelpFunc.CORINFO_HELP_JIT_REVERSE_PINVOKE_ENTER:
case CorInfoHelpFunc.CORINFO_HELP_JIT_REVERSE_PINVOKE_EXIT:
throw new RequiresRuntimeJitException(ftnNum.ToString());

default:
Expand Down Expand Up @@ -1145,6 +1151,25 @@ private void ceeInfoGetCallInfo(
ThrowHelper.ThrowInvalidProgramException(ExceptionStringID.InvalidProgramCallVirtStatic, originalMethod);
}

if ((flags & CORINFO_CALLINFO_FLAGS.CORINFO_CALLINFO_LDFTN) != 0
&& originalMethod.IsNativeCallable)
{
if (!originalMethod.Signature.IsStatic) // Must be a static method
{
ThrowHelper.ThrowInvalidProgramException(ExceptionStringID.InvalidProgramNonStaticMethod, originalMethod);
}

if (originalMethod.HasInstantiation || originalMethod.OwningType.HasInstantiation) // No generics involved
{
ThrowHelper.ThrowInvalidProgramException(ExceptionStringID.InvalidProgramGenericMethod, originalMethod);
}

if (Marshaller.IsMarshallingRequired(originalMethod.Signature, Array.Empty<ParameterMetadata>())) // Only blittable arguments
{
ThrowHelper.ThrowInvalidProgramException(ExceptionStringID.InvalidProgramNonBlittableTypes, originalMethod);
}
}

exactType = type;

constrainedType = null;
Expand Down Expand Up @@ -1635,6 +1660,14 @@ private void getCallInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_RESO

pResult->methodFlags = FilterNamedIntrinsicMethodAttribs(pResult->methodFlags, methodToCall);

var targetDetails = _compilation.TypeSystemContext.Target;
if (targetDetails.Architecture == TargetArchitecture.X86
&& targetDetails.OperatingSystem == TargetOS.Windows
&& targetMethod.IsNativeCallable)
{
throw new RequiresRuntimeJitException("ReadyToRun: References to methods with NativeCallableAttribute not implemented");
}

if (pResult->thisTransform == CORINFO_THIS_TRANSFORM.CORINFO_BOX_THIS)
{
// READYTORUN: FUTURE: Optionally create boxing stub at runtime
Expand Down Expand Up @@ -2297,6 +2330,7 @@ private bool canGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig)
}

private int SizeOfPInvokeTransitionFrame => ReadyToRunRuntimeConstants.READYTORUN_PInvokeTransitionFrameSizeInPointerUnits * _compilation.NodeFactory.Target.PointerSize;
private int SizeOfReversePInvokeTransitionFrame => ReadyToRunRuntimeConstants.READYTORUN_ReversePInvokeTransitionFrameSizeInPointerUnits * _compilation.NodeFactory.Target.PointerSize;

private void setEHcount(uint cEH)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1366,6 +1366,14 @@ private void ParseHelper(StringBuilder builder)
builder.Append("GCPOLL");
break;

case ReadyToRunHelper.ReversePInvokeEnter:
builder.Append("REVERSE_PINVOKE_ENTER");
break;

case ReadyToRunHelper.ReversePInvokeExit:
builder.Append("REVERSE_PINVOKE_EXIT");
break;

// Get string handle lazily
case ReadyToRunHelper.GetString:
builder.Append("GET_STRING");
Expand Down
8 changes: 8 additions & 0 deletions src/coreclr/src/vm/cgensys.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ extern "C" void GenericComPlusCallStub(void);
extern "C" void GenericComCallStub(void);
#endif // FEATURE_COMINTEROP

// The GC mode for the thread that initially called ThePreStub().
enum class CallerGCMode
{
Unknown,
Coop,
Preemptive // (e.g. NativeCallableAttribute)
};

// Non-CPU-specific helper functions called by the CPU-dependent code
extern "C" PCODE STDCALL PreStubWorker(TransitionBlock * pTransitionBlock, MethodDesc * pMD);

Expand Down
6 changes: 5 additions & 1 deletion src/coreclr/src/vm/codeversion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1611,6 +1611,7 @@ HRESULT CodeVersionManager::AddNativeCodeVersion(

PCODE CodeVersionManager::PublishVersionableCodeIfNecessary(
MethodDesc* pMethodDesc,
CallerGCMode callerGCMode,
bool *doBackpatchRef,
bool *doFullBackpatchRef)
{
Expand Down Expand Up @@ -1655,7 +1656,7 @@ PCODE CodeVersionManager::PublishVersionableCodeIfNecessary(
_ASSERTE(hr == E_OUTOFMEMORY);
ReportCodePublishError(pMethodDesc, hr);
*doBackpatchRef = false;
return pCode != NULL ? pCode : pMethodDesc->PrepareInitialCode();
return pCode != NULL ? pCode : pMethodDesc->PrepareInitialCode(callerGCMode);
} while (false);

while (true)
Expand All @@ -1670,6 +1671,9 @@ PCODE CodeVersionManager::PublishVersionableCodeIfNecessary(
{
PrepareCodeConfigBuffer configBuffer(activeVersion);
PrepareCodeConfig *config = configBuffer.GetConfig();

// Record the caller's GC mode.
config->SetCallerGCMode(callerGCMode);
pCode = pMethodDesc->PrepareCode(config);

#ifdef FEATURE_CODE_VERSIONING
Expand Down
7 changes: 5 additions & 2 deletions src/coreclr/src/vm/codeversion.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#ifndef CODE_VERSION_H
#define CODE_VERSION_H

class NativeCodeVersion;
class ILCodeVersion;
typedef DWORD NativeCodeVersionId;

Expand Down Expand Up @@ -572,7 +571,11 @@ class CodeVersionManager

HRESULT AddILCodeVersion(Module* pModule, mdMethodDef methodDef, ReJITID rejitId, ILCodeVersion* pILCodeVersion);
HRESULT AddNativeCodeVersion(ILCodeVersion ilCodeVersion, MethodDesc* pClosedMethodDesc, NativeCodeVersion::OptimizationTier optimizationTier, NativeCodeVersion* pNativeCodeVersion);
PCODE PublishVersionableCodeIfNecessary(MethodDesc* pMethodDesc, bool *doBackpatchRef, bool *doFullBackpatchRef);
PCODE PublishVersionableCodeIfNecessary(
MethodDesc* pMethodDesc,
CallerGCMode callerGCMode,
bool *doBackpatchRef,
bool *doFullBackpatchRef);
HRESULT PublishNativeCodeVersion(MethodDesc* pMethodDesc, NativeCodeVersion nativeCodeVersion);
HRESULT GetOrCreateMethodDescVersioningState(MethodDesc* pMethod, MethodDescVersioningState** ppMethodDescVersioningState);
HRESULT GetOrCreateILCodeVersioningState(Module* pModule, mdMethodDef methodDef, ILCodeVersioningState** ppILCodeVersioningState);
Expand Down
23 changes: 7 additions & 16 deletions src/coreclr/src/vm/comdelegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1132,36 +1132,26 @@ void COMDelegate::BindToMethod(DELEGATEREF *pRefThis,
GCPROTECT_END();
}

#if defined(TARGET_X86) && defined(TARGET_WINDOWS)
// Marshals a managed method to an unmanaged callback provided the
// managed method is static and it's parameters require no marshalling.
PCODE COMDelegate::ConvertToCallback(MethodDesc* pMD)
{
CONTRACTL
{
THROWS;
GC_TRIGGERS;
INJECT_FAULT(COMPlusThrowOM());
GC_TRIGGERS;
PRECONDITION(pMD != NULL);
INJECT_FAULT(COMPlusThrowOM());
}
CONTRACTL_END;

PCODE pCode = NULL;

// only static methods are allowed
if (!pMD->IsStatic())
COMPlusThrow(kNotSupportedException, W("NotSupported_NonStaticMethod"));

// no generic methods
if (pMD->IsGenericMethodDefinition())
COMPlusThrow(kNotSupportedException, W("NotSupported_GenericMethod"));

// Arguments
if (NDirect::MarshalingRequired(pMD, pMD->GetSig(), pMD->GetModule()))
COMPlusThrow(kNotSupportedException, W("NotSupported_NonBlittableTypes"));

// Get UMEntryThunk from the thunk cache.
UMEntryThunk *pUMEntryThunk = pMD->GetLoaderAllocator()->GetUMEntryThunkCache()->GetUMEntryThunk(pMD);

#if defined(TARGET_X86) && !defined(FEATURE_STUBS_AS_IL)
#if !defined(FEATURE_STUBS_AS_IL)

// System.Runtime.InteropServices.NativeCallableAttribute
BYTE* pData = NULL;
Expand Down Expand Up @@ -1193,12 +1183,13 @@ PCODE COMDelegate::ConvertToCallback(MethodDesc* pMD)
pUMThunkMarshalInfo->SetCallingConvention(callConv);
}
}
#endif //TARGET_X86 && !FEATURE_STUBS_AS_IL
#endif // !FEATURE_STUBS_AS_IL

pCode = (PCODE)pUMEntryThunk->GetCode();
_ASSERTE(pCode != NULL);
return pCode;
}
#endif // defined(TARGET_X86) && defined(TARGET_WINDOWS)

// Marshals a delegate to a unmanaged callback.
LPVOID COMDelegate::ConvertToCallback(OBJECTREF pDelegateObj)
Expand Down
6 changes: 4 additions & 2 deletions src/coreclr/src/vm/comdelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,11 @@ class COMDelegate
// Marshals a delegate to a unmanaged callback.
static LPVOID ConvertToCallback(OBJECTREF pDelegate);

// Marshals a managed method to an unmanaged callback , provided the method is static and uses only
// blittable parameter types.
#if defined(TARGET_X86) && defined(TARGET_WINDOWS)
// Marshals a managed method to an unmanaged callback.
// This is only used on x86 Windows. See usage for further details.
static PCODE ConvertToCallback(MethodDesc* pMD);
#endif // defined(TARGET_X86) && defined(TARGET_WINDOWS)

// Marshals an unmanaged callback to Delegate
static OBJECTREF ConvertToDelegate(LPVOID pCallback, MethodTable* pMT);
Expand Down
15 changes: 14 additions & 1 deletion src/coreclr/src/vm/exceptionhandling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4655,7 +4655,6 @@ VOID DECLSPEC_NORETURN UnwindManagedExceptionPass1(PAL_SEHException& ex, CONTEXT
}
else
{
// TODO: This needs to implemented. Make it fail for now.
UNREACHABLE();
}
}
Expand All @@ -4664,6 +4663,20 @@ VOID DECLSPEC_NORETURN UnwindManagedExceptionPass1(PAL_SEHException& ex, CONTEXT
controlPc = Thread::VirtualUnwindLeafCallFrame(frameContext);
}

GcInfoDecoder gcInfoDecoder(codeInfo.GetGCInfoToken(), DECODE_REVERSE_PINVOKE_VAR);

if (gcInfoDecoder.GetReversePInvokeFrameStackSlot() != NO_REVERSE_PINVOKE_FRAME)
{
// Propagating exception from a method marked by NativeCallable attribute is prohibited on Unix
if (!GetThread()->HasThreadStateNC(Thread::TSNC_ProcessedUnhandledException))
{
LONG disposition = InternalUnhandledExceptionFilter_Worker(&ex.ExceptionPointers);
_ASSERTE(disposition == EXCEPTION_CONTINUE_SEARCH);
}
TerminateProcess(GetCurrentProcess(), 1);
UNREACHABLE();
}

// Check whether we are crossing managed-to-native boundary
while (!ExecutionManager::IsManagedCode(controlPc))
{
Expand Down
6 changes: 6 additions & 0 deletions src/coreclr/src/vm/frames.h
Original file line number Diff line number Diff line change
Expand Up @@ -2785,6 +2785,12 @@ class UMThkCallFrame : public UnmanagedToManagedFrame
};
#endif // TARGET_X86 && !TARGET_UNIX

// Frame for the Reverse PInvoke (i.e. NativeCallableAttribute).
struct ReversePInvokeFrame
{
Thread* currentThread;
};

#if defined(TARGET_X86) && defined(FEATURE_COMINTEROP)
//-------------------------------------------------------------------------
// Exception handler for COM to managed frame
Expand Down
Loading