Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ private static ref byte GetNonGCThreadStaticsByIndexSlow(int index)
{
ByteRef result = default;
GetThreadStaticsByIndex(ByteRefOnStack.Create(ref result), index, false);
return ref result.Get();
return ref result.Value;
}

[DebuggerHidden]
Expand All @@ -149,7 +149,7 @@ private static ref byte GetGCThreadStaticsByIndexSlow(int index)
{
ByteRef result = default;
GetThreadStaticsByIndex(ByteRefOnStack.Create(ref result), index, true);
return ref result.Get();
return ref result.Value;
}

[DebuggerHidden]
Expand All @@ -158,7 +158,7 @@ private static ref byte GetNonGCThreadStaticBaseSlow(MethodTable* mt)
{
ByteRef result = default;
GetThreadStaticsByMethodTable(ByteRefOnStack.Create(ref result), mt, false);
return ref result.Get();
return ref result.Value;
}

[DebuggerHidden]
Expand All @@ -167,7 +167,7 @@ private static ref byte GetGCThreadStaticBaseSlow(MethodTable* mt)
{
ByteRef result = default;
GetThreadStaticsByMethodTable(ByteRefOnStack.Create(ref result), mt, true);
return ref result.Get();
return ref result.Value;
}

[DebuggerHidden]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1553,9 +1553,9 @@ internal static ref byte GetFieldDataReference(object target, RuntimeFieldInfo f
{
ByteRef fieldDataRef = default;
GetFieldDataReference(((RtFieldInfo)field).GetFieldDesc(), ObjectHandleOnStack.Create(ref target), ByteRefOnStack.Create(ref fieldDataRef));
Debug.Assert(!Unsafe.IsNullRef(ref fieldDataRef.Get()));
Debug.Assert(!Unsafe.IsNullRef(ref fieldDataRef.Value));
GC.KeepAlive(field);
return ref fieldDataRef.Get();
return ref fieldDataRef.Value;
}

internal static ref byte GetFieldDataReference(ref byte target, RuntimeFieldInfo field)
Expand Down
58 changes: 54 additions & 4 deletions src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -831,6 +831,19 @@ internal static void ClearNative(IntPtr pMarshalState, in object pManagedHome, I

internal static unsafe partial class MngdRefCustomMarshaler
{
[UnmanagedCallersOnly]
internal static void ConvertContentsToNative(ICustomMarshaler* pMarshaler, object* pManagedHome, IntPtr* pNativeHome, Exception* pException)
{
try
{
ConvertContentsToNative(*pMarshaler, in *pManagedHome, pNativeHome);
}
catch (Exception ex)
{
*pException = ex;
}
}

internal static void ConvertContentsToNative(ICustomMarshaler marshaler, in object pManagedHome, IntPtr* pNativeHome)
{
// COMPAT: We never pass null to MarshalManagedToNative.
Expand All @@ -843,6 +856,19 @@ internal static void ConvertContentsToNative(ICustomMarshaler marshaler, in obje
*pNativeHome = marshaler.MarshalManagedToNative(pManagedHome);
}

[UnmanagedCallersOnly]
internal static void ConvertContentsToManaged(ICustomMarshaler* pMarshaler, object* pManagedHome, IntPtr* pNativeHome, Exception* pException)
{
try
{
ConvertContentsToManaged(*pMarshaler, ref *pManagedHome, pNativeHome);
}
catch (Exception ex)
{
*pException = ex;
}
}

internal static void ConvertContentsToManaged(ICustomMarshaler marshaler, ref object? pManagedHome, IntPtr* pNativeHome)
{
// COMPAT: We never pass null to MarshalNativeToManaged.
Expand All @@ -855,8 +881,20 @@ internal static void ConvertContentsToManaged(ICustomMarshaler marshaler, ref ob
pManagedHome = marshaler.MarshalNativeToManaged(*pNativeHome);
}

#pragma warning disable IDE0060 // Remove unused parameter. These APIs need to match a the shape of a "managed" marshaler.
internal static void ClearNative(ICustomMarshaler marshaler, ref object pManagedHome, IntPtr* pNativeHome)
[UnmanagedCallersOnly]
internal static void ClearNative(ICustomMarshaler* pMarshaler, object* pManagedHome, IntPtr* pNativeHome, Exception* pException)
{
try
{
ClearNative(*pMarshaler, ref *pManagedHome, pNativeHome);
}
catch (Exception ex)
{
*pException = ex;
}
}

internal static void ClearNative(ICustomMarshaler marshaler, ref object _, IntPtr* pNativeHome)
{
// COMPAT: We never pass null to CleanUpNativeData.
if (*pNativeHome == IntPtr.Zero)
Expand All @@ -874,7 +912,20 @@ internal static void ClearNative(ICustomMarshaler marshaler, ref object pManaged
}
}

internal static void ClearManaged(ICustomMarshaler marshaler, in object pManagedHome, IntPtr* pNativeHome)
[UnmanagedCallersOnly]
internal static void ClearManaged(ICustomMarshaler* pMarshaler, object* pManagedHome, IntPtr* pNativeHome, Exception* pException)
{
try
{
ClearManaged(*pMarshaler, in *pManagedHome, pNativeHome);
}
catch (Exception ex)
{
*pException = ex;
}
}

internal static void ClearManaged(ICustomMarshaler marshaler, in object pManagedHome, IntPtr* _)
{
// COMPAT: We never pass null to CleanUpManagedData.
if (pManagedHome is null)
Expand All @@ -884,7 +935,6 @@ internal static void ClearManaged(ICustomMarshaler marshaler, in object pManaged

marshaler.CleanUpManagedData(pManagedHome);
}
#pragma warning restore IDE0060
} // class MngdRefCustomMarshaler

internal struct AsAnyMarshaler
Expand Down
80 changes: 80 additions & 0 deletions src/coreclr/vm/callhelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,86 @@ enum DispatchCallSimpleFlags

void CallDefaultConstructor(OBJECTREF ref);

//
// Helper types for calling managed methods marked with [UnmanagedCallersOnly]
// from native code.
//

// Helper class for calling managed methods marked with [UnmanagedCallersOnly].
// This provides a more efficient alternative to MethodDescCallSite for methods
// using the reverse P/Invoke infrastructure.
// This class assumes the target method signature has a trailing argument for
// returning the exception (that is, Exception* in C#).
//
// Example usage:
// UnmanagedCallersOnlyCaller caller(BinderMethodID::MyMethod);
// ...
// caller.InvokeThrowing(arg1, arg2);
//
// The corresponding C# method would be declared as:
// [UnmanagedCallersOnly]
// public static void MyMethod(int arg1, object* arg2, Exception* pException);
//
class UnmanagedCallersOnlyCaller final
{
MethodDesc* _pMD;
public:
explicit UnmanagedCallersOnlyCaller(BinderMethodID id)
: _pMD{}
{
CONTRACTL
{
THROWS;
GC_TRIGGERS;
MODE_COOPERATIVE;
}
CONTRACTL_END;

_pMD = CoreLibBinder::GetMethod(id);
_ASSERTE(_pMD != NULL);
_ASSERTE(_pMD->HasUnmanagedCallersOnlyAttribute());
}

template<typename... Args>
void InvokeThrowing(Args... args)
{
CONTRACTL
{
THROWS;
GC_TRIGGERS;
MODE_COOPERATIVE;
}
CONTRACTL_END;

struct
{
OBJECTREF Exception;
} gc;
gc.Exception = NULL;
GCPROTECT_BEGIN(gc);

{
GCX_PREEMP();

PCODE methodEntry = _pMD->GetSingleCallableAddrOfCodeForUnmanagedCallersOnly();
_ASSERTE(methodEntry != (PCODE)NULL);

// Cast the function pointer to the appropriate type.
// Note that we append the exception handle argument.
auto fptr = reinterpret_cast<void(*)(Args..., OBJECTREF*)>(methodEntry);

// The last argument is the implied exception handle for any exceptions.
fptr(args..., &gc.Exception);
}

// If an exception was thrown, propagate it
if (gc.Exception != NULL)
COMPlusThrow(gc.Exception);

GCPROTECT_END();
}
};

#endif //!DACCESS_COMPILE

#endif // __CALLHELPERS_H__
6 changes: 5 additions & 1 deletion src/coreclr/vm/corelib.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ DEFINE_FIELD(ACCESS_VIOLATION_EXCEPTION, TARGET, _target)
DEFINE_FIELD(ACCESS_VIOLATION_EXCEPTION, ACCESSTYPE, _accessType)

DEFINE_CLASS(APPCONTEXT, System, AppContext)
DEFINE_METHOD(APPCONTEXT, SETUP, Setup, SM_PtrPtrChar_PtrPtrChar_Int_RetVoid)
DEFINE_METHOD(APPCONTEXT, SETUP, Setup, SM_PtrPtrChar_PtrPtrChar_Int_PtrException_RetVoid)
DEFINE_METHOD(APPCONTEXT, ON_PROCESS_EXIT, OnProcessExit, SM_RetVoid)
DEFINE_METHOD(APPCONTEXT, ON_UNHANDLED_EXCEPTION, OnUnhandledException, SM_Obj_RetVoid)
DEFINE_FIELD(APPCONTEXT, FIRST_CHANCE_EXCEPTION, FirstChanceException)
Expand Down Expand Up @@ -1187,6 +1187,10 @@ DEFINE_METHOD(MNGD_REF_CUSTOM_MARSHALER, CONVERT_CONTENTS_TO_NATIVE, ConvertCon
DEFINE_METHOD(MNGD_REF_CUSTOM_MARSHALER, CONVERT_CONTENTS_TO_MANAGED, ConvertContentsToManaged, SM_ICustomMarshaler_RefObj_PtrIntPtr_RetVoid)
DEFINE_METHOD(MNGD_REF_CUSTOM_MARSHALER, CLEAR_NATIVE, ClearNative, SM_ICustomMarshaler_RefObj_PtrIntPtr_RetVoid)
DEFINE_METHOD(MNGD_REF_CUSTOM_MARSHALER, CLEAR_MANAGED, ClearManaged, SM_ICustomMarshaler_RefObj_PtrIntPtr_RetVoid)
DEFINE_METHOD(MNGD_REF_CUSTOM_MARSHALER, CONVERT_CONTENTS_TO_NATIVE_UCO, ConvertContentsToNative, SM_PtrICustomMarshaler_PtrObj_PtrIntPtr_PtrException_RetVoid)
DEFINE_METHOD(MNGD_REF_CUSTOM_MARSHALER, CONVERT_CONTENTS_TO_MANAGED_UCO, ConvertContentsToManaged, SM_PtrICustomMarshaler_PtrObj_PtrIntPtr_PtrException_RetVoid)
DEFINE_METHOD(MNGD_REF_CUSTOM_MARSHALER, CLEAR_NATIVE_UCO, ClearNative, SM_PtrICustomMarshaler_PtrObj_PtrIntPtr_PtrException_RetVoid)
DEFINE_METHOD(MNGD_REF_CUSTOM_MARSHALER, CLEAR_MANAGED_UCO, ClearManaged, SM_PtrICustomMarshaler_PtrObj_PtrIntPtr_PtrException_RetVoid)

DEFINE_CLASS(ASANY_MARSHALER, StubHelpers, AsAnyMarshaler)
DEFINE_METHOD(ASANY_MARSHALER, CTOR, .ctor, IM_IntPtr_RetVoid)
Expand Down
10 changes: 2 additions & 8 deletions src/coreclr/vm/corhost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -571,14 +571,8 @@ HRESULT CorHost2::CreateAppDomainWithManager(
{
GCX_COOP();

MethodDescCallSite setup(METHOD__APPCONTEXT__SETUP);

ARG_SLOT args[3];
args[0] = PtrToArgSlot(pPropertyNames);
args[1] = PtrToArgSlot(pPropertyValues);
args[2] = PtrToArgSlot(nProperties);

setup.Call(args);
UnmanagedCallersOnlyCaller setup(METHOD__APPCONTEXT__SETUP);
setup.InvokeThrowing(pPropertyNames, pPropertyValues, nProperties);
}

LPCWSTR pwzNativeDllSearchDirectories = NULL;
Expand Down
Loading
Loading