@@ -4193,19 +4193,40 @@ static void CreateNDirectStubWorker(StubState* pss,
4193
4193
UINT nativeStackSize = (SF_IsCOMStub (dwStubFlags) ? sizeof (SLOT) : 0 );
4194
4194
bool fHasCopyCtorArgs = false ;
4195
4195
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
+ {
4196
4207
4197
4208
#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);
4207
4216
#endif
4208
4217
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
+
4209
4230
if (fMarshalReturnValueFirst )
4210
4231
{
4211
4232
marshalType = DoMarshalReturnValue (msig,
0 commit comments