Skip to content

Commit

Permalink
Fallback to old behavior when marshaling a non-blittable fixed buffer (
Browse files Browse the repository at this point in the history
…dotnet#20575)

* Throw an exception only when attempting to marshal nonblittable fixed buffers to/from native instead of on all marshalling operations.

* Assert in debug and checked builds when trying to marshal a fixed buffer of a non-blittable type.
  • Loading branch information
jkoritzinsky authored and A-And committed Nov 20, 2018
1 parent 39f523e commit 612de41
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 8 deletions.
23 changes: 15 additions & 8 deletions src/vm/fieldmarshaler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@
BOOL CheckForPrimitiveType(CorElementType elemType, CQuickArray<WCHAR> *pStrPrimitiveType);
TypeHandle ArraySubTypeLoadWorker(const SString &strUserDefTypeName, Assembly* pAssembly);
TypeHandle GetFieldTypeHandleWorker(MetaSig *pFieldSig);
#ifdef _DEBUG
BOOL IsFixedBuffer(mdFieldDef field, IMDInternalImport *pInternalImport);
#endif


//=======================================================================
Expand Down Expand Up @@ -660,14 +662,11 @@ do \
{
if (IsStructMarshalable(thNestedType))
{
if (IsFixedBuffer(pfwalk->m_MD, pInternalImport) && !thNestedType.GetMethodTable()->IsBlittable())
{
INITFIELDMARSHALER(NFT_ILLEGAL, FieldMarshaler_Illegal, (IDS_EE_BADMARSHAL_NOTMARSHALABLE));
}
else
{
INITFIELDMARSHALER(NFT_NESTEDVALUECLASS, FieldMarshaler_NestedValueClass, (thNestedType.GetMethodTable()));
}
#ifdef _DEBUG
INITFIELDMARSHALER(NFT_NESTEDVALUECLASS, FieldMarshaler_NestedValueClass, (thNestedType.GetMethodTable(), IsFixedBuffer(pfwalk->m_MD, pInternalImport)));
#else
INITFIELDMARSHALER(NFT_NESTEDVALUECLASS, FieldMarshaler_NestedValueClass, (thNestedType.GetMethodTable()));
#endif
}
else
{
Expand Down Expand Up @@ -1237,12 +1236,14 @@ BOOL IsStructMarshalable(TypeHandle th)
return TRUE;
}

#ifdef _DEBUG
BOOL IsFixedBuffer(mdFieldDef field, IMDInternalImport *pInternalImport)
{
HRESULT hr = pInternalImport->GetCustomAttributeByName(field, g_FixedBufferAttribute, NULL, NULL);

return hr == S_OK ? TRUE : FALSE;
}
#endif


//=======================================================================
Expand Down Expand Up @@ -2897,6 +2898,9 @@ VOID FieldMarshaler_NestedValueClass::NestedValueClassUpdateNativeImpl(const VOI
}
else
{
#ifdef _DEBUG
_ASSERTE_MSG(!IsFixedBuffer(), "Cannot correctly marshal fixed buffers of non-blittable types");
#endif
LayoutUpdateNative((LPVOID*)ppProtectedCLR, startoffset, pMT, (BYTE*)pNative, ppCleanupWorkListOnStack);
}
}
Expand Down Expand Up @@ -2931,6 +2935,9 @@ VOID FieldMarshaler_NestedValueClass::NestedValueClassUpdateCLRImpl(const VOID *
}
else
{
#ifdef _DEBUG
_ASSERTE_MSG(!IsFixedBuffer(), "Cannot correctly marshal fixed buffers of non-blittable types");
#endif
LayoutUpdateCLR((LPVOID*)ppProtectedCLR,
startoffset,
pMT,
Expand Down
20 changes: 20 additions & 0 deletions src/vm/fieldmarshaler.h
Original file line number Diff line number Diff line change
Expand Up @@ -710,10 +710,17 @@ class FieldMarshaler_NestedLayoutClass : public FieldMarshaler
class FieldMarshaler_NestedValueClass : public FieldMarshaler
{
public:
#ifndef _DEBUG
FieldMarshaler_NestedValueClass(MethodTable *pMT)
#else
FieldMarshaler_NestedValueClass(MethodTable *pMT, BOOL isFixedBuffer)
#endif
{
WRAPPER_NO_CONTRACT;
m_pNestedMethodTable.SetValueMaybeNull(pMT);
#ifdef _DEBUG
m_isFixedBuffer = isFixedBuffer;
#endif
}

BOOL IsNestedValueClassMarshalerImpl() const
Expand Down Expand Up @@ -761,6 +768,9 @@ class FieldMarshaler_NestedValueClass : public FieldMarshaler
START_COPY_TO_IMPL(FieldMarshaler_NestedValueClass)
{
pDestFieldMarshaller->m_pNestedMethodTable.SetValueMaybeNull(GetMethodTable());
#ifdef _DEBUG
pDestFieldMarshaller->m_isFixedBuffer = m_isFixedBuffer;
#endif
}
END_COPY_TO_IMPL(FieldMarshaler_NestedValueClass)

Expand Down Expand Up @@ -793,10 +803,20 @@ class FieldMarshaler_NestedValueClass : public FieldMarshaler
return m_pNestedMethodTable.GetValueMaybeNull();
}

#ifdef _DEBUG
BOOL IsFixedBuffer() const
{
return m_isFixedBuffer;
}
#endif


private:
// MethodTable of nested NStruct.
RelativeFixupPointer<PTR_MethodTable> m_pNestedMethodTable;
#ifdef _DEBUG
BOOL m_isFixedBuffer;
#endif
};


Expand Down

0 comments on commit 612de41

Please sign in to comment.