}
}
- // Keeps a Delegate instance alive across the full Managed->Native call.
+ // Keeps an object instance alive across the full Managed->Native call.
// This ensures that users don't have to call GC.KeepAlive after passing a struct or class
// that has a delegate field to native code.
- internal sealed class DelegateCleanupWorkListElement : CleanupWorkListElement
+ internal sealed class KeepAliveCleanupWorkListElement : CleanupWorkListElement
{
- public DelegateCleanupWorkListElement(Delegate del)
+ public KeepAliveCleanupWorkListElement(object obj)
{
- m_del = del;
+ m_obj = obj;
}
- private Delegate m_del;
+ private object m_obj;
protected override void DestroyCore()
{
- GC.KeepAlive(m_del);
+ GC.KeepAlive(m_obj);
}
}
return element.AddRef();
}
- internal static void AddToCleanupList(ref CleanupWorkListElement pCleanupWorkList, Delegate del)
+ internal static void KeepAliveViaCleanupList(ref CleanupWorkListElement pCleanupWorkList, object obj)
{
- DelegateCleanupWorkListElement element = new DelegateCleanupWorkListElement(del);
+ KeepAliveCleanupWorkListElement element = new KeepAliveCleanupWorkListElement(obj);
CleanupWorkListElement.AddToCleanupList(ref pCleanupWorkList, element);
}
if (*pCLRValue != NULL && ppCleanupWorkListOnStack != NULL)
{
// Call StubHelpers.AddToCleanupList to ensure the delegate is kept alive across the full native call.
- MethodDescCallSite AddToCleanupList(METHOD__STUBHELPERS__ADD_TO_CLEANUP_LIST_DELEGATE);
+ MethodDescCallSite AddToCleanupList(METHOD__STUBHELPERS__KEEP_ALIVE_VIA_CLEANUP_LIST);
ARG_SLOT args[] =
{
if (IsCLRToNative(m_dwMarshalFlags))
{
- // keep the object alive across the call-out to native
+ EmitLoadCleanupWorkList(pslILEmit);
if (tokStruct__m_object != 0)
{
- EmitLoadManagedHomeAddr(m_pcsUnmarshal);
- m_pcsUnmarshal->EmitLDFLD(tokStruct__m_object);
+ EmitLoadManagedHomeAddr(pslILEmit);
+ pslILEmit->EmitLDFLD(tokStruct__m_object);
}
else
{
- EmitLoadManagedValue(m_pcsUnmarshal);
+ EmitLoadManagedValue(pslILEmit);
}
- m_pcsUnmarshal->EmitCALL(METHOD__GC__KEEP_ALIVE, 1, 0);
+ pslILEmit->EmitCALL(METHOD__STUBHELPERS__KEEP_ALIVE_VIA_CLEANUP_LIST, 2, 0);
}
}
EmitLoadManagedValue(pslILEmit);
pslILEmit->EmitCALL(METHOD__MARSHAL__GET_FUNCTION_POINTER_FOR_DELEGATE, 1, 1);
EmitStoreNativeValue(pslILEmit);
+ EmitLoadCleanupWorkList(pslILEmit);
+ EmitLoadManagedValue(pslILEmit);
+ pslILEmit->EmitCALL(METHOD__STUBHELPERS__KEEP_ALIVE_VIA_CLEANUP_LIST, 2, 0);
pslILEmit->EmitLabel(pNullLabel);
-
- //
- // @TODO: is there a better way to do this?
- //
- if (IsCLRToNative(m_dwMarshalFlags))
- {
- // keep the delegate ref alive across the call-out to native
- EmitLoadManagedValue(m_pcsUnmarshal);
- m_pcsUnmarshal->EmitCALL(METHOD__GC__KEEP_ALIVE, 1, 0);
- }
}
void ILDelegateMarshaler::EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit)
pslILEmit->EmitLabel(pIsNullLabel);
}
-bool ILWSTRMarshaler::NeedsClearNative()
-{
- LIMITED_METHOD_CONTRACT;
-
- // will evaluate to true iff there is something CoTaskMemAlloc'ed that we need to free
- bool needsClear = (IsByref(m_dwMarshalFlags) && IsOut(m_dwMarshalFlags)) || IsRetval(m_dwMarshalFlags);
-
- // m_fCoMemoryAllocated => needsClear
- // (if we allocated the memory, we will free it; for byref [out] and retval we free memory allocated by the callee)
- _ASSERTE(!m_fCoMemoryAllocated || needsClear);
-
- return needsClear;
-}
-
-void ILWSTRMarshaler::EmitClearNative(ILCodeStream* pslILEmit)
-{
- STANDARD_VM_CONTRACT;
-
- EmitLoadNativeValue(pslILEmit);
- // static void CoTaskMemFree(IntPtr ptr)
- pslILEmit->EmitCALL(METHOD__MARSHAL__FREE_CO_TASK_MEM, 1, 0);
-}
-
-void ILWSTRMarshaler::EmitClearNativeTemp(ILCodeStream* pslILEmit)
-{
- LIMITED_METHOD_CONTRACT;
- UNREACHABLE_MSG("The string is either pinned or a copy is stack-allocated, NeedsClearNative should have returned false");
-}
-
-bool ILWSTRMarshaler::CanUsePinnedManagedString(DWORD dwMarshalFlags)
-{
- LIMITED_METHOD_CONTRACT;
- return IsCLRToNative(dwMarshalFlags) && !IsByref(dwMarshalFlags) && IsIn(dwMarshalFlags) && !IsOut(dwMarshalFlags);
-}
-
//
// input stack: 0: managed string
// output stack: 0: (string_length+1) * sizeof(WCHAR)
{
STANDARD_VM_CONTRACT;
- INDEBUG(m_fCoMemoryAllocated = true);
-
ILCodeLabel* pNullRefLabel = pslILEmit->NewCodeLabel();
DWORD dwLengthLocalNum = pslILEmit->NewLocal(ELEMENT_TYPE_I4);
pslILEmit->EmitLabel(pNullRefLabel);
}
-void ILWSTRMarshaler::EmitConvertSpaceAndContentsCLRToNativeTemp(ILCodeStream* pslILEmit)
+void ILWSTRMarshaler::EmitMarshalViaPinning(ILCodeStream* pslILEmit)
{
STANDARD_VM_CONTRACT;
- if (CanUsePinnedManagedString(m_dwMarshalFlags))
- {
- LocalDesc locDesc = GetManagedType();
- locDesc.MakePinned();
- DWORD dwPinnedLocal = pslILEmit->NewLocal(locDesc);
- int fieldDef = pslILEmit->GetToken(MscorlibBinder::GetField(FIELD__STRING__M_FIRST_CHAR));
- ILCodeLabel* pNullRefLabel = pslILEmit->NewCodeLabel();
-
- pslILEmit->EmitLoadNullPtr();
- EmitStoreNativeValue(pslILEmit);
+ LocalDesc locDesc = GetManagedType();
+ locDesc.MakePinned();
+ DWORD dwPinnedLocal = pslILEmit->NewLocal(locDesc);
+ int fieldDef = pslILEmit->GetToken(MscorlibBinder::GetField(FIELD__STRING__M_FIRST_CHAR));
+ ILCodeLabel* pNullRefLabel = pslILEmit->NewCodeLabel();
+
+ pslILEmit->EmitLoadNullPtr();
+ EmitStoreNativeValue(pslILEmit);
- EmitLoadManagedValue(pslILEmit);
- pslILEmit->EmitBRFALSE(pNullRefLabel);
+ EmitLoadManagedValue(pslILEmit);
+ pslILEmit->EmitBRFALSE(pNullRefLabel);
- EmitLoadManagedValue(pslILEmit);
- pslILEmit->EmitSTLOC(dwPinnedLocal);
- pslILEmit->EmitLDLOC(dwPinnedLocal);
- pslILEmit->EmitLDFLDA(fieldDef);
- EmitStoreNativeValue(pslILEmit);
+ EmitLoadManagedValue(pslILEmit);
+ pslILEmit->EmitSTLOC(dwPinnedLocal);
+ pslILEmit->EmitLDLOC(dwPinnedLocal);
+ pslILEmit->EmitLDFLDA(fieldDef);
+ EmitStoreNativeValue(pslILEmit);
- if (g_pConfig->InteropLogArguments())
- {
- m_pslNDirect->EmitLogNativeArgument(pslILEmit, dwPinnedLocal);
- }
+ EmitLogNativeArgumentsIfNeeded(pslILEmit, dwPinnedLocal);
- pslILEmit->EmitLabel(pNullRefLabel);
+ pslILEmit->EmitLabel(pNullRefLabel);
+}
- }
- else
- {
- ILCodeLabel* pNullRefLabel = pslILEmit->NewCodeLabel();
- DWORD dwLengthLocalNum = pslILEmit->NewLocal(ELEMENT_TYPE_I4);
-
- pslILEmit->EmitLoadNullPtr();
- EmitStoreNativeValue(pslILEmit);
-
- EmitLoadManagedValue(pslILEmit);
- pslILEmit->EmitBRFALSE(pNullRefLabel);
-
- EmitLoadManagedValue(pslILEmit);
- EmitCheckManagedStringLength(pslILEmit);
+void ILWSTRMarshaler::EmitConvertSpaceAndContentsCLRToNativeTemp(ILCodeStream* pslILEmit)
+{
+ STANDARD_VM_CONTRACT;
+
+ ILCodeLabel* pNullRefLabel = pslILEmit->NewCodeLabel();
+ DWORD dwLengthLocalNum = pslILEmit->NewLocal(ELEMENT_TYPE_I4);
+
+ pslILEmit->EmitLoadNullPtr();
+ EmitStoreNativeValue(pslILEmit);
+
+ EmitLoadManagedValue(pslILEmit);
+ pslILEmit->EmitBRFALSE(pNullRefLabel);
+
+ EmitLoadManagedValue(pslILEmit);
+ EmitCheckManagedStringLength(pslILEmit);
- // cb
+ pslILEmit->EmitSTLOC(dwLengthLocalNum);
- pslILEmit->EmitDUP();
- pslILEmit->EmitSTLOC(dwLengthLocalNum);
+ ILCodeLabel* pAllocRejoin = pslILEmit->NewCodeLabel();
+ ILCodeLabel* pNoOptimize = pslILEmit->NewCodeLabel();
+ m_dwLocalBuffer = pslILEmit->NewLocal(ELEMENT_TYPE_I);
- // cb
+ // LocalBuffer = 0
+ pslILEmit->EmitLoadNullPtr();
+ pslILEmit->EmitSTLOC(m_dwLocalBuffer);
- pslILEmit->EmitLOCALLOC(); // @TODO: add a non-localloc path for large strings
- EmitStoreNativeValue(pslILEmit);
+ pslILEmit->EmitLDLOC(dwLengthLocalNum);
+ // if (alloc_size_in_bytes > MAX_LOCAL_BUFFER_LENGTH) goto NoOptimize
+ pslILEmit->EmitDUP();
+ pslILEmit->EmitLDC(MAX_LOCAL_BUFFER_LENGTH);
+ pslILEmit->EmitCGT_UN();
+ pslILEmit->EmitBRTRUE(pNoOptimize);
- EmitLoadManagedValue(pslILEmit);
- EmitLoadNativeValue(pslILEmit);
+ pslILEmit->EmitLOCALLOC();
+ pslILEmit->EmitDUP();
+ pslILEmit->EmitSTLOC(m_dwLocalBuffer);
+ pslILEmit->EmitBR(pAllocRejoin);
- // src, dst
+ pslILEmit->EmitLabel(pNoOptimize);
- pslILEmit->EmitLDLOC(dwLengthLocalNum); // length
-
- // static void System.String.InternalCopy(String src, IntPtr dest,int len)
- pslILEmit->EmitCALL(METHOD__STRING__INTERNAL_COPY, 3, 0);
- pslILEmit->EmitLabel(pNullRefLabel);
- }
+ pslILEmit->EmitCALL(METHOD__MARSHAL__ALLOC_CO_TASK_MEM, 1, 1);
+ pslILEmit->EmitLabel(pAllocRejoin);
+ EmitStoreNativeValue(pslILEmit);
+
+ EmitLoadManagedValue(pslILEmit);
+ EmitLoadNativeValue(pslILEmit);
+
+ // src, dst
+
+ pslILEmit->EmitLDLOC(dwLengthLocalNum); // length
+
+ // static void System.String.InternalCopy(String src, IntPtr dest,int len)
+ pslILEmit->EmitCALL(METHOD__STRING__INTERNAL_COPY, 3, 0);
+ pslILEmit->EmitLabel(pNullRefLabel);
}
//
pslILEmit->EmitLDTOKEN(managedVCToken); // pMT
pslILEmit->EmitCALL(METHOD__RT_TYPE_HANDLE__GETVALUEINTERNAL, 1, 1); // Convert RTH to IntPtr
- m_pslNDirect->LoadCleanupWorkList(pslILEmit);
+ EmitLoadCleanupWorkList(pslILEmit);
pslILEmit->EmitCALL(METHOD__VALUECLASSMARSHALER__CONVERT_TO_NATIVE, 4, 0); // void ConvertToNative(IntPtr dst, IntPtr src, IntPtr pMT, ref CleanupWorkListElement pCleanupWorkList)
}
//
// The fix is to extend the lifetime of the argument across the call to native by doing a GC.KeepAlive
// keep the delegate ref alive across the call-out to native
- EmitLoadManagedValue(m_pcsUnmarshal);
- m_pcsUnmarshal->EmitCALL(METHOD__GC__KEEP_ALIVE, 1, 0);
+ EmitLoadCleanupWorkList(pslILEmit);
+ EmitLoadManagedValue(pslILEmit);
+ pslILEmit->EmitCALL(METHOD__STUBHELPERS__KEEP_ALIVE_VIA_CLEANUP_LIST, 2, 0);
}
}
return false;
}
+void ILVBByValStrWMarshaler::EmitSetupArgumentForMarshalling(ILCodeStream* pslILEmit)
+{
+ m_dwLocalBuffer = pslILEmit->NewLocal(ELEMENT_TYPE_I);
+ pslILEmit->EmitLoadNullPtr();
+ pslILEmit->EmitSTLOC(m_dwLocalBuffer);
+}
+
void ILVBByValStrWMarshaler::EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit)
{
STANDARD_VM_CONTRACT;
- ILCodeStream *pcsSetup = m_pslNDirect->GetSetupCodeStream();
- m_dwLocalBuffer = pcsSetup->NewLocal(ELEMENT_TYPE_I);
- pcsSetup->EmitLoadNullPtr();
- pcsSetup->EmitSTLOC(m_dwLocalBuffer);
-
-
ILCodeLabel* pNullRefLabel = pslILEmit->NewCodeLabel();
m_dwCCHLocal = pslILEmit->NewLocal(ELEMENT_TYPE_I4);
DWORD dwNumBytesLocal = pslILEmit->NewLocal(ELEMENT_TYPE_I4);
pslILEmit->EmitLDLOCA(dwHStringHeaderLocal);
pslILEmit->EmitCALL(METHOD__HSTRINGMARSHALER__CONVERT_TO_NATIVE_REFERENCE, 2, 1);
- if (g_pConfig->InteropLogArguments())
- {
- m_pslNDirect->EmitLogNativeArgument(pslILEmit, dwPinnedStringLocal);
- }
+ EmitLogNativeArgumentsIfNeeded(pslILEmit, dwPinnedStringLocal);
EmitStoreNativeValue(pslILEmit);
}
EmitLoadManagedValue(pslILEmit);
EmitLoadNativeValue(pslILEmit);
- m_pslNDirect->LoadCleanupWorkList(pslILEmit);
+ EmitLoadCleanupWorkList(pslILEmit);
// static void FmtClassUpdateNativeInternal(object obj, byte* pNative, IntPtr pOptionalCleanupList);
pslILEmit->EmitLabel(pNullRefLabel);
}
-void ILBlittablePtrMarshaler::EmitMarshalArgumentCLRToNative()
+bool ILBlittablePtrMarshaler::CanUsePinnedLayoutClass()
{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(IsCLRToNative(m_dwMarshalFlags) && !IsByref(m_dwMarshalFlags));
- }
- CONTRACTL_END;
+ return IsCLRToNative(m_dwMarshalFlags) && !IsByref(m_dwMarshalFlags);
+}
- EmitSetupSigAndDefaultHomesCLRToNative();
+void ILBlittablePtrMarshaler::EmitConvertSpaceAndContentsCLRToNativeTemp(ILCodeStream* pslILEmit)
+{
+ STANDARD_VM_CONTRACT;
- //
- // marshal
- //
+ if (CanUsePinnedLayoutClass())
+ {
+ ILCodeLabel* pSkipAddLabel = pslILEmit->NewCodeLabel();
+ LocalDesc managedTypePinned = GetManagedType();
+ managedTypePinned.MakePinned();
+ DWORD dwPinnedLocal = pslILEmit->NewLocal(managedTypePinned);
- ILCodeLabel* pSkipAddLabel = m_pcsMarshal->NewCodeLabel();
- LocalDesc managedTypePinned = GetManagedType();
- managedTypePinned.MakePinned();
- DWORD dwPinnedLocal = m_pcsMarshal->NewLocal(managedTypePinned);
+ EmitLoadManagedValue(pslILEmit);
- EmitLoadManagedValue(m_pcsMarshal);
-
- m_pcsMarshal->EmitSTLOC(dwPinnedLocal);
- m_pcsMarshal->EmitLDLOC(dwPinnedLocal);
- m_pcsMarshal->EmitCONV_U();
- m_pcsMarshal->EmitDUP();
- m_pcsMarshal->EmitBRFALSE(pSkipAddLabel);
- m_pcsMarshal->EmitLDC(Object::GetOffsetOfFirstField());
- m_pcsMarshal->EmitADD();
- m_pcsMarshal->EmitLabel(pSkipAddLabel);
+ pslILEmit->EmitSTLOC(dwPinnedLocal);
+ pslILEmit->EmitLDLOC(dwPinnedLocal);
+ pslILEmit->EmitCONV_U();
+ pslILEmit->EmitDUP();
+ pslILEmit->EmitBRFALSE(pSkipAddLabel);
+ pslILEmit->EmitLDC(Object::GetOffsetOfFirstField());
+ pslILEmit->EmitADD();
+ pslILEmit->EmitLabel(pSkipAddLabel);
+
+ EmitLogNativeArgumentsIfNeeded(pslILEmit, dwPinnedLocal);
- if (g_pConfig->InteropLogArguments())
+ EmitStoreNativeValue(pslILEmit);
+ }
+ else
{
- m_pslNDirect->EmitLogNativeArgument(m_pcsMarshal, dwPinnedLocal);
+ ILLayoutClassPtrMarshalerBase::EmitConvertSpaceAndContentsCLRToNativeTemp(pslILEmit);
}
-
- EmitStoreNativeValue(m_pcsMarshal);
}
return DISALLOWED;
}
-LocalDesc ILSafeHandleMarshaler::GetManagedType()
-{
- STANDARD_VM_CONTRACT;
-
- return LocalDesc(MscorlibBinder::GetClass(CLASS__SAFE_HANDLE));
-}
-
-LocalDesc ILSafeHandleMarshaler::GetNativeType()
-{
- LIMITED_METHOD_CONTRACT;
-
- return LocalDesc(ELEMENT_TYPE_I);
-}
-
-bool ILSafeHandleMarshaler::NeedsClearNative()
-{
- LIMITED_METHOD_CONTRACT;
- return true;
-}
-
-void ILSafeHandleMarshaler::EmitClearNative(ILCodeStream* pslILEmit)
-{
- STANDARD_VM_CONTRACT;
-
- _ASSERTE(IsCLRToNative(m_dwMarshalFlags) && !IsByref(m_dwMarshalFlags));
-
- // call StubHelpers::SafeHandleRelease
- EmitLoadManagedValue(pslILEmit);
- pslILEmit->EmitCALL(METHOD__STUBHELPERS__SAFE_HANDLE_RELEASE, 1, 0);
-}
-
-void ILSafeHandleMarshaler::EmitMarshalArgumentCLRToNative()
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(IsCLRToNative(m_dwMarshalFlags) && !IsByref(m_dwMarshalFlags));
- }
- CONTRACTL_END;
-
- EmitSetupSigAndDefaultHomesCLRToNative();
-
- // by-value CLR-to-native SafeHandle is always passed in-only regardless of [In], [Out]
- // marshal and cleanup communicate via an extra local and are both emitted in this method
-
- // bool <dwHandleAddRefedLocalNum> = false
- ILCodeStream *pcsSetup = m_pslNDirect->GetSetupCodeStream();
- DWORD dwHandleAddRefedLocalNum = pcsSetup->NewLocal(ELEMENT_TYPE_BOOLEAN);
-
- pcsSetup->EmitLDC(0);
- pcsSetup->EmitSTLOC(dwHandleAddRefedLocalNum);
-
- // <nativeHandle> = StubHelpers::SafeHandleAddRef(<managedSH>, ref <dwHandleAddRefedLocalNum>)
- EmitLoadManagedValue(m_pcsMarshal);
- m_pcsMarshal->EmitLDLOCA(dwHandleAddRefedLocalNum);
- m_pcsMarshal->EmitCALL(METHOD__STUBHELPERS__SAFE_HANDLE_ADD_REF, 2, 1);
- EmitStoreNativeValue(m_pcsMarshal);
-
- // cleanup:
- // if (<dwHandleAddRefedLocalNum>) StubHelpers.SafeHandleRelease(<managedSH>)
- ILCodeStream *pcsCleanup = m_pslNDirect->GetCleanupCodeStream();
- ILCodeLabel *pSkipClearNativeLabel = pcsCleanup->NewCodeLabel();
-
- pcsCleanup->EmitLDLOC(dwHandleAddRefedLocalNum);
- pcsCleanup->EmitBRFALSE(pSkipClearNativeLabel);
-
- EmitClearNativeTemp(pcsCleanup);
- m_pslNDirect->SetCleanupNeeded();
-
- pcsCleanup->EmitLabel(pSkipClearNativeLabel);
-}
-
MarshalerOverrideStatus ILSafeHandleMarshaler::ArgumentOverride(NDirectStubLinker* psl,
BOOL byref,
BOOL fin,
if (fManagedToNative)
{
+ pslIL->SetStubTargetArgType(ELEMENT_TYPE_I);
if (byref)
{
- pslIL->SetStubTargetArgType(ELEMENT_TYPE_I);
-
// The specific SafeHandle subtype we're dealing with here.
MethodTable *pHandleType = pargs->m_pMT;
}
else
{
- // Avoid using the cleanup list in this common case for perf reasons (cleanup list is
- // unmanaged and destroying it means excessive managed<->native transitions; in addition,
- // as X86 IL stubs do not use interop frames, there's nothing protecting the cleanup list
- // and the SafeHandle references must be GC handles which does not help perf either).
- //
- // This code path generates calls to StubHelpers.SafeHandleAddRef and SafeHandleRelease.
- // NICE: Could SafeHandle.DangerousAddRef and DangerousRelease be implemented in managed?
- return HANDLEASNORMAL;
+ DWORD dwNativeHandle = pslIL->NewLocal(ELEMENT_TYPE_I);
+ psl->LoadCleanupWorkList(pslIL);
+ pslIL->EmitLDARG(argidx);
+ pslIL->EmitCALL(METHOD__STUBHELPERS__ADD_TO_CLEANUP_LIST_SAFEHANDLE, 2, 1);
+ pslIL->EmitSTLOC(dwNativeHandle);
+
+ pslILDispatch->EmitLDLOC(dwNativeHandle);
}
return OVERRIDDEN;
return true;
}
-void ILArgIteratorMarshaler::EmitMarshalArgumentCLRToNative()
+void ILArgIteratorMarshaler::EmitConvertSpaceAndContentsCLRToNative(ILCodeStream* pslILEmit)
{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(IsCLRToNative(m_dwMarshalFlags) && !IsByref(m_dwMarshalFlags));
- }
- CONTRACTL_END;
-
- EmitSetupSigAndDefaultHomesCLRToNative();
-
- //
- // marshal
- //
+ STANDARD_VM_CONTRACT;
// Allocate enough memory for va_list
- DWORD dwVaListSizeLocal = m_pcsMarshal->NewLocal(LocalDesc(ELEMENT_TYPE_U4));
- EmitLoadManagedHomeAddr(m_pcsMarshal);
- m_pcsMarshal->EmitCALL(METHOD__STUBHELPERS__CALC_VA_LIST_SIZE, 1, 1);
- m_pcsMarshal->EmitSTLOC(dwVaListSizeLocal);
- m_pcsMarshal->EmitLDLOC(dwVaListSizeLocal);
- m_pcsMarshal->EmitLOCALLOC();
- EmitStoreNativeValue(m_pcsMarshal);
-
- // void MarshalToUnmanagedVaListInternal(cbVaListSize, va_list, VARARGS* data)
- EmitLoadNativeValue(m_pcsMarshal);
- m_pcsMarshal->EmitLDLOC(dwVaListSizeLocal);
- EmitLoadManagedHomeAddr(m_pcsMarshal);
- m_pcsMarshal->EmitCALL(METHOD__STUBHELPERS__MARSHAL_TO_UNMANAGED_VA_LIST_INTERNAL, 3, 0);
+ DWORD dwVaListSizeLocal = pslILEmit->NewLocal(LocalDesc(ELEMENT_TYPE_U4));
+ EmitLoadManagedHomeAddr(pslILEmit);
+ pslILEmit->EmitCALL(METHOD__STUBHELPERS__CALC_VA_LIST_SIZE, 1, 1);
+ pslILEmit->EmitSTLOC(dwVaListSizeLocal);
+ pslILEmit->EmitLDLOC(dwVaListSizeLocal);
+ pslILEmit->EmitLOCALLOC();
+ EmitStoreNativeValue(pslILEmit);
+
+ // void MarshalToUnmanagedVaListInternal(va_list, uint vaListSize, VARARGS* data)
+ EmitLoadNativeValue(pslILEmit);
+ pslILEmit->EmitLDLOC(dwVaListSizeLocal);
+ EmitLoadManagedHomeAddr(pslILEmit);
+ pslILEmit->EmitCALL(METHOD__STUBHELPERS__MARSHAL_TO_UNMANAGED_VA_LIST_INTERNAL, 3, 0);
}
-void ILArgIteratorMarshaler::EmitMarshalArgumentNativeToCLR()
+void ILArgIteratorMarshaler::EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit)
{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(!IsCLRToNative(m_dwMarshalFlags) && !IsByref(m_dwMarshalFlags));
- }
- CONTRACTL_END;
-
- EmitSetupSigAndDefaultHomesNativeToCLR();
-
- EmitLoadNativeValue(m_pcsMarshal);
- EmitLoadManagedHomeAddr(m_pcsMarshal);
+ EmitLoadNativeValue(pslILEmit);
+ EmitLoadManagedHomeAddr(pslILEmit);
// void MarshalToManagedVaList(va_list va, VARARGS *dataout)
- m_pcsMarshal->EmitCALL(METHOD__STUBHELPERS__MARSHAL_TO_MANAGED_VA_LIST_INTERNAL, 2, 0);
+ pslILEmit->EmitCALL(METHOD__STUBHELPERS__MARSHAL_TO_MANAGED_VA_LIST_INTERNAL, 2, 0);
}
-
LocalDesc ILArrayWithOffsetMarshaler::GetNativeType()
{
LIMITED_METHOD_CONTRACT;
return false;
}
-void ILAsAnyMarshalerBase::EmitMarshalArgumentCLRToNative()
+void ILAsAnyMarshalerBase::EmitCreateMngdMarshaler(ILCodeStream* pslILEmit)
{
CONTRACTL
{
- STANDARD_VM_CHECK;
- PRECONDITION(IsCLRToNative(m_dwMarshalFlags) && !IsByref(m_dwMarshalFlags));
- CONSISTENCY_CHECK(LOCAL_NUM_UNUSED == m_dwMarshalerLocalNum);
+ THROWS;
+ GC_TRIGGERS;
+ MODE_ANY;
+ CONSISTENCY_CHECK(LOCAL_NUM_UNUSED == m_dwMngdMarshalerLocalNum);
}
CONTRACTL_END;
- EmitSetupSigAndDefaultHomesCLRToNative();
-
- BYTE inout = (IsIn(m_dwMarshalFlags) ? ML_IN : 0) | (IsOut(m_dwMarshalFlags) ? ML_OUT : 0);
- BYTE fIsAnsi = IsAnsi() ? 1 : 0;
- BYTE fBestFit = m_pargs->m_pMarshalInfo->GetBestFitMapping();
- BYTE fThrow = m_pargs->m_pMarshalInfo->GetThrowOnUnmappableChar();
-
- DWORD dwFlags = 0;
-
- dwFlags |= inout << 24;
- dwFlags |= fIsAnsi << 16;
- dwFlags |= fThrow << 8;
- dwFlags |= fBestFit << 0;
-
- //
- // marshal
- //
-
LocalDesc marshalerType(MscorlibBinder::GetClass(CLASS__ASANY_MARSHALER));
- m_dwMarshalerLocalNum = m_pcsMarshal->NewLocal(marshalerType);
- DWORD dwTmpLocalNum = m_pcsMarshal->NewLocal(ELEMENT_TYPE_I);
+ m_dwMngdMarshalerLocalNum = pslILEmit->NewLocal(marshalerType);
+ DWORD dwTmpLocalNum = pslILEmit->NewLocal(ELEMENT_TYPE_I);
- m_pcsMarshal->EmitLDC(sizeof(MngdNativeArrayMarshaler));
- m_pcsMarshal->EmitLOCALLOC();
- m_pcsMarshal->EmitSTLOC(dwTmpLocalNum);
+ pslILEmit->EmitLDC(sizeof(MngdNativeArrayMarshaler));
+ pslILEmit->EmitLOCALLOC();
+ pslILEmit->EmitSTLOC(dwTmpLocalNum);
// marshaler = new AsAnyMarshaler(local_buffer)
- m_pcsMarshal->EmitLDLOCA(m_dwMarshalerLocalNum);
- m_pcsMarshal->EmitINITOBJ(m_pcsMarshal->GetToken(marshalerType.InternalToken));
+ pslILEmit->EmitLDLOCA(m_dwMngdMarshalerLocalNum);
+ pslILEmit->EmitINITOBJ(pslILEmit->GetToken(marshalerType.InternalToken));
- m_pcsMarshal->EmitLDLOCA(m_dwMarshalerLocalNum);
- m_pcsMarshal->EmitLDLOC(dwTmpLocalNum);
- m_pcsMarshal->EmitCALL(METHOD__ASANY_MARSHALER__CTOR, 2, 0);
+ pslILEmit->EmitLDLOCA(m_dwMngdMarshalerLocalNum);
+ pslILEmit->EmitLDLOC(dwTmpLocalNum);
+ pslILEmit->EmitCALL(METHOD__ASANY_MARSHALER__CTOR, 2, 0);
+}
+void ILAsAnyMarshalerBase::EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit)
+{
// nativeValue = marshaler.ConvertToNative(managedValue, flags);
- m_pcsMarshal->EmitLDLOCA(m_dwMarshalerLocalNum);
- EmitLoadManagedValue(m_pcsMarshal);
- m_pcsMarshal->EmitLDC(dwFlags);
- m_pcsMarshal->EmitCALL(METHOD__ASANY_MARSHALER__CONVERT_TO_NATIVE, 3, 1);
- EmitStoreNativeValue(m_pcsMarshal);
-
- //
- // unmarshal
- //
- if (IsOut(m_dwMarshalFlags))
- {
- // marshaler.ConvertToManaged(managedValue, nativeValue)
- m_pcsUnmarshal->EmitLDLOCA(m_dwMarshalerLocalNum);
- EmitLoadManagedValue(m_pcsUnmarshal);
- EmitLoadNativeValue(m_pcsUnmarshal);
- m_pcsUnmarshal->EmitCALL(METHOD__ASANY_MARSHALER__CONVERT_TO_MANAGED, 3, 0);
- }
+ EmitLoadMngdMarshalerAddr(pslILEmit);
+ EmitLoadManagedValue(pslILEmit);
+ pslILEmit->EmitLDC(GetAsAnyFlags());
+ pslILEmit->EmitCALL(METHOD__ASANY_MARSHALER__CONVERT_TO_NATIVE, 3, 1);
+ EmitStoreNativeValue(pslILEmit);
+}
- //
- // cleanup
- //
- EmitCleanupCLRToNativeTemp();
+void ILAsAnyMarshalerBase::EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit)
+{
+ // marshaler.ConvertToManaged(managedValue, nativeValue)
+ EmitLoadMngdMarshalerAddr(pslILEmit);
+ EmitLoadManagedValue(pslILEmit);
+ EmitLoadNativeValue(pslILEmit);
+ pslILEmit->EmitCALL(METHOD__ASANY_MARSHALER__CONVERT_TO_MANAGED, 3, 0);
}
+
bool ILAsAnyMarshalerBase::NeedsClearNative()
{
LIMITED_METHOD_CONTRACT;
STANDARD_VM_CONTRACT;
// marshaler.ClearNative(nativeHome)
- pslILEmit->EmitLDLOCA(m_dwMarshalerLocalNum);
+ EmitLoadMngdMarshalerAddr(pslILEmit);
EmitLoadNativeValue(pslILEmit);
pslILEmit->EmitCALL(METHOD__ASANY_MARSHALER__CLEAR_NATIVE, 2, 0);
}
}
}
-bool ILNativeArrayMarshaler::UsePinnedArraySpecialCase()
-{
- if (IsCLRToNative(m_dwMarshalFlags) && !IsByref(m_dwMarshalFlags) && (NULL == OleVariant::GetMarshalerForVarType(m_pargs->na.m_vt, TRUE)))
- {
- return true;
- }
-
- return false;
-}
-
void ILNativeArrayMarshaler::EmitCreateMngdMarshaler(ILCodeStream* pslILEmit)
{
STANDARD_VM_CONTRACT;
-
- if (UsePinnedArraySpecialCase())
- {
- return;
- }
m_dwMngdMarshalerLocalNum = pslILEmit->NewLocal(ELEMENT_TYPE_I);
pslILEmit->EmitCALL(METHOD__MNGD_NATIVE_ARRAY_MARSHALER__CREATE_MARSHALER, 3, 0);
}
+bool ILNativeArrayMarshaler::CanMarshalViaPinning()
+{
+ return IsCLRToNative(m_dwMarshalFlags) && !IsByref(m_dwMarshalFlags) && (NULL == OleVariant::GetMarshalerForVarType(m_pargs->na.m_vt, TRUE));
+}
-void ILNativeArrayMarshaler::EmitMarshalArgumentCLRToNative()
+void ILNativeArrayMarshaler::EmitMarshalViaPinning(ILCodeStream* pslILEmit)
{
CONTRACTL
{
}
CONTRACTL_END;
- if (UsePinnedArraySpecialCase())
- {
- //
- // Replicate ML_PINNEDISOMORPHICARRAY_C2N_EXPRESS behavior -- note that this
- // gives in/out semantics "for free" even if the app doesn't specify one or
- // the other. Since there is no enforcement of this, apps blithely depend
- // on it.
- //
+ //
+ // Replicate ML_PINNEDISOMORPHICARRAY_C2N_EXPRESS behavior -- note that this
+ // gives in/out semantics "for free" even if the app doesn't specify one or
+ // the other. Since there is no enforcement of this, apps blithely depend
+ // on it.
+ //
- EmitSetupSigAndDefaultHomesCLRToNative();
-
- LocalDesc managedType = GetManagedType();
- managedType.MakePinned();
-
- DWORD dwPinnedLocal = m_pcsMarshal->NewLocal(managedType);
- ILCodeLabel* pNullRefLabel = m_pcsMarshal->NewCodeLabel();
-
- m_pcsMarshal->EmitLoadNullPtr();
- EmitStoreNativeValue(m_pcsMarshal);
-
- EmitLoadManagedValue(m_pcsMarshal);
- m_pcsMarshal->EmitBRFALSE(pNullRefLabel);
-
- // COMPAT: We cannot generate the same code that the C# compiler generates for
- // a fixed() statement on an array since we need to provide a non-null value
- // for a 0-length array. For compat reasons, we need to preserve old behavior.
- // Additionally, we need to ensure that we do not pass non-null for a zero-length
- // array when interacting with GDI/GDI+ since they fail on null arrays but succeed
- // on 0-length arrays.
- EmitLoadManagedValue(m_pcsMarshal);
- m_pcsMarshal->EmitSTLOC(dwPinnedLocal);
- m_pcsMarshal->EmitLDLOC(dwPinnedLocal);
- m_pcsMarshal->EmitCONV_I();
- // Optimize marshalling by emitting the data ptr offset directly into the IL stream
- // instead of doing an FCall to recalulate it each time when possible.
- m_pcsMarshal->EmitLDC(ArrayBase::GetDataPtrOffset(m_pargs->m_pMarshalInfo->GetArrayElementTypeHandle().MakeSZArray().GetMethodTable()));
- m_pcsMarshal->EmitADD();
- EmitStoreNativeValue(m_pcsMarshal);
-
- if (g_pConfig->InteropLogArguments())
- {
- m_pslNDirect->EmitLogNativeArgument(m_pcsMarshal, dwPinnedLocal);
- }
+ LocalDesc managedType = GetManagedType();
+ managedType.MakePinned();
- m_pcsMarshal->EmitLabel(pNullRefLabel);
- }
- else
- {
- ILMngdMarshaler::EmitMarshalArgumentCLRToNative();
- }
+ DWORD dwPinnedLocal = pslILEmit->NewLocal(managedType);
+ ILCodeLabel* pNullRefLabel = pslILEmit->NewCodeLabel();
+
+ pslILEmit->EmitLoadNullPtr();
+ EmitStoreNativeValue(pslILEmit);
+
+ EmitLoadManagedValue(pslILEmit);
+ pslILEmit->EmitBRFALSE(pNullRefLabel);
+
+ // COMPAT: We cannot generate the same code that the C# compiler generates for
+ // a fixed() statement on an array since we need to provide a non-null value
+ // for a 0-length array. For compat reasons, we need to preserve old behavior.
+ // Additionally, we need to ensure that we do not pass non-null for a zero-length
+ // array when interacting with GDI/GDI+ since they fail on null arrays but succeed
+ // on 0-length arrays.
+ EmitLoadManagedValue(pslILEmit);
+ pslILEmit->EmitSTLOC(dwPinnedLocal);
+ pslILEmit->EmitLDLOC(dwPinnedLocal);
+ pslILEmit->EmitCONV_I();
+ // Optimize marshalling by emitting the data ptr offset directly into the IL stream
+ // instead of doing an FCall to recalulate it each time when possible.
+ pslILEmit->EmitLDC(ArrayBase::GetDataPtrOffset(m_pargs->m_pMarshalInfo->GetArrayElementTypeHandle().MakeSZArray().GetMethodTable()));
+ pslILEmit->EmitADD();
+ EmitStoreNativeValue(pslILEmit);
+
+ EmitLogNativeArgumentsIfNeeded(pslILEmit, dwPinnedLocal);
+
+ pslILEmit->EmitLabel(pNullRefLabel);
}
//
unsigned countParamIdx = mops.countParamIdx;
if (!IsCLRToNative(m_dwMarshalFlags))
{
- int lcidParamIdx = m_pslNDirect->GetLCIDParamIdx();
+ int lcidParamIdx = GetLCIDParamIndex();
if (lcidParamIdx >= 0 && (unsigned)lcidParamIdx <= countParamIdx)
{
pslILEmit->EmitCALL(pslILEmit->GetToken(GetClearNativeContentsMethod()), 3, 0);
}
-void ILNativeArrayMarshaler::EmitNewSavedSizeArgLocal()
+void ILNativeArrayMarshaler::EmitSetupArgumentForMarshalling(ILCodeStream* pslILEmit)
{
- STANDARD_VM_CONTRACT;
-
- _ASSERTE(m_dwSavedSizeArg == LOCAL_NUM_UNUSED);
- ILCodeStream *pcsSetup = m_pslNDirect->GetSetupCodeStream();
- m_dwSavedSizeArg = pcsSetup->NewLocal(ELEMENT_TYPE_I4);
- pcsSetup->EmitLDC(0);
- pcsSetup->EmitSTLOC(m_dwSavedSizeArg);
-}
-
-void ILNativeArrayMarshaler::EmitMarshalArgumentNativeToCLRByref()
-{
- STANDARD_VM_CONTRACT;
-
if (IsByref(m_dwMarshalFlags))
{
- EmitNewSavedSizeArgLocal();
+ EmitNewSavedSizeArgLocal(pslILEmit);
}
-
- ILMngdMarshaler::EmitMarshalArgumentNativeToCLRByref();
}
-void ILNativeArrayMarshaler::EmitMarshalArgumentCLRToNativeByref()
+void ILNativeArrayMarshaler::EmitNewSavedSizeArgLocal(ILCodeStream* pslILEmit)
{
STANDARD_VM_CONTRACT;
- if (IsByref(m_dwMarshalFlags))
- {
- EmitNewSavedSizeArgLocal();
- }
-
- ILMngdMarshaler::EmitMarshalArgumentCLRToNativeByref();
+ _ASSERTE(m_dwSavedSizeArg == LOCAL_NUM_UNUSED);
+ m_dwSavedSizeArg = pslILEmit->NewLocal(ELEMENT_TYPE_I4);
+ pslILEmit->EmitLDC(0);
+ pslILEmit->EmitSTLOC(m_dwSavedSizeArg);
}
-
#ifndef CROSSGEN_COMPILE
FCIMPL3(void, MngdNativeArrayMarshaler::CreateMarshaler, MngdNativeArrayMarshaler* pThis, MethodTable* pMT, UINT32 dwFlags)
{
STANDARD_VM_CONTRACT;
- if (!CanUsePinnedArray())
- {
- m_dwMngdMarshalerLocalNum = pslILEmit->NewLocal(ELEMENT_TYPE_I);
-
- pslILEmit->EmitLDC(sizeof(MngdHiddenLengthArrayMarshaler));
- pslILEmit->EmitLOCALLOC();
- pslILEmit->EmitSTLOC(m_dwMngdMarshalerLocalNum);
+ m_dwMngdMarshalerLocalNum = pslILEmit->NewLocal(ELEMENT_TYPE_I);
+
+ pslILEmit->EmitLDC(sizeof(MngdHiddenLengthArrayMarshaler));
+ pslILEmit->EmitLOCALLOC();
+ pslILEmit->EmitSTLOC(m_dwMngdMarshalerLocalNum);
- MethodTable *pElementMT = m_pargs->m_pMarshalInfo->GetArrayElementTypeHandle().GetMethodTable();
- pslILEmit->EmitLDLOC(m_dwMngdMarshalerLocalNum);
- pslILEmit->EmitLDTOKEN(pslILEmit->GetToken(pElementMT));
- pslILEmit->EmitCALL(METHOD__RT_TYPE_HANDLE__GETVALUEINTERNAL, 1, 1);
+ MethodTable *pElementMT = m_pargs->m_pMarshalInfo->GetArrayElementTypeHandle().GetMethodTable();
+ pslILEmit->EmitLDLOC(m_dwMngdMarshalerLocalNum);
+ pslILEmit->EmitLDTOKEN(pslILEmit->GetToken(pElementMT));
+ pslILEmit->EmitCALL(METHOD__RT_TYPE_HANDLE__GETVALUEINTERNAL, 1, 1);
- pslILEmit->EmitLDC(m_pargs->na.m_cbElementSize);
- pslILEmit->EmitLDC(m_pargs->na.m_vt);
+ pslILEmit->EmitLDC(m_pargs->na.m_cbElementSize);
+ pslILEmit->EmitLDC(m_pargs->na.m_vt);
- pslILEmit->EmitCALL(METHOD__MNGD_HIDDEN_LENGTH_ARRAY_MARSHALER__CREATE_MARSHALER, 4, 0);
- }
+ pslILEmit->EmitCALL(METHOD__MNGD_HIDDEN_LENGTH_ARRAY_MARSHALER__CREATE_MARSHALER, 4, 0);
}
-void ILHiddenLengthArrayMarshaler::EmitMarshalArgumentCLRToNative()
+void ILHiddenLengthArrayMarshaler::EmitMarshalViaPinning(ILCodeStream* pslILEmit)
{
- STANDARD_VM_CONTRACT;
-
- // If we can pin the array, then do that rather than marshaling it in a more heavy weight way
- // Otherwise, fall back to doing a full marshal
- if (CanUsePinnedArray())
- {
- EmitSetupSigAndDefaultHomesCLRToNative();
-
- LocalDesc managedType = GetManagedType();
- managedType.MakePinned();
- DWORD dwPinnedLocal = m_pcsMarshal->NewLocal(managedType);
+ LocalDesc managedType = GetManagedType();
+ managedType.MakePinned();
+ DWORD dwPinnedLocal = pslILEmit->NewLocal(managedType);
- ILCodeLabel* pMarshalDoneLabel = m_pcsMarshal->NewCodeLabel();
+ ILCodeLabel* pMarshalDoneLabel = pslILEmit->NewCodeLabel();
- // native = NULL
- m_pcsMarshal->EmitLoadNullPtr();
- EmitStoreNativeValue(m_pcsMarshal);
-
- // if (managed == null) goto MarshalDone
- EmitLoadManagedValue(m_pcsMarshal);
- m_pcsMarshal->EmitBRFALSE(pMarshalDoneLabel);
+ // native = NULL
+ pslILEmit->EmitLoadNullPtr();
+ EmitStoreNativeValue(pslILEmit);
- // pinnedLocal = managed;
- EmitLoadManagedValue(m_pcsMarshal);
- m_pcsMarshal->EmitSTLOC(dwPinnedLocal);
+ // if (managed == null) goto MarshalDone
+ EmitLoadManagedValue(pslILEmit);
+ pslILEmit->EmitBRFALSE(pMarshalDoneLabel);
- // native = pinnedLocal + dataOffset
+ // pinnedLocal = managed;
+ EmitLoadManagedValue(pslILEmit);
+ pslILEmit->EmitSTLOC(dwPinnedLocal);
- // COMPAT: We cannot generate the same code that the C# compiler generates for
- // a fixed() statement on an array since we need to provide a non-null value
- // for a 0-length array. For compat reasons, we need to preserve old behavior.
- EmitLoadManagedValue(m_pcsMarshal);
- m_pcsMarshal->EmitSTLOC(dwPinnedLocal);
- m_pcsMarshal->EmitLDLOC(dwPinnedLocal);
- m_pcsMarshal->EmitCONV_I();
- // Optimize marshalling by emitting the data ptr offset directly into the IL stream
- // instead of doing an FCall to recalulate it each time.
- m_pcsMarshal->EmitLDC(ArrayBase::GetDataPtrOffset(m_pargs->m_pMarshalInfo->GetArrayElementTypeHandle().MakeSZArray().GetMethodTable()));
- m_pcsMarshal->EmitADD();
- EmitStoreNativeValue(m_pcsMarshal);
+ // native = pinnedLocal + dataOffset
- if (g_pConfig->InteropLogArguments())
- {
- m_pslNDirect->EmitLogNativeArgument(m_pcsMarshal, dwPinnedLocal);
- }
+ // COMPAT: We cannot generate the same code that the C# compiler generates for
+ // a fixed() statement on an array since we need to provide a non-null value
+ // for a 0-length array. For compat reasons, we need to preserve old behavior.
+ EmitLoadManagedValue(pslILEmit);
+ pslILEmit->EmitSTLOC(dwPinnedLocal);
+ pslILEmit->EmitLDLOC(dwPinnedLocal);
+ pslILEmit->EmitCONV_I();
+ // Optimize marshalling by emitting the data ptr offset directly into the IL stream
+ // instead of doing an FCall to recalulate it each time.
+ pslILEmit->EmitLDC(ArrayBase::GetDataPtrOffset(m_pargs->m_pMarshalInfo->GetArrayElementTypeHandle().MakeSZArray().GetMethodTable()));
+ pslILEmit->EmitADD();
+ EmitStoreNativeValue(pslILEmit);
- // MarshalDone:
- m_pcsMarshal->EmitLabel(pMarshalDoneLabel);
- }
- else
- {
- ILMngdMarshaler::EmitMarshalArgumentCLRToNative();
- }
+ EmitLogNativeArgumentsIfNeeded(pslILEmit, dwPinnedLocal);
+ // MarshalDone:
+ pslILEmit->EmitLabel(pMarshalDoneLabel);
}
void ILHiddenLengthArrayMarshaler::EmitConvertSpaceNativeToCLR(ILCodeStream* pslILEmit)
{
STANDARD_VM_CONTRACT;
- if (!CanUsePinnedArray())
- {
- EmitLoadMngdMarshaler(pslILEmit);
- EmitLoadManagedHomeAddr(pslILEmit);
- EmitLoadNativeHomeAddr(pslILEmit);
- EmitLoadNativeArrayLength(pslILEmit);
-
- // MngdHiddenLengthArrayMarshaler::ConvertSpaceToManaged
- pslILEmit->EmitCALL(pslILEmit->GetToken(GetConvertSpaceToManagedMethod()), 4, 0);
- }
+ EmitLoadMngdMarshaler(pslILEmit);
+ EmitLoadManagedHomeAddr(pslILEmit);
+ EmitLoadNativeHomeAddr(pslILEmit);
+ EmitLoadNativeArrayLength(pslILEmit);
+
+ // MngdHiddenLengthArrayMarshaler::ConvertSpaceToManaged
+ pslILEmit->EmitCALL(pslILEmit->GetToken(GetConvertSpaceToManagedMethod()), 4, 0);
}
void ILHiddenLengthArrayMarshaler::EmitConvertSpaceCLRToNative(ILCodeStream* pslILEmit)
{
if (IsByref(m_dwMarshalFlags) || IsRetval(m_dwMarshalFlags) || IsOut(m_dwMarshalFlags))
{
- ILCodeLabel *pSkipGetLengthLabel = m_pcsMarshal->NewCodeLabel();
+ ILCodeLabel *pSkipGetLengthLabel = pslILEmit->NewCodeLabel();
// nativeLen = 0
pslILEmit->EmitLDC(0);
}
}
- if (!CanUsePinnedArray())
- {
- ILMngdMarshaler::EmitConvertSpaceCLRToNative(pslILEmit);
- }
+ ILMngdMarshaler::EmitConvertSpaceCLRToNative(pslILEmit);
}
void ILHiddenLengthArrayMarshaler::EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit)
{
STANDARD_VM_CONTRACT;
- if (!CanUsePinnedArray())
+ if (m_pargs->na.m_vt == VTHACK_REDIRECTEDTYPE &&
+ (m_pargs->na.m_redirectedTypeIndex == WinMDAdapter::RedirectedTypeIndex_System_Uri ||
+ m_pargs->na.m_redirectedTypeIndex == WinMDAdapter::RedirectedTypeIndex_System_Collections_Specialized_NotifyCollectionChangedEventArgs ||
+ m_pargs->na.m_redirectedTypeIndex == WinMDAdapter::RedirectedTypeIndex_System_ComponentModel_PropertyChangedEventArgs))
{
- if (m_pargs->na.m_vt == VTHACK_REDIRECTEDTYPE &&
- (m_pargs->na.m_redirectedTypeIndex == WinMDAdapter::RedirectedTypeIndex_System_Uri ||
- m_pargs->na.m_redirectedTypeIndex == WinMDAdapter::RedirectedTypeIndex_System_Collections_Specialized_NotifyCollectionChangedEventArgs ||
- m_pargs->na.m_redirectedTypeIndex == WinMDAdapter::RedirectedTypeIndex_System_ComponentModel_PropertyChangedEventArgs))
- {
- // System.Uri/NotifyCollectionChangedEventArgs don't live in mscorlib so there's no marshaling helper to call - inline the loop
- DWORD dwLoopCounterLocalNum = pslILEmit->NewLocal(ELEMENT_TYPE_I4);
- DWORD dwNativePtrLocalNum = pslILEmit->NewLocal(ELEMENT_TYPE_I);
- ILCodeLabel *pConditionLabel = pslILEmit->NewCodeLabel();
- ILCodeLabel *pLoopBodyLabel = pslILEmit->NewCodeLabel();
+ // System.Uri/NotifyCollectionChangedEventArgs don't live in mscorlib so there's no marshaling helper to call - inline the loop
+ DWORD dwLoopCounterLocalNum = pslILEmit->NewLocal(ELEMENT_TYPE_I4);
+ DWORD dwNativePtrLocalNum = pslILEmit->NewLocal(ELEMENT_TYPE_I);
+ ILCodeLabel *pConditionLabel = pslILEmit->NewCodeLabel();
+ ILCodeLabel *pLoopBodyLabel = pslILEmit->NewCodeLabel();
- // for (IntPtr ptr = pNative, int i = 0; ...
- pslILEmit->EmitLDC(0);
- pslILEmit->EmitSTLOC(dwLoopCounterLocalNum);
- EmitLoadNativeValue(pslILEmit);
- pslILEmit->EmitSTLOC(dwNativePtrLocalNum);
- pslILEmit->EmitBR(pConditionLabel);
-
- // *ptr = EmitConvertCLR*ToWinRT*(pManaged[i]);
- pslILEmit->EmitLabel(pLoopBodyLabel);
- pslILEmit->EmitLDLOC(dwNativePtrLocalNum);
- EmitLoadManagedValue(pslILEmit);
- pslILEmit->EmitLDLOC(dwLoopCounterLocalNum);
- pslILEmit->EmitLDELEM_REF();
+ // for (IntPtr ptr = pNative, int i = 0; ...
+ pslILEmit->EmitLDC(0);
+ pslILEmit->EmitSTLOC(dwLoopCounterLocalNum);
+ EmitLoadNativeValue(pslILEmit);
+ pslILEmit->EmitSTLOC(dwNativePtrLocalNum);
+ pslILEmit->EmitBR(pConditionLabel);
- switch (m_pargs->na.m_redirectedTypeIndex)
- {
- case WinMDAdapter::RedirectedTypeIndex_System_Uri:
- ILUriMarshaler::EmitConvertCLRUriToWinRTUri(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator());
- break;
+ // *ptr = EmitConvertCLR*ToWinRT*(pManaged[i]);
+ pslILEmit->EmitLabel(pLoopBodyLabel);
+ pslILEmit->EmitLDLOC(dwNativePtrLocalNum);
+ EmitLoadManagedValue(pslILEmit);
+ pslILEmit->EmitLDLOC(dwLoopCounterLocalNum);
+ pslILEmit->EmitLDELEM_REF();
- case WinMDAdapter::RedirectedTypeIndex_System_Collections_Specialized_NotifyCollectionChangedEventArgs:
- ILNCCEventArgsMarshaler::EmitConvertCLREventArgsToWinRTEventArgs(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator());
- break;
+ switch (m_pargs->na.m_redirectedTypeIndex)
+ {
+ case WinMDAdapter::RedirectedTypeIndex_System_Uri:
+ ILUriMarshaler::EmitConvertCLRUriToWinRTUri(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator());
+ break;
- case WinMDAdapter::RedirectedTypeIndex_System_ComponentModel_PropertyChangedEventArgs:
- ILPCEventArgsMarshaler::EmitConvertCLREventArgsToWinRTEventArgs(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator());
- break;
+ case WinMDAdapter::RedirectedTypeIndex_System_Collections_Specialized_NotifyCollectionChangedEventArgs:
+ ILNCCEventArgsMarshaler::EmitConvertCLREventArgsToWinRTEventArgs(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator());
+ break;
- default: UNREACHABLE();
- }
+ case WinMDAdapter::RedirectedTypeIndex_System_ComponentModel_PropertyChangedEventArgs:
+ ILPCEventArgsMarshaler::EmitConvertCLREventArgsToWinRTEventArgs(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator());
+ break;
- pslILEmit->EmitSTIND_I();
-
- // ... i++, ptr += IntPtr.Size ...
- pslILEmit->EmitLDLOC(dwLoopCounterLocalNum);
- pslILEmit->EmitLDC(1);
- pslILEmit->EmitADD();
- pslILEmit->EmitSTLOC(dwLoopCounterLocalNum);
- pslILEmit->EmitLDLOC(dwNativePtrLocalNum);
- pslILEmit->EmitLDC(sizeof(LPVOID));
- pslILEmit->EmitADD();
- pslILEmit->EmitSTLOC(dwNativePtrLocalNum);
-
- // ... i < pManaged.Length; ...
- pslILEmit->EmitLabel(pConditionLabel);
- pslILEmit->EmitLDLOC(dwLoopCounterLocalNum);
- EmitLoadNativeArrayLength(pslILEmit);
- pslILEmit->EmitBLT(pLoopBodyLabel);
- }
- else
- {
- ILMngdMarshaler::EmitConvertContentsCLRToNative(pslILEmit);
+ default: UNREACHABLE();
}
+
+ pslILEmit->EmitSTIND_I();
+
+ // ... i++, ptr += IntPtr.Size ...
+ pslILEmit->EmitLDLOC(dwLoopCounterLocalNum);
+ pslILEmit->EmitLDC(1);
+ pslILEmit->EmitADD();
+ pslILEmit->EmitSTLOC(dwLoopCounterLocalNum);
+ pslILEmit->EmitLDLOC(dwNativePtrLocalNum);
+ pslILEmit->EmitLDC(sizeof(LPVOID));
+ pslILEmit->EmitADD();
+ pslILEmit->EmitSTLOC(dwNativePtrLocalNum);
+
+ // ... i < pManaged.Length; ...
+ pslILEmit->EmitLabel(pConditionLabel);
+ pslILEmit->EmitLDLOC(dwLoopCounterLocalNum);
+ EmitLoadNativeArrayLength(pslILEmit);
+ pslILEmit->EmitBLT(pLoopBodyLabel);
+ }
+ else
+ {
+ ILMngdMarshaler::EmitConvertContentsCLRToNative(pslILEmit);
}
}
{
STANDARD_VM_CONTRACT;
- if (!CanUsePinnedArray())
+ if (m_pargs->na.m_vt == VTHACK_REDIRECTEDTYPE &&
+ (m_pargs->na.m_redirectedTypeIndex == WinMDAdapter::RedirectedTypeIndex_System_Uri ||
+ m_pargs->na.m_redirectedTypeIndex == WinMDAdapter::RedirectedTypeIndex_System_Collections_Specialized_NotifyCollectionChangedEventArgs ||
+ m_pargs->na.m_redirectedTypeIndex == WinMDAdapter::RedirectedTypeIndex_System_ComponentModel_PropertyChangedEventArgs))
{
- if (m_pargs->na.m_vt == VTHACK_REDIRECTEDTYPE &&
- (m_pargs->na.m_redirectedTypeIndex == WinMDAdapter::RedirectedTypeIndex_System_Uri ||
- m_pargs->na.m_redirectedTypeIndex == WinMDAdapter::RedirectedTypeIndex_System_Collections_Specialized_NotifyCollectionChangedEventArgs ||
- m_pargs->na.m_redirectedTypeIndex == WinMDAdapter::RedirectedTypeIndex_System_ComponentModel_PropertyChangedEventArgs))
- {
- // System.Uri/NotifyCollectionChangedEventArgs don't live in mscorlib so there's no marshaling helper to call - inline the loop
- DWORD dwLoopCounterLocalNum = pslILEmit->NewLocal(ELEMENT_TYPE_I4);
- DWORD dwNativePtrLocalNum = pslILEmit->NewLocal(ELEMENT_TYPE_I);
- ILCodeLabel *pConditionLabel = pslILEmit->NewCodeLabel();
- ILCodeLabel *pLoopBodyLabel = pslILEmit->NewCodeLabel();
+ // System.Uri/NotifyCollectionChangedEventArgs don't live in mscorlib so there's no marshaling helper to call - inline the loop
+ DWORD dwLoopCounterLocalNum = pslILEmit->NewLocal(ELEMENT_TYPE_I4);
+ DWORD dwNativePtrLocalNum = pslILEmit->NewLocal(ELEMENT_TYPE_I);
+ ILCodeLabel *pConditionLabel = pslILEmit->NewCodeLabel();
+ ILCodeLabel *pLoopBodyLabel = pslILEmit->NewCodeLabel();
- // for (IntPtr ptr = pNative, int i = 0; ...
- pslILEmit->EmitLDC(0);
- pslILEmit->EmitSTLOC(dwLoopCounterLocalNum);
- EmitLoadNativeValue(pslILEmit);
- pslILEmit->EmitSTLOC(dwNativePtrLocalNum);
- pslILEmit->EmitBR(pConditionLabel);
+ // for (IntPtr ptr = pNative, int i = 0; ...
+ pslILEmit->EmitLDC(0);
+ pslILEmit->EmitSTLOC(dwLoopCounterLocalNum);
+ EmitLoadNativeValue(pslILEmit);
+ pslILEmit->EmitSTLOC(dwNativePtrLocalNum);
+ pslILEmit->EmitBR(pConditionLabel);
- // pManaged[i] = EmitConvertWinRT*ToCLR*(*ptr);
- pslILEmit->EmitLabel(pLoopBodyLabel);
- EmitLoadManagedValue(pslILEmit);
- pslILEmit->EmitLDLOC(dwLoopCounterLocalNum);
- pslILEmit->EmitLDLOC(dwNativePtrLocalNum);
- pslILEmit->EmitLDIND_I();
+ // pManaged[i] = EmitConvertWinRT*ToCLR*(*ptr);
+ pslILEmit->EmitLabel(pLoopBodyLabel);
+ EmitLoadManagedValue(pslILEmit);
+ pslILEmit->EmitLDLOC(dwLoopCounterLocalNum);
+ pslILEmit->EmitLDLOC(dwNativePtrLocalNum);
+ pslILEmit->EmitLDIND_I();
- switch (m_pargs->na.m_redirectedTypeIndex)
- {
- case WinMDAdapter::RedirectedTypeIndex_System_Uri:
- ILUriMarshaler::EmitConvertWinRTUriToCLRUri(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator());
- break;
+ switch (m_pargs->na.m_redirectedTypeIndex)
+ {
+ case WinMDAdapter::RedirectedTypeIndex_System_Uri:
+ ILUriMarshaler::EmitConvertWinRTUriToCLRUri(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator());
+ break;
- case WinMDAdapter::RedirectedTypeIndex_System_Collections_Specialized_NotifyCollectionChangedEventArgs:
- ILNCCEventArgsMarshaler::EmitConvertWinRTEventArgsToCLREventArgs(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator());
- break;
+ case WinMDAdapter::RedirectedTypeIndex_System_Collections_Specialized_NotifyCollectionChangedEventArgs:
+ ILNCCEventArgsMarshaler::EmitConvertWinRTEventArgsToCLREventArgs(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator());
+ break;
- case WinMDAdapter::RedirectedTypeIndex_System_ComponentModel_PropertyChangedEventArgs:
- ILPCEventArgsMarshaler::EmitConvertWinRTEventArgsToCLREventArgs(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator());
- break;
+ case WinMDAdapter::RedirectedTypeIndex_System_ComponentModel_PropertyChangedEventArgs:
+ ILPCEventArgsMarshaler::EmitConvertWinRTEventArgsToCLREventArgs(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator());
+ break;
- default: UNREACHABLE();
- }
-
- pslILEmit->EmitSTELEM_REF();
-
- // ... i++, ptr += IntPtr.Size)
- pslILEmit->EmitLDLOC(dwLoopCounterLocalNum);
- pslILEmit->EmitLDC(1);
- pslILEmit->EmitADD();
- pslILEmit->EmitSTLOC(dwLoopCounterLocalNum);
- pslILEmit->EmitLDLOC(dwNativePtrLocalNum);
- pslILEmit->EmitLDC(sizeof(LPVOID));
- pslILEmit->EmitADD();
- pslILEmit->EmitSTLOC(dwNativePtrLocalNum);
-
- // ... i < pManaged.Length; ...
- pslILEmit->EmitLabel(pConditionLabel);
- pslILEmit->EmitLDLOC(dwLoopCounterLocalNum);
- EmitLoadNativeArrayLength(pslILEmit);
- pslILEmit->EmitBLT(pLoopBodyLabel);
- }
- else
- {
- ILMngdMarshaler::EmitConvertContentsNativeToCLR(pslILEmit);
+ default: UNREACHABLE();
}
+
+ pslILEmit->EmitSTELEM_REF();
+
+ // ... i++, ptr += IntPtr.Size)
+ pslILEmit->EmitLDLOC(dwLoopCounterLocalNum);
+ pslILEmit->EmitLDC(1);
+ pslILEmit->EmitADD();
+ pslILEmit->EmitSTLOC(dwLoopCounterLocalNum);
+ pslILEmit->EmitLDLOC(dwNativePtrLocalNum);
+ pslILEmit->EmitLDC(sizeof(LPVOID));
+ pslILEmit->EmitADD();
+ pslILEmit->EmitSTLOC(dwNativePtrLocalNum);
+
+ // ... i < pManaged.Length; ...
+ pslILEmit->EmitLabel(pConditionLabel);
+ pslILEmit->EmitLDLOC(dwLoopCounterLocalNum);
+ EmitLoadNativeArrayLength(pslILEmit);
+ pslILEmit->EmitBLT(pLoopBodyLabel);
+ }
+ else
+ {
+ ILMngdMarshaler::EmitConvertContentsNativeToCLR(pslILEmit);
}
}
EmitClearNativeContents(pslILEmit);
- if (!CanUsePinnedArray())
- {
- EmitLoadNativeValue(pslILEmit);
- pslILEmit->EmitCALL(pslILEmit->GetToken(GetClearNativeMethod()), 1, 0);
- }
+ EmitLoadNativeValue(pslILEmit);
+ pslILEmit->EmitCALL(pslILEmit->GetToken(GetClearNativeMethod()), 1, 0);
}
void ILHiddenLengthArrayMarshaler::EmitClearNativeContents(ILCodeStream* pslILEmit)
{
STANDARD_VM_CONTRACT;
- if (!CanUsePinnedArray())
+ MethodDesc *pMD = GetClearNativeContentsMethod();
+ if (pMD != NULL)
{
- MethodDesc *pMD = GetClearNativeContentsMethod();
- if (pMD != NULL)
- {
- MetaSig sig(pMD);
- UINT numArgs = sig.NumFixedArgs();
-
- if (numArgs == 3)
- {
- EmitLoadMngdMarshaler(pslILEmit);
- }
- else
- {
- _ASSERTE(numArgs == 2);
- }
+ MetaSig sig(pMD);
+ UINT numArgs = sig.NumFixedArgs();
- EmitLoadNativeHomeAddr(pslILEmit);
- EmitLoadNativeArrayLength(pslILEmit);
- pslILEmit->EmitCALL(pslILEmit->GetToken(pMD), numArgs, 0);
+ if (numArgs == 3)
+ {
+ EmitLoadMngdMarshaler(pslILEmit);
}
+ else
+ {
+ _ASSERTE(numArgs == 2);
+ }
+
+ EmitLoadNativeHomeAddr(pslILEmit);
+ EmitLoadNativeArrayLength(pslILEmit);
+ pslILEmit->EmitCALL(pslILEmit->GetToken(pMD), numArgs, 0);
}
}
// Determine if we can simply pin the managed array, rather than doing a full marshal
-bool ILHiddenLengthArrayMarshaler::CanUsePinnedArray()
+bool ILHiddenLengthArrayMarshaler::CanMarshalViaPinning()
{
STANDARD_VM_CONTRACT;
void InitHome(MarshalHomeType homeType, DWORD dwHomeIndex)
{
LIMITED_METHOD_CONTRACT;
+
m_homeType = homeType;
m_dwHomeIndex = dwHomeIndex;
}
#endif // _DEBUG
OverrideProcArgs* m_pargs;
- NDirectStubLinker* m_pslNDirect;
- ILCodeStream* m_pcsMarshal;
- ILCodeStream* m_pcsUnmarshal;
UINT m_argidx;
-
DWORD m_dwMarshalFlags;
+ DWORD m_dwMngdMarshalerLocalNum;
+private:
+ ILCodeStream* m_pcsMarshal;
+ ILCodeStream* m_pcsUnmarshal;
ILStubMarshalHome m_nativeHome;
ILStubMarshalHome m_managedHome;
-
- DWORD m_dwMngdMarshalerLocalNum;
+ NDirectStubLinker* m_pslNDirect;
public:
m_pslNDirect = pslNDirect;
}
+private:
void Init(ILCodeStream* pcsMarshal,
ILCodeStream* pcsUnmarshal,
UINT argidx,
m_nativeHome.EmitStoreHomeAddr(pslILEmit);
}
+ void EmitLogNativeArgumentsIfNeeded(ILCodeStream* pslILEmit, DWORD dwPinnedLocal)
+ {
+ if (g_pConfig->InteropLogArguments())
+ {
+ m_pslNDirect->EmitLogNativeArgument(pslILEmit, dwPinnedLocal);
+ }
+ }
+
public:
virtual bool SupportsArgumentMarshal(DWORD dwMarshalFlags, UINT* pErrorResID)
// before we were able to marshal them. Therefore this must not happen within the try block so we don't try
// to use marshalers that have not been initialized. Potentially leaking unmanaged resources is by-design and
// there's not much we can do about it (we cannot do cleanup if we cannot create the marshaler).
- EmitCreateMngdMarshaler(m_pslNDirect->GetSetupCodeStream());
+ // Some marshalers have a managed marshaler for the general path but can pin on the fast path.
+ // If we're in a scenario where this marshaler can pin on a by-value managed->native call,
+ // we know that we don't need a managed marshaler since we will just pin.
+ if (!CanMarshalViaPinning())
+ {
+ EmitCreateMngdMarshaler(m_pslNDirect->GetSetupCodeStream());
+ }
+
+ EmitSetupArgumentForMarshalling(m_pslNDirect->GetSetupCodeStream());
if (IsCLRToNative(dwMarshalFlags))
{
CONTRACTL_END;
Init(pcsMarshal, pcsUnmarshal, hiddenArgIndex, dwMarshalFlags, pargs);
- EmitCreateMngdMarshaler(m_pslNDirect->GetSetupCodeStream());
+
+ if (!CanMarshalViaPinning())
+ {
+ EmitCreateMngdMarshaler(m_pslNDirect->GetSetupCodeStream());
+ }
+
+ EmitSetupArgumentForMarshalling(m_pslNDirect->GetSetupCodeStream());
// Create a local to be the home of the length parameter
DWORD dwManagedLocalHome = m_pcsMarshal->NewLocal(GetManagedType());
#endif // FEATURE_COMINTEROP
- virtual void EmitSetupArgument(ILCodeStream* pslILEmit)
+ void EmitSetupArgumentForDispatch(ILCodeStream* pslILEmit)
{
STANDARD_VM_CONTRACT;
}
}
- virtual void EmitMarshalReturnValue(
+ void EmitMarshalReturnValue(
ILCodeStream* pcsMarshal,
ILCodeStream* pcsUnmarshal,
ILCodeStream* pcsDispatch,
LIMITED_METHOD_CONTRACT;
}
- virtual void EmitLoadMngdMarshaler(ILCodeStream* pslILEmit)
+ void EmitLoadMngdMarshaler(ILCodeStream* pslILEmit)
{
CONTRACTL
{
pslILEmit->EmitLDLOC(m_dwMngdMarshalerLocalNum);
}
+ void EmitLoadMngdMarshalerAddr(ILCodeStream* pslILEmit)
+ {
+ CONTRACTL
+ {
+ THROWS;
+ GC_TRIGGERS;
+ MODE_ANY;
+ }
+ CONTRACTL_END;
+
+ CONSISTENCY_CHECK((DWORD)-1 != m_dwMngdMarshalerLocalNum);
+ pslILEmit->EmitLDLOCA(m_dwMngdMarshalerLocalNum);
+ }
+
+ void EmitLoadCleanupWorkList(ILCodeStream* pslILEmit)
+ {
+ m_pslNDirect->LoadCleanupWorkList(pslILEmit);
+ }
+
+ int GetLCIDParamIndex()
+ {
+ return m_pslNDirect->GetLCIDParamIdx();
+ }
+
void EmitSetupSigAndDefaultHomesCLRToNative()
{
CONTRACTL
}
}
- virtual void EmitMarshalArgumentCLRToNative()
+ void EmitMarshalArgumentCLRToNative()
{
CONTRACTL
{
}
CONTRACTL_END;
- //
- // marshal
- //
- if (IsIn(m_dwMarshalFlags))
+ if (CanMarshalViaPinning())
{
- EmitConvertSpaceAndContentsCLRToNativeTemp(m_pcsMarshal);
+ // If we can marshal via pinning, all we need to do to marshal is pin.
+ EmitMarshalViaPinning(m_pcsMarshal);
}
else
{
- EmitConvertSpaceCLRToNativeTemp(m_pcsMarshal);
- }
+ //
+ // marshal
+ //
+ if (IsIn(m_dwMarshalFlags) || AlwaysConvertByValContentsCLRToNative())
+ {
+ EmitConvertSpaceAndContentsCLRToNativeTemp(m_pcsMarshal);
+ }
+ else
+ {
+ EmitConvertSpaceCLRToNativeTemp(m_pcsMarshal);
+ }
- //
- // unmarshal
- //
- if (IsOut(m_dwMarshalFlags))
- {
- if (IsIn(m_dwMarshalFlags))
+ //
+ // unmarshal
+ //
+ if (IsOut(m_dwMarshalFlags))
{
- EmitClearCLRContents(m_pcsUnmarshal);
+ if (IsIn(m_dwMarshalFlags))
+ {
+ EmitClearCLRContents(m_pcsUnmarshal);
+ }
+ EmitConvertContentsNativeToCLR(m_pcsUnmarshal);
}
- EmitConvertContentsNativeToCLR(m_pcsUnmarshal);
+
+ EmitCleanupCLRToNativeTemp();
}
-
- EmitCleanupCLRToNativeTemp();
}
void EmitSetupSigAndDefaultHomesCLRToNativeByref(bool fBlittable = false)
}
}
+ void EmitMarshalArgumentAddressCLRToNative()
+ {
+ EmitLoadManagedHomeAddr(m_pcsMarshal);
+ EmitStoreNativeHomeAddr(m_pcsMarshal);
+ }
+
+ void EmitMarshalArgumentAddressNativeToCLR()
+ {
+ EmitLoadNativeHomeAddr(m_pcsMarshal);
+ EmitStoreManagedHomeAddr(m_pcsMarshal);
+ }
+
// Emits cleanup code that runs only if an exception is thrown during execution of an IL stub (its try
// block to be precise). The goal is to roll back allocations of native resources that may have already
// happened to prevent leaks, and also clear output arguments to prevent passing out invalid data - most
}
}
- virtual void EmitMarshalArgumentNativeToCLR()
+ void EmitMarshalArgumentNativeToCLR()
{
CONTRACTL
{
virtual LocalDesc GetNativeType() = 0;
virtual LocalDesc GetManagedType() = 0;
+ virtual void EmitSetupArgumentForMarshalling(ILCodeStream* pslILEmit)
+ {
+ LIMITED_METHOD_CONTRACT;
+ }
+
//
// Native-to-CLR
//
EmitConvertSpaceCLRToNative(pslILEmit);
EmitConvertContentsCLRToNative(pslILEmit);
}
-
+
+ // Emits marshalling code to allocate space and convert a value from a CLR value to a native value.
+ // Usable in situations where temporary (i.e. pinned or stack-allocated) space is usable.
+ // For marshalling scenarios that require heap-allocated space, call EmitConvertSpaceAndContentsCLRToNative.
virtual void EmitConvertSpaceAndContentsCLRToNativeTemp(ILCodeStream* pslILEmit)
{
WRAPPER_NO_CONTRACT;
LIMITED_METHOD_CONTRACT;
}
+ virtual bool CanMarshalViaPinning()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return false;
+ }
+
+ virtual void EmitMarshalViaPinning(ILCodeStream* pslILEmit)
+ {
+ LIMITED_METHOD_CONTRACT;
+ }
+
virtual void EmitReInitNative(ILCodeStream* pslILEmit)
{
STANDARD_VM_CONTRACT;
EmitStoreNativeValue(pslILEmit);
}
- virtual bool IsManagedPassedByRef()
+ bool IsManagedPassedByRef()
{
LIMITED_METHOD_CONTRACT;
return IsByref(m_dwMarshalFlags);
void EmitInterfaceClearNative(ILCodeStream* pslILEmit);
+ virtual bool AlwaysConvertByValContentsCLRToNative()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return false;
+ }
+
public:
+
+ // Extension point to allow a marshaler to conditionally override all of the ILMarshaler logic with its own or block marshalling when marshalling an argument.
+ // See MarshalInfo::GetArgumentOverrideProc for the implementation.
static MarshalerOverrideStatus ArgumentOverride(NDirectStubLinker* psl,
BOOL byref,
BOOL fin,
return HANDLEASNORMAL;
}
+ // Extension point to allow a marshaler to conditionally override all of the ILMarshaler logic with its own or block marshalling when marshalling a return value.
+ // See MarshalInfo::GetReturnOverrideProc for the implementation.
static MarshalerOverrideStatus ReturnOverride(NDirectStubLinker* psl,
BOOL fManagedToNative,
BOOL fHresultSwap,
class ILCopyMarshalerBase : public ILMarshaler
{
- virtual LocalDesc GetManagedType()
+ LocalDesc GetManagedType() override
{
WRAPPER_NO_CONTRACT;
return GetNativeType();
}
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit)
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override
{
STANDARD_VM_CONTRACT;
EmitStoreNativeValue(pslILEmit);
}
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit)
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override
{
STANDARD_VM_CONTRACT;
// This method was changed to pin instead of copy in Dev10 in order
// to match the original ML behavior.
//
- virtual void EmitMarshalArgumentCLRToNativeByref()
+ void EmitMarshalArgumentCLRToNativeByref() override
{
CONTRACTL
{
//
// marshal
//
- EmitLoadManagedHomeAddr(m_pcsMarshal);
- EmitStoreNativeHomeAddr(m_pcsMarshal);
-
+ EmitMarshalArgumentAddressCLRToNative();
+
//
// no unmarshaling is necessary since we directly passed the pinned byref to native,
// the argument is therefore automatically in/out
// need to pin the pointer - if it is pointing to GC heap, it must have been
// pinned on the way to unmanaged.
//
- virtual void EmitMarshalArgumentNativeToCLRByref()
+ void EmitMarshalArgumentNativeToCLRByref() override
{
CONTRACTL
{
//
// marshal
//
- EmitLoadNativeHomeAddr(m_pcsMarshal);
- EmitStoreManagedHomeAddr(m_pcsMarshal);
+ EmitMarshalArgumentAddressNativeToCLR();
//
// no unmarshaling is necessary since we directly passed the pointer to managed
};
protected:
- virtual LocalDesc GetNativeType();
- virtual LocalDesc GetManagedType();
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit);
+ LocalDesc GetNativeType() override;
+ LocalDesc GetManagedType() override;
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override;
};
class ILReflectionObjectMarshaler : public ILMarshaler
};
protected:
- virtual LocalDesc GetManagedType();
- virtual LocalDesc GetNativeType();
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit);
- virtual BinderFieldID GetStructureFieldID() {LIMITED_METHOD_CONTRACT; return (BinderFieldID)0;}
+ LocalDesc GetManagedType() override;
+ LocalDesc GetNativeType() override;
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override;
+ virtual BinderFieldID GetStructureFieldID() { LIMITED_METHOD_CONTRACT; return (BinderFieldID)0; }
virtual BinderFieldID GetObjectFieldID() = 0;
virtual BinderClassID GetManagedTypeBinderID() = 0;
};
class ILRuntimeTypeHandleMarshaler : public ILReflectionObjectMarshaler
{
protected:
- virtual BinderFieldID GetStructureFieldID() { LIMITED_METHOD_CONTRACT; return FIELD__RT_TYPE_HANDLE__M_TYPE; }
- virtual BinderFieldID GetObjectFieldID() { LIMITED_METHOD_CONTRACT; return FIELD__CLASS__TYPEHANDLE; }
- virtual BinderClassID GetManagedTypeBinderID() { LIMITED_METHOD_CONTRACT; return CLASS__RT_TYPE_HANDLE; }
+ BinderFieldID GetStructureFieldID() override { LIMITED_METHOD_CONTRACT; return FIELD__RT_TYPE_HANDLE__M_TYPE; }
+ BinderFieldID GetObjectFieldID() override { LIMITED_METHOD_CONTRACT; return FIELD__CLASS__TYPEHANDLE; }
+ BinderClassID GetManagedTypeBinderID() override { LIMITED_METHOD_CONTRACT; return CLASS__RT_TYPE_HANDLE; }
};
class ILRuntimeMethodHandleMarshaler : public ILReflectionObjectMarshaler
{
protected:
- virtual BinderFieldID GetStructureFieldID() { LIMITED_METHOD_CONTRACT; return FIELD__METHOD_HANDLE__METHOD; }
- virtual BinderFieldID GetObjectFieldID() { LIMITED_METHOD_CONTRACT; return FIELD__STUBMETHODINFO__HANDLE; }
- virtual BinderClassID GetManagedTypeBinderID() { LIMITED_METHOD_CONTRACT; return CLASS__METHOD_HANDLE; }
+ BinderFieldID GetStructureFieldID() override { LIMITED_METHOD_CONTRACT; return FIELD__METHOD_HANDLE__METHOD; }
+ BinderFieldID GetObjectFieldID() override { LIMITED_METHOD_CONTRACT; return FIELD__STUBMETHODINFO__HANDLE; }
+ BinderClassID GetManagedTypeBinderID() override { LIMITED_METHOD_CONTRACT; return CLASS__METHOD_HANDLE; }
};
class ILRuntimeFieldHandleMarshaler : public ILReflectionObjectMarshaler
{
protected:
- virtual BinderFieldID GetStructureFieldID() { LIMITED_METHOD_CONTRACT; return FIELD__FIELD_HANDLE__M_FIELD; }
- virtual BinderFieldID GetObjectFieldID() { LIMITED_METHOD_CONTRACT; return FIELD__RT_FIELD_INFO__HANDLE; }
- virtual BinderClassID GetManagedTypeBinderID() { LIMITED_METHOD_CONTRACT; return CLASS__FIELD_HANDLE; }
+ BinderFieldID GetStructureFieldID() override { LIMITED_METHOD_CONTRACT; return FIELD__FIELD_HANDLE__M_FIELD; }
+ BinderFieldID GetObjectFieldID() override { LIMITED_METHOD_CONTRACT; return FIELD__RT_FIELD_INFO__HANDLE; }
+ BinderClassID GetManagedTypeBinderID() override { LIMITED_METHOD_CONTRACT; return CLASS__FIELD_HANDLE; }
};
class ILBoolMarshaler : public ILMarshaler
virtual int GetNativeFalseValue() = 0;
protected:
- virtual LocalDesc GetNativeType();
- virtual LocalDesc GetManagedType();
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit);
+ LocalDesc GetNativeType() override;
+ LocalDesc GetManagedType() override;
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override;
};
class ILWinBoolMarshaler : public ILBoolMarshaler
};
protected:
- virtual CorElementType GetNativeBoolElementType()
+ CorElementType GetNativeBoolElementType() override
{
LIMITED_METHOD_CONTRACT;
return ELEMENT_TYPE_I4;
}
- virtual int GetNativeTrueValue()
+ int GetNativeTrueValue() override
{
LIMITED_METHOD_CONTRACT;
return 1;
}
- virtual int GetNativeFalseValue()
+ int GetNativeFalseValue() override
{
LIMITED_METHOD_CONTRACT;
return 0;
};
protected:
- virtual CorElementType GetNativeBoolElementType()
+ CorElementType GetNativeBoolElementType() override
{
LIMITED_METHOD_CONTRACT;
return ELEMENT_TYPE_I1;
}
- virtual int GetNativeTrueValue()
+ int GetNativeTrueValue() override
{
LIMITED_METHOD_CONTRACT;
return 1;
}
- virtual int GetNativeFalseValue()
+ int GetNativeFalseValue() override
{
LIMITED_METHOD_CONTRACT;
return 0;
};
protected:
- virtual CorElementType GetNativeBoolElementType()
+ CorElementType GetNativeBoolElementType() override
{
LIMITED_METHOD_CONTRACT;
return ELEMENT_TYPE_I2;
}
- virtual int GetNativeTrueValue()
+ int GetNativeTrueValue() override
{
LIMITED_METHOD_CONTRACT;
return VARIANT_TRUE;
}
- virtual int GetNativeFalseValue()
+ int GetNativeFalseValue() override
{
LIMITED_METHOD_CONTRACT;
return VARIANT_FALSE;
};
#endif // FEATURE_COMINTEROP
-class ILWSTRMarshaler : public ILMarshaler
-{
-public:
- enum
- {
- c_fInOnly = FALSE,
- c_nativeSize = sizeof(void *),
- c_CLRSize = sizeof(OBJECTREF),
- };
-
-#ifdef _DEBUG
- bool m_fCoMemoryAllocated;
-
- ILWSTRMarshaler()
- {
- LIMITED_METHOD_CONTRACT;
- m_fCoMemoryAllocated = false;
- }
-#endif // _DEBUG
-
-
- virtual bool SupportsArgumentMarshal(DWORD dwMarshalFlags, UINT* pErrorResID)
- {
- if (IsOut(dwMarshalFlags) && !IsByref(dwMarshalFlags) && IsCLRToNative(dwMarshalFlags))
- {
- *pErrorResID = IDS_EE_BADMARSHAL_STRING_OUT;
- return false;
- }
-
- return true;
- }
-
-protected:
- virtual LocalDesc GetNativeType();
- virtual LocalDesc GetManagedType();
-
- virtual void EmitConvertSpaceCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertSpaceAndContentsCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertSpaceAndContentsCLRToNativeTemp(ILCodeStream* pslILEmit);
-
- virtual void EmitConvertSpaceNativeToCLR(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit);
-
- virtual bool NeedsClearNative();
- virtual void EmitClearNative(ILCodeStream* pslILEmit);
- virtual void EmitClearNativeTemp(ILCodeStream* pslILEmit);
-
- static bool CanUsePinnedManagedString(DWORD dwMarshalFlags);
- static void EmitCheckManagedStringLength(ILCodeStream* pslILEmit);
- static void EmitCheckNativeStringLength(ILCodeStream* pslILEmit);
-};
-
// A marshaler that makes run-time decision based on argument size whether native space will
// be allocated using localloc or on the heap. The ctor argument is a heap free function.
class ILOptimizedAllocMarshaler : public ILMarshaler
LIMITED_METHOD_CONTRACT;
}
- virtual LocalDesc GetNativeType();
- virtual bool NeedsClearNative();
- virtual void EmitClearNative(ILCodeStream* pslILEmit);
+ LocalDesc GetNativeType() override;
+ bool NeedsClearNative() override;
+ void EmitClearNative(ILCodeStream* pslILEmit) override;
protected:
const BinderMethodID m_idClearNative;
LIMITED_METHOD_CONTRACT;
}
- virtual LocalDesc GetManagedType();
- virtual void EmitConvertSpaceCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertSpaceNativeToCLR(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit);
+ LocalDesc GetManagedType() override;
+ void EmitConvertSpaceCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertSpaceNativeToCLR(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override;
};
class ILWSTRBufferMarshaler : public ILOptimizedAllocMarshaler
LIMITED_METHOD_CONTRACT;
}
- virtual LocalDesc GetManagedType();
- virtual void EmitConvertSpaceCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertSpaceNativeToCLR(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit);
+ LocalDesc GetManagedType() override;
+ void EmitConvertSpaceCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertSpaceNativeToCLR(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override;
};
class ILCSTRBufferMarshaler : public ILOptimizedAllocMarshaler
LIMITED_METHOD_CONTRACT;
}
- virtual LocalDesc GetManagedType();
- virtual void EmitConvertSpaceCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertSpaceNativeToCLR(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit);
+ LocalDesc GetManagedType() override;
+ void EmitConvertSpaceCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertSpaceNativeToCLR(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override;
};
c_CLRSize = sizeof(SAFEHANDLE),
};
- virtual LocalDesc GetManagedType();
- virtual LocalDesc GetNativeType();
-
- virtual bool NeedsClearNative();
- virtual void EmitClearNative(ILCodeStream* pslILEmit);
-
- virtual void EmitMarshalArgumentCLRToNative();
+ LocalDesc GetManagedType() override
+ {
+ LIMITED_METHOD_CONTRACT;
+ return LocalDesc();
+ }
+
+ LocalDesc GetNativeType() override
+ {
+ LIMITED_METHOD_CONTRACT;
+ return LocalDesc();
+ }
static MarshalerOverrideStatus ArgumentOverride(NDirectStubLinker* psl,
BOOL byref,
public:
- LocalDesc GetManagedType()
+ LocalDesc GetManagedType() override
{
LIMITED_METHOD_CONTRACT;
return LocalDesc();
}
- LocalDesc GetNativeType()
+ LocalDesc GetNativeType() override
{
LIMITED_METHOD_CONTRACT;
return LocalDesc();
};
protected:
- virtual LocalDesc GetNativeType();
- virtual LocalDesc GetManagedType();
- virtual void EmitReInitNative(ILCodeStream* pslILEmit);
- virtual bool NeedsClearNative();
- virtual void EmitClearNative(ILCodeStream * pslILEmit);
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit);
+ LocalDesc GetNativeType() override;
+ LocalDesc GetManagedType() override;
+ void EmitReInitNative(ILCodeStream* pslILEmit) override;
+ bool NeedsClearNative() override;
+ void EmitClearNative(ILCodeStream * pslILEmit) override;
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override;
};
#ifdef FEATURE_COMINTEROP
};
protected:
- virtual LocalDesc GetNativeType();
- virtual LocalDesc GetManagedType();
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit);
- virtual bool NeedsClearNative();
- virtual void EmitClearNative(ILCodeStream* pslILEmit);
- virtual void EmitReInitNative(ILCodeStream* pslILEmit);
+ LocalDesc GetNativeType() override;
+ LocalDesc GetManagedType() override;
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override;
+ bool NeedsClearNative() override;
+ void EmitClearNative(ILCodeStream* pslILEmit) override;
+ void EmitReInitNative(ILCodeStream* pslILEmit) override;
};
#endif // FEATURE_COMINTEROP
};
protected:
- virtual LocalDesc GetNativeType();
- virtual LocalDesc GetManagedType();
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit);
- virtual void EmitReInitNative(ILCodeStream* pslILEmit);
+ LocalDesc GetNativeType() override;
+ LocalDesc GetManagedType() override;
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override;
+ void EmitReInitNative(ILCodeStream* pslILEmit) override;
};
};
protected:
- virtual LocalDesc GetNativeType();
- virtual LocalDesc GetManagedType();
- virtual void EmitReInitNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit);
+ LocalDesc GetNativeType() override;
+ LocalDesc GetManagedType() override;
+ void EmitReInitNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override;
};
};
protected:
- virtual LocalDesc GetNativeType();
- virtual LocalDesc GetManagedType();
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit);
- virtual bool NeedsClearNative();
- virtual void EmitClearNative(ILCodeStream* pslILEmit);
+ LocalDesc GetNativeType() override;
+ LocalDesc GetManagedType() override;
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override;
+ bool NeedsClearNative() override;
+ void EmitClearNative(ILCodeStream* pslILEmit) override;
};
#endif // FEATURE_COMINTEROP
};
protected:
- virtual LocalDesc GetNativeType();
- virtual LocalDesc GetManagedType();
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit);
+ LocalDesc GetNativeType() override;
+ LocalDesc GetManagedType() override;
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override;
};
};
protected:
- virtual LocalDesc GetNativeType()
+ LocalDesc GetNativeType() override
{
LIMITED_METHOD_CONTRACT;
return LocalDesc(ELEMENT_TYPE_I);
}
- virtual LocalDesc GetManagedType()
+ LocalDesc GetManagedType() override
{
STANDARD_VM_CONTRACT;
return LocalDesc(MscorlibBinder::GetClass(CLASS__ID));
}
- virtual bool NeedsClearNative()
+ bool NeedsClearNative() override
{
LIMITED_METHOD_CONTRACT;
return (IsByref(m_dwMarshalFlags) && IsOut(m_dwMarshalFlags));
}
- virtual void EmitClearNative(ILCodeStream* pslILEmit)
+ void EmitClearNative(ILCodeStream* pslILEmit) override
{
STANDARD_VM_CONTRACT;
pslILEmit->EmitCALL(METHOD__MARSHAL__FREE_CO_TASK_MEM, 1, 0);
}
- virtual void EmitConvertSpaceCLRToNative(ILCodeStream* pslILEmit)
+ void EmitConvertSpaceCLRToNative(ILCodeStream* pslILEmit) override
{
STANDARD_VM_CONTRACT;
}
}
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit)
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override
{
STANDARD_VM_CONTRACT;
}
}
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit)
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override
{
STANDARD_VM_CONTRACT;
};
protected:
- virtual LocalDesc GetNativeType();
- virtual LocalDesc GetManagedType();
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit);
+ LocalDesc GetNativeType() override;
+ LocalDesc GetManagedType() override;
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override;
};
class ILVBByValStrWMarshaler : public ILMarshaler
LIMITED_METHOD_CONTRACT;
}
- virtual bool SupportsArgumentMarshal(DWORD dwMarshalFlags, UINT* pErrorResID);
- virtual bool SupportsReturnMarshal(DWORD dwMarshalFlags, UINT* pErrorResID);
+ bool SupportsArgumentMarshal(DWORD dwMarshalFlags, UINT* pErrorResID) override;
+ bool SupportsReturnMarshal(DWORD dwMarshalFlags, UINT* pErrorResID) override;
protected:
- virtual LocalDesc GetNativeType();
- virtual LocalDesc GetManagedType();
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit);
- virtual bool NeedsClearNative();
- virtual void EmitClearNative(ILCodeStream* pslILEmit);
- virtual bool IsNativePassedByRef();
+ LocalDesc GetNativeType() override;
+ LocalDesc GetManagedType() override;
+ void EmitSetupArgumentForMarshalling(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override;
+ bool NeedsClearNative() override;
+ void EmitClearNative(ILCodeStream* pslILEmit) override;
+ bool IsNativePassedByRef() override;
DWORD m_dwCCHLocal;
DWORD m_dwLocalBuffer;
LIMITED_METHOD_CONTRACT;
}
- virtual bool SupportsArgumentMarshal(DWORD dwMarshalFlags, UINT* pErrorResID);
- virtual bool SupportsReturnMarshal(DWORD dwMarshalFlags, UINT* pErrorResID);
+ bool SupportsArgumentMarshal(DWORD dwMarshalFlags, UINT* pErrorResID) override;
+ bool SupportsReturnMarshal(DWORD dwMarshalFlags, UINT* pErrorResID) override;
protected:
- virtual LocalDesc GetNativeType();
- virtual LocalDesc GetManagedType();
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit);
- virtual bool NeedsClearNative();
- virtual void EmitClearNative(ILCodeStream* pslILEmit);
- virtual bool IsNativePassedByRef();
+ LocalDesc GetNativeType() override;
+ LocalDesc GetManagedType() override;
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override;
+ bool NeedsClearNative() override;
+ void EmitClearNative(ILCodeStream* pslILEmit) override;
+ bool IsNativePassedByRef() override;
DWORD m_dwCCHLocal;
};
};
protected:
- virtual LocalDesc GetNativeType();
- virtual LocalDesc GetManagedType();
+ LocalDesc GetNativeType() override;
+ LocalDesc GetManagedType() override;
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit);
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override;
void EmitConvertCLRToHSTRINGReference(ILCodeStream* pslILEmit);
void EmitConvertCLRToHSTRING(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit);
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override;
- virtual bool NeedsClearNative();
- virtual void EmitClearNative(ILCodeStream* pslILEmit);
+ bool NeedsClearNative() override;
+ void EmitClearNative(ILCodeStream* pslILEmit) override;
};
#endif // FEATURE_COMINTEROP
}
protected:
- virtual LocalDesc GetManagedType();
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit);
+ LocalDesc GetManagedType() override;
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override;
};
+class ILWSTRMarshaler : public ILOptimizedAllocMarshaler
+{
+public:
+ enum
+ {
+ c_fInOnly = FALSE,
+ c_nativeSize = sizeof(void *),
+ c_CLRSize = sizeof(OBJECTREF),
+ };
+ enum
+ {
+ // If required buffer length > MAX_LOCAL_BUFFER_LENGTH, don't optimize by allocating memory on stack
+ MAX_LOCAL_BUFFER_LENGTH = (MAX_PATH_FNAME + 1) * 2
+ };
+
+ ILWSTRMarshaler()
+ :ILOptimizedAllocMarshaler(METHOD__MARSHAL__FREE_CO_TASK_MEM)
+ {
+ LIMITED_METHOD_CONTRACT;
+ }
+
+
+ bool SupportsArgumentMarshal(DWORD dwMarshalFlags, UINT* pErrorResID) override
+ {
+ if (IsOut(dwMarshalFlags) && !IsByref(dwMarshalFlags) && IsCLRToNative(dwMarshalFlags))
+ {
+ *pErrorResID = IDS_EE_BADMARSHAL_STRING_OUT;
+ return false;
+ }
+
+ return true;
+ }
+
+protected:
+ LocalDesc GetNativeType() override;
+ LocalDesc GetManagedType() override;
+
+ void EmitConvertSpaceCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertSpaceAndContentsCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertSpaceAndContentsCLRToNativeTemp(ILCodeStream* pslILEmit) override;
+
+ void EmitConvertSpaceNativeToCLR(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override;
+
+ bool CanMarshalViaPinning() override
+ {
+ LIMITED_METHOD_CONTRACT;
+ return IsCLRToNative(m_dwMarshalFlags) && !IsByref(m_dwMarshalFlags) && IsIn(m_dwMarshalFlags) && !IsOut(m_dwMarshalFlags);
+ }
+ void EmitMarshalViaPinning(ILCodeStream* pslILEmit) override;
+
+ static void EmitCheckManagedStringLength(ILCodeStream* pslILEmit);
+ static void EmitCheckNativeStringLength(ILCodeStream* pslILEmit);
+};
class ILCSTRMarshaler : public ILOptimizedAllocMarshaler
{
}
protected:
- virtual LocalDesc GetManagedType();
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit);
+ LocalDesc GetManagedType() override;
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override;
};
class ILBSTRMarshaler : public ILOptimizedAllocMarshaler
}
protected:
- virtual LocalDesc GetManagedType();
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit);
+ LocalDesc GetManagedType() override;
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override;
};
class ILAnsiBSTRMarshaler : public ILMarshaler
};
protected:
- virtual LocalDesc GetNativeType();
- virtual LocalDesc GetManagedType();
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit);
- virtual bool NeedsClearNative();
- virtual void EmitClearNative(ILCodeStream* pslILEmit);
+ LocalDesc GetNativeType() override;
+ LocalDesc GetManagedType() override;
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override;
+ bool NeedsClearNative() override;
+ void EmitClearNative(ILCodeStream* pslILEmit) override;
};
class ILLayoutClassPtrMarshalerBase : public ILMarshaler
};
protected:
- virtual LocalDesc GetNativeType();
- virtual LocalDesc GetManagedType();
- virtual void EmitConvertSpaceCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertSpaceCLRToNativeTemp(ILCodeStream* pslILEmit);
- virtual void EmitConvertSpaceAndContentsCLRToNativeTemp(ILCodeStream* pslILEmit);
- virtual void EmitConvertSpaceNativeToCLR(ILCodeStream* pslILEmit);
- virtual bool NeedsClearNative();
- virtual void EmitClearNative(ILCodeStream* pslILEmit);
- virtual void EmitClearNativeTemp(ILCodeStream* pslILEmit);
+ LocalDesc GetNativeType() override;
+ LocalDesc GetManagedType() override;
+ void EmitConvertSpaceCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertSpaceCLRToNativeTemp(ILCodeStream* pslILEmit) override;
+ void EmitConvertSpaceAndContentsCLRToNativeTemp(ILCodeStream* pslILEmit) override;
+ void EmitConvertSpaceNativeToCLR(ILCodeStream* pslILEmit) override;
+ bool NeedsClearNative() override;
+ void EmitClearNative(ILCodeStream* pslILEmit) override;
+ void EmitClearNativeTemp(ILCodeStream* pslILEmit) override;
};
class ILLayoutClassPtrMarshaler : public ILLayoutClassPtrMarshalerBase
};
protected:
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit);
- virtual void EmitClearNativeContents(ILCodeStream * pslILEmit);
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override;
+ void EmitClearNativeContents(ILCodeStream * pslILEmit) override;
};
class ILBlittablePtrMarshaler : public ILLayoutClassPtrMarshalerBase
c_fInOnly = FALSE,
};
-protected:
- virtual void EmitMarshalArgumentCLRToNative();
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit);
+protected:
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override;
+ void EmitConvertSpaceAndContentsCLRToNativeTemp(ILCodeStream* pslILEmit) override;
+private:
+ bool CanUsePinnedLayoutClass();
};
class ILBlittableValueClassWithCopyCtorMarshaler : public ILMarshaler
};
protected:
- virtual LocalDesc GetNativeType();
- virtual LocalDesc GetManagedType();
- virtual bool SupportsArgumentMarshal(DWORD dwMarshalFlags, UINT* pErrorResID);
- virtual void EmitMarshalArgumentCLRToNative();
- virtual void EmitMarshalArgumentNativeToCLR();
+ LocalDesc GetNativeType() override;
+ LocalDesc GetManagedType() override;
+ bool SupportsArgumentMarshal(DWORD dwMarshalFlags, UINT* pErrorResID) override;
+ void EmitConvertSpaceAndContentsCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override;
+
+private:
+ DWORD m_dwVaListSizeLocalNum;
};
class ILArrayWithOffsetMarshaler : public ILMarshaler
}
protected:
- virtual LocalDesc GetNativeType();
- virtual LocalDesc GetManagedType();
- virtual bool SupportsArgumentMarshal(DWORD dwMarshalFlags, UINT* pErrorResID);
+ LocalDesc GetNativeType() override;
+ LocalDesc GetManagedType() override;
+ bool SupportsArgumentMarshal(DWORD dwMarshalFlags, UINT* pErrorResID) override;
- virtual void EmitConvertSpaceAndContentsCLRToNativeTemp(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit);
- virtual void EmitClearNativeTemp(ILCodeStream* pslILEmit);
+ void EmitConvertSpaceAndContentsCLRToNativeTemp(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override;
+ void EmitClearNativeTemp(ILCodeStream* pslILEmit) override;
-
+private:
DWORD m_dwCountLocalNum;
DWORD m_dwOffsetLocalNum;
DWORD m_dwPinnedLocalNum;
c_CLRSize = sizeof(OBJECTREF),
};
- ILAsAnyMarshalerBase() :
- m_dwMarshalerLocalNum(-1)
+protected:
+
+ virtual bool IsAnsi() const = 0;
+ LocalDesc GetNativeType() override final;
+ LocalDesc GetManagedType() override final;
+ void EmitCreateMngdMarshaler(ILCodeStream* pslILEmit) override final;
+ bool SupportsArgumentMarshal(DWORD dwMarshalFlags, UINT* pErrorResID) override final;
+ bool SupportsReturnMarshal(DWORD dwMarshalFlags, UINT* pErrorResID) override final;
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override final;
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override final;
+ bool NeedsClearNative() override final;
+ void EmitClearNativeTemp(ILCodeStream* pslILEmit) override final;
+ bool AlwaysConvertByValContentsCLRToNative() override final
{
LIMITED_METHOD_CONTRACT;
+ return true;
}
-protected:
+private:
+ // These flags correspond to System.StubHelpers.AsAnyMarshaler.AsAnyFlags.In and Out respectively.
+ // We have to pre-calculate the flags and emit them into the IL stream since the AsAny marshalers
+ // are effectively lazily resolved based on the runtime type of the object.
static const BYTE ML_IN = 0x10;
static const BYTE ML_OUT = 0x20;
- virtual bool IsAnsi() = 0;
- virtual LocalDesc GetNativeType();
- virtual LocalDesc GetManagedType();
- virtual bool SupportsArgumentMarshal(DWORD dwMarshalFlags, UINT* pErrorResID);
- virtual bool SupportsReturnMarshal(DWORD dwMarshalFlags, UINT* pErrorResID);
- virtual void EmitMarshalArgumentCLRToNative();
- virtual bool NeedsClearNative();
- virtual void EmitClearNativeTemp(ILCodeStream* pslILEmit);
+ DWORD GetAsAnyFlags() const
+ {
+ BYTE inout = (IsIn(m_dwMarshalFlags) ? ML_IN : 0) | (IsOut(m_dwMarshalFlags) ? ML_OUT : 0);
+ BYTE fIsAnsi = IsAnsi() ? 1 : 0;
+ BYTE fBestFit = m_pargs->m_pMarshalInfo->GetBestFitMapping();
+ BYTE fThrow = m_pargs->m_pMarshalInfo->GetThrowOnUnmappableChar();
+
+ DWORD dwFlags = 0;
- DWORD m_dwMarshalerLocalNum;
+ dwFlags |= inout << 24;
+ dwFlags |= fIsAnsi << 16;
+ dwFlags |= fThrow << 8;
+ dwFlags |= fBestFit << 0;
+ return dwFlags;
+ }
};
class ILAsAnyWMarshaler : public ILAsAnyMarshalerBase
};
protected:
- virtual bool IsAnsi()
+ bool IsAnsi() const override
{
return false;
}
};
protected:
- virtual bool IsAnsi()
+ bool IsAnsi() const override
{
return true;
}
}
protected:
- virtual LocalDesc GetNativeType();
- virtual LocalDesc GetManagedType();
+ LocalDesc GetNativeType() override;
+ LocalDesc GetManagedType() override;
- virtual void EmitCreateMngdMarshaler(ILCodeStream* pslILEmit) = 0;
+ void EmitCreateMngdMarshaler(ILCodeStream* pslILEmit) override = 0;
virtual void EmitCallMngdMarshalerMethod(ILCodeStream* pslILEmit, MethodDesc *pMD);
- virtual void EmitConvertSpaceNativeToCLR(ILCodeStream* pslILEmit)
+ void EmitConvertSpaceNativeToCLR(ILCodeStream* pslILEmit) override
{
WRAPPER_NO_CONTRACT;
EmitCallMngdMarshalerMethod(pslILEmit, GetConvertSpaceToManagedMethod());
}
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit)
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override
{
WRAPPER_NO_CONTRACT;
EmitCallMngdMarshalerMethod(pslILEmit, GetConvertContentsToManagedMethod());
}
- virtual void EmitConvertSpaceCLRToNative(ILCodeStream* pslILEmit)
+ void EmitConvertSpaceCLRToNative(ILCodeStream* pslILEmit) override
{
WRAPPER_NO_CONTRACT;
EmitCallMngdMarshalerMethod(pslILEmit, GetConvertSpaceToNativeMethod());
}
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit)
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override
{
WRAPPER_NO_CONTRACT;
EmitCallMngdMarshalerMethod(pslILEmit, GetConvertContentsToNativeMethod());
}
- virtual bool NeedsClearNative()
+ bool NeedsClearNative() override
{
LIMITED_METHOD_CONTRACT;
return false;
}
- virtual void EmitClearNative(ILCodeStream* pslILEmit)
+ void EmitClearNative(ILCodeStream* pslILEmit) override
{
WRAPPER_NO_CONTRACT;
EmitCallMngdMarshalerMethod(pslILEmit, GetClearNativeMethod());
}
- virtual void EmitClearNativeContents(ILCodeStream* pslILEmit)
+ void EmitClearNativeContents(ILCodeStream* pslILEmit) override
{
WRAPPER_NO_CONTRACT;
EmitCallMngdMarshalerMethod(pslILEmit, GetClearNativeContentsMethod());
}
-
- virtual bool NeedsClearCLR()
+ bool NeedsClearCLR() override
{
LIMITED_METHOD_CONTRACT;
return false;
}
- virtual void EmitClearCLR(ILCodeStream* pslILEmit)
+ void EmitClearCLR(ILCodeStream* pslILEmit) override
{
WRAPPER_NO_CONTRACT;
EmitCallMngdMarshalerMethod(pslILEmit, GetClearManagedMethod());
m_dwSavedSizeArg = LOCAL_NUM_UNUSED;
}
- virtual void EmitMarshalArgumentCLRToNative();
- virtual void EmitConvertSpaceNativeToCLR(ILCodeStream* pslILEmit);
- virtual void EmitConvertSpaceCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitClearNative(ILCodeStream* pslILEmit);
- virtual void EmitClearNativeContents(ILCodeStream* pslILEmit);
- virtual void EmitMarshalArgumentNativeToCLRByref();
- virtual void EmitMarshalArgumentCLRToNativeByref();
+ bool CanMarshalViaPinning() override;
+
+ void EmitMarshalViaPinning(ILCodeStream* pslILEmit) override;
+ void EmitSetupArgumentForMarshalling(ILCodeStream* pslILEmit) override;
+ void EmitConvertSpaceNativeToCLR(ILCodeStream* pslILEmit) override;
+ void EmitConvertSpaceCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitClearNative(ILCodeStream* pslILEmit) override;
+ void EmitClearNativeContents(ILCodeStream* pslILEmit) override;
protected:
- bool UsePinnedArraySpecialCase();
-
BOOL CheckSizeParamIndexArg(const CREATE_MARSHALER_CARRAY_OPERANDS &mops, CorElementType *pElementType);
// Calculate element count and load it on evaluation stack
void EmitLoadElementCount(ILCodeStream* pslILEmit);
- virtual void EmitCreateMngdMarshaler(ILCodeStream* pslILEmit);
+ void EmitCreateMngdMarshaler(ILCodeStream* pslILEmit) override;
void EmitLoadNativeSize(ILCodeStream* pslILEmit);
- void EmitNewSavedSizeArgLocal();
+ void EmitNewSavedSizeArgLocal(ILCodeStream* pslILEmit);
private :
DWORD m_dwSavedSizeArg;
protected:
- virtual void EmitCreateMngdMarshaler(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit);
+ void EmitCreateMngdMarshaler(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override;
- virtual void EmitReInitNative(ILCodeStream* pslILEmit)
+ void EmitReInitNative(ILCodeStream* pslILEmit) override
{
CONTRACTL
{
}
protected:
- virtual LocalDesc GetNativeType();
- virtual LocalDesc GetManagedType();
-
- virtual void EmitCreateMngdMarshaler(ILCodeStream* pslILEmit);
- virtual void EmitMarshalArgumentCLRToNative();
- virtual void EmitConvertSpaceCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertSpaceNativeToCLR(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit);
- virtual void EmitClearNative(ILCodeStream* pslILEmit);
- virtual void EmitClearNativeContents(ILCodeStream* pslILEmit);
+ LocalDesc GetNativeType() override;
+ LocalDesc GetManagedType() override;
+ bool CanMarshalViaPinning() override;
+
+ void EmitMarshalViaPinning(ILCodeStream* pslILEmit) override;
+ void EmitCreateMngdMarshaler(ILCodeStream* pslILEmit) override;
+ void EmitConvertSpaceCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertSpaceNativeToCLR(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override;
+ void EmitClearNative(ILCodeStream* pslILEmit) override;
+ void EmitClearNativeContents(ILCodeStream* pslILEmit) override;
private:
- bool CanUsePinnedArray();
void EmitLoadNativeArrayLength(ILCodeStream *pslILEmit);
- virtual MethodDesc *GetConvertContentsToManagedMethod();
- virtual MethodDesc *GetConvertContentsToNativeMethod();
- virtual MethodDesc *GetClearNativeContentsMethod();
+ MethodDesc *GetConvertContentsToManagedMethod() override;
+ MethodDesc *GetConvertContentsToNativeMethod() override;
+ MethodDesc *GetClearNativeContentsMethod() override;
MethodDesc *GetExactMarshalerMethod(MethodDesc *pGenericMD);
};
}
protected:
- virtual void EmitCreateMngdMarshaler(ILCodeStream* pslILEmit);
+ void EmitCreateMngdMarshaler(ILCodeStream* pslILEmit) override;
};
class MngdRefCustomMarshaler
static FCDECL3(void, ClearNative, MngdRefCustomMarshaler* pThis, OBJECTREF* pManagedHome, void** pNativeHome);
static FCDECL3(void, ClearManaged, MngdRefCustomMarshaler* pThis, OBJECTREF* pManagedHome, void** pNativeHome);
- static void DoClearNativeContents(MngdRefCustomMarshaler* pThis, OBJECTREF* pManagedHome, void** pNativeHome);
-
CustomMarshalerHelper* m_pCMHelper;
};
static void EmitConvertWinRTUriToCLRUri(ILCodeStream* pslILEmit, LoaderAllocator* pLoader);
protected:
- virtual LocalDesc GetNativeType();
- virtual LocalDesc GetManagedType();
+ LocalDesc GetNativeType() override;
+ LocalDesc GetManagedType() override;
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit);
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override;
- virtual bool NeedsClearNative();
+ bool NeedsClearNative() override;
void EmitClearNative(ILCodeStream* pslILEmit);
};
static void EmitConvertWinRTEventArgsToCLREventArgs(ILCodeStream* pslILEmit, LoaderAllocator* pLoader);
protected:
- virtual LocalDesc GetNativeType();
- virtual LocalDesc GetManagedType();
+ LocalDesc GetNativeType() override;
+ LocalDesc GetManagedType() override;
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit);
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override;
- virtual bool NeedsClearNative();
+ bool NeedsClearNative() override;
void EmitClearNative(ILCodeStream* pslILEmit);
};
static void EmitConvertWinRTEventArgsToCLREventArgs(ILCodeStream* pslILEmit, LoaderAllocator* pLoader);
protected:
- virtual LocalDesc GetNativeType();
- virtual LocalDesc GetManagedType();
+ LocalDesc GetNativeType() override;
+ LocalDesc GetManagedType() override;
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit);
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override;
- virtual bool NeedsClearNative();
+ bool NeedsClearNative() override;
void EmitClearNative(ILCodeStream* pslILEmit);
};
};
protected:
- virtual LocalDesc GetNativeType();
- virtual LocalDesc GetManagedType();
+ LocalDesc GetNativeType() override;
+ LocalDesc GetManagedType() override;
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit);
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override;
- virtual bool NeedsClearNative();
- virtual void EmitReInitNative(ILCodeStream* pslILEmit);
+ bool NeedsClearNative() override;
+ void EmitReInitNative(ILCodeStream* pslILEmit) override;
};
class ILNullableMarshaler : public ILMarshaler
};
protected:
- virtual LocalDesc GetNativeType();
- virtual LocalDesc GetManagedType();
- virtual bool NeedsClearNative();
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit);
- virtual void EmitClearNative(ILCodeStream* pslILEmit);
+ LocalDesc GetNativeType() override;
+ LocalDesc GetManagedType() override;
+ bool NeedsClearNative() override;
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override;
+ void EmitClearNative(ILCodeStream* pslILEmit) override;
private:
MethodDesc *GetExactMarshalerMethod(MethodDesc *pGenericMD);
};
protected:
- virtual LocalDesc GetNativeType();
- virtual LocalDesc GetManagedType();
+ LocalDesc GetNativeType() override;
+ LocalDesc GetManagedType() override;
- virtual void EmitConvertContentsCLRToNative(ILCodeStream * pslILEmit);
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream * pslILEmit);
+ void EmitConvertContentsCLRToNative(ILCodeStream * pslILEmit) override;
+ void EmitConvertContentsNativeToCLR(ILCodeStream * pslILEmit) override;
- virtual bool NeedsClearNative();
- virtual void EmitClearNative(ILCodeStream * pslILEmit);
- virtual void EmitReInitNative(ILCodeStream * pslILEmit);
+ bool NeedsClearNative() override;
+ void EmitClearNative(ILCodeStream * pslILEmit) override;
+ void EmitReInitNative(ILCodeStream * pslILEmit) override;
};
class ILHResultExceptionMarshaler : public ILMarshaler
};
protected:
- virtual LocalDesc GetNativeType();
- virtual LocalDesc GetManagedType();
+ LocalDesc GetNativeType() override;
+ LocalDesc GetManagedType() override;
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit);
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override;
- virtual bool NeedsClearNative();
+ bool NeedsClearNative() override;
};
class ILKeyValuePairMarshaler : public ILMarshaler
};
protected:
- virtual LocalDesc GetNativeType();
- virtual LocalDesc GetManagedType();
- virtual bool NeedsClearNative();
- virtual void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit);
- virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit);
- virtual void EmitClearNative(ILCodeStream* pslILEmit);
+ LocalDesc GetNativeType() override;
+ LocalDesc GetManagedType() override;
+ bool NeedsClearNative() override;
+ void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override;
+ void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override;
+ void EmitClearNative(ILCodeStream* pslILEmit) override;
private:
MethodDesc *GetExactMarshalerMethod(MethodDesc *pGenericMD);
DEFINE_METASIG_T(SM(RefCleanupWorkListElement_RetVoid, r(C(CLEANUP_WORK_LIST_ELEMENT)), v))
DEFINE_METASIG_T(SM(RefCleanupWorkListElement_SafeHandle_RetIntPtr, r(C(CLEANUP_WORK_LIST_ELEMENT)) C(SAFE_HANDLE), I))
-DEFINE_METASIG_T(SM(RefCleanupWorkListElement_Delegate_RetVoid, r(C(CLEANUP_WORK_LIST_ELEMENT)) C(DELEGATE), v))
+DEFINE_METASIG_T(SM(RefCleanupWorkListElement_Obj_RetVoid, r(C(CLEANUP_WORK_LIST_ELEMENT)) j, v))
#ifdef FEATURE_ICASTABLE
DEFINE_METASIG_T(SM(ICastable_RtType_RefException_RetBool, C(ICASTABLE) C(CLASS) r(C(EXCEPTION)), F))
pcsMarshal->EmitNOP("// } argument");
pcsUnmarshal->EmitNOP("// } argument");
- pMarshaler->EmitSetupArgument(pcsDispatch);
+ pMarshaler->EmitSetupArgumentForDispatch(pcsDispatch);
if (m_paramidx == 0)
{
CorCallingConvention callConv = psl->GetStubTargetCallingConv();
if (managedToNative)
{
ILCodeStream* pcsDispatch = psl->GetDispatchCodeStream();
- pHiddenLengthMarshaler->EmitSetupArgument(pcsDispatch);
+ pHiddenLengthMarshaler->EmitSetupArgumentForDispatch(pcsDispatch);
}
}
DEFINE_METHOD(STUBHELPERS, THROW_INTEROP_PARAM_EXCEPTION, ThrowInteropParamException, SM_Int_Int_RetVoid)
DEFINE_METHOD(STUBHELPERS, ADD_TO_CLEANUP_LIST_SAFEHANDLE, AddToCleanupList, SM_RefCleanupWorkListElement_SafeHandle_RetIntPtr)
-DEFINE_METHOD(STUBHELPERS, ADD_TO_CLEANUP_LIST_DELEGATE, AddToCleanupList, SM_RefCleanupWorkListElement_Delegate_RetVoid)
+DEFINE_METHOD(STUBHELPERS, KEEP_ALIVE_VIA_CLEANUP_LIST, KeepAliveViaCleanupList, SM_RefCleanupWorkListElement_Obj_RetVoid)
DEFINE_METHOD(STUBHELPERS, DESTROY_CLEANUP_LIST, DestroyCleanupList, SM_RefCleanupWorkListElement_RetVoid)
DEFINE_METHOD(STUBHELPERS, GET_HR_EXCEPTION_OBJECT, GetHRExceptionObject, SM_Int_RetException)
DEFINE_METHOD(STUBHELPERS, CREATE_CUSTOM_MARSHALER_HELPER, CreateCustomMarshalerHelper, SM_IntPtr_Int_IntPtr_RetIntPtr)