diff --git a/src/coreclr/src/vm/corelib.h b/src/coreclr/src/vm/corelib.h index ad892439138409..75d13d2e52985d 100644 --- a/src/coreclr/src/vm/corelib.h +++ b/src/coreclr/src/vm/corelib.h @@ -488,11 +488,6 @@ DEFINE_METHOD(MARSHAL, ALLOC_CO_TASK_MEM, AllocCoTa DEFINE_METHOD(MARSHAL, FREE_CO_TASK_MEM, FreeCoTaskMem, SM_IntPtr_RetVoid) DEFINE_FIELD(MARSHAL, SYSTEM_MAX_DBCS_CHAR_SIZE, SystemMaxDBCSCharSize) -DEFINE_METHOD(MARSHAL, STRUCTURE_TO_PTR, StructureToPtr, SM_Obj_IntPtr_Bool_RetVoid) -DEFINE_METHOD(MARSHAL, PTR_TO_STRUCTURE, PtrToStructure, SM_IntPtr_Obj_RetVoid) -DEFINE_METHOD(MARSHAL, DESTROY_STRUCTURE, DestroyStructure, SM_IntPtr_Type_RetVoid) -DEFINE_METHOD(MARSHAL, SIZEOF_TYPE, SizeOf, SM_Type_RetInt) - DEFINE_CLASS(NATIVELIBRARY, Interop, NativeLibrary) DEFINE_METHOD(NATIVELIBRARY, LOADLIBRARYCALLBACKSTUB, LoadLibraryCallbackStub, SM_Str_AssemblyBase_Bool_UInt_RetIntPtr) diff --git a/src/coreclr/src/vm/ilmarshalers.cpp b/src/coreclr/src/vm/ilmarshalers.cpp index f224d7c477c7a4..0e74014a45f158 100644 --- a/src/coreclr/src/vm/ilmarshalers.cpp +++ b/src/coreclr/src/vm/ilmarshalers.cpp @@ -2149,30 +2149,14 @@ void ILLayoutClassPtrMarshalerBase::EmitConvertSpaceCLRToNative(ILCodeStream* ps EmitLoadManagedValue(pslILEmit); pslILEmit->EmitBRFALSE(pNullRefLabel); - ILCodeLabel* pTypeMismatchedLabel = pslILEmit->NewCodeLabel(); - bool emittedTypeCheck = EmitExactTypeCheck(pslILEmit, pTypeMismatchedLabel); - DWORD sizeLocal = pslILEmit->NewLocal(LocalDesc(ELEMENT_TYPE_I4)); - pslILEmit->EmitLDC(uNativeSize); - if (emittedTypeCheck) - { - ILCodeLabel* pHaveSizeLabel = pslILEmit->NewCodeLabel(); - pslILEmit->EmitBR(pHaveSizeLabel); - pslILEmit->EmitLabel(pTypeMismatchedLabel); - EmitLoadManagedValue(pslILEmit); - pslILEmit->EmitCALL(METHOD__OBJECT__GET_TYPE, 1, 1); - pslILEmit->EmitCALL(METHOD__MARSHAL__SIZEOF_TYPE, 1, 1); - pslILEmit->EmitLabel(pHaveSizeLabel); - } - pslILEmit->EmitSTLOC(sizeLocal); - pslILEmit->EmitLDLOC(sizeLocal); pslILEmit->EmitCALL(METHOD__MARSHAL__ALLOC_CO_TASK_MEM, 1, 1); pslILEmit->EmitDUP(); // for INITBLK EmitStoreNativeValue(pslILEmit); // initialize local block we just allocated pslILEmit->EmitLDC(0); - pslILEmit->EmitLDLOC(sizeLocal); + pslILEmit->EmitLDC(uNativeSize); pslILEmit->EmitINITBLK(); pslILEmit->EmitLabel(pNullRefLabel); @@ -2196,30 +2180,15 @@ void ILLayoutClassPtrMarshalerBase::EmitConvertSpaceCLRToNativeTemp(ILCodeStream EmitLoadManagedValue(pslILEmit); pslILEmit->EmitBRFALSE(pNullRefLabel); - ILCodeLabel* pTypeMismatchedLabel = pslILEmit->NewCodeLabel(); - bool emittedTypeCheck = EmitExactTypeCheck(pslILEmit, pTypeMismatchedLabel); - DWORD sizeLocal = pslILEmit->NewLocal(LocalDesc(ELEMENT_TYPE_I4)); pslILEmit->EmitLDC(uNativeSize); - if (emittedTypeCheck) - { - ILCodeLabel* pHaveSizeLabel = pslILEmit->NewCodeLabel(); - pslILEmit->EmitBR(pHaveSizeLabel); - pslILEmit->EmitLabel(pTypeMismatchedLabel); - EmitLoadManagedValue(pslILEmit); - pslILEmit->EmitCALL(METHOD__OBJECT__GET_TYPE, 1, 1); - pslILEmit->EmitCALL(METHOD__MARSHAL__SIZEOF_TYPE, 1, 1); - pslILEmit->EmitLabel(pHaveSizeLabel); - } - pslILEmit->EmitSTLOC(sizeLocal); - pslILEmit->EmitLDLOC(sizeLocal); pslILEmit->EmitLOCALLOC(); pslILEmit->EmitDUP(); // for INITBLK EmitStoreNativeValue(pslILEmit); // initialize local block we just allocated pslILEmit->EmitLDC(0); - pslILEmit->EmitLDLOC(sizeLocal); + pslILEmit->EmitLDC(uNativeSize); pslILEmit->EmitINITBLK(); pslILEmit->EmitLabel(pNullRefLabel); @@ -2295,24 +2264,7 @@ void ILLayoutClassPtrMarshalerBase::EmitClearNativeTemp(ILCodeStream* pslILEmit) } } -bool ILLayoutClassPtrMarshalerBase::EmitExactTypeCheck(ILCodeStream* pslILEmit, ILCodeLabel* isNotMatchingTypeLabel) -{ - STANDARD_VM_CONTRACT; - if (m_pargs->m_pMT->IsSealed()) - { - // If the provided type cannot be derived from, then we don't need to emit the type check. - return false; - } - EmitLoadManagedValue(pslILEmit); - pslILEmit->EmitCALL(METHOD__OBJECT__GET_TYPE, 1, 1); - pslILEmit->EmitLDTOKEN(pslILEmit->GetToken(m_pargs->m_pMT)); - pslILEmit->EmitCALL(METHOD__TYPE__GET_TYPE_FROM_HANDLE, 1, 1); - pslILEmit->EmitCALLVIRT(pslILEmit->GetToken(CoreLibBinder::GetMethod(METHOD__OBJECT__EQUALS)), 1, 1); - pslILEmit->EmitBRFALSE(isNotMatchingTypeLabel); - - return true; -} void ILLayoutClassPtrMarshaler::EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) { @@ -2329,9 +2281,6 @@ void ILLayoutClassPtrMarshaler::EmitConvertContentsCLRToNative(ILCodeStream* psl pslILEmit->EmitLDC(uNativeSize); pslILEmit->EmitINITBLK(); - ILCodeLabel* isNotMatchingTypeLabel = pslILEmit->NewCodeLabel(); - bool emittedTypeCheck = EmitExactTypeCheck(pslILEmit, isNotMatchingTypeLabel); - MethodDesc* pStructMarshalStub = NDirect::CreateStructMarshalILStub(m_pargs->m_pMT); EmitLoadManagedValue(pslILEmit); @@ -2341,18 +2290,6 @@ void ILLayoutClassPtrMarshaler::EmitConvertContentsCLRToNative(ILCodeStream* psl EmitLoadCleanupWorkList(pslILEmit); pslILEmit->EmitCALL(pslILEmit->GetToken(pStructMarshalStub), 4, 0); - - if (emittedTypeCheck) - { - pslILEmit->EmitBR(pNullRefLabel); - - pslILEmit->EmitLabel(isNotMatchingTypeLabel); - EmitLoadManagedValue(pslILEmit); - EmitLoadNativeValue(pslILEmit); - pslILEmit->EmitLDC(0); - pslILEmit->EmitCALL(METHOD__MARSHAL__STRUCTURE_TO_PTR, 3, 0); - } - pslILEmit->EmitLabel(pNullRefLabel); } @@ -2365,9 +2302,6 @@ void ILLayoutClassPtrMarshaler::EmitConvertContentsNativeToCLR(ILCodeStream* psl EmitLoadManagedValue(pslILEmit); pslILEmit->EmitBRFALSE(pNullRefLabel); - ILCodeLabel* isNotMatchingTypeLabel = pslILEmit->NewCodeLabel(); - bool emittedTypeCheck = EmitExactTypeCheck(pslILEmit, isNotMatchingTypeLabel); - MethodDesc* pStructMarshalStub = NDirect::CreateStructMarshalILStub(m_pargs->m_pMT); EmitLoadManagedValue(pslILEmit); @@ -2377,15 +2311,6 @@ void ILLayoutClassPtrMarshaler::EmitConvertContentsNativeToCLR(ILCodeStream* psl EmitLoadCleanupWorkList(pslILEmit); pslILEmit->EmitCALL(pslILEmit->GetToken(pStructMarshalStub), 4, 0); - if (emittedTypeCheck) - { - pslILEmit->EmitBR(pNullRefLabel); - - pslILEmit->EmitLabel(isNotMatchingTypeLabel); - EmitLoadNativeValue(pslILEmit); - EmitLoadManagedValue(pslILEmit); - pslILEmit->EmitCALL(METHOD__MARSHAL__PTR_TO_STRUCTURE, 2, 0); - } pslILEmit->EmitLabel(pNullRefLabel); } @@ -2393,10 +2318,6 @@ void ILLayoutClassPtrMarshaler::EmitClearNativeContents(ILCodeStream * pslILEmit { STANDARD_VM_CONTRACT; - ILCodeLabel* isNotMatchingTypeLabel = pslILEmit->NewCodeLabel(); - ILCodeLabel* cleanedUpLabel = pslILEmit->NewCodeLabel(); - bool emittedTypeCheck = EmitExactTypeCheck(pslILEmit, isNotMatchingTypeLabel); - MethodDesc* pStructMarshalStub = NDirect::CreateStructMarshalILStub(m_pargs->m_pMT); EmitLoadManagedValue(pslILEmit); @@ -2406,19 +2327,6 @@ void ILLayoutClassPtrMarshaler::EmitClearNativeContents(ILCodeStream * pslILEmit EmitLoadCleanupWorkList(pslILEmit); pslILEmit->EmitCALL(pslILEmit->GetToken(pStructMarshalStub), 4, 0); - - if (emittedTypeCheck) - { - pslILEmit->EmitBR(cleanedUpLabel); - - pslILEmit->EmitLabel(isNotMatchingTypeLabel); - EmitLoadNativeValue(pslILEmit); - EmitLoadManagedValue(pslILEmit); - pslILEmit->EmitCALL(METHOD__OBJECT__GET_TYPE, 1, 1); - pslILEmit->EmitCALL(METHOD__MARSHAL__DESTROY_STRUCTURE, 2, 0); - } - - pslILEmit->EmitLabel(cleanedUpLabel); } @@ -2433,9 +2341,6 @@ void ILBlittablePtrMarshaler::EmitConvertContentsCLRToNative(ILCodeStream* pslIL EmitLoadNativeValue(pslILEmit); pslILEmit->EmitBRFALSE(pNullRefLabel); - ILCodeLabel* isNotMatchingTypeLabel = pslILEmit->NewCodeLabel(); - bool emittedTypeCheck = EmitExactTypeCheck(pslILEmit, isNotMatchingTypeLabel); - EmitLoadNativeValue(pslILEmit); // dest EmitLoadManagedValue(pslILEmit); @@ -2444,17 +2349,6 @@ void ILBlittablePtrMarshaler::EmitConvertContentsCLRToNative(ILCodeStream* pslIL pslILEmit->EmitLDC(uNativeSize); // size pslILEmit->EmitCPBLK(); - - if (emittedTypeCheck) - { - pslILEmit->EmitBR(pNullRefLabel); - - pslILEmit->EmitLabel(isNotMatchingTypeLabel); - EmitLoadManagedValue(pslILEmit); - EmitLoadNativeValue(pslILEmit); - pslILEmit->EmitLDC(0); - pslILEmit->EmitCALL(METHOD__MARSHAL__STRUCTURE_TO_PTR, 3, 0); - } pslILEmit->EmitLabel(pNullRefLabel); } @@ -2469,9 +2363,6 @@ void ILBlittablePtrMarshaler::EmitConvertContentsNativeToCLR(ILCodeStream* pslIL EmitLoadManagedValue(pslILEmit); pslILEmit->EmitBRFALSE(pNullRefLabel); - ILCodeLabel* isNotMatchingTypeLabel = pslILEmit->NewCodeLabel(); - bool emittedTypeCheck = EmitExactTypeCheck(pslILEmit, isNotMatchingTypeLabel); - EmitLoadManagedValue(pslILEmit); pslILEmit->EmitLDFLDA(fieldDef); // dest @@ -2480,26 +2371,12 @@ void ILBlittablePtrMarshaler::EmitConvertContentsNativeToCLR(ILCodeStream* pslIL pslILEmit->EmitLDC(uNativeSize); // size pslILEmit->EmitCPBLK(); - - if (emittedTypeCheck) - { - pslILEmit->EmitBR(pNullRefLabel); - - pslILEmit->EmitLabel(isNotMatchingTypeLabel); - EmitLoadNativeValue(pslILEmit); - EmitLoadManagedValue(pslILEmit); - pslILEmit->EmitCALL(METHOD__MARSHAL__PTR_TO_STRUCTURE, 2, 0); - } - pslILEmit->EmitLabel(pNullRefLabel); } bool ILBlittablePtrMarshaler::CanMarshalViaPinning() { - return IsCLRToNative(m_dwMarshalFlags) && - !IsByref(m_dwMarshalFlags) && - !IsFieldMarshal(m_dwMarshalFlags) && - m_pargs->m_pMT->IsSealed(); // We can't marshal via pinning if we might need to marshal differently at runtime. See calls to EmitExactTypeCheck where we check the runtime type of the object being marshalled. + return IsCLRToNative(m_dwMarshalFlags) && !IsByref(m_dwMarshalFlags) && !IsFieldMarshal(m_dwMarshalFlags); } void ILBlittablePtrMarshaler::EmitMarshalViaPinning(ILCodeStream* pslILEmit) diff --git a/src/coreclr/src/vm/ilmarshalers.h b/src/coreclr/src/vm/ilmarshalers.h index 21b552eb76f780..c08f4f3efc49be 100644 --- a/src/coreclr/src/vm/ilmarshalers.h +++ b/src/coreclr/src/vm/ilmarshalers.h @@ -2915,7 +2915,6 @@ class ILLayoutClassPtrMarshalerBase : public ILMarshaler bool NeedsClearNative() override; void EmitClearNative(ILCodeStream* pslILEmit) override; void EmitClearNativeTemp(ILCodeStream* pslILEmit) override; - bool EmitExactTypeCheck(ILCodeStream* pslILEmit, ILCodeLabel* isNotMatchingTypeLabel); }; class ILLayoutClassPtrMarshaler : public ILLayoutClassPtrMarshalerBase diff --git a/src/coreclr/src/vm/metasig.h b/src/coreclr/src/vm/metasig.h index 4915f7d6b0fa4f..179dcd206378e5 100644 --- a/src/coreclr/src/vm/metasig.h +++ b/src/coreclr/src/vm/metasig.h @@ -604,10 +604,6 @@ DEFINE_METASIG_T(SM(Array_Int_Array_Int_Int_RetVoid, C(ARRAY) i C(ARRAY) i i, v) DEFINE_METASIG_T(SM(Array_Int_Obj_RetVoid, C(ARRAY) i j, v)) DEFINE_METASIG_T(SM(Array_Int_PtrVoid_RetRefObj, C(ARRAY) i P(v), r(j))) -DEFINE_METASIG(SM(Obj_IntPtr_Bool_RetVoid, j I F, v)) -DEFINE_METASIG(SM(IntPtr_Obj_RetVoid, I j, v)) -DEFINE_METASIG_T(SM(IntPtr_Type_RetVoid, I C(TYPE), v)) - // Undefine macros in case we include the file again in the compilation unit #undef DEFINE_METASIG diff --git a/src/coreclr/src/vm/mlinfo.cpp b/src/coreclr/src/vm/mlinfo.cpp index 3606df2c84874a..36b07edcfce33c 100644 --- a/src/coreclr/src/vm/mlinfo.cpp +++ b/src/coreclr/src/vm/mlinfo.cpp @@ -1231,8 +1231,6 @@ MarshalInfo::MarshalInfo(Module* pModule, m_pMT = NULL; m_pMD = pMD; m_onInstanceMethod = onInstanceMethod; - // [Compat] For backward compatibility reasons, some marshalers imply [In, Out] behavior when marked as [In], [Out], or not marked with either. - BOOL byValAlwaysInOut = FALSE; #ifdef FEATURE_COMINTEROP m_fDispItf = FALSE; @@ -2009,7 +2007,6 @@ MarshalInfo::MarshalInfo(Module* pModule, } m_type = IsFieldScenario() ? MARSHAL_TYPE_BLITTABLE_LAYOUTCLASS : MARSHAL_TYPE_BLITTABLEPTR; m_args.m_pMT = m_pMT; - byValAlwaysInOut = TRUE; } else if (m_pMT->HasLayout()) { @@ -2517,16 +2514,10 @@ MarshalInfo::MarshalInfo(Module* pModule, } } - if (!m_byref && byValAlwaysInOut) + // If neither IN nor OUT are true, this signals the URT to use the default + // rules. + if (!m_in && !m_out) { - // Some marshalers expect [In, Out] behavior with [In], [Out], or no directional attributes. - m_in = TRUE; - m_out = TRUE; - } - else if (!m_in && !m_out) - { - // If neither IN nor OUT are true, this signals the URT to use the default - // rules. if (m_byref || (mtype == ELEMENT_TYPE_CLASS && !(sig.IsStringType(pModule, pTypeContext)) diff --git a/src/tests/Interop/LayoutClass/LayoutClassNative.cpp b/src/tests/Interop/LayoutClass/LayoutClassNative.cpp index 59c4645afba321..0bf0af967f0637 100644 --- a/src/tests/Interop/LayoutClass/LayoutClassNative.cpp +++ b/src/tests/Interop/LayoutClass/LayoutClassNative.cpp @@ -5,16 +5,7 @@ #include typedef void *voidPtr; - -struct EmptyBase -{ -}; - -struct DerivedSeqClass : public EmptyBase -{ - int a; -}; - + struct SeqClass { int a; @@ -23,7 +14,7 @@ struct SeqClass }; struct ExpClass -{ +{ int a; int padding; //padding needs to be added here as we have added 8 byte offset. union @@ -56,35 +47,32 @@ DLL_EXPORT BOOL STDMETHODCALLTYPE SimpleSeqLayoutClassByRef(SeqClass* p) } extern "C" -DLL_EXPORT BOOL STDMETHODCALLTYPE DerivedSeqLayoutClassByRef(EmptyBase* p, int expected) +DLL_EXPORT BOOL STDMETHODCALLTYPE SimpleExpLayoutClassByRef(ExpClass* p) { - if(((DerivedSeqClass*)p)->a != expected) + if((p->a != 0) || (p->udata.i != 10)) { - printf("FAIL: p->a=%d, expected %d\n", ((DerivedSeqClass*)p)->a, expected); + printf("FAIL: p->a=%d, p->udata.i=%d\n",p->a,p->udata.i); return FALSE; } return TRUE; } extern "C" -DLL_EXPORT BOOL STDMETHODCALLTYPE SimpleExpLayoutClassByRef(ExpClass* p) +DLL_EXPORT BOOL STDMETHODCALLTYPE SimpleBlittableSeqLayoutClassByRef(BlittableClass* p) { - if((p->a != 0) || (p->udata.i != 10)) + if(p->a != 10) { - printf("FAIL: p->a=%d, p->udata.i=%d\n",p->a,p->udata.i); + printf("FAIL: p->a=%d\n", p->a); return FALSE; } return TRUE; } extern "C" -DLL_EXPORT BOOL STDMETHODCALLTYPE SimpleBlittableSeqLayoutClass_UpdateField(BlittableClass* p) +DLL_EXPORT BOOL STDMETHODCALLTYPE SimpleBlittableSeqLayoutClassByOutAttr(BlittableClass* p) { - if(p->a != 10) - { - printf("FAIL: p->a=%d\n", p->a); + if(!SimpleBlittableSeqLayoutClassByRef(p)) return FALSE; - } p->a++; return TRUE; diff --git a/src/tests/Interop/LayoutClass/LayoutClassTest.cs b/src/tests/Interop/LayoutClass/LayoutClassTest.cs index 81048a22b332d8..32ecfcb3548f93 100644 --- a/src/tests/Interop/LayoutClass/LayoutClassTest.cs +++ b/src/tests/Interop/LayoutClass/LayoutClassTest.cs @@ -8,23 +8,7 @@ namespace PInvokeTests { [StructLayout(LayoutKind.Sequential)] - public class EmptyBase - { - } - - [StructLayout(LayoutKind.Sequential)] - public class SeqDerivedClass : EmptyBase - { - public int a; - - public SeqDerivedClass(int _a) - { - a = _a; - } - } - - [StructLayout(LayoutKind.Sequential)] - public sealed class SeqClass + public class SeqClass { public int a; public bool b; @@ -94,17 +78,6 @@ public Blittable(int _a) } } - [StructLayout(LayoutKind.Sequential)] - public sealed class SealedBlittable - { - public int a; - - public SealedBlittable(int _a) - { - a = _a; - } - } - public struct NestedLayout { public SeqClass value; @@ -123,35 +96,18 @@ public struct RecursiveTestStruct class StructureTests { - private const string SimpleBlittableSeqLayoutClass_UpdateField = nameof(SimpleBlittableSeqLayoutClass_UpdateField); - [DllImport("LayoutClassNative")] private static extern bool SimpleSeqLayoutClassByRef(SeqClass p); - [DllImport("LayoutClassNative")] - private static extern bool DerivedSeqLayoutClassByRef(EmptyBase p, int expected); - [DllImport("LayoutClassNative")] private static extern bool SimpleExpLayoutClassByRef(ExpClass p); - [DllImport("LayoutClassNative", EntryPoint = SimpleBlittableSeqLayoutClass_UpdateField)] + [DllImport("LayoutClassNative")] private static extern bool SimpleBlittableSeqLayoutClassByRef(Blittable p); - [DllImport("LayoutClassNative", EntryPoint = SimpleBlittableSeqLayoutClass_UpdateField)] - private static extern bool SimpleBlittableSeqLayoutClassByInAttr([In] Blittable p); - - [DllImport("LayoutClassNative", EntryPoint = SimpleBlittableSeqLayoutClass_UpdateField)] + [DllImport("LayoutClassNative")] private static extern bool SimpleBlittableSeqLayoutClassByOutAttr([Out] Blittable p); - [DllImport("LayoutClassNative", EntryPoint = SimpleBlittableSeqLayoutClass_UpdateField)] - private static extern bool SealedBlittableSeqLayoutClassByRef(SealedBlittable p); - - [DllImport("LayoutClassNative", EntryPoint = SimpleBlittableSeqLayoutClass_UpdateField)] - private static extern bool SealedBlittableSeqLayoutClassByInAttr([In] SealedBlittable p); - - [DllImport("LayoutClassNative", EntryPoint = SimpleBlittableSeqLayoutClass_UpdateField)] - private static extern bool SealedBlittableSeqLayoutClassByOutAttr([Out] SealedBlittable p); - [DllImport("LayoutClassNative")] private static extern bool SimpleNestedLayoutClassByValue(NestedLayout p); @@ -167,15 +123,6 @@ public static void SequentialClass() Assert.IsTrue(SimpleSeqLayoutClassByRef(p)); } - public static void DerivedClassWithEmptyBase() - { - Console.WriteLine($"Running {nameof(DerivedClassWithEmptyBase)}..."); - - string s = "before"; - var p = new SeqDerivedClass(42); - Assert.IsTrue(DerivedSeqLayoutClassByRef(p, 42)); - } - public static void ExplicitClass() { Console.WriteLine($"Running {nameof(ExplicitClass)}..."); @@ -184,66 +131,25 @@ public static void ExplicitClass() Assert.IsTrue(SimpleExpLayoutClassByRef(p)); } - private static void ValidateBlittableClassInOut(Func pinvoke) - { - int a = 10; - int expected = a + 1; - Blittable p = new Blittable(a); - Assert.IsTrue(pinvoke(p)); - Assert.AreEqual(expected, p.a); - } - public static void BlittableClass() { - // [Compat] Marshalled with [In, Out] behaviour by default Console.WriteLine($"Running {nameof(BlittableClass)}..."); - ValidateBlittableClassInOut(SimpleBlittableSeqLayoutClassByRef); - } - public static void BlittableClassByInAttr() - { - // [Compat] Marshalled with [In, Out] behaviour even when only [In] is specified - Console.WriteLine($"Running {nameof(BlittableClassByInAttr)}..."); - ValidateBlittableClassInOut(SimpleBlittableSeqLayoutClassByInAttr); + Blittable p = new Blittable(10); + Assert.IsTrue(SimpleBlittableSeqLayoutClassByRef(p)); } public static void BlittableClassByOutAttr() { - // [Compat] Marshalled with [In, Out] behaviour even when only [Out] is specified Console.WriteLine($"Running {nameof(BlittableClassByOutAttr)}..."); - ValidateBlittableClassInOut(SimpleBlittableSeqLayoutClassByOutAttr); - } - private static void ValidateSealedBlittableClassInOut(Func pinvoke) - { int a = 10; int expected = a + 1; - SealedBlittable p = new SealedBlittable(a); - Assert.IsTrue(pinvoke(p)); + Blittable p = new Blittable(a); + Assert.IsTrue(SimpleBlittableSeqLayoutClassByOutAttr(p)); Assert.AreEqual(expected, p.a); } - public static void SealedBlittableClass() - { - // [Compat] Marshalled with [In, Out] behaviour by default - Console.WriteLine($"Running {nameof(SealedBlittableClass)}..."); - ValidateSealedBlittableClassInOut(SealedBlittableSeqLayoutClassByRef); - } - - public static void SealedBlittableClassByInAttr() - { - // [Compat] Marshalled with [In, Out] behaviour even when only [In] is specified - Console.WriteLine($"Running {nameof(SealedBlittableClassByOutAttr)}..."); - ValidateSealedBlittableClassInOut(SealedBlittableSeqLayoutClassByInAttr); - } - - public static void SealedBlittableClassByOutAttr() - { - // [Compat] Marshalled with [In, Out] behaviour even when only [Out] is specified - Console.WriteLine($"Running {nameof(SealedBlittableClassByOutAttr)}..."); - ValidateSealedBlittableClassInOut(SealedBlittableSeqLayoutClassByOutAttr); - } - public static void NestedLayoutClass() { Console.WriteLine($"Running {nameof(NestedLayoutClass)}..."); @@ -269,14 +175,9 @@ public static int Main(string[] argv) try { SequentialClass(); - DerivedClassWithEmptyBase(); ExplicitClass(); BlittableClass(); - SealedBlittableClass(); - BlittableClassByInAttr(); - SealedBlittableClassByInAttr(); BlittableClassByOutAttr(); - SealedBlittableClassByOutAttr(); NestedLayoutClass(); RecursiveNativeLayout(); }