From 737913c618eee944daf82c3f689b48273462d6f8 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Wed, 11 May 2022 21:19:50 -0700 Subject: [PATCH] Revert internal helper methods --- .../TypeSystem/Interop/IL/Marshaller.cs | 51 ++++++++++--------- src/coreclr/vm/corelib.h | 7 +-- src/coreclr/vm/ilmarshalers.cpp | 41 +++++++-------- src/coreclr/vm/metasig.h | 2 +- .../Marshalling/Utf8StringMarshaller.cs | 27 +--------- 5 files changed, 54 insertions(+), 74 deletions(-) diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs index 018dc7c76d932..a59f595311438 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs @@ -1795,10 +1795,11 @@ protected override void TransformManagedToNative(ILCodeStream codeStream) ILEmitter emitter = _ilCodeStreams.Emitter; TypeDesc marshaller = Marshaller; - if (In && !Out && !IsManagedByRef) - { + if (_marshallerInstance == null) _marshallerInstance = emitter.NewLocal(marshaller); + if (In && !Out && !IsManagedByRef) + { var vBuffer = emitter.NewLocal(Context.GetWellKnownType(WellKnownType.IntPtr)); codeStream.EmitLdc(LocalBufferLength); codeStream.Emit(ILOpcode.localloc); @@ -1821,47 +1822,47 @@ protected override void TransformManagedToNative(ILCodeStream codeStream) new MethodSignature(0, 0, Context.GetWellKnownType(WellKnownType.Void), new TypeDesc[] { Context.GetWellKnownType(WellKnownType.String), spanOfByte })))); codeStream.EmitStLoc(_marshallerInstance.Value); - - codeStream.EmitLdLoca(_marshallerInstance.Value); - codeStream.Emit(ILOpcode.call, emitter.NewToken(marshaller.GetKnownMethod("ToNativeValue", null))); - StoreNativeValue(codeStream); } else { LoadManagedValue(codeStream); - codeStream.Emit(ILOpcode.call, emitter.NewToken(marshaller.GetKnownMethod("ConvertManagedToNative", null))); - StoreNativeValue(codeStream); + codeStream.Emit(ILOpcode.newobj, emitter.NewToken(marshaller.GetKnownMethod(".ctor", + new MethodSignature(0, 0, Context.GetWellKnownType(WellKnownType.Void), + new TypeDesc[] { Context.GetWellKnownType(WellKnownType.String) })))); + codeStream.EmitStLoc(_marshallerInstance.Value); } + + codeStream.EmitLdLoca(_marshallerInstance.Value); + codeStream.Emit(ILOpcode.call, emitter.NewToken(marshaller.GetKnownMethod("ToNativeValue", null))); + StoreNativeValue(codeStream); } protected override void TransformNativeToManaged(ILCodeStream codeStream) { - Debug.Assert(_marshallerInstance is null); - ILEmitter emitter = _ilCodeStreams.Emitter; TypeDesc marshaller = Marshaller; - LoadManagedValue(codeStream); - codeStream.Emit(ILOpcode.call, emitter.NewToken(marshaller.GetKnownMethod("ConvertNativeToManaged", null))); - StoreNativeValue(codeStream); + if (_marshallerInstance == null) + _marshallerInstance = emitter.NewLocal(marshaller); + + codeStream.EmitLdLoca(_marshallerInstance.Value); + LoadNativeValue(codeStream); + codeStream.Emit(ILOpcode.call, emitter.NewToken(marshaller.GetKnownMethod("FromNativeValue", null))); + + codeStream.EmitLdLoca(_marshallerInstance.Value); + codeStream.Emit(ILOpcode.call, emitter.NewToken(marshaller.GetKnownMethod("ToManaged", null))); + StoreManagedValue(codeStream); } protected override void EmitCleanupManaged(ILCodeStream codeStream) { ILEmitter emitter = _ilCodeStreams.Emitter; - if (_marshallerInstance is null) - { - LoadNativeValue(codeStream); - codeStream.Emit(ILOpcode.call, emitter.NewToken( - InteropTypes.GetMarshal(Context).GetKnownMethod("CoTaskMemFree", null))); - } - else - { - codeStream.EmitLdLoca(_marshallerInstance.Value); - codeStream.Emit(ILOpcode.call, emitter.NewToken( - Marshaller.GetKnownMethod("FreeNative", null))); - } + Debug.Assert(_marshallerInstance != null); + + codeStream.EmitLdLoca(_marshallerInstance.Value); + codeStream.Emit(ILOpcode.call, emitter.NewToken( + Marshaller.GetKnownMethod("FreeNative", null))); } } diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index a891037c704e8..77ba0f3bde22c 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -1184,11 +1184,12 @@ DEFINE_METHOD(ICASTABLEHELPERS, GETIMPLTYPE, GetImplType, SM_ICast #endif // FEATURE_ICASTABLE DEFINE_CLASS(UTF8STRINGMARSHALLER, Marshalling, Utf8StringMarshaller) -DEFINE_METHOD(UTF8STRINGMARSHALLER, CTOR, .ctor, IM_Str_SpanOfByte_RetVoid) +DEFINE_METHOD(UTF8STRINGMARSHALLER, CTOR, .ctor, IM_Str_RetVoid) +DEFINE_METHOD(UTF8STRINGMARSHALLER, CTOR_SPAN, .ctor, IM_Str_SpanOfByte_RetVoid) DEFINE_METHOD(UTF8STRINGMARSHALLER, TO_NATIVE_VALUE, ToNativeValue, IM_RetPtrByte) +DEFINE_METHOD(UTF8STRINGMARSHALLER, FROM_NATIVE_VALUE, FromNativeValue, IM_PtrByte_RetVoid) +DEFINE_METHOD(UTF8STRINGMARSHALLER, TO_MANAGED, ToManaged, IM_RetStr) DEFINE_METHOD(UTF8STRINGMARSHALLER, FREE_NATIVE, FreeNative, IM_RetVoid) -DEFINE_METHOD(UTF8STRINGMARSHALLER, CONVERT_TO_NATIVE, ConvertToNative, NoSig) -DEFINE_METHOD(UTF8STRINGMARSHALLER, CONVERT_TO_MANAGED, ConvertToManaged, NoSig) DEFINE_CLASS(UTF8BUFFERMARSHALER, StubHelpers, UTF8BufferMarshaler) DEFINE_METHOD(UTF8BUFFERMARSHALER, CONVERT_TO_NATIVE, ConvertToNative, NoSig) diff --git a/src/coreclr/vm/ilmarshalers.cpp b/src/coreclr/vm/ilmarshalers.cpp index f034dd9d16ec9..3a37699a07f9a 100644 --- a/src/coreclr/vm/ilmarshalers.cpp +++ b/src/coreclr/vm/ilmarshalers.cpp @@ -1958,11 +1958,12 @@ void ILCUTF8Marshaler::EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) { STANDARD_VM_CONTRACT; + if (m_dwInstance == LOCAL_NUM_UNUSED) + m_dwInstance = pslILEmit->NewLocal(LocalDesc(CoreLibBinder::GetClass(CLASS__UTF8STRINGMARSHALLER))); + bool bPassByValueInOnly = IsIn(m_dwMarshalFlags) && !IsOut(m_dwMarshalFlags) && !IsByref(m_dwMarshalFlags); if (bPassByValueInOnly) { - m_dwInstance = pslILEmit->NewLocal(LocalDesc(CoreLibBinder::GetClass(CLASS__UTF8STRINGMARSHALLER))); - DWORD dwBuffer = pslILEmit->NewLocal(ELEMENT_TYPE_I); pslILEmit->EmitLDC(LOCAL_BUFFER_LENGTH); pslILEmit->EmitLOCALLOC(); @@ -1979,29 +1980,35 @@ void ILCUTF8Marshaler::EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) FALSE, Instantiation(), FALSE); pslILEmit->EmitNEWOBJ(pslILEmit->GetToken(pSpanCtor), 2); - pslILEmit->EmitNEWOBJ(METHOD__UTF8STRINGMARSHALLER__CTOR, 2); + pslILEmit->EmitNEWOBJ(METHOD__UTF8STRINGMARSHALLER__CTOR_SPAN, 2); pslILEmit->EmitSTLOC(m_dwInstance); - pslILEmit->EmitLDLOCA(m_dwInstance); - pslILEmit->EmitCALL(METHOD__UTF8STRINGMARSHALLER__TO_NATIVE_VALUE, 1, 1); - EmitStoreNativeValue(pslILEmit); } else { EmitLoadManagedValue(pslILEmit); - pslILEmit->EmitCALL(METHOD__UTF8STRINGMARSHALLER__CONVERT_TO_NATIVE, 1, 1); - EmitStoreNativeValue(pslILEmit); + pslILEmit->EmitNEWOBJ(METHOD__UTF8STRINGMARSHALLER__CTOR, 1); + pslILEmit->EmitSTLOC(m_dwInstance); } + + pslILEmit->EmitLDLOCA(m_dwInstance); + pslILEmit->EmitCALL(METHOD__UTF8STRINGMARSHALLER__TO_NATIVE_VALUE, 1, 1); + EmitStoreNativeValue(pslILEmit); } void ILCUTF8Marshaler::EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) { STANDARD_VM_CONTRACT; - _ASSERTE(m_dwInstance == LOCAL_NUM_UNUSED); + if (m_dwInstance == LOCAL_NUM_UNUSED) + m_dwInstance = pslILEmit->NewLocal(LocalDesc(CoreLibBinder::GetClass(CLASS__UTF8STRINGMARSHALLER))); + pslILEmit->EmitLDLOCA(m_dwInstance); EmitLoadNativeValue(pslILEmit); - pslILEmit->EmitCALL(METHOD__UTF8STRINGMARSHALLER__CONVERT_TO_MANAGED, 1, 1); + pslILEmit->EmitCALL(METHOD__UTF8STRINGMARSHALLER__FROM_NATIVE_VALUE, 2, 0); + + pslILEmit->EmitLDLOCA(m_dwInstance); + pslILEmit->EmitCALL(METHOD__UTF8STRINGMARSHALLER__TO_MANAGED, 1, 1); EmitStoreManagedValue(pslILEmit); } @@ -2009,16 +2016,10 @@ void ILCUTF8Marshaler::EmitClearNative(ILCodeStream* pslILEmit) { STANDARD_VM_CONTRACT; - if (m_dwInstance == LOCAL_NUM_UNUSED) - { - EmitLoadNativeValue(pslILEmit); - pslILEmit->EmitCALL(METHOD__MARSHAL__FREE_CO_TASK_MEM, 1, 0); - } - else - { - pslILEmit->EmitLDLOCA(m_dwInstance); - pslILEmit->EmitCALL(METHOD__UTF8STRINGMARSHALLER__FREE_NATIVE, 1, 0); - } + _ASSERTE(m_dwInstance != LOCAL_NUM_UNUSED); + + pslILEmit->EmitLDLOCA(m_dwInstance); + pslILEmit->EmitCALL(METHOD__UTF8STRINGMARSHALLER__FREE_NATIVE, 1, 0); } LocalDesc ILCSTRMarshaler::GetManagedType() diff --git a/src/coreclr/vm/metasig.h b/src/coreclr/vm/metasig.h index 22302d8d41f4e..56570b28ee9d7 100644 --- a/src/coreclr/vm/metasig.h +++ b/src/coreclr/vm/metasig.h @@ -606,9 +606,9 @@ 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)) +DEFINE_METASIG_T(IM(Str_SpanOfByte_RetVoid, s GI(g(SPAN), 1, b), v)) DEFINE_METASIG(IM(RetPtrByte, , P(b))) DEFINE_METASIG(IM(VoidPtr_Int_RetVoid, P(v) i, v)) -DEFINE_METASIG_T(IM(Str_SpanOfByte_RetVoid, s GI(g(SPAN), 1, b), v)) // Undefine macros in case we include the file again in the compilation unit diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/Utf8StringMarshaller.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/Utf8StringMarshaller.cs index 4f42c9593fbb2..be37a40586f92 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/Utf8StringMarshaller.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/Utf8StringMarshaller.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; using System.Runtime.CompilerServices; using System.Text; @@ -23,9 +22,8 @@ public unsafe ref struct Utf8StringMarshaller /// /// The string to marshal. public Utf8StringMarshaller(string? str) - { - _allocated = ConvertToNative(str); - } + : this(str, default) + { } /// /// Initializes a new instance of the . @@ -107,26 +105,5 @@ public void FreeNative() if (_allocated) Marshal.FreeCoTaskMem((IntPtr)_nativeValue); } - - internal static string? ConvertToManaged(byte* value) - => Marshal.PtrToStringUTF8((IntPtr)value); - - internal static byte* ConvertToNative(string? str) - { - // This is functionally equivalent to Marshal.StringToCoTaskMemUTF8 except the conservative over-allocations - - if (str == null) - return null; - - fixed (char* charsPtr = str) - { - int length = Encoding.UTF8.GetByteCount(charsPtr, str.Length); - byte* bytesPtr = (byte*)Marshal.AllocCoTaskMem(length + 1); - int bytes = Encoding.UTF8.GetBytes(charsPtr, str.Length, bytesPtr, length); - Debug.Assert(bytes == length); - bytesPtr[length] = 0; - return bytesPtr; - } - } } }