Skip to content

Commit

Permalink
Fix UTF8 string marshalling regression
Browse files Browse the repository at this point in the history
We need to compensate for the differences in lifetime management patterns used by built-in marshalling system vs. the publicly explosed marshallers.

Fixes dotnet#69349
  • Loading branch information
jkotas committed May 14, 2022
1 parent 0aa3930 commit 6951661
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 7 deletions.
19 changes: 15 additions & 4 deletions src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1858,11 +1858,22 @@ protected override void EmitCleanupManaged(ILCodeStream codeStream)
{
ILEmitter emitter = _ilCodeStreams.Emitter;

Debug.Assert(_marshallerInstance != null);
if (In && !Out && !IsManagedByRef)
{
Debug.Assert(_marshallerInstance != null);

codeStream.EmitLdLoca(_marshallerInstance.Value);
codeStream.Emit(ILOpcode.call, emitter.NewToken(
Marshaller.GetKnownMethod("FreeNative", null)));
codeStream.EmitLdLoca(_marshallerInstance.Value);
codeStream.Emit(ILOpcode.call, emitter.NewToken(
Marshaller.GetKnownMethod("FreeNative", null)));
}
else
{
// The marshaller instance is not guaranteed to be initialized with the latest native value.
// Free the native value directly.
LoadNativeValue(codeStream);
codeStream.Emit(ILOpcode.call, emitter.NewToken(
InteropTypes.GetMarshal(Context).GetKnownMethod("CoTaskMemFree", null)));
}
}
}

Expand Down
17 changes: 14 additions & 3 deletions src/coreclr/vm/ilmarshalers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2016,10 +2016,21 @@ void ILCUTF8Marshaler::EmitClearNative(ILCodeStream* pslILEmit)
{
STANDARD_VM_CONTRACT;

_ASSERTE(m_dwInstance != LOCAL_NUM_UNUSED);
bool bPassByValueInOnly = IsIn(m_dwMarshalFlags) && !IsOut(m_dwMarshalFlags) && !IsByref(m_dwMarshalFlags);
if (bPassByValueInOnly)
{
_ASSERTE(m_dwInstance != LOCAL_NUM_UNUSED);

pslILEmit->EmitLDLOCA(m_dwInstance);
pslILEmit->EmitCALL(METHOD__UTF8STRINGMARSHALLER__FREE_NATIVE, 1, 0);
pslILEmit->EmitLDLOCA(m_dwInstance);
pslILEmit->EmitCALL(METHOD__UTF8STRINGMARSHALLER__FREE_NATIVE, 1, 0);
}
else
{
// The marshaller instance is not guaranteed to be initialized with the latest native value.
// Free the native value directly.
EmitLoadNativeValue(pslILEmit);
pslILEmit->EmitCALL(METHOD__MARSHAL__FREE_CO_TASK_MEM, 1, 0);
}
}

LocalDesc ILCSTRMarshaler::GetManagedType()
Expand Down

0 comments on commit 6951661

Please sign in to comment.