@@ -2657,7 +2657,9 @@ void PInvokeStaticSigInfo::PreInit(MethodDesc* pMD)
26572657}
26582658
26592659PInvokeStaticSigInfo::PInvokeStaticSigInfo (
2660- _In_ MethodDesc* pMD, _Outptr_opt_ LPCUTF8 *pLibName, _Outptr_opt_ LPCUTF8 *pEntryPointName)
2660+ _In_ MethodDesc* pMD,
2661+ _Outptr_opt_ LPCUTF8* pLibName,
2662+ _Outptr_opt_ LPCUTF8* pEntryPointName)
26612663{
26622664 CONTRACTL
26632665 {
@@ -2755,7 +2757,10 @@ PInvokeStaticSigInfo::PInvokeStaticSigInfo(
27552757 InitCallConv (CallConvWinApiSentinel, FALSE );
27562758}
27572759
2758- void PInvokeStaticSigInfo::DllImportInit (_In_ MethodDesc* pMD, _Outptr_opt_ LPCUTF8 *ppLibName, _Outptr_opt_ LPCUTF8 *ppEntryPointName)
2760+ void PInvokeStaticSigInfo::DllImportInit (
2761+ _In_ MethodDesc* pMD,
2762+ _Outptr_opt_ LPCUTF8* ppLibName,
2763+ _Outptr_opt_ LPCUTF8* ppEntryPointName)
27592764{
27602765 CONTRACTL
27612766 {
@@ -2784,7 +2789,6 @@ void PInvokeStaticSigInfo::DllImportInit(_In_ MethodDesc* pMD, _Outptr_opt_ LPCU
27842789 return ;
27852790 }
27862791
2787- // out parameter pEntryPointName
27882792 if (ppEntryPointName && *ppEntryPointName == NULL )
27892793 *ppEntryPointName = pMD->GetName ();
27902794
@@ -3128,16 +3132,12 @@ BOOL NDirect::MarshalingRequired(
31283132 return TRUE ;
31293133 }
31303134
3131- // SetLastError is handled by stub
3132- PInvokeStaticSigInfo sigInfo (pMD);
3133- if (sigInfo.GetLinkFlags () & nlfLastError)
3134- return TRUE ;
3135-
3136- // LCID argument is handled by stub
3137- if (GetLCIDParameterIndex (pMD) != -1 )
3138- return TRUE ;
3139-
3140- if (pMD->IsNDirect ())
3135+ PInvokeStaticSigInfo sigInfo;
3136+ if (!pMD->IsNDirect ())
3137+ {
3138+ new (&sigInfo) PInvokeStaticSigInfo (pMD);
3139+ }
3140+ else
31413141 {
31423142 // A P/Invoke marked with UnmanagedCallersOnlyAttribute
31433143 // doesn't technically require marshalling. However, we
@@ -3154,13 +3154,23 @@ BOOL NDirect::MarshalingRequired(
31543154 if (pNMD->IsClassConstructorTriggeredByILStub ())
31553155 return TRUE ;
31563156
3157+ InitializeSigInfoAndPopulateNDirectMethodDesc (pNMD, &sigInfo);
3158+
31573159#ifndef CROSSGEN_COMPILE
31583160 // Pending exceptions are handled by stub
31593161 if (Interop::ShouldCheckForPendingException (pNMD))
31603162 return TRUE ;
31613163#endif // !CROSSGEN_COMPILE
31623164 }
31633165
3166+ // SetLastError is handled by stub
3167+ if (sigInfo.GetLinkFlags () & nlfLastError)
3168+ return TRUE ;
3169+
3170+ // LCID argument is handled by stub
3171+ if (GetLCIDParameterIndex (pMD) != -1 )
3172+ return TRUE ;
3173+
31643174 callConv = sigInfo.GetCallConv ();
31653175 }
31663176
@@ -4225,7 +4235,11 @@ static void CreateNDirectStubAccessMetadata(
42254235
42264236namespace
42274237{
4228- void PopulateNDirectMethodDescImpl (_Inout_ NDirectMethodDesc* pNMD, _In_ const PInvokeStaticSigInfo& sigInfo, _In_opt_z_ LPCUTF8 libName, _In_opt_z_ LPCUTF8 entryPointName)
4238+ void PopulateNDirectMethodDescImpl (
4239+ _Inout_ NDirectMethodDesc* pNMD,
4240+ _In_ const PInvokeStaticSigInfo& sigInfo,
4241+ _In_opt_z_ LPCUTF8 libName,
4242+ _In_opt_z_ LPCUTF8 entryPointName)
42294243 {
42304244 CONTRACTL
42314245 {
@@ -4263,9 +4277,8 @@ namespace
42634277 pNMD->ndirect .m_pszEntrypointName .SetValueMaybeNull (entryPointName);
42644278 }
42654279
4266- // Call this exactly ONCE per thread. Do not publish incomplete prestub flags
4267- // or you will introduce a race condition.
4268- pNMD->InterlockedSetNDirectFlags (ndirectflags);
4280+ // Do not publish incomplete prestub flags or you will introduce a race condition.
4281+ pNMD->InterlockedSetNDirectFlags (ndirectflags | NDirectMethodDesc::kNDirectPopulated );
42694282 }
42704283}
42714284
@@ -4281,6 +4294,9 @@ void NDirect::PopulateNDirectMethodDesc(_Inout_ NDirectMethodDesc* pNMD)
42814294 if (pNMD->IsSynchronized ())
42824295 COMPlusThrow (kTypeLoadException , IDS_EE_NOSYNCHRONIZED);
42834296
4297+ if (pNMD->IsPopulated ())
4298+ return ;
4299+
42844300 LPCUTF8 szLibName = NULL , szEntryPointName = NULL ;
42854301 PInvokeStaticSigInfo sigInfo (pNMD, &szLibName, &szEntryPointName);
42864302 PopulateNDirectMethodDescImpl (pNMD, sigInfo, szLibName, szEntryPointName);
@@ -4302,6 +4318,9 @@ void NDirect::InitializeSigInfoAndPopulateNDirectMethodDesc(_Inout_ NDirectMetho
43024318 LPCUTF8 szLibName = NULL , szEntryPointName = NULL ;
43034319 new (pSigInfo) PInvokeStaticSigInfo (pNMD, &szLibName, &szEntryPointName);
43044320
4321+ if (pNMD->IsPopulated ())
4322+ return ;
4323+
43054324 PopulateNDirectMethodDescImpl (pNMD, *pSigInfo, szLibName, szEntryPointName);
43064325}
43074326
0 commit comments