diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/InteropTypes.cs b/src/coreclr/tools/Common/TypeSystem/Interop/InteropTypes.cs index e6a684ba82e10f..9b21bf91c26496 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/InteropTypes.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/InteropTypes.cs @@ -139,7 +139,7 @@ public static bool IsSystemRuntimeIntrinsicsVector64T(TypeSystemContext context, public static bool IsInt128Type(TypeSystemContext context, TypeDesc type) { - return IsCoreNamedType(context, type, "System", "Int128") || IsCoreNamedType(context, type, "System", "UInt128"); + return type is DefType defType && defType.IsInt128OrHasInt128Fields; } public static bool IsSystemRuntimeIntrinsicsVector128T(TypeSystemContext context, TypeDesc type) diff --git a/src/tests/Interop/PInvoke/Int128/Int128Native.cpp b/src/tests/Interop/PInvoke/Int128/Int128Native.cpp index 9cd68311421632..5b7e298b1e45f7 100644 --- a/src/tests/Interop/PInvoke/Int128/Int128Native.cpp +++ b/src/tests/Interop/PInvoke/Int128/Int128Native.cpp @@ -50,10 +50,11 @@ extern "C" DLL_EXPORT Int128 STDMETHODCALLTYPE GetInt128(uint64_t upper, uint64_ return result; } -extern "C" DLL_EXPORT void STDMETHODCALLTYPE GetInt128Out(uint64_t upper, uint64_t lower, Int128* pValue) + +extern "C" DLL_EXPORT void STDMETHODCALLTYPE GetInt128Out(uint64_t upper, uint64_t lower, char* pValue /* This is a char*, as .NET does not currently guarantee that Int128 values are aligned */) { Int128 value = GetInt128(upper, lower); - *pValue = value; + memcpy(pValue, &value, sizeof(value)); // Perform unaligned write } extern "C" DLL_EXPORT uint64_t STDMETHODCALLTYPE GetInt128Lower(Int128 value) @@ -76,7 +77,7 @@ extern "C" DLL_EXPORT uint64_t STDMETHODCALLTYPE GetInt128Lower_S(StructJustInt1 extern "C" DLL_EXPORT const Int128* STDMETHODCALLTYPE GetInt128Ptr(uint64_t upper, uint64_t lower) { - GetInt128Out(upper, lower, &Int128Value); + GetInt128Out(upper, lower, (char*)&Int128Value); return &Int128Value; } @@ -96,11 +97,13 @@ extern "C" DLL_EXPORT Int128 STDMETHODCALLTYPE AddInt128(Int128 lhs, Int128 rhs) } // Test that struct alignment behavior matches with the standard OS compiler -extern "C" DLL_EXPORT void STDMETHODCALLTYPE AddStructWithInt128_ByRef(StructWithInt128 *pLhs, StructWithInt128 *pRhs) +extern "C" DLL_EXPORT void STDMETHODCALLTYPE AddStructWithInt128_ByRef(char *pLhs, char *pRhs) /* These are char*, as .NET does not currently guarantee that Int128 values are aligned */ { StructWithInt128 result = {}; - StructWithInt128 lhs = *pLhs; - StructWithInt128 rhs = *pRhs; + StructWithInt128 lhs; + memcpy(&lhs, pLhs, sizeof(lhs)); // Perform unaligned read + StructWithInt128 rhs; + memcpy(&rhs, pRhs, sizeof(rhs)); // Perform unaligned read result.messUpPadding = lhs.messUpPadding; @@ -112,7 +115,7 @@ extern "C" DLL_EXPORT void STDMETHODCALLTYPE AddStructWithInt128_ByRef(StructWit result.value.upper = lhs.value.upper + rhs.value.upper + carry; #endif - *pLhs = result; + memcpy(pLhs, &result, sizeof(result)); // Perform unaligned write } extern "C" DLL_EXPORT StructWithInt128 STDMETHODCALLTYPE AddStructWithInt128(StructWithInt128 lhs, StructWithInt128 rhs) @@ -299,13 +302,15 @@ extern "C" DLL_EXPORT Int128 STDMETHODCALLTYPE AddInt128_9(int64_t dummy1, int64 } -extern "C" DLL_EXPORT Int128 STDMETHODCALLTYPE AddInt128s(const Int128* pValues, uint32_t count) +extern "C" DLL_EXPORT Int128 STDMETHODCALLTYPE AddInt128s(const char* pValues /* These are char*, as .NET does not currently guarantee that Int128 values are aligned */, uint32_t count) { Int128 result = {}; for (uint32_t i = 0; i < count; i++) { - result = AddInt128(result, pValues[i]); + Int128 input; + memcpy(&input, pValues + (sizeof(Int128) * i), sizeof(Int128)); // Perform unaligned read + result = AddInt128(result, input); } return result; diff --git a/src/tests/Interop/PInvoke/Int128/UInt128Native.cpp b/src/tests/Interop/PInvoke/Int128/UInt128Native.cpp index 6d561cf4243439..d07d9d8f5ceb32 100644 --- a/src/tests/Interop/PInvoke/Int128/UInt128Native.cpp +++ b/src/tests/Interop/PInvoke/Int128/UInt128Native.cpp @@ -35,15 +35,15 @@ extern "C" DLL_EXPORT UInt128 STDMETHODCALLTYPE GetUInt128(uint64_t upper, uint6 return result; } -extern "C" DLL_EXPORT void STDMETHODCALLTYPE GetUInt128Out(uint64_t upper, uint64_t lower, UInt128* pValue) +extern "C" DLL_EXPORT void STDMETHODCALLTYPE GetUInt128Out(uint64_t upper, uint64_t lower, char* pValue /* This is a char*, as .NET does not currently guarantee that Int128 values are aligned */) { UInt128 value = GetUInt128(upper, lower); - *pValue = value; + memcpy(pValue, &value, sizeof(value)); // Perform unaligned write } extern "C" DLL_EXPORT const UInt128* STDMETHODCALLTYPE GetUInt128Ptr(uint64_t upper, uint64_t lower) { - GetUInt128Out(upper, lower, &UInt128Value); + GetUInt128Out(upper, lower, (char*)&UInt128Value); return &UInt128Value; } @@ -62,13 +62,15 @@ extern "C" DLL_EXPORT UInt128 STDMETHODCALLTYPE AddUInt128(UInt128 lhs, UInt128 return result; } -extern "C" DLL_EXPORT UInt128 STDMETHODCALLTYPE AddUInt128s(const UInt128* pValues, uint32_t count) +extern "C" DLL_EXPORT UInt128 STDMETHODCALLTYPE AddUInt128s(const char* pValues /* These are char*, as .NET does not currently guarantee that Int128 values are aligned */, uint32_t count) { UInt128 result = {}; for (uint32_t i = 0; i < count; i++) { - result = AddUInt128(result, pValues[i]); + UInt128 input; + memcpy(&input, pValues + (sizeof(UInt128) * i), sizeof(UInt128)); // Perform unaligned read + result = AddUInt128(result, input); } return result;