Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check if the marshalling of a field is possible across all platforms. #53194

Merged
merged 5 commits into from
Jun 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/coreclr/vm/comtoclrcall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1013,7 +1013,6 @@ void ComCallMethodDesc::InitNativeInfo()
CONSISTENCY_CHECK_MSGF(false, ("BreakOnComToClrNativeInfoInit: '%s' ", szDebugName));
#endif // _DEBUG

#ifdef TARGET_X86
MetaSig fsig(pFD);
fsig.NextArg();

Expand All @@ -1030,6 +1029,10 @@ void ComCallMethodDesc::InitNativeInfo()
#endif
);

if (info.GetMarshalType() == MarshalInfo::MARSHAL_TYPE_UNKNOWN)
info.ThrowTypeLoadExceptionForInvalidFieldMarshal(pFD, info.GetErrorResourceId());
Comment on lines +1032 to +1033
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a test for the failure case?


#ifdef TARGET_X86
if (IsFieldGetter())
{
// getter takes 'this' and the output argument by-ref
Expand Down
6 changes: 6 additions & 0 deletions src/coreclr/vm/mlinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,12 @@ class MarshalInfo
return m_ms == MarshalInfo::MARSHAL_SCENARIO_FIELD;
}

UINT GetErrorResourceId()
{
LIMITED_METHOD_CONTRACT;
return m_resID;
}

private:

UINT16 GetNativeSize(MarshalType mtype);
Expand Down
36 changes: 35 additions & 1 deletion src/tests/Interop/PInvoke/Variant/VariantTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,20 @@
using TestLibrary;
using static VariantNative;

#pragma warning disable CS0612, CS0618
// Class used to validate the IClassX generation path doesn't fail.
// Support for this scenario is extremely limited so we simply validate
// it continues be generated and can be marshalled to native.
//
// This class must be marked public in order for the IDispatch path for
// field access to be validated.
public class GenerateIClassX
{
public int FieldPrimitive;
public System.Collections.Generic.List<int> FieldWithGeneric;
public object FieldRefType;
public DateTime FieldValueType;
}

partial class Test
{
private const byte NumericValue = 15;
Expand Down Expand Up @@ -41,10 +54,13 @@ private unsafe static void TestByValue(bool hasComSupport)
Assert.IsTrue(Marshal_ByValue_Null(DBNull.Value));
Assert.IsTrue(Marshal_ByValue_Missing(System.Reflection.Missing.Value));
Assert.IsTrue(Marshal_ByValue_Empty(null));

if (hasComSupport)
{
Assert.IsTrue(Marshal_ByValue_Object(new object()));
Assert.IsTrue(Marshal_ByValue_Object_IUnknown(new UnknownWrapper(new object())));
Assert.IsTrue(Marshal_ByValue_Object(new GenerateIClassX()));
Assert.IsTrue(Marshal_ByValue_Object_IUnknown(new UnknownWrapper(new GenerateIClassX())));
}

Assert.Throws<ArgumentException>(() => Marshal_ByValue_Invalid(TimeSpan.Zero));
Expand Down Expand Up @@ -123,6 +139,12 @@ private unsafe static void TestByRef(bool hasComSupport)

obj = new UnknownWrapper(new object());
Assert.IsTrue(Marshal_ByRef_Object_IUnknown(ref obj));

obj = new GenerateIClassX();
Assert.IsTrue(Marshal_ByRef_Object(ref obj));

obj = new UnknownWrapper(new GenerateIClassX());
Assert.IsTrue(Marshal_ByRef_Object_IUnknown(ref obj));
}

obj = DecimalValue;
Expand Down Expand Up @@ -209,6 +231,12 @@ private unsafe static void TestFieldByValue(bool hasComSupport)

wrapper.value = new UnknownWrapper(new object());
Assert.IsTrue(Marshal_Struct_ByValue_Object_IUnknown(wrapper));

wrapper.value = new GenerateIClassX();
Assert.IsTrue(Marshal_Struct_ByValue_Object(wrapper));

wrapper.value = new UnknownWrapper(new GenerateIClassX());
Assert.IsTrue(Marshal_Struct_ByValue_Object_IUnknown(wrapper));
}
}

Expand Down Expand Up @@ -283,6 +311,12 @@ private unsafe static void TestFieldByRef(bool hasComSupport)

wrapper.value = new UnknownWrapper(new object());
Assert.IsTrue(Marshal_Struct_ByRef_Object_IUnknown(ref wrapper));

wrapper.value = new GenerateIClassX();
Assert.IsTrue(Marshal_Struct_ByRef_Object(ref wrapper));

wrapper.value = new UnknownWrapper(new GenerateIClassX());
Assert.IsTrue(Marshal_Struct_ByRef_Object_IUnknown(ref wrapper));
}
}
}