return OVERRIDDEN;
} // ILCriticalHandleMarshaler::ReturnOverride
-#ifndef FEATURE_CORECLR
-//---------------------------------------------------------------------------------------
-//
-MarshalerOverrideStatus ILBlittableValueClassWithCopyCtorMarshaler::ArgumentOverride(NDirectStubLinker* psl,
- BOOL byref,
- BOOL fin,
- BOOL fout,
- BOOL fManagedToNative,
- OverrideProcArgs* pargs,
- UINT* pResID,
- UINT argidx,
- UINT nativeStackOffset)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- ILCodeStream* pslIL = psl->GetMarshalCodeStream();
- ILCodeStream* pslILDispatch = psl->GetDispatchCodeStream();
-
- if (byref)
- {
- *pResID = IDS_EE_BADMARSHAL_COPYCTORRESTRICTION;
- return DISALLOWED;
- }
-
- if (fManagedToNative)
- {
-#ifdef _TARGET_X86_
- _ASSERTE(nativeStackOffset != (UINT)-1);
-
- // get a new copy ctor cookie
- DWORD dwCookieLocalNum = psl->CreateCopyCtorCookie(pslIL);
-
- // and initialize it with our values
- pslIL->EmitLDLOCA(dwCookieLocalNum);
- pslIL->EmitLDARG(argidx);
- pslIL->EmitLDC(nativeStackOffset);
-
- // SetData takes pointers to managed methods although code:CopyCtorCallStubWorker
- // currently calls them via reverse P/Invokes
- if (pargs->mm.m_pCopyCtor)
- {
- pslIL->EmitLDFTN(pslIL->GetToken(pargs->mm.m_pCopyCtor));
- }
- else
- {
- pslIL->EmitLoadNullPtr();
- }
-
- if (pargs->mm.m_pDtor)
- {
- pslIL->EmitLDFTN(pslIL->GetToken(pargs->mm.m_pDtor));
- }
- else
- {
- pslIL->EmitLoadNullPtr();
- }
-
- // <dwCookieLocalNum>.SetData(<argidx>, <nativeStackOffset>, ctorPtr, dtorPtr)
- pslIL->EmitCALL(METHOD__COPYCTORSTUBCOOKIE__SET_DATA, 5, 0);
-
- LocalDesc locDesc(pargs->mm.m_pMT);
- pslIL->SetStubTargetArgType(&locDesc); // native type is the value type
-
- pslILDispatch->EmitLDARG(argidx); // we load the argument directly
- pslILDispatch->EmitLDOBJ(pslILDispatch->GetToken(pargs->mm.m_pMT));
-#else // _TARGET_X86_
- // On WIN64 platforms, copy-constructed arguments are actually passed by reference.
- // This is the same calling convention as used by managed code, but to maintain parity,
- // we mimic the x86 behaviour:
- //
- // 1) create new native value type local
- // 2) run new->CopyCtor(old)
- // 3) run old->Dtor()
-
- LocalDesc locDesc(pargs->mm.m_pMT);
-
- DWORD dwNewValueTypeLocal;
-
- // Step 1
- dwNewValueTypeLocal = pslIL->NewLocal(locDesc);
-
- // Step 2
- if (pargs->mm.m_pCopyCtor)
- {
- pslIL->EmitLDLOCA(dwNewValueTypeLocal);
- pslIL->EmitLDARG(argidx);
- pslIL->EmitCALL(pslIL->GetToken(pargs->mm.m_pCopyCtor), 2, 0);
- }
- else
- {
- pslIL->EmitLDARG(argidx);
- pslIL->EmitLDOBJ(pslIL->GetToken(pargs->mm.m_pMT));
- pslIL->EmitSTLOC(dwNewValueTypeLocal);
- }
-
- // Step 3
- if (pargs->mm.m_pDtor)
- {
- pslIL->EmitLDARG(argidx);
- pslIL->EmitCALL(pslIL->GetToken(pargs->mm.m_pDtor), 1, 0);
- }
-
- pslIL->SetStubTargetArgType(ELEMENT_TYPE_I); // native type is a pointer
- pslILDispatch->EmitLDLOCA(dwNewValueTypeLocal);
-#endif // _TARGET_X86_
-
- return OVERRIDDEN;
- }
- else
- {
- // nothing to do but pass the value along
- // note that on x86 the argument comes by-value but is converted to pointer by the UM thunk
- // so that we don't make copies that would not be accounted for by copy ctors
- LocalDesc locDesc(pargs->mm.m_pMT);
- locDesc.MakeCopyConstructedPointer();
-
- pslIL->SetStubTargetArgType(&locDesc); // native type is a pointer
- pslILDispatch->EmitLDARG(argidx);
-
- return OVERRIDDEN;
- }
-}
-#endif // FEATURE_CORECLR
LocalDesc ILArgIteratorMarshaler::GetNativeType()
{