diff --git a/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs b/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs index 1f67966a7353a..117a322a5e59b 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs @@ -120,11 +120,6 @@ internal static unsafe IntPtr ConvertToNative(int flags, string strManaged, IntP return new string((sbyte*)cstr); } - internal static void ClearNative(IntPtr pNative) - { - Marshal.FreeCoTaskMem(pNative); - } - internal static unsafe void ConvertFixedToNative(int flags, string strManaged, IntPtr pNativeBuffer, int length) { if (strManaged == null) @@ -191,60 +186,6 @@ internal static unsafe string ConvertFixedToManaged(IntPtr cstr, int length) } } // class CSTRMarshaler - internal static class UTF8Marshaler - { - private const int MAX_UTF8_CHAR_SIZE = 3; - internal static unsafe IntPtr ConvertToNative(int flags, string strManaged, IntPtr pNativeBuffer) - { - if (null == strManaged) - { - return IntPtr.Zero; - } - - int nb; - byte* pbNativeBuffer = (byte*)pNativeBuffer; - - // If we are marshaling into a stack buffer allocated by the ILStub - // we will use a "1-pass" mode where we convert the string directly into the unmanaged buffer. - // else we will allocate the precise native heap memory. - if (pbNativeBuffer != null) - { - // this is the number of bytes allocated by the ILStub. - nb = (strManaged.Length + 1) * MAX_UTF8_CHAR_SIZE; - - // nb is the actual number of bytes written by Encoding.GetBytes. - // use nb to de-limit the string since we are allocating more than - // required on stack - nb = strManaged.GetBytesFromEncoding(pbNativeBuffer, nb, Encoding.UTF8); - } - // required bytes > 260 , allocate required bytes on heap - else - { - nb = Encoding.UTF8.GetByteCount(strManaged); - // + 1 for the null character. - pbNativeBuffer = (byte*)Marshal.AllocCoTaskMem(nb + 1); - strManaged.GetBytesFromEncoding(pbNativeBuffer, nb, Encoding.UTF8); - } - pbNativeBuffer[nb] = 0x0; - return (IntPtr)pbNativeBuffer; - } - - internal static unsafe string? ConvertToManaged(IntPtr cstr) - { - if (IntPtr.Zero == cstr) - return null; - - byte* pBytes = (byte*)cstr; - int nbBytes = string.strlen(pBytes); - return string.CreateStringFromEncoding(pBytes, nbBytes, Encoding.UTF8); - } - - internal static void ClearNative(IntPtr pNative) - { - Marshal.FreeCoTaskMem(pNative); - } - } - internal static class UTF8BufferMarshaler { internal static unsafe IntPtr ConvertToNative(StringBuilder sb, IntPtr pNativeBuffer, int flags) 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 551cb7d583628..2216dda0da2fe 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 @@ -33,30 +33,6 @@ public static unsafe string AnsiStringToString(byte* buffer) return PInvokeMarshal.AnsiStringToString(buffer); } - internal static unsafe byte* StringToUTF8String(string str) - { - if (str == null) - return null; - - fixed (char* charsPtr = str) - { - int length = Encoding.UTF8.GetByteCount(str); - byte* bytesPtr = (byte*)Marshal.AllocCoTaskMem(checked(length + 1)); - int bytes = Encoding.UTF8.GetBytes(charsPtr, str.Length, bytesPtr, length); - Debug.Assert(bytes == length); - bytesPtr[length] = 0; - return bytesPtr; - } - } - - public static unsafe string UTF8StringToString(byte* buffer) - { - if (buffer == null) - return null; - - return Encoding.UTF8.GetString(buffer, string.strlen(buffer)); - } - internal static unsafe void StringToByValAnsiString(string str, byte* pNative, int charCount, bool bestFit, bool throwOnUnmappableChar) { if (str != null) diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs index 7b7e3a24d9813..a59f595311438 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs @@ -1772,62 +1772,99 @@ protected override void EmitCleanupManaged(ILCodeStream codeStream) } } -#if !READYTORUN class UTF8StringMarshaller : Marshaller { - internal override bool CleanupRequired - { - get - { - return true; - } - } + private const int LocalBufferLength = 0x100; + + private ILLocalVariable? _marshallerInstance = null; + + private TypeDesc Marshaller => Context.SystemModule.GetKnownType("System.Runtime.InteropServices.Marshalling", "Utf8StringMarshaller"); + + internal override bool CleanupRequired => true; internal override void EmitElementCleanup(ILCodeStream codeStream, ILEmitter emitter) { + Debug.Assert(_marshallerInstance is null); + codeStream.Emit(ILOpcode.call, emitter.NewToken( - Context.GetHelperEntryPoint("InteropHelpers", "CoTaskMemFree"))); + InteropTypes.GetMarshal(Context).GetKnownMethod("CoTaskMemFree", null))); } protected override void TransformManagedToNative(ILCodeStream codeStream) { ILEmitter emitter = _ilCodeStreams.Emitter; + TypeDesc marshaller = Marshaller; - // - // UTF8 marshalling. Allocate a byte array, copy characters - // - var stringToAnsi = Context.GetHelperEntryPoint("InteropHelpers", "StringToUTF8String"); - LoadManagedValue(codeStream); - codeStream.Emit(ILOpcode.call, emitter.NewToken(stringToAnsi)); + 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); + codeStream.EmitStLoc(vBuffer); + + LoadManagedValue(codeStream); + + // Create ReadOnlySpan from the stack-allocated buffer + codeStream.EmitLdLoc(vBuffer); + codeStream.EmitLdc(LocalBufferLength); + + var spanOfByte = Context.SystemModule.GetKnownType("System", "Span`1").MakeInstantiatedType( + new TypeDesc[] { Context.GetWellKnownType(WellKnownType.Byte) }); + + codeStream.Emit(ILOpcode.newobj, emitter.NewToken(spanOfByte.GetKnownMethod(".ctor", + new MethodSignature(0, 0, Context.GetWellKnownType(WellKnownType.Void), + new TypeDesc[] { Context.GetWellKnownType(WellKnownType.Void).MakePointerType(), Context.GetWellKnownType(WellKnownType.Int32) })))); + + codeStream.Emit(ILOpcode.newobj, emitter.NewToken(marshaller.GetKnownMethod(".ctor", + new MethodSignature(0, 0, Context.GetWellKnownType(WellKnownType.Void), + new TypeDesc[] { Context.GetWellKnownType(WellKnownType.String), spanOfByte })))); + codeStream.EmitStLoc(_marshallerInstance.Value); + } + else + { + LoadManagedValue(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) { ILEmitter emitter = _ilCodeStreams.Emitter; - var ansiToString = Context.GetHelperEntryPoint("InteropHelpers", "UTF8StringToString"); + TypeDesc marshaller = Marshaller; + + if (_marshallerInstance == null) + _marshallerInstance = emitter.NewLocal(marshaller); + + codeStream.EmitLdLoca(_marshallerInstance.Value); LoadNativeValue(codeStream); - codeStream.Emit(ILOpcode.call, emitter.NewToken(ansiToString)); + 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) { - var emitter = _ilCodeStreams.Emitter; - var lNullCheck = emitter.NewCodeLabel(); + ILEmitter emitter = _ilCodeStreams.Emitter; - // Check for null array - LoadManagedValue(codeStream); - codeStream.Emit(ILOpcode.brfalse, lNullCheck); + Debug.Assert(_marshallerInstance != null); - LoadNativeValue(codeStream); + codeStream.EmitLdLoca(_marshallerInstance.Value); codeStream.Emit(ILOpcode.call, emitter.NewToken( - Context.GetHelperEntryPoint("InteropHelpers", "CoTaskMemFree"))); - - codeStream.EmitLabel(lNullCheck); + Marshaller.GetKnownMethod("FreeNative", null))); } } -#endif class SafeHandleMarshaller : Marshaller { diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index 7000bd2447967..77ba0f3bde22c 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -575,6 +575,7 @@ DEFINE_CLASS(BYREFERENCE, System, ByReference`1) DEFINE_METHOD(BYREFERENCE, CTOR, .ctor, NoSig) DEFINE_METHOD(BYREFERENCE, GET_VALUE, get_Value, NoSig) DEFINE_CLASS(SPAN, System, Span`1) +DEFINE_METHOD(SPAN, CTOR_PTR_INT, .ctor, IM_VoidPtr_Int_RetVoid) DEFINE_METHOD(SPAN, GET_ITEM, get_Item, IM_Int_RetRefT) DEFINE_CLASS(READONLY_SPAN, System, ReadOnlySpan`1) DEFINE_METHOD(READONLY_SPAN, GET_ITEM, get_Item, IM_Int_RetReadOnlyRefT) @@ -1035,7 +1036,6 @@ DEFINE_METHOD(CSTRMARSHALER, CONVERT_TO_NATIVE, ConvertToNative, DEFINE_METHOD(CSTRMARSHALER, CONVERT_FIXED_TO_NATIVE,ConvertFixedToNative, SM_Int_Str_IntPtr_Int_RetVoid) DEFINE_METHOD(CSTRMARSHALER, CONVERT_TO_MANAGED, ConvertToManaged, SM_IntPtr_RetStr) DEFINE_METHOD(CSTRMARSHALER, CONVERT_FIXED_TO_MANAGED,ConvertFixedToManaged, SM_IntPtr_Int_RetStr) -DEFINE_METHOD(CSTRMARSHALER, CLEAR_NATIVE, ClearNative, SM_IntPtr_RetVoid) DEFINE_CLASS(FIXEDWSTRMARSHALER, StubHelpers, FixedWSTRMarshaler) DEFINE_METHOD(FIXEDWSTRMARSHALER, CONVERT_TO_NATIVE, ConvertToNative, SM_Str_IntPtr_Int_RetVoid) @@ -1183,10 +1183,13 @@ DEFINE_METHOD(ICASTABLEHELPERS, GETIMPLTYPE, GetImplType, SM_ICast #endif // FEATURE_ICASTABLE -DEFINE_CLASS(CUTF8MARSHALER, StubHelpers, UTF8Marshaler) -DEFINE_METHOD(CUTF8MARSHALER, CONVERT_TO_NATIVE, ConvertToNative, SM_Int_Str_IntPtr_RetIntPtr) -DEFINE_METHOD(CUTF8MARSHALER, CONVERT_TO_MANAGED, ConvertToManaged, SM_IntPtr_RetStr) -DEFINE_METHOD(CUTF8MARSHALER, CLEAR_NATIVE, ClearNative, SM_IntPtr_RetVoid) +DEFINE_CLASS(UTF8STRINGMARSHALLER, Marshalling, Utf8StringMarshaller) +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_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 b6cb70ccf56c7..3a37699a07f9a 100644 --- a/src/coreclr/vm/ilmarshalers.cpp +++ b/src/coreclr/vm/ilmarshalers.cpp @@ -1938,97 +1938,89 @@ void ILFixedCSTRMarshaler::EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmi LocalDesc ILCUTF8Marshaler::GetManagedType() { - LIMITED_METHOD_CONTRACT; - - return LocalDesc(ELEMENT_TYPE_STRING); + LIMITED_METHOD_CONTRACT; + return LocalDesc(ELEMENT_TYPE_STRING); } -void ILCUTF8Marshaler::EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) +LocalDesc ILCUTF8Marshaler::GetNativeType() { - STANDARD_VM_CONTRACT; - - DWORD dwUtf8MarshalFlags = - (m_pargs->m_pMarshalInfo->GetBestFitMapping() & 0xFF) | - (m_pargs->m_pMarshalInfo->GetThrowOnUnmappableChar() << 8); - - bool bPassByValueInOnly = IsIn(m_dwMarshalFlags) && !IsOut(m_dwMarshalFlags) && !IsByref(m_dwMarshalFlags); - if (bPassByValueInOnly) - { - DWORD dwBufSize = pslILEmit->NewLocal(ELEMENT_TYPE_I4); - m_dwLocalBuffer = pslILEmit->NewLocal(ELEMENT_TYPE_I); - - // LocalBuffer = 0 - pslILEmit->EmitLoadNullPtr(); - pslILEmit->EmitSTLOC(m_dwLocalBuffer); + LIMITED_METHOD_CONTRACT; + return LocalDesc(ELEMENT_TYPE_I); +} - ILCodeLabel* pNoOptimize = pslILEmit->NewCodeLabel(); +bool ILCUTF8Marshaler::NeedsClearNative() +{ + LIMITED_METHOD_CONTRACT; + return true; +} - // if == NULL, goto NoOptimize - EmitLoadManagedValue(pslILEmit); - pslILEmit->EmitBRFALSE(pNoOptimize); +void ILCUTF8Marshaler::EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) +{ + STANDARD_VM_CONTRACT; - // (String.Length + 1) - // Characters would be # of characters + 1 in case left over high surrogate is ? - EmitLoadManagedValue(pslILEmit); - pslILEmit->EmitCALL(METHOD__STRING__GET_LENGTH, 1, 1); - pslILEmit->EmitLDC(1); - pslILEmit->EmitADD(); + if (m_dwInstance == LOCAL_NUM_UNUSED) + m_dwInstance = pslILEmit->NewLocal(LocalDesc(CoreLibBinder::GetClass(CLASS__UTF8STRINGMARSHALLER))); - // Max 3 bytes per char. - // (String.Length + 1) * 3 - pslILEmit->EmitLDC(3); - pslILEmit->EmitMUL(); + bool bPassByValueInOnly = IsIn(m_dwMarshalFlags) && !IsOut(m_dwMarshalFlags) && !IsByref(m_dwMarshalFlags); + if (bPassByValueInOnly) + { + DWORD dwBuffer = pslILEmit->NewLocal(ELEMENT_TYPE_I); + pslILEmit->EmitLDC(LOCAL_BUFFER_LENGTH); + pslILEmit->EmitLOCALLOC(); + pslILEmit->EmitSTLOC(dwBuffer); - // +1 for the 0x0 that we put in. - // ((String.Length + 1) * 3) + 1 - pslILEmit->EmitLDC(1); - pslILEmit->EmitADD(); + EmitLoadManagedValue(pslILEmit); - // BufSize = ( (String.Length+1) * 3) + 1 - pslILEmit->EmitSTLOC(dwBufSize); + // Create ReadOnlySpan from the stack-allocated buffer + pslILEmit->EmitLDLOC(dwBuffer); + pslILEmit->EmitLDC(LOCAL_BUFFER_LENGTH); + TypeHandle thByte = CoreLibBinder::GetClass(CLASS__BYTE); + MethodDesc* pSpanCtor = MethodDesc::FindOrCreateAssociatedMethodDesc(CoreLibBinder::GetMethod(METHOD__SPAN__CTOR_PTR_INT), + TypeHandle(CoreLibBinder::GetClass(CLASS__SPAN)).Instantiate(Instantiation(&thByte, 1)).AsMethodTable(), + FALSE, Instantiation(), FALSE); + pslILEmit->EmitNEWOBJ(pslILEmit->GetToken(pSpanCtor), 2); - // if (MAX_LOCAL_BUFFER_LENGTH < BufSize ) goto NoOptimize - pslILEmit->EmitLDC(MAX_LOCAL_BUFFER_LENGTH); - pslILEmit->EmitLDLOC(dwBufSize); - pslILEmit->EmitCLT(); - pslILEmit->EmitBRTRUE(pNoOptimize); + pslILEmit->EmitNEWOBJ(METHOD__UTF8STRINGMARSHALLER__CTOR_SPAN, 2); + pslILEmit->EmitSTLOC(m_dwInstance); - // LocalBuffer = localloc(BufSize); - pslILEmit->EmitLDLOC(dwBufSize); - pslILEmit->EmitLOCALLOC(); - pslILEmit->EmitSTLOC(m_dwLocalBuffer); + } + else + { + EmitLoadManagedValue(pslILEmit); + pslILEmit->EmitNEWOBJ(METHOD__UTF8STRINGMARSHALLER__CTOR, 1); + pslILEmit->EmitSTLOC(m_dwInstance); + } - // NoOptimize: - pslILEmit->EmitLabel(pNoOptimize); - } + pslILEmit->EmitLDLOCA(m_dwInstance); + pslILEmit->EmitCALL(METHOD__UTF8STRINGMARSHALLER__TO_NATIVE_VALUE, 1, 1); + EmitStoreNativeValue(pslILEmit); +} - // UTF8Marshaler.ConvertToNative(dwUtf8MarshalFlags,pManaged, pLocalBuffer) - pslILEmit->EmitLDC(dwUtf8MarshalFlags); - EmitLoadManagedValue(pslILEmit); +void ILCUTF8Marshaler::EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) +{ + STANDARD_VM_CONTRACT; - if (m_dwLocalBuffer != LOCAL_NUM_UNUSED) - { - pslILEmit->EmitLDLOC(m_dwLocalBuffer); - } - else - { - pslILEmit->EmitLoadNullPtr(); - } + if (m_dwInstance == LOCAL_NUM_UNUSED) + m_dwInstance = pslILEmit->NewLocal(LocalDesc(CoreLibBinder::GetClass(CLASS__UTF8STRINGMARSHALLER))); - pslILEmit->EmitCALL(METHOD__CUTF8MARSHALER__CONVERT_TO_NATIVE, 3, 1); + pslILEmit->EmitLDLOCA(m_dwInstance); + EmitLoadNativeValue(pslILEmit); + pslILEmit->EmitCALL(METHOD__UTF8STRINGMARSHALLER__FROM_NATIVE_VALUE, 2, 0); - EmitStoreNativeValue(pslILEmit); + pslILEmit->EmitLDLOCA(m_dwInstance); + pslILEmit->EmitCALL(METHOD__UTF8STRINGMARSHALLER__TO_MANAGED, 1, 1); + EmitStoreManagedValue(pslILEmit); } -void ILCUTF8Marshaler::EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) +void ILCUTF8Marshaler::EmitClearNative(ILCodeStream* pslILEmit) { - STANDARD_VM_CONTRACT; + STANDARD_VM_CONTRACT; - EmitLoadNativeValue(pslILEmit); - pslILEmit->EmitCALL(METHOD__CUTF8MARSHALER__CONVERT_TO_MANAGED, 1, 1); - EmitStoreManagedValue(pslILEmit); -} + _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/ilmarshalers.h b/src/coreclr/vm/ilmarshalers.h index 8d24d07500472..f3c9f31628f15 100644 --- a/src/coreclr/vm/ilmarshalers.h +++ b/src/coreclr/vm/ilmarshalers.h @@ -2016,32 +2016,63 @@ class ILOptimizedAllocMarshaler : public ILMarshaler DWORD m_dwLocalBuffer; // localloc'ed temp buffer variable or LOCAL_NUM_UNUSED if not used }; +class ILCUTF8Marshaler : public ILMarshaler +{ +public: + enum + { + c_fInOnly = TRUE, + c_nativeSize = TARGET_POINTER_SIZE, + }; + + enum + { + LOCAL_BUFFER_LENGTH = 0x100 + }; + + ILCUTF8Marshaler() : + m_dwInstance(LOCAL_NUM_UNUSED) + { + LIMITED_METHOD_CONTRACT; + } + + LocalDesc GetManagedType() override; + LocalDesc GetNativeType() override; + bool NeedsClearNative() override; + void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override; + void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override; + void EmitClearNative(ILCodeStream* pslILEmit) override; + +protected: + DWORD m_dwInstance; // local marshaler instance or LOCAL_NUM_UNUSED if not used +}; + class ILUTF8BufferMarshaler : public ILOptimizedAllocMarshaler { public: - enum - { - c_fInOnly = FALSE, - c_nativeSize = TARGET_POINTER_SIZE, - }; - - enum - { - // If required buffer length > MAX_LOCAL_BUFFER_LENGTH, don't optimize by allocating memory on stack - MAX_LOCAL_BUFFER_LENGTH = MAX_PATH_FNAME + 1 - }; - - ILUTF8BufferMarshaler() : - ILOptimizedAllocMarshaler(METHOD__MARSHAL__FREE_CO_TASK_MEM) - { - LIMITED_METHOD_CONTRACT; - } - - LocalDesc GetManagedType() override; - void EmitConvertSpaceCLRToNative(ILCodeStream* pslILEmit) override; - void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override; - void EmitConvertSpaceNativeToCLR(ILCodeStream* pslILEmit) override; - void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override; + enum + { + c_fInOnly = FALSE, + c_nativeSize = TARGET_POINTER_SIZE, + }; + + enum + { + // If required buffer length > MAX_LOCAL_BUFFER_LENGTH, don't optimize by allocating memory on stack + MAX_LOCAL_BUFFER_LENGTH = MAX_PATH_FNAME + 1 + }; + + ILUTF8BufferMarshaler() : + ILOptimizedAllocMarshaler(METHOD__MARSHAL__FREE_CO_TASK_MEM) + { + LIMITED_METHOD_CONTRACT; + } + + LocalDesc GetManagedType() override; + void EmitConvertSpaceCLRToNative(ILCodeStream* pslILEmit) override; + void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override; + void EmitConvertSpaceNativeToCLR(ILCodeStream* pslILEmit) override; + void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override; }; class ILWSTRBufferMarshaler : public ILOptimizedAllocMarshaler @@ -2554,33 +2585,6 @@ class ILVBByValStrMarshaler : public ILMarshaler #endif // FEATURE_COMINTEROP -class ILCUTF8Marshaler : public ILOptimizedAllocMarshaler -{ -public: - enum - { - c_fInOnly = TRUE, - c_nativeSize = TARGET_POINTER_SIZE, - }; - - enum - { - // If required buffer length > MAX_LOCAL_BUFFER_LENGTH, don't optimize by allocating memory on stack - MAX_LOCAL_BUFFER_LENGTH = MAX_PATH_FNAME + 1 - }; - - ILCUTF8Marshaler() : - ILOptimizedAllocMarshaler(METHOD__CSTRMARSHALER__CLEAR_NATIVE) - { - LIMITED_METHOD_CONTRACT; - } - -protected: - LocalDesc GetManagedType() override; - void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override; - void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override; -}; - class ILWSTRMarshaler : public ILOptimizedAllocMarshaler { public: @@ -2653,7 +2657,7 @@ class ILCSTRMarshaler : public ILOptimizedAllocMarshaler }; ILCSTRMarshaler() : - ILOptimizedAllocMarshaler(METHOD__CSTRMARSHALER__CLEAR_NATIVE) + ILOptimizedAllocMarshaler(METHOD__MARSHAL__FREE_CO_TASK_MEM) { LIMITED_METHOD_CONTRACT; } diff --git a/src/coreclr/vm/metasig.h b/src/coreclr/vm/metasig.h index d6f082ac4cafc..56570b28ee9d7 100644 --- a/src/coreclr/vm/metasig.h +++ b/src/coreclr/vm/metasig.h @@ -606,6 +606,10 @@ 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)) + // Undefine macros in case we include the file again in the compilation unit #undef DEFINE_METASIG diff --git a/src/coreclr/vm/namespace.h b/src/coreclr/vm/namespace.h index a6e6d23cc4f32..aca16475ae1cd 100644 --- a/src/coreclr/vm/namespace.h +++ b/src/coreclr/vm/namespace.h @@ -33,6 +33,7 @@ #define g_InteropNS g_RuntimeNS ".InteropServices" #define g_ObjectiveCNS g_InteropNS ".ObjectiveC" +#define g_MarshallingNS g_InteropNS ".Marshalling" #define g_IntrinsicsNS g_RuntimeNS ".Intrinsics" #define g_NumericsNS g_SystemNS ".Numerics"