Skip to content

Commit

Permalink
Revert internal helper methods
Browse files Browse the repository at this point in the history
  • Loading branch information
jkotas committed May 13, 2022
1 parent 9d98e3d commit 737913c
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 74 deletions.
51 changes: 26 additions & 25 deletions src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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)));
}
}

Expand Down
7 changes: 4 additions & 3 deletions src/coreclr/vm/corelib.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
41 changes: 21 additions & 20 deletions src/coreclr/vm/ilmarshalers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -1979,46 +1980,46 @@ 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);
}

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()
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/vm/metasig.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -23,9 +22,8 @@ public unsafe ref struct Utf8StringMarshaller
/// </summary>
/// <param name="str">The string to marshal.</param>
public Utf8StringMarshaller(string? str)
{
_allocated = ConvertToNative(str);
}
: this(str, default)
{ }

/// <summary>
/// Initializes a new instance of the <see cref="Utf8StringMarshaller"/>.
Expand Down Expand Up @@ -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;
}
}
}
}

0 comments on commit 737913c

Please sign in to comment.