Skip to content

Commit 0c67acb

Browse files
authored
JIT: Sign/zero-extend small primitive arguments for pinvokes on arm32 and Apple arm64 (#106314)
Fix #101046
1 parent 9d9af3d commit 0c67acb

26 files changed

+194
-48
lines changed

docs/design/coreclr/botr/clr-abi.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ ARM64: See [Overview of ARM64 ABI conventions](https://learn.microsoft.com/cpp/b
2323
## Non-Windows ABI documentation
2424

2525
Arm corporation ABI documentation (for ARM32 and ARM64) is [here](https://developer.arm.com/architectures/system-architectures/software-standards/abi) and [here](https://github.com/ARM-software/abi-aa).
26+
Apple's ARM64 calling convention differences can be found [here](https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms).
2627

2728
The Linux System V x86_64 ABI is documented in [System V Application Binary Interface / AMD64 Architecture Processor Supplement](https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf), with document source material [here](https://gitlab.com/x86-psABIs/x86-64-ABI).
2829

@@ -117,6 +118,10 @@ ARM64-only: When a method returns a structure that is larger than 16 bytes the c
117118

118119
Primitive value types smaller than 32-bits are widened to 32-bits: signed small types are sign extended and unsigned small types are zero extended. This can be different from the standard calling conventions that may leave the state of unused bits in the return register undefined.
119120

121+
## Small primitive arguments
122+
123+
Small primitive arguments have undefined upper bits. This can be different from the standard calling conventions that may require normalization (e.g. on ARM32 and Apple ARM64).
124+
120125
# PInvokes
121126

122127
The convention is that any method with an InlinedCallFrame (either an IL stub or a normal method with an inlined PInvoke) saves/restores all non-volatile integer registers in its prolog/epilog respectively. This is done so that the InlinedCallFrame can just contain a return address, a stack pointer and a frame pointer. Then using just those three it can start a full stack walk using the normal RtlVirtualUnwind.

src/coreclr/jit/importercalls.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6184,6 +6184,18 @@ void Compiler::impPopCallArgs(CORINFO_SIG_INFO* sig, GenTreeCall* call)
61846184
argNode = impImplicitR4orR8Cast(argNode, jitSigType);
61856185
// insert any widening or narrowing casts for backwards compatibility
61866186
argNode = impImplicitIorI4Cast(argNode, jitSigType);
6187+
6188+
if ((compAppleArm64Abi() || TargetArchitecture::IsArm32) && call->IsUnmanaged() &&
6189+
varTypeIsSmall(jitSigType))
6190+
{
6191+
// Apple arm64 and arm32 ABIs require arguments to be zero/sign
6192+
// extended up to 32 bit. The managed ABI does not require
6193+
// this.
6194+
if (fgCastNeeded(argNode, jitSigType))
6195+
{
6196+
argNode = gtNewCastNode(TYP_INT, argNode, false, jitSigType);
6197+
}
6198+
}
61876199
}
61886200

61896201
NewCallArg arg;

src/coreclr/nativeaot/Runtime/CommonMacros.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -293,14 +293,11 @@ typedef uint8_t CODE_LOCATION;
293293

294294
typedef bool CLR_BOOL;
295295

296-
#if defined(TARGET_X86) || defined(TARGET_AMD64)
297-
// The return value is artificially widened on x86 and amd64
298296
typedef int32_t FC_BOOL_RET;
299-
#else
300-
typedef bool FC_BOOL_RET;
301-
#endif
297+
typedef int32_t FC_BOOL_ARG;
302298

303299
#define FC_RETURN_BOOL(x) do { return !!(x); } while(0)
300+
#define FC_ACCESS_BOOL(x) ((uint8_t)x != 0)
304301

305302
#ifndef DACCESS_COMPILE
306303
#define IN_DAC(x)

src/coreclr/nativeaot/Runtime/GCHelpers.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,9 @@ FCIMPL0(int32_t, RhGetMaxGcGeneration)
170170
}
171171
FCIMPLEND
172172

173-
FCIMPL2(int32_t, RhGetGcCollectionCount, int32_t generation, CLR_BOOL getSpecialGCCount)
173+
FCIMPL2(int32_t, RhGetGcCollectionCount, int32_t generation, FC_BOOL_ARG getSpecialGCCount)
174174
{
175-
return GCHeapUtilities::GetGCHeap()->CollectionCount(generation, getSpecialGCCount);
175+
return GCHeapUtilities::GetGCHeap()->CollectionCount(generation, FC_ACCESS_BOOL(getSpecialGCCount));
176176
}
177177
FCIMPLEND
178178

src/coreclr/nativeaot/Runtime/StackFrameIterator.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2139,9 +2139,9 @@ bool StackFrameIterator::Next(uint32_t* puExCollideClauseIdx, bool* pfUnwoundRev
21392139
return isValid;
21402140
}
21412141

2142-
FCIMPL4(FC_BOOL_RET, RhpSfiInit, StackFrameIterator* pThis, PAL_LIMITED_CONTEXT* pStackwalkCtx, CLR_BOOL instructionFault, CLR_BOOL* pfIsExceptionIntercepted)
2142+
FCIMPL4(FC_BOOL_RET, RhpSfiInit, StackFrameIterator* pThis, PAL_LIMITED_CONTEXT* pStackwalkCtx, FC_BOOL_ARG instructionFault, CLR_BOOL* pfIsExceptionIntercepted)
21432143
{
2144-
bool isValid = pThis->Init(pStackwalkCtx, instructionFault);
2144+
bool isValid = pThis->Init(pStackwalkCtx, FC_ACCESS_BOOL(instructionFault));
21452145

21462146
if (pfIsExceptionIntercepted)
21472147
{

src/coreclr/nativeaot/Runtime/threadstore.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -406,9 +406,9 @@ EXTERN_C void* QCALLTYPE RhpGetCurrentThread()
406406
return ThreadStore::GetCurrentThread();
407407
}
408408

409-
FCIMPL3(void, RhpInitiateThreadAbort, void* thread, Object * threadAbortException, CLR_BOOL doRudeAbort)
409+
FCIMPL3(void, RhpInitiateThreadAbort, void* thread, Object * threadAbortException, FC_BOOL_ARG doRudeAbort)
410410
{
411-
GetThreadStore()->InitiateThreadAbort((Thread*)thread, threadAbortException, doRudeAbort);
411+
GetThreadStore()->InitiateThreadAbort((Thread*)thread, threadAbortException, FC_ACCESS_BOOL(doRudeAbort));
412412
}
413413
FCIMPLEND
414414

src/coreclr/vm/binder.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -775,22 +775,22 @@ static void FCallCheckSignature(MethodDesc* pMD, PCODE pImpl)
775775
expectedType = pMD->IsCtor() ? NULL : "void";
776776
break;
777777
case ELEMENT_TYPE_BOOLEAN:
778-
expectedType = (argIndex == -2) ? "FC_BOOL_RET" : "CLR_BOOL";
778+
expectedType = (argIndex == -2) ? "FC_BOOL_RET" : "FC_BOOL_ARG";
779779
break;
780780
case ELEMENT_TYPE_CHAR:
781-
expectedType = (argIndex == -2) ? "FC_CHAR_RET" : "CLR_CHAR";
781+
expectedType = (argIndex == -2) ? "FC_CHAR_RET" : "FC_CHAR_ARG";
782782
break;
783783
case ELEMENT_TYPE_I1:
784-
expectedType = (argIndex == -2) ? "FC_INT8_RET" : "INT8";
784+
expectedType = (argIndex == -2) ? "FC_INT8_RET" : "FC_INT8_ARG";
785785
break;
786786
case ELEMENT_TYPE_U1:
787-
expectedType = (argIndex == -2) ? "FC_UINT8_RET" : "UINT8";
787+
expectedType = (argIndex == -2) ? "FC_UINT8_RET" : "FC_UINT8_ARG";
788788
break;
789789
case ELEMENT_TYPE_I2:
790-
expectedType = (argIndex == -2) ? "FC_INT16_RET" : "INT16";
790+
expectedType = (argIndex == -2) ? "FC_INT16_RET" : "FC_INT16_ARG";
791791
break;
792792
case ELEMENT_TYPE_U2:
793-
expectedType = (argIndex == -2) ? "FC_UINT16_RET" : "UINT16";
793+
expectedType = (argIndex == -2) ? "FC_UINT16_RET" : "FC_UINT16_ARG";
794794
break;
795795
//case ELEMENT_TYPE_I4:
796796
// expectedType = "INT32";

src/coreclr/vm/comutilnative.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ class ExceptionNative
4040
public:
4141
static FCDECL1(FC_BOOL_RET, IsImmutableAgileException, Object* pExceptionUNSAFE);
4242
static FCDECL1(FC_BOOL_RET, IsTransient, INT32 hresult);
43-
static FCDECL3(StringObject *, StripFileInfo, Object *orefExcepUNSAFE, StringObject *orefStrUNSAFE, CLR_BOOL isRemoteStackTrace);
4443
static FCDECL0(VOID, PrepareForForeignExceptionRaise);
4544
static FCDECL1(Object *, GetFrozenStackTrace, Object* pExceptionObjectUnsafe);
4645

src/coreclr/vm/comwaithandle.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#include "excep.h"
1717
#include "comwaithandle.h"
1818

19-
FCIMPL3(INT32, WaitHandleNative::CorWaitOneNative, HANDLE handle, INT32 timeout, CLR_BOOL useTrivialWaits)
19+
FCIMPL3(INT32, WaitHandleNative::CorWaitOneNative, HANDLE handle, INT32 timeout, FC_BOOL_ARG useTrivialWaits)
2020
{
2121
FCALL_CONTRACT;
2222

@@ -28,7 +28,7 @@ FCIMPL3(INT32, WaitHandleNative::CorWaitOneNative, HANDLE handle, INT32 timeout,
2828

2929
Thread* pThread = GET_THREAD();
3030

31-
WaitMode waitMode = (WaitMode)((!useTrivialWaits ? WaitMode_Alertable : WaitMode_None) | WaitMode_IgnoreSyncCtx);
31+
WaitMode waitMode = (WaitMode)((!FC_ACCESS_BOOL(useTrivialWaits) ? WaitMode_Alertable : WaitMode_None) | WaitMode_IgnoreSyncCtx);
3232
retVal = pThread->DoAppropriateWait(1, &handle, TRUE, timeout, waitMode);
3333

3434
HELPER_METHOD_FRAME_END();
@@ -55,7 +55,7 @@ extern "C" INT32 QCALLTYPE WaitHandle_CorWaitOnePrioritizedNative(HANDLE handle,
5555
}
5656
#endif
5757

58-
FCIMPL4(INT32, WaitHandleNative::CorWaitMultipleNative, HANDLE *handleArray, INT32 numHandles, CLR_BOOL waitForAll, INT32 timeout)
58+
FCIMPL4(INT32, WaitHandleNative::CorWaitMultipleNative, HANDLE *handleArray, INT32 numHandles, FC_BOOL_ARG waitForAll, INT32 timeout)
5959
{
6060
FCALL_CONTRACT;
6161

@@ -67,13 +67,13 @@ FCIMPL4(INT32, WaitHandleNative::CorWaitMultipleNative, HANDLE *handleArray, INT
6767
#ifdef FEATURE_COMINTEROP_APARTMENT_SUPPORT
6868
// There are some issues with wait-all from an STA thread
6969
// - https://github.com/dotnet/runtime/issues/10243#issuecomment-385117537
70-
if (waitForAll && numHandles > 1 && pThread->GetApartment() == Thread::AS_InSTA)
70+
if (FC_ACCESS_BOOL(waitForAll) && numHandles > 1 && pThread->GetApartment() == Thread::AS_InSTA)
7171
{
7272
COMPlusThrow(kNotSupportedException, W("NotSupported_WaitAllSTAThread"));
7373
}
7474
#endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT
7575

76-
ret = pThread->DoAppropriateWait(numHandles, handleArray, waitForAll, timeout, (WaitMode)(WaitMode_Alertable | WaitMode_IgnoreSyncCtx));
76+
ret = pThread->DoAppropriateWait(numHandles, handleArray, FC_ACCESS_BOOL(waitForAll), timeout, (WaitMode)(WaitMode_Alertable | WaitMode_IgnoreSyncCtx));
7777

7878
HELPER_METHOD_FRAME_END();
7979
return ret;

src/coreclr/vm/comwaithandle.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
class WaitHandleNative
1919
{
2020
public:
21-
static FCDECL3(INT32, CorWaitOneNative, HANDLE handle, INT32 timeout, CLR_BOOL useTrivialWaits);
22-
static FCDECL4(INT32, CorWaitMultipleNative, HANDLE *handleArray, INT32 numHandles, CLR_BOOL waitForAll, INT32 timeout);
21+
static FCDECL3(INT32, CorWaitOneNative, HANDLE handle, INT32 timeout, FC_BOOL_ARG useTrivialWaits);
22+
static FCDECL4(INT32, CorWaitMultipleNative, HANDLE *handleArray, INT32 numHandles, FC_BOOL_ARG waitForAll, INT32 timeout);
2323
static FCDECL3(INT32, CorSignalAndWaitOneNative, HANDLE waitHandleSignalUNSAFE, HANDLE waitHandleWaitUNSAFE, INT32 timeout);
2424
};
2525
#ifdef TARGET_UNIX

src/coreclr/vm/debugdebugger.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ FCIMPLEND
233233
FCIMPL4(void, DebugStackTrace::GetStackFramesInternal,
234234
StackFrameHelper* pStackFrameHelperUNSAFE,
235235
INT32 iSkip,
236-
CLR_BOOL fNeedFileInfo,
236+
FC_BOOL_ARG fNeedFileInfo,
237237
Object* pExceptionUNSAFE
238238
)
239239
{
@@ -282,7 +282,7 @@ FCIMPL4(void, DebugStackTrace::GetStackFramesInternal,
282282
if (data.cElements != 0)
283283
{
284284
#if defined(FEATURE_ISYM_READER) && defined(FEATURE_COMINTEROP)
285-
if (fNeedFileInfo)
285+
if (FC_ACCESS_BOOL(fNeedFileInfo))
286286
{
287287
// Calls to COM up ahead.
288288
EnsureComStarted();
@@ -467,7 +467,7 @@ FCIMPL4(void, DebugStackTrace::GetStackFramesInternal,
467467
}
468468
#endif
469469
// Check if the user wants the filenumber, linenumber info and that it is possible.
470-
if (!fIsEnc && fNeedFileInfo)
470+
if (!fIsEnc && FC_ACCESS_BOOL(fNeedFileInfo))
471471
{
472472
#ifdef FEATURE_ISYM_READER
473473
BOOL fPortablePDB = FALSE;

src/coreclr/vm/debugdebugger.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ class DebugStackTrace
152152
GetStackFramesInternal,
153153
StackFrameHelper* pStackFrameHelper,
154154
INT32 iSkip,
155-
CLR_BOOL fNeedFileInfo,
155+
FC_BOOL_ARG fNeedFileInfo,
156156
Object* pException
157157
);
158158

src/coreclr/vm/fcall.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@
151151
// Also, initialize all the OBJECTREF's first. Like this:
152152
//
153153
// FCIMPL4(Object*, COMNlsInfo::nativeChangeCaseString, LocaleIDObject* localeUNSAFE,
154-
// INT_PTR pNativeTextInfo, StringObject* pStringUNSAFE, CLR_BOOL bIsToUpper)
154+
// INT_PTR pNativeTextInfo, StringObject* pStringUNSAFE, FC_BOOL_ARG bIsToUpper)
155155
// {
156156
// [ignoring CONTRACT for now]
157157
// struct _gc
@@ -1335,7 +1335,10 @@ typedef UINT32 FC_UINT8_RET;
13351335
typedef INT32 FC_INT16_RET;
13361336
typedef UINT32 FC_UINT16_RET;
13371337

1338+
// Small primitive args are not widened.
1339+
typedef INT32 FC_BOOL_ARG;
13381340

1341+
#define FC_ACCESS_BOOL(x) ((BYTE)x != 0)
13391342

13401343
// The fcall entrypoints has to be at unique addresses. Use this helper macro to make
13411344
// the code of the fcalls unique if you get assert in ecall.cpp that mentions it.

src/coreclr/vm/jitinterface.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -106,27 +106,27 @@ int64_t AtomicLoad64WithoutTearing(int64_t volatile *valueRef)
106106
#endif // TARGET_64BIT
107107
}
108108

109-
FCIMPL1(INT64, GetCompiledILBytes, CLR_BOOL currentThread)
109+
FCIMPL1(INT64, GetCompiledILBytes, FC_BOOL_ARG currentThread)
110110
{
111111
FCALL_CONTRACT;
112112

113-
return currentThread ? t_cbILJittedForThread : AtomicLoad64WithoutTearing(&g_cbILJitted);
113+
return FC_ACCESS_BOOL(currentThread) ? t_cbILJittedForThread : AtomicLoad64WithoutTearing(&g_cbILJitted);
114114
}
115115
FCIMPLEND
116116

117-
FCIMPL1(INT64, GetCompiledMethodCount, CLR_BOOL currentThread)
117+
FCIMPL1(INT64, GetCompiledMethodCount, FC_BOOL_ARG currentThread)
118118
{
119119
FCALL_CONTRACT;
120120

121-
return currentThread ? t_cMethodsJittedForThread : AtomicLoad64WithoutTearing(&g_cMethodsJitted);
121+
return FC_ACCESS_BOOL(currentThread) ? t_cMethodsJittedForThread : AtomicLoad64WithoutTearing(&g_cMethodsJitted);
122122
}
123123
FCIMPLEND
124124

125-
FCIMPL1(INT64, GetCompilationTimeInTicks, CLR_BOOL currentThread)
125+
FCIMPL1(INT64, GetCompilationTimeInTicks, FC_BOOL_ARG currentThread)
126126
{
127127
FCALL_CONTRACT;
128128

129-
return currentThread ? t_c100nsTicksInJitForThread : AtomicLoad64WithoutTearing(&g_c100nsTicksInJit);
129+
return FC_ACCESS_BOOL(currentThread) ? t_c100nsTicksInJitForThread : AtomicLoad64WithoutTearing(&g_c100nsTicksInJit);
130130
}
131131
FCIMPLEND
132132

src/coreclr/vm/jitinterface.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,8 +1136,8 @@ extern thread_local int64_t t_cbILJittedForThread;
11361136
extern thread_local int64_t t_cMethodsJittedForThread;
11371137
extern thread_local int64_t t_c100nsTicksInJitForThread;
11381138

1139-
FCDECL1(INT64, GetCompiledILBytes, CLR_BOOL currentThread);
1140-
FCDECL1(INT64, GetCompiledMethodCount, CLR_BOOL currentThread);
1141-
FCDECL1(INT64, GetCompilationTimeInTicks, CLR_BOOL currentThread);
1139+
FCDECL1(INT64, GetCompiledILBytes, FC_BOOL_ARG currentThread);
1140+
FCDECL1(INT64, GetCompiledMethodCount, FC_BOOL_ARG currentThread);
1141+
FCDECL1(INT64, GetCompilationTimeInTicks, FC_BOOL_ARG currentThread);
11421142

11431143
#endif // JITINTERFACE_H

src/coreclr/vm/qcall.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
//
2828
//
2929
// The preferred type of QCall arguments is primitive types that efficiently handled by the P/Invoke marshaler (INT32, LPCWSTR, BOOL).
30-
// (Notice that BOOL is the correct boolean flavor for QCall arguments. CLR_BOOL is the correct boolean flavor for FCall arguments.)
30+
// (Notice that BOOL is the correct boolean flavor for QCall arguments. FC_BOOL_ARG is the correct boolean flavor for FCall arguments.)
3131
//
3232
// The pointers to common unmanaged EE structures should be wrapped into helper handle types. This is to make the managed implementation
3333
// type safe and avoid falling into unsafe C# everywhere. See the AssemblyHandle below for a good example.

src/coreclr/vm/reflectioninvocation.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ FCIMPL4(Object*, RuntimeMethodHandle::InvokeMethod,
410410
Object *target,
411411
PVOID* args, // An array of byrefs
412412
SignatureNative* pSigUNSAFE,
413-
CLR_BOOL fConstructor)
413+
FC_BOOL_ARG fConstructor)
414414
{
415415
FCALL_CONTRACT;
416416

@@ -443,7 +443,7 @@ FCIMPL4(Object*, RuntimeMethodHandle::InvokeMethod,
443443

444444
BOOL fCtorOfVariableSizedObject = FALSE;
445445

446-
if (fConstructor)
446+
if (FC_ACCESS_BOOL(fConstructor))
447447
{
448448
// If we are invoking a constructor on an array then we must
449449
// handle this specially.
@@ -550,7 +550,7 @@ FCIMPL4(Object*, RuntimeMethodHandle::InvokeMethod,
550550
if (!pMeth->IsStatic() && !fCtorOfVariableSizedObject) {
551551
PVOID pThisPtr;
552552

553-
if (fConstructor)
553+
if (FC_ACCESS_BOOL(fConstructor))
554554
{
555555
// Copy "this" pointer: only unbox if type is value type and method is not unboxing stub
556556
if (ownerType.IsValueType() && !pMeth->IsUnboxingStub()) {
@@ -672,7 +672,7 @@ FCIMPL4(Object*, RuntimeMethodHandle::InvokeMethod,
672672
CallDescrWorkerWithHandler(&callDescrData);
673673

674674
// It is still illegal to do a GC here. The return type might have/contain GC pointers.
675-
if (fConstructor)
675+
if (FC_ACCESS_BOOL(fConstructor))
676676
{
677677
// We have a special case for Strings...The object is returned...
678678
if (fCtorOfVariableSizedObject) {

src/coreclr/vm/runtimehandles.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1815,7 +1815,7 @@ FCIMPLEND
18151815
FCIMPL3(Object *, SignatureNative::GetCustomModifiersAtOffset,
18161816
SignatureNative* pSignatureUNSAFE,
18171817
INT32 offset,
1818-
CLR_BOOL fRequired)
1818+
FC_BOOL_ARG fRequired)
18191819
{
18201820
FCALL_CONTRACT;
18211821

@@ -1840,7 +1840,7 @@ FCIMPL3(Object *, SignatureNative::GetCustomModifiersAtOffset,
18401840
INT32 cMods = 0;
18411841
CorElementType cmodType;
18421842

1843-
CorElementType cmodTypeExpected = fRequired ? ELEMENT_TYPE_CMOD_REQD : ELEMENT_TYPE_CMOD_OPT;
1843+
CorElementType cmodTypeExpected = FC_ACCESS_BOOL(fRequired) ? ELEMENT_TYPE_CMOD_REQD : ELEMENT_TYPE_CMOD_OPT;
18441844

18451845
// Discover the number of required and optional custom modifiers.
18461846
while(TRUE)

src/coreclr/vm/runtimehandles.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ extern "C" void QCALLTYPE RuntimeTypeHandle_RegisterCollectibleTypeDependency(QC
199199
class RuntimeMethodHandle {
200200

201201
public:
202-
static FCDECL4(Object*, InvokeMethod, Object *target, PVOID* args, SignatureNative* pSig, CLR_BOOL fConstructor);
202+
static FCDECL4(Object*, InvokeMethod, Object *target, PVOID* args, SignatureNative* pSig, FC_BOOL_ARG fConstructor);
203203

204204
static FCDECL2(Object*, ReboxToNullable, Object *pBoxedValUNSAFE, ReflectClassBaseObject *pDestUNSAFE);
205205
static FCDECL1(Object*, ReboxFromNullable, Object *pBoxedValUNSAFE);
@@ -368,7 +368,7 @@ class SignatureNative : public Object
368368

369369
static FCDECL2(FC_INT8_RET, GetCallingConventionFromFunctionPointerAtOffset, SignatureNative* pSig, INT32 offset);
370370

371-
static FCDECL3(Object *, GetCustomModifiersAtOffset, SignatureNative* pSig, INT32 offset, CLR_BOOL fRequired);
371+
static FCDECL3(Object *, GetCustomModifiersAtOffset, SignatureNative* pSig, INT32 offset, FC_BOOL_ARG fRequired);
372372

373373
BOOL HasThis() { LIMITED_METHOD_CONTRACT; return (m_managedCallingConvention & CALLCONV_HasThis); }
374374
INT32 NumFixedArgs() { WRAPPER_NO_CONTRACT; return m_PtrArrayarguments->GetNumComponents(); }
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
include_directories(${INC_PLATFORM_DIR})
2+
3+
# This test always needs to be optimized to hit the problem.
4+
set(CMAKE_BUILD_TYPE Release)
5+
6+
add_library(Runtime101046Native SHARED Runtime_101046.cpp)
7+
target_link_libraries(Runtime101046Native PRIVATE platformdefines)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
#include <platformdefines.h>
5+
#include <stdint.h>
6+
7+
extern "C" DLL_EXPORT int32_t ReturnExtendedShort(int16_t s)
8+
{
9+
return s;
10+
}

0 commit comments

Comments
 (0)