Don't generate __thiscall return wrapper for primitive values #28
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
On x86, assume the following method signature:
In other words, the method returns a primitive value type, in which case there is no
__thiscall return value pointer. However, the __thiscall return wrapper was still generated because it passes the current wrapper generator check:
MonoMod.Common/RuntimeDetour/Platforms/Runtime/DetourRuntimeILPlatform.cs
Lines 335 to 346 in 25de541
Specifically:
fromInfo.ReturnType.IsValueType == typeof(long).IsValueType == true-> passes the firstifsizeof(long) > IntPtr.Size8 > 4true(because we're running x86, specifically 32-bit) -> passes secondifThis causes argument shifting, observed at least in Unity 2018 and .NET 6.
This commit fixes the logic by modifying
IsValueType=>IsValueType && !IsPrimitive && !IsEnumwhich preventsnon-struct return values getting __thiscall return wrappers. The logic is similar to Harmony 2:s return buffer check:
https://github.com/pardeike/Harmony/blob/d1aa13b919adf1089ec8b3198c5c081873c51440/Harmony/Internal/StructReturnBufferCheck.cs#L117
This PR was tested on UnityMono (MonoBleedingEdge) and CoreCLR (.NET 5 & 6). For the latter, a Unit test was written (MonoMod/MonoMod#99) and run locally on 32bit CoreCLR