Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit e1946b9

Browse files
author
Rahul Kumar
committed
Revert Pinvoke ILStub calli signature for desktop clr
1 parent 60dcd3b commit e1946b9

File tree

2 files changed

+37
-10
lines changed

2 files changed

+37
-10
lines changed

src/vm/dllimport.cpp

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4193,19 +4193,40 @@ static void CreateNDirectStubWorker(StubState* pss,
41934193
UINT nativeStackSize = (SF_IsCOMStub(dwStubFlags) ? sizeof(SLOT) : 0);
41944194
bool fHasCopyCtorArgs = false;
41954195
bool fStubNeedsCOM = SF_IsCOMStub(dwStubFlags);
4196+
4197+
// Normally we would like this to be false so that we use the correct signature
4198+
// in the IL_STUB, (i.e if it returns a value class then the signature will use that)
4199+
// When this bool is true we change the return type to void and explicitly add a
4200+
// return buffer argument as the first argument.
4201+
BOOL fMarshalReturnValueFirst = false;
4202+
4203+
// We can only change fMarshalReturnValueFirst to true when we are NOT doing HRESULT-swapping!
4204+
//
4205+
if (!SF_IsHRESULTSwapping(dwStubFlags))
4206+
{
41964207

41974208
#if defined(_TARGET_X86_) || defined(_TARGET_ARM_)
4198-
// JIT32 has problems in generating code for pinvoke ILStubs which do a return in return buffer.
4199-
// Therefore instead we change the signature of calli to return void and make the return buffer as first
4200-
// argument. This matches the ABI i.e. return buffer is passed as first arg. So native target will get the
4201-
// return buffer in correct register.
4202-
// The return structure secret arg comes first, however byvalue return is processed at
4203-
// the end because it could be the HRESULT-swapped argument which always comes last.
4204-
bool fMarshalReturnValueFirst = !SF_IsHRESULTSwapping(dwStubFlags) && HasRetBuffArg(&msig);
4205-
#else
4206-
bool fMarshalReturnValueFirst = false;
4209+
// JIT32 has problems in generating code for pinvoke ILStubs which do a return in return buffer.
4210+
// Therefore instead we change the signature of calli to return void and make the return buffer as first
4211+
// argument. This matches the ABI i.e. return buffer is passed as first arg. So native target will get the
4212+
// return buffer in correct register.
4213+
// The return structure secret arg comes first, however byvalue return is processed at
4214+
// the end because it could be the HRESULT-swapped argument which always comes last.
4215+
fMarshalReturnValueFirst = HasRetBuffArg(&msig);
42074216
#endif
42084217

4218+
#if defined(_TARGET_AMD64_) && defined(_WIN64) && !defined(FEATURE_CORECLR)
4219+
// JIT64 (which is only used on the Windows Desktop CLR) has a problem generating code
4220+
// for the pinvoke ILStubs which do a return using a struct type. Therefore, we
4221+
// change the signature of calli to return void and make the return buffer as first argument.
4222+
// This matches the ABI i.e. return buffer is passed as first arg. So native target will get
4223+
// the return buffer in correct register.
4224+
// Ideally we only want to set it for JIT64 and not ryujit but currently there isn't a fast way
4225+
// to determine that at runtime.
4226+
fMarshalReturnValueFirst = HasRetBuffArg(&msig);
4227+
#endif
4228+
}
4229+
42094230
if (fMarshalReturnValueFirst)
42104231
{
42114232
marshalType = DoMarshalReturnValue(msig,

src/vm/ilmarshalers.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,13 @@ class ILMarshaler
600600
nativeSize = wNativeSize;
601601
}
602602

603-
#if defined(_TARGET_X86_)
603+
#if defined(_TARGET_X86_) || (defined(_TARGET_AMD64_) && defined(_WIN64) && !defined(FEATURE_CORECLR))
604+
// JIT32 and JIT64 (which is only used on the Windows Desktop CLR) has a problem generating
605+
// code for the pinvoke ILStubs which do a return using a struct type. Therefore, we
606+
// change the signature of calli to return void and make the return buffer as first argument.
607+
608+
// for X86 and AMD64-Windows we bash the return type from struct to U1, U2, U4 or U8
609+
// and use byrefNativeReturn for all other structs.
604610
switch (nativeSize)
605611
{
606612
case 1: typ = ELEMENT_TYPE_U1; break;

0 commit comments

Comments
 (0)