From 0988fc809a4fabc0d73cca60392c15d0a0f999b9 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Wed, 19 May 2021 17:29:48 +0600 Subject: [PATCH 01/16] Add Variant marshalling --- .../src/System.Private.CoreLib.csproj | 9 ++++ .../Runtime/InteropServices/Marshal.Com.cs | 36 ++++++++++++-- .../TypeSystem/Interop/IL/MarshalHelpers.cs | 5 +- .../TypeSystem/Interop/IL/Marshaller.Aot.cs | 47 +++++++++++++++++++ .../Common/TypeSystem/Interop/InteropTypes.cs | 5 ++ 5 files changed, 96 insertions(+), 6 deletions(-) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj index 9c26bcba9c98..47ed769880f4 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj @@ -255,6 +255,12 @@ + + System\Runtime\InteropServices\IDispatch.cs + + + System\Runtime\InteropServices\Variant.cs + Interop\Windows\Kernel32\Interop.GetCurrentThreadId.cs @@ -273,6 +279,9 @@ Interop\Windows\Ole32\Interop.CoGetApartmentType.cs + + Interop\Windows\OleAut32\Interop.VariantClear.cs + diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs index cecb57c22c5c..3a50003bbbf1 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs @@ -103,15 +103,35 @@ public static IntPtr GetIUnknownForObject(object o) } [SupportedOSPlatform("windows")] - public static void GetNativeVariantForObject(object? obj, IntPtr pDstNativeVariant) + public static unsafe void GetNativeVariantForObject(object? obj, IntPtr pDstNativeVariant) { - throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); + Variant* data = (Variant*)pDstNativeVariant; + if (obj == null) + { + data->SetAsNULL(); + return; + } + + if (obj is byte) + { + data->VariantType = VarEnum.VT_UI1; + } + else if (obj is int) + { + data->VariantType = VarEnum.VT_I4; + } + else if (obj is string) + { + data->VariantType = VarEnum.VT_BSTR; + } + + data->CopyFromIndirect(obj); } [SupportedOSPlatform("windows")] public static void GetNativeVariantForObject(T? obj, IntPtr pDstNativeVariant) { - throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); + GetNativeVariantForObject((object?)obj, pDstNativeVariant); } [SupportedOSPlatform("windows")] @@ -127,9 +147,15 @@ public static object GetObjectForIUnknown(IntPtr pUnk) } [SupportedOSPlatform("windows")] - public static object? GetObjectForNativeVariant(IntPtr pSrcNativeVariant) + public static unsafe object? GetObjectForNativeVariant(IntPtr pSrcNativeVariant) { - throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); + if (pSrcNativeVariant == IntPtr.Zero) + { + return null; + } + + Variant* data = (Variant*)pSrcNativeVariant; + return data->ToObject(); } [return: MaybeNull] diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs index c38df7f285ed..bd2a0311b563 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs @@ -162,6 +162,9 @@ internal static TypeDesc GetNativeTypeFromMarshallerKind(TypeDesc type, case MarshallerKind.ComInterface: return context.GetWellKnownType(WellKnownType.IntPtr); + case MarshallerKind.Variant: + return InteropTypes.GetVariant(context); + case MarshallerKind.Unknown: default: throw new NotSupportedException(); @@ -566,7 +569,7 @@ internal static MarshallerKind GetMarshallerKind( || nativeType == NativeTypeKind.IUnknown) return MarshallerKind.ComInterface; else - return MarshallerKind.Invalid; + return MarshallerKind.Variant; } else if (InteropTypes.IsStringBuilder(context, type)) { diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs index ebaa34743c88..0f51e5cebe35 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs @@ -82,6 +82,8 @@ protected static Marshaller CreateMarshaller(MarshallerKind kind) return new ComInterfaceMarshaller(); case MarshallerKind.OleDateTime: return new OleDateTimeMarshaller(); + case MarshallerKind.Variant: + return new VariantMarshaller(); default: // ensures we don't throw during create marshaller. We will throw NSE // during EmitIL which will be handled and an Exception method body @@ -1037,4 +1039,49 @@ protected override void TransformNativeToManaged(ILCodeStream codeStream) StoreManagedValue(codeStream); } } + + class VariantMarshaller : Marshaller + { + protected override void AllocManagedToNative(ILCodeStream codeStream) + { + LoadNativeAddr(codeStream); + codeStream.Emit(ILOpcode.initobj, _ilCodeStreams.Emitter.NewToken(NativeType)); + } + + protected override void TransformManagedToNative(ILCodeStream codeStream) + { + ILEmitter emitter = _ilCodeStreams.Emitter; + + LoadManagedValue(codeStream); + LoadNativeAddr(codeStream); + + var helper = InteropTypes.GetMarshal(Context).GetKnownMethod("GetNativeVariantForObject", null); + codeStream.Emit(ILOpcode.call, emitter.NewToken(helper)); + } + + protected override void TransformNativeToManaged(ILCodeStream codeStream) + { + ILEmitter emitter = _ilCodeStreams.Emitter; + + LoadNativeAddr(codeStream); + + var helper = InteropTypes.GetMarshal(Context).GetKnownMethod("GetNativeVariantForObject", null); + codeStream.Emit(ILOpcode.call, emitter.NewToken(helper)); + + StoreManagedValue(codeStream); + } + + protected override void EmitCleanupManaged(ILCodeStream codeStream) + { + // Only do cleanup if it is IN + if (!In) + { + return; + } + + LoadNativeAddr(codeStream); + codeStream.Emit(ILOpcode.call, _ilCodeStreams.Emitter.NewToken( + InteropStateManager.GetStructMarshallingCleanupThunk(ManagedType))); + } + } } diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/InteropTypes.cs b/src/coreclr/tools/Common/TypeSystem/Interop/InteropTypes.cs index ff219c6418ca..4007dc756494 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/InteropTypes.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/InteropTypes.cs @@ -54,6 +54,11 @@ public static MetadataType GetNativeFunctionPointerWrapper(TypeSystemContext con return context.SystemModule.GetKnownType("System.Runtime.InteropServices", "NativeFunctionPointerWrapper"); } + public static MetadataType GetVariant(TypeSystemContext context) + { + return context.SystemModule.GetKnownType("System.Runtime.InteropServices", "Variant"); + } + public static bool IsSafeHandle(TypeSystemContext context, TypeDesc type) { return IsOrDerivesFromType(type, GetSafeHandle(context)); From a4662da74c45a164177261b0afbbc11c422d7b7f Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Wed, 19 May 2021 17:39:28 +0600 Subject: [PATCH 02/16] Implement cleanup --- .../Runtime/CompilerHelpers/InteropHelpers.cs | 12 ++++++++++++ .../Common/TypeSystem/Interop/IL/Marshaller.Aot.cs | 6 ++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs index 433acaddaca1..a62de73f4cfa 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs @@ -549,6 +549,18 @@ o is string || Marshal.DestroyStructure(address, o.GetType()); } + internal static unsafe void CleanupVariant(IntPtr pDstNativeVariant) + { +#if TARGET_WINDOWS +#pragma warning disable CA1416 + Variant* data = (Variant*)pDstNativeVariant; + data->Clear(); +#pragma warning restore CA1416 +#else + throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); +#endif + } + [StructLayout(LayoutKind.Sequential)] internal unsafe struct ModuleFixupCell { diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs index 0f51e5cebe35..6c7200fa21dc 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs @@ -1079,9 +1079,11 @@ protected override void EmitCleanupManaged(ILCodeStream codeStream) return; } + ILEmitter emitter = _ilCodeStreams.Emitter; + LoadNativeAddr(codeStream); - codeStream.Emit(ILOpcode.call, _ilCodeStreams.Emitter.NewToken( - InteropStateManager.GetStructMarshallingCleanupThunk(ManagedType))); + var helper = Context.GetHelperEntryPoint("InteropHelpers", "CleanupVariant"); + codeStream.Emit(ILOpcode.call, emitter.NewToken(helper)); } } } From 8264e9c3912ded45b3c4c9678715d31578691d95 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Thu, 20 May 2021 21:01:46 +0600 Subject: [PATCH 03/16] Not tested marshalling - Marshal_XXX_Boolean - Marshal_XXX_Currency - Marshal_XXX_Object - Marshal_XXX_Object_IUnknown VariantBool somehow does not recognized. Probably something is messed up. I will do that in subsequent commit. --- .../Runtime/InteropServices/Marshal.Com.cs | 89 +++++++++++++++++-- .../TypeSystem/Interop/IL/MarshalHelpers.cs | 3 + .../TypeSystem/Interop/IL/Marshaller.Aot.cs | 25 +++++- .../TypeSystem/Interop/IL/Marshaller.cs | 1 + .../TypeSystem/Interop/MarshalAsDescriptor.cs | 1 + 5 files changed, 109 insertions(+), 10 deletions(-) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs index 3a50003bbbf1..0c4076d35fa3 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs @@ -108,24 +108,94 @@ public static unsafe void GetNativeVariantForObject(object? obj, IntPtr pDstNati Variant* data = (Variant*)pDstNativeVariant; if (obj == null) { - data->SetAsNULL(); + data->VariantType = VarEnum.VT_EMPTY; return; } - if (obj is byte) + if (obj is bool flag) { - data->VariantType = VarEnum.VT_UI1; + data->AsBool = flag; } - else if (obj is int) + else if (obj is byte b) { - data->VariantType = VarEnum.VT_I4; + data->AsUi1 = b; } - else if (obj is string) + else if (obj is sbyte sb) { - data->VariantType = VarEnum.VT_BSTR; + data->AsI1 = sb; + } + else if (obj is short s) + { + data->AsI2 = s; + } + else if (obj is ushort us) + { + data->AsUi2 = us; + } + else if (obj is int i) + { + data->AsI4 = i; + } + else if (obj is uint ui) + { + data->AsUi4 = ui; + } + else if (obj is long l) + { + data->AsI8 = l; + } + else if (obj is ulong ul) + { + data->AsUi8 = ul; + } + else if (obj is float f) + { + data->AsR4 = f; + } + else if (obj is double d) + { + data->AsR8 = d; + } + else if (obj is DateTime date) + { + data->AsDate = date; + } + else if (obj is decimal dec) + { + data->AsDecimal = dec; + } + else if (obj is char c) + { + data->AsUi2 = c; + } + else if (obj is string str) + { + data->AsBstr = str; + } + else if (obj is BStrWrapper strWrapper) + { + data->AsBstr = strWrapper.WrappedObject; + } + else if (obj is CurrencyWrapper currWrapper) + { + data->AsCy = currWrapper.WrappedObject; + } + else if (obj is UnknownWrapper unkWrapper) + { + data->AsUnknown = unkWrapper.WrappedObject; + } + else if (obj is DBNull) + { + data->SetAsNULL(); + } + else if (obj is System.Reflection.Missing) + { + data->AsError = -2147352572 /*DISP_E_PARAMNOTFOUND*/; + } + else + { + data->AsDispatch = obj; } - - data->CopyFromIndirect(obj); } [SupportedOSPlatform("windows")] @@ -155,6 +225,7 @@ public static object GetObjectForIUnknown(IntPtr pUnk) } Variant* data = (Variant*)pSrcNativeVariant; + return data->ToObject(); } diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs index bd2a0311b563..ad187070de57 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs @@ -257,6 +257,9 @@ internal static MarshallerKind GetMarshallerKind( case NativeTypeKind.I1: return MarshallerKind.CBool; + case NativeTypeKind.VariantBool: + return MarshallerKind.VariantBool; + default: return MarshallerKind.Invalid; } diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs index 6c7200fa21dc..41774c0593c6 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs @@ -84,6 +84,8 @@ protected static Marshaller CreateMarshaller(MarshallerKind kind) return new OleDateTimeMarshaller(); case MarshallerKind.Variant: return new VariantMarshaller(); + case MarshallerKind.VariantBool: + return new VariantBoolMarshaller(); default: // ensures we don't throw during create marshaller. We will throw NSE // during EmitIL which will be handled and an Exception method body @@ -1065,7 +1067,7 @@ protected override void TransformNativeToManaged(ILCodeStream codeStream) LoadNativeAddr(codeStream); - var helper = InteropTypes.GetMarshal(Context).GetKnownMethod("GetNativeVariantForObject", null); + var helper = InteropTypes.GetMarshal(Context).GetKnownMethod("GetObjectForNativeVariant", null); codeStream.Emit(ILOpcode.call, emitter.NewToken(helper)); StoreManagedValue(codeStream); @@ -1086,4 +1088,25 @@ protected override void EmitCleanupManaged(ILCodeStream codeStream) codeStream.Emit(ILOpcode.call, emitter.NewToken(helper)); } } + + class VariantBoolMarshaller : Marshaller + { + protected override void AllocAndTransformManagedToNative(ILCodeStream codeStream) + { + LoadManagedValue(codeStream); + codeStream.EmitLdc(0); + codeStream.Emit(ILOpcode.ceq); + codeStream.Emit(ILOpcode.neg); + StoreNativeValue(codeStream); + } + + protected override void AllocAndTransformNativeToManaged(ILCodeStream codeStream) + { + LoadNativeValue(codeStream); + codeStream.Emit(ILOpcode.neg); + codeStream.EmitLdc(0); + codeStream.Emit(ILOpcode.ceq); + StoreManagedValue(codeStream); + } + } } diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs index 8a7c18393d39..06902cc4cdc5 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs @@ -19,6 +19,7 @@ enum MarshallerKind BlittableArray, Bool, // 4 byte bool CBool, // 1 byte bool + VariantBool, // Variant bool Enum, AnsiChar, // Marshal char (Unicode 16bits) for byte (Ansi 8bits) UnicodeChar, diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/MarshalAsDescriptor.cs b/src/coreclr/tools/Common/TypeSystem/Interop/MarshalAsDescriptor.cs index 05c95826e265..66d78e6632e3 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/MarshalAsDescriptor.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/MarshalAsDescriptor.cs @@ -33,6 +33,7 @@ public enum NativeTypeKind : byte SysUInt = 0x20, AnsiBStr = 0x23, TBStr = 0x24, + VariantBool = 0x25, Func = 0x26, AsAny = 0x28, Array = 0x2a, From 3b0c7fc805101792de0158c696c67e35328e8afc Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Fri, 21 May 2021 12:06:19 +0600 Subject: [PATCH 04/16] Add bool and OLE currency marshalling --- .../TypeSystem/Interop/IL/MarshalHelpers.cs | 8 +++ .../TypeSystem/Interop/IL/Marshaller.Aot.cs | 52 +++++++++++-------- .../TypeSystem/Interop/IL/Marshaller.cs | 36 +++++++++++-- .../TypeSystem/Interop/MarshalAsDescriptor.cs | 1 + 4 files changed, 70 insertions(+), 27 deletions(-) diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs index ad187070de57..76768fb74a0c 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs @@ -63,6 +63,9 @@ internal static TypeDesc GetNativeTypeFromMarshallerKind(TypeDesc type, case MarshallerKind.CBool: return context.GetWellKnownType(WellKnownType.Byte); + case MarshallerKind.VariantBool: + return context.GetWellKnownType(WellKnownType.Int16); + case MarshallerKind.Enum: case MarshallerKind.BlittableStruct: case MarshallerKind.Decimal: @@ -165,6 +168,9 @@ internal static TypeDesc GetNativeTypeFromMarshallerKind(TypeDesc type, case MarshallerKind.Variant: return InteropTypes.GetVariant(context); + case MarshallerKind.OleCurrency: + return context.GetWellKnownType(WellKnownType.Int64); + case MarshallerKind.Unknown: default: throw new NotSupportedException(); @@ -361,6 +367,8 @@ internal static MarshallerKind GetMarshallerKind( return MarshallerKind.Decimal; else if (nativeType == NativeTypeKind.LPStruct && !isField) return MarshallerKind.BlittableStructPtr; + else if (nativeType == NativeTypeKind.Currency) + return MarshallerKind.OleCurrency; else return MarshallerKind.Invalid; } diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs index 41774c0593c6..a86f79155c25 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs @@ -36,6 +36,8 @@ protected static Marshaller CreateMarshaller(MarshallerKind kind) case MarshallerKind.Bool: case MarshallerKind.CBool: return new BooleanMarshaller(); + case MarshallerKind.VariantBool: + return new BooleanMarshaller((short)-1, 0); case MarshallerKind.AnsiString: return new AnsiStringMarshaller(); case MarshallerKind.UTF8String: @@ -82,10 +84,10 @@ protected static Marshaller CreateMarshaller(MarshallerKind kind) return new ComInterfaceMarshaller(); case MarshallerKind.OleDateTime: return new OleDateTimeMarshaller(); + case MarshallerKind.OleCurrency: + return new OleCurrencyMarshaller(); case MarshallerKind.Variant: return new VariantMarshaller(); - case MarshallerKind.VariantBool: - return new VariantBoolMarshaller(); default: // ensures we don't throw during create marshaller. We will throw NSE // during EmitIL which will be handled and an Exception method body @@ -1042,6 +1044,31 @@ protected override void TransformNativeToManaged(ILCodeStream codeStream) } } + class OleCurrencyMarshaller : Marshaller + { + protected override void TransformManagedToNative(ILCodeStream codeStream) + { + ILEmitter emitter = _ilCodeStreams.Emitter; + LoadManagedValue(codeStream); + + var helper = Context.GetHelperEntryPoint("InteropHelpers", "DecimalToOleCurrency"); + codeStream.Emit(ILOpcode.call, emitter.NewToken(helper)); + + StoreNativeValue(codeStream); + } + + protected override void TransformNativeToManaged(ILCodeStream codeStream) + { + ILEmitter emitter = _ilCodeStreams.Emitter; + LoadNativeValue(codeStream); + + var helper = Context.GetHelperEntryPoint("InteropHelpers", "OleCurrencyToDecimal"); + codeStream.Emit(ILOpcode.call, emitter.NewToken(helper)); + + StoreManagedValue(codeStream); + } + } + class VariantMarshaller : Marshaller { protected override void AllocManagedToNative(ILCodeStream codeStream) @@ -1088,25 +1115,4 @@ protected override void EmitCleanupManaged(ILCodeStream codeStream) codeStream.Emit(ILOpcode.call, emitter.NewToken(helper)); } } - - class VariantBoolMarshaller : Marshaller - { - protected override void AllocAndTransformManagedToNative(ILCodeStream codeStream) - { - LoadManagedValue(codeStream); - codeStream.EmitLdc(0); - codeStream.Emit(ILOpcode.ceq); - codeStream.Emit(ILOpcode.neg); - StoreNativeValue(codeStream); - } - - protected override void AllocAndTransformNativeToManaged(ILCodeStream codeStream) - { - LoadNativeValue(codeStream); - codeStream.Emit(ILOpcode.neg); - codeStream.EmitLdc(0); - codeStream.Emit(ILOpcode.ceq); - StoreManagedValue(codeStream); - } - } } diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs index 06902cc4cdc5..7de3b873e30e 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs @@ -44,6 +44,7 @@ enum MarshallerKind Object, OleDateTime, Decimal, + OleCurrency, Guid, Struct, BlittableStruct, @@ -1412,13 +1413,40 @@ protected override void EmitCleanupManaged(ILCodeStream codeStream) class BooleanMarshaller : Marshaller { + private int _trueValue; + private int _falseValue; + public BooleanMarshaller(int trueValue = 1, int falseValue = 0) + { + _trueValue = trueValue; + _falseValue = falseValue; + } + protected override void AllocAndTransformManagedToNative(ILCodeStream codeStream) { + ILEmitter emitter = _ilCodeStreams.Emitter; + ILCodeLabel pLoadFalseLabel = emitter.NewCodeLabel(); + ILCodeLabel pDoneLabel = emitter.NewCodeLabel(); + LoadManagedValue(codeStream); - codeStream.EmitLdc(0); - codeStream.Emit(ILOpcode.ceq); - codeStream.EmitLdc(0); - codeStream.Emit(ILOpcode.ceq); + if (_trueValue == 1 && _falseValue == 0) + { + codeStream.EmitLdc(0); + codeStream.Emit(ILOpcode.ceq); + codeStream.EmitLdc(0); + codeStream.Emit(ILOpcode.ceq); + } + else + { + codeStream.Emit(ILOpcode.brfalse, pLoadFalseLabel); + codeStream.EmitLdc(_trueValue); + codeStream.Emit(ILOpcode.br, pDoneLabel); + + codeStream.EmitLabel(pLoadFalseLabel); + codeStream.EmitLdc(_falseValue); + + codeStream.EmitLabel(pDoneLabel); + } + StoreNativeValue(codeStream); } diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/MarshalAsDescriptor.cs b/src/coreclr/tools/Common/TypeSystem/Interop/MarshalAsDescriptor.cs index 66d78e6632e3..26b5312c4b8f 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/MarshalAsDescriptor.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/MarshalAsDescriptor.cs @@ -19,6 +19,7 @@ public enum NativeTypeKind : byte U8 = 0xa, R4 = 0xb, R8 = 0xc, + Currency = 0xf, BStr = 0x13, LPStr = 0x14, LPWStr = 0x15, From 18faf32ea445834d09dc8a262e8e6d2cfc410363 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Fri, 21 May 2021 12:07:03 +0600 Subject: [PATCH 05/16] Add missing interop --- .../Internal/Runtime/CompilerHelpers/InteropHelpers.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs index a62de73f4cfa..fe4bb6e430e7 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs @@ -233,6 +233,16 @@ internal static DateTime OleDateTimeToDateTime(double value) return DateTime.FromOADate(value); } + internal static long DecimalToOleCurrency(decimal value) + { + return decimal.ToOACurrency(value); + } + + internal static decimal OleCurrencyToDecimal(long value) + { + return decimal.FromOACurrency(value); + } + internal static unsafe string BstrBufferToString(char* buffer) { if (buffer == null) From d3e3f80213c486e4c446cb2b413035409146a3c5 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Fri, 21 May 2021 12:52:01 +0600 Subject: [PATCH 06/16] Use constant for DISP_E_PARAMNOTFOUND --- .../Runtime/InteropServices/Marshal.Com.cs | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs index 0c4076d35fa3..81387e6c261b 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs @@ -12,6 +12,9 @@ namespace System.Runtime.InteropServices { public static partial class Marshal { + private static readonly Guid IID_IDispatch = new Guid("00020400-0000-0000-C000-000000000046"); + private const int DISP_E_PARAMNOTFOUND = unchecked((int)0x80020004); + public static int GetHRForException(Exception? e) { return PInvokeMarshal.GetHRForException(e); @@ -69,7 +72,17 @@ public static int FinalReleaseComObject(object o) [SupportedOSPlatform("windows")] public static IntPtr GetComInterfaceForObject(object o, Type T) { - throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); + if (o is null) + { + throw new ArgumentNullException(nameof(o)); + } + + if (T is null) + { + throw new ArgumentNullException(nameof(T)); + } + + return ComWrappers.ComInterfaceForObject(o, new Guid(T.GetCustomAttribute().Value)); } [SupportedOSPlatform("windows")] @@ -81,7 +94,7 @@ public static IntPtr GetComInterfaceForObject(object o, Type T, CustomQueryInter [SupportedOSPlatform("windows")] public static IntPtr GetComInterfaceForObject([DisallowNull] T o) { - throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); + return GetComInterfaceForObject(o!, typeof(T)); } [SupportedOSPlatform("windows")] @@ -93,7 +106,12 @@ public static IntPtr GetComInterfaceForObject([DisallowNull] T o) [SupportedOSPlatform("windows")] public static IntPtr GetIDispatchForObject(object o) { - throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); + if (o is null) + { + throw new ArgumentNullException(nameof(o)); + } + + return ComWrappers.ComInterfaceForObject(o, IID_IDispatch); } [SupportedOSPlatform("windows")] @@ -190,7 +208,7 @@ public static unsafe void GetNativeVariantForObject(object? obj, IntPtr pDstNati } else if (obj is System.Reflection.Missing) { - data->AsError = -2147352572 /*DISP_E_PARAMNOTFOUND*/; + data->AsError = DISP_E_PARAMNOTFOUND; } else { From b3f7e93a60502c624077966da4946fd909654845 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Fri, 21 May 2021 14:22:45 +0600 Subject: [PATCH 07/16] Add couple rare cases --- .../Runtime/InteropServices/Marshal.Com.cs | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs index 81387e6c261b..50316289c473 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs @@ -202,6 +202,19 @@ public static unsafe void GetNativeVariantForObject(object? obj, IntPtr pDstNati { data->AsUnknown = unkWrapper.WrappedObject; } + else if (obj is DispatchWrapper dispWrapper) + { + data->AsDispatch = dispWrapper.WrappedObject; + } + else if (obj is ErrorWrapper errWrapper) + { + data->AsError = errWrapper.WrappedObject; + } + else if (obj is VariantWrapper variantWrapper) + { + // Do not want to implement that yet. + throw new NotSupportedException(); + } else if (obj is DBNull) { data->SetAsNULL(); @@ -212,7 +225,20 @@ public static unsafe void GetNativeVariantForObject(object? obj, IntPtr pDstNati } else { - data->AsDispatch = obj; + var type = obj.GetType(); + if (type.IsValueType) + { + throw new NotSupportedException(); + } + else if (type.IsArray) + { + // SAFEARRAY impementation goes here. + throw new NotSupportedException(); + } + else + { + data->AsDispatch = obj; + } } } From 40d10b2d337fe644035d654c0246ce26ab3ec829 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Fri, 21 May 2021 14:38:03 +0600 Subject: [PATCH 08/16] Fix compilation error --- .../src/System/Runtime/InteropServices/Marshal.Com.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs index 50316289c473..373386cf1db8 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs @@ -208,7 +208,7 @@ public static unsafe void GetNativeVariantForObject(object? obj, IntPtr pDstNati } else if (obj is ErrorWrapper errWrapper) { - data->AsError = errWrapper.WrappedObject; + data->AsError = errWrapper.ErrorCode; } else if (obj is VariantWrapper variantWrapper) { From 238777708658e3e8073c53ca5dcc3d33cb55ff9b Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Mon, 24 May 2021 14:47:35 +0600 Subject: [PATCH 09/16] Use Type.GUID instead of querying for custom attributes --- .../src/System/Runtime/InteropServices/Marshal.Com.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs index 373386cf1db8..34068ed0db77 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs @@ -82,7 +82,7 @@ public static IntPtr GetComInterfaceForObject(object o, Type T) throw new ArgumentNullException(nameof(T)); } - return ComWrappers.ComInterfaceForObject(o, new Guid(T.GetCustomAttribute().Value)); + return ComWrappers.ComInterfaceForObject(o, T.GUID); } [SupportedOSPlatform("windows")] From 324876a6d08e42a8dbcf4da42afd18c2871bfe1b Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Mon, 24 May 2021 14:48:09 +0600 Subject: [PATCH 10/16] Remove constant false value --- .../tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs | 2 +- .../tools/Common/TypeSystem/Interop/IL/Marshaller.cs | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs index a86f79155c25..1f4e77d59dbd 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs @@ -37,7 +37,7 @@ protected static Marshaller CreateMarshaller(MarshallerKind kind) case MarshallerKind.CBool: return new BooleanMarshaller(); case MarshallerKind.VariantBool: - return new BooleanMarshaller((short)-1, 0); + return new BooleanMarshaller((short)-1); case MarshallerKind.AnsiString: return new AnsiStringMarshaller(); case MarshallerKind.UTF8String: diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs index 7de3b873e30e..46c53157b465 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs @@ -1414,11 +1414,9 @@ protected override void EmitCleanupManaged(ILCodeStream codeStream) class BooleanMarshaller : Marshaller { private int _trueValue; - private int _falseValue; - public BooleanMarshaller(int trueValue = 1, int falseValue = 0) + public BooleanMarshaller(int trueValue = 1) { _trueValue = trueValue; - _falseValue = falseValue; } protected override void AllocAndTransformManagedToNative(ILCodeStream codeStream) @@ -1428,7 +1426,7 @@ protected override void AllocAndTransformManagedToNative(ILCodeStream codeStream ILCodeLabel pDoneLabel = emitter.NewCodeLabel(); LoadManagedValue(codeStream); - if (_trueValue == 1 && _falseValue == 0) + if (_trueValue == 1) { codeStream.EmitLdc(0); codeStream.Emit(ILOpcode.ceq); @@ -1442,7 +1440,7 @@ protected override void AllocAndTransformManagedToNative(ILCodeStream codeStream codeStream.Emit(ILOpcode.br, pDoneLabel); codeStream.EmitLabel(pLoadFalseLabel); - codeStream.EmitLdc(_falseValue); + codeStream.EmitLdc(0); codeStream.EmitLabel(pDoneLabel); } From a729924cec55be44be87bd31d2d487cd4b69fab8 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Mon, 24 May 2021 14:52:09 +0600 Subject: [PATCH 11/16] Remove no longer needed interface --- .../System.Private.CoreLib/src/System.Private.CoreLib.csproj | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj index 47ed769880f4..f815d00a0f85 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj @@ -255,9 +255,6 @@ - - System\Runtime\InteropServices\IDispatch.cs - System\Runtime\InteropServices\Variant.cs From db09743948c766f502a4da30e9a19a116757db4b Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Thu, 27 May 2021 19:04:31 +0600 Subject: [PATCH 12/16] Do not support reverse direction for marshalling of VARIANT --- .../Common/TypeSystem/Interop/IL/Marshaller.Aot.cs | 10 ++++++++++ .../tools/Common/TypeSystem/Interop/IL/Marshaller.cs | 3 +++ 2 files changed, 13 insertions(+) diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs index 1f4e77d59dbd..6a77dbffcbcc 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs @@ -1079,6 +1079,11 @@ protected override void AllocManagedToNative(ILCodeStream codeStream) protected override void TransformManagedToNative(ILCodeStream codeStream) { + if (this.MarshalDirection == MarshalDirection.Reverse) + { + throw new NotSupportedException(); + } + ILEmitter emitter = _ilCodeStreams.Emitter; LoadManagedValue(codeStream); @@ -1090,6 +1095,11 @@ protected override void TransformManagedToNative(ILCodeStream codeStream) protected override void TransformNativeToManaged(ILCodeStream codeStream) { + if (this.MarshalDirection == MarshalDirection.Reverse) + { + throw new NotSupportedException(); + } + ILEmitter emitter = _ilCodeStreams.Emitter; LoadNativeAddr(codeStream); diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs index 46c53157b465..aefe2efca3fd 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs @@ -1438,6 +1438,9 @@ protected override void AllocAndTransformManagedToNative(ILCodeStream codeStream codeStream.Emit(ILOpcode.brfalse, pLoadFalseLabel); codeStream.EmitLdc(_trueValue); codeStream.Emit(ILOpcode.br, pDoneLabel); +#if DEBUG + codeStream.Emit(ILOpcode.pop); // keep the simple stack level calculator happy +#endif // DEBUG codeStream.EmitLabel(pLoadFalseLabel); codeStream.EmitLdc(0); From 1c5a424847c0472c3061274a4cec5d76f05f5cda Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Thu, 27 May 2021 22:28:45 +0600 Subject: [PATCH 13/16] Address PR feedback --- .../src/System/Runtime/InteropServices/Marshal.Com.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs index 34068ed0db77..65c49aefe381 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs @@ -12,7 +12,6 @@ namespace System.Runtime.InteropServices { public static partial class Marshal { - private static readonly Guid IID_IDispatch = new Guid("00020400-0000-0000-C000-000000000046"); private const int DISP_E_PARAMNOTFOUND = unchecked((int)0x80020004); public static int GetHRForException(Exception? e) @@ -111,7 +110,7 @@ public static IntPtr GetIDispatchForObject(object o) throw new ArgumentNullException(nameof(o)); } - return ComWrappers.ComInterfaceForObject(o, IID_IDispatch); + return ComWrappers.ComInterfaceForObject(o, new Guid(0x00020400, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46) /* IID_IDispatch */); } [SupportedOSPlatform("windows")] From dada49c7e8a709525978d7d828e24ba8ca1ff609 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Thu, 27 May 2021 23:37:07 +0600 Subject: [PATCH 14/16] Apply suggestions from feedback --- .../Runtime/InteropServices/Marshal.Com.cs | 45 +++++++++++++++++-- .../TypeSystem/Interop/IL/Marshaller.cs | 3 -- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs index 65c49aefe381..a69e8ed30b12 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs @@ -122,6 +122,11 @@ public static IntPtr GetIUnknownForObject(object o) [SupportedOSPlatform("windows")] public static unsafe void GetNativeVariantForObject(object? obj, IntPtr pDstNativeVariant) { + if (pDstNativeVariant == IntPtr.Zero) + { + throw new ArgumentNullException(nameof(pDstNativeVariant)); + } + Variant* data = (Variant*)pDstNativeVariant; if (obj == null) { @@ -231,7 +236,7 @@ public static unsafe void GetNativeVariantForObject(object? obj, IntPtr pDstNati } else if (type.IsArray) { - // SAFEARRAY impementation goes here. + // SAFEARRAY implementation goes here. throw new NotSupportedException(); } else @@ -264,12 +269,46 @@ public static object GetObjectForIUnknown(IntPtr pUnk) { if (pSrcNativeVariant == IntPtr.Zero) { - return null; + throw new ArgumentNullException(nameof(pSrcNativeVariant)); } Variant* data = (Variant*)pSrcNativeVariant; - return data->ToObject(); + if (data->IsEmpty) + { + return null; + } + + switch (data->VariantType) + { + case VarEnum.VT_NULL: + return DBNull.Value; + + case VarEnum.VT_I1: return data->AsI1; + case VarEnum.VT_I2: return data->AsI2; + case VarEnum.VT_I4: return data->AsI4; + case VarEnum.VT_I8: return data->AsI8; + case VarEnum.VT_UI1: return data->AsUi1; + case VarEnum.VT_UI2: return data->AsUi2; + case VarEnum.VT_UI4: return data->AsUi4; + case VarEnum.VT_UI8: return data->AsUi8; + case VarEnum.VT_INT: return data->AsInt; + case VarEnum.VT_UINT: return data->AsUint; + case VarEnum.VT_BOOL: return data->AsBool; + case VarEnum.VT_ERROR: return data->AsError; + case VarEnum.VT_R4: return data->AsR4; + case VarEnum.VT_R8: return data->AsR8; + case VarEnum.VT_DECIMAL: return data->AsDecimal; + case VarEnum.VT_CY: return data->AsCy; + case VarEnum.VT_DATE: return data->AsDate; + case VarEnum.VT_BSTR: return data->AsBstr; + case VarEnum.VT_UNKNOWN: return data->AsUnknown; + case VarEnum.VT_DISPATCH: return data->AsDispatch; + + default: + // Other VARIANT types not supported yet. + throw new NotSupportedException(); + } } [return: MaybeNull] diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs index aefe2efca3fd..46c53157b465 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs @@ -1438,9 +1438,6 @@ protected override void AllocAndTransformManagedToNative(ILCodeStream codeStream codeStream.Emit(ILOpcode.brfalse, pLoadFalseLabel); codeStream.EmitLdc(_trueValue); codeStream.Emit(ILOpcode.br, pDoneLabel); -#if DEBUG - codeStream.Emit(ILOpcode.pop); // keep the simple stack level calculator happy -#endif // DEBUG codeStream.EmitLabel(pLoadFalseLabel); codeStream.EmitLdc(0); From 21753cd268fbd9938f1fcd1241a60918cec21c8d Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Fri, 28 May 2021 00:09:50 +0600 Subject: [PATCH 15/16] Stylistical change of multiple ifs to switch. --- .../Runtime/InteropServices/Marshal.Com.cs | 196 ++++++++---------- 1 file changed, 88 insertions(+), 108 deletions(-) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs index a69e8ed30b12..4fae5215a3e0 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs @@ -134,115 +134,95 @@ public static unsafe void GetNativeVariantForObject(object? obj, IntPtr pDstNati return; } - if (obj is bool flag) - { - data->AsBool = flag; - } - else if (obj is byte b) - { - data->AsUi1 = b; - } - else if (obj is sbyte sb) - { - data->AsI1 = sb; - } - else if (obj is short s) - { - data->AsI2 = s; - } - else if (obj is ushort us) - { - data->AsUi2 = us; - } - else if (obj is int i) - { - data->AsI4 = i; - } - else if (obj is uint ui) - { - data->AsUi4 = ui; - } - else if (obj is long l) - { - data->AsI8 = l; - } - else if (obj is ulong ul) - { - data->AsUi8 = ul; - } - else if (obj is float f) - { - data->AsR4 = f; - } - else if (obj is double d) - { - data->AsR8 = d; - } - else if (obj is DateTime date) - { - data->AsDate = date; - } - else if (obj is decimal dec) - { - data->AsDecimal = dec; - } - else if (obj is char c) - { - data->AsUi2 = c; - } - else if (obj is string str) - { - data->AsBstr = str; - } - else if (obj is BStrWrapper strWrapper) - { - data->AsBstr = strWrapper.WrappedObject; - } - else if (obj is CurrencyWrapper currWrapper) - { - data->AsCy = currWrapper.WrappedObject; - } - else if (obj is UnknownWrapper unkWrapper) - { - data->AsUnknown = unkWrapper.WrappedObject; - } - else if (obj is DispatchWrapper dispWrapper) - { - data->AsDispatch = dispWrapper.WrappedObject; - } - else if (obj is ErrorWrapper errWrapper) - { - data->AsError = errWrapper.ErrorCode; - } - else if (obj is VariantWrapper variantWrapper) - { - // Do not want to implement that yet. - throw new NotSupportedException(); - } - else if (obj is DBNull) - { - data->SetAsNULL(); - } - else if (obj is System.Reflection.Missing) - { - data->AsError = DISP_E_PARAMNOTFOUND; - } - else - { - var type = obj.GetType(); - if (type.IsValueType) - { - throw new NotSupportedException(); - } - else if (type.IsArray) - { - // SAFEARRAY implementation goes here. + switch (obj) + { + // Int and String most used types. + case int value: + data->AsI4 = value; + break; + case string value: + data->AsBstr = value; + break; + + case bool value: + data->AsBool = value; + break; + case byte value: + data->AsUi1 = value; + break; + case sbyte value: + data->AsI1 = value; + break; + case short value: + data->AsI2 = value; + break; + case ushort value: + data->AsUi2 = value; + break; + case uint value: + data->AsUi4 = value; + break; + case long value: + data->AsI8 = value; + break; + case ulong value: + data->AsUi8 = value; + break; + case float value: + data->AsR4 = value; + break; + case double value: + data->AsR8 = value; + break; + case DateTime value: + data->AsDate = value; + break; + case decimal value: + data->AsDecimal = value; + break; + case char value: + data->AsUi2 = value; + break; + case BStrWrapper value: + data->AsBstr = value.WrappedObject; + break; + case CurrencyWrapper value: + data->AsCy = value.WrappedObject; + break; + case UnknownWrapper value: + data->AsUnknown = value.WrappedObject; + break; + case DispatchWrapper value: + data->AsDispatch = value.WrappedObject; + break; + case ErrorWrapper value: + data->AsError = value.WrappedObject; + break; + case VariantWrapper value: + // Do not want to implement that yet. throw new NotSupportedException(); - } - else - { - data->AsDispatch = obj; - } + case DBNull value: + data->SetAsNULL(); + break; + case System.Reflection.Missing value: + data->AsError = DISP_E_PARAMNOTFOUND; + break; + default: + var type = obj.GetType(); + if (type.IsValueType) + { + throw new NotSupportedException(); + } + else if (type.IsArray) + { + // SAFEARRAY implementation goes here. + throw new NotSupportedException(); + } + else + { + data->AsDispatch = obj; + } + break; } } From 73a851cfbe748aec90fb2cd7c0b71d79b7745d86 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Fri, 28 May 2021 10:31:28 +0600 Subject: [PATCH 16/16] Fix typo --- .../src/System/Runtime/InteropServices/Marshal.Com.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs index 4fae5215a3e0..0f45d0b423c3 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Com.cs @@ -196,7 +196,7 @@ public static unsafe void GetNativeVariantForObject(object? obj, IntPtr pDstNati data->AsDispatch = value.WrappedObject; break; case ErrorWrapper value: - data->AsError = value.WrappedObject; + data->AsError = value.ErrorCode; break; case VariantWrapper value: // Do not want to implement that yet.