[release/3.1] Fix marshalling a pinnable multi-dimensional arr… (#26664)
authorJeremy Koritzinsky <jekoritz@microsoft.com>
Tue, 17 Sep 2019 19:26:35 +0000 (12:26 -0700)
committerGitHub <noreply@github.com>
Tue, 17 Sep 2019 19:26:35 +0000 (12:26 -0700)
* Use the exact methodtable of the parameter to calculate the offset into a pinned array.

src/vm/ilmarshalers.cpp
src/vm/mlinfo.cpp
src/vm/mlinfo.h

index 19db7df..a89aeaf 100644 (file)
@@ -3808,7 +3808,7 @@ void ILMngdMarshaler::EmitCallMngdMarshalerMethod(ILCodeStream* pslILEmit, Metho
 
 bool ILNativeArrayMarshaler::UsePinnedArraySpecialCase()
 {
-    if (IsCLRToNative(m_dwMarshalFlags) && !IsByref(m_dwMarshalFlags) && (NULL == OleVariant::GetMarshalerForVarType(m_pargs->na.m_vt, TRUE)))
+    if (IsCLRToNative(m_dwMarshalFlags) && !IsByref(m_dwMarshalFlags) && (NULL != m_pargs->na.m_pArrayMT) && (NULL == OleVariant::GetMarshalerForVarType(m_pargs->na.m_vt, TRUE)))
     {
         return true;
     }
@@ -3855,7 +3855,6 @@ void ILNativeArrayMarshaler::EmitCreateMngdMarshaler(ILCodeStream* pslILEmit)
     pslILEmit->EmitCALL(METHOD__MNGD_NATIVE_ARRAY_MARSHALER__CREATE_MARSHALER, 3, 0);
 }
 
-
 void ILNativeArrayMarshaler::EmitMarshalArgumentCLRToNative()
 {
     CONTRACTL
@@ -3900,7 +3899,7 @@ void ILNativeArrayMarshaler::EmitMarshalArgumentCLRToNative()
         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->EmitLDC(ArrayBase::GetDataPtrOffset(m_pargs->na.m_pArrayMT));
         m_pcsMarshal->EmitADD();
         EmitStoreNativeValue(m_pcsMarshal);
 
index 4e5ddf9..586044b 100644 (file)
@@ -2802,6 +2802,8 @@ MarshalInfo::MarshalInfo(Module* pModule,
                 }
             }
 
+            m_args.na.m_pArrayMT = arrayTypeHnd.GetMethodTable();
+
             // Handle retrieving the information for the array type.
             IfFailGoto(HandleArrayElemType(&ParamInfo, thElement, asArray->GetRank(), mtype == ELEMENT_TYPE_SZARRAY, isParam, pAssembly), lFail);
             break;
index 46057d5..46dd79c 100644 (file)
@@ -82,6 +82,7 @@ struct OverrideProcArgs
 
         struct
         {
+            MethodTable*    m_pArrayMT;
             VARTYPE         m_vt;
 #ifdef FEATURE_COMINTEROP
             SIZE_T          m_cbElementSize;