Skip to content

Commit bd4bea6

Browse files
Fix issues found in recent Int128 ABI change (#74386)
* Fixed check for Int128 in the routine used to abort marshalling Int128 parameters in R2R * Fix test to tolerate unaligned Int128 data
1 parent 334cb5a commit bd4bea6

File tree

3 files changed

+22
-15
lines changed

3 files changed

+22
-15
lines changed

src/coreclr/tools/Common/TypeSystem/Interop/InteropTypes.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ public static bool IsSystemRuntimeIntrinsicsVector64T(TypeSystemContext context,
139139

140140
public static bool IsInt128Type(TypeSystemContext context, TypeDesc type)
141141
{
142-
return IsCoreNamedType(context, type, "System", "Int128") || IsCoreNamedType(context, type, "System", "UInt128");
142+
return type is DefType defType && defType.IsInt128OrHasInt128Fields;
143143
}
144144

145145
public static bool IsSystemRuntimeIntrinsicsVector128T(TypeSystemContext context, TypeDesc type)

src/tests/Interop/PInvoke/Int128/Int128Native.cpp

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,11 @@ extern "C" DLL_EXPORT Int128 STDMETHODCALLTYPE GetInt128(uint64_t upper, uint64_
5050
return result;
5151
}
5252

53-
extern "C" DLL_EXPORT void STDMETHODCALLTYPE GetInt128Out(uint64_t upper, uint64_t lower, Int128* pValue)
53+
54+
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 */)
5455
{
5556
Int128 value = GetInt128(upper, lower);
56-
*pValue = value;
57+
memcpy(pValue, &value, sizeof(value)); // Perform unaligned write
5758
}
5859

5960
extern "C" DLL_EXPORT uint64_t STDMETHODCALLTYPE GetInt128Lower(Int128 value)
@@ -76,7 +77,7 @@ extern "C" DLL_EXPORT uint64_t STDMETHODCALLTYPE GetInt128Lower_S(StructJustInt1
7677

7778
extern "C" DLL_EXPORT const Int128* STDMETHODCALLTYPE GetInt128Ptr(uint64_t upper, uint64_t lower)
7879
{
79-
GetInt128Out(upper, lower, &Int128Value);
80+
GetInt128Out(upper, lower, (char*)&Int128Value);
8081
return &Int128Value;
8182
}
8283

@@ -96,11 +97,13 @@ extern "C" DLL_EXPORT Int128 STDMETHODCALLTYPE AddInt128(Int128 lhs, Int128 rhs)
9697
}
9798

9899
// Test that struct alignment behavior matches with the standard OS compiler
99-
extern "C" DLL_EXPORT void STDMETHODCALLTYPE AddStructWithInt128_ByRef(StructWithInt128 *pLhs, StructWithInt128 *pRhs)
100+
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 */
100101
{
101102
StructWithInt128 result = {};
102-
StructWithInt128 lhs = *pLhs;
103-
StructWithInt128 rhs = *pRhs;
103+
StructWithInt128 lhs;
104+
memcpy(&lhs, pLhs, sizeof(lhs)); // Perform unaligned read
105+
StructWithInt128 rhs;
106+
memcpy(&rhs, pRhs, sizeof(rhs)); // Perform unaligned read
104107

105108
result.messUpPadding = lhs.messUpPadding;
106109

@@ -112,7 +115,7 @@ extern "C" DLL_EXPORT void STDMETHODCALLTYPE AddStructWithInt128_ByRef(StructWit
112115
result.value.upper = lhs.value.upper + rhs.value.upper + carry;
113116
#endif
114117

115-
*pLhs = result;
118+
memcpy(pLhs, &result, sizeof(result)); // Perform unaligned write
116119
}
117120

118121
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
299302
}
300303

301304

302-
extern "C" DLL_EXPORT Int128 STDMETHODCALLTYPE AddInt128s(const Int128* pValues, uint32_t count)
305+
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)
303306
{
304307
Int128 result = {};
305308

306309
for (uint32_t i = 0; i < count; i++)
307310
{
308-
result = AddInt128(result, pValues[i]);
311+
Int128 input;
312+
memcpy(&input, pValues + (sizeof(Int128) * i), sizeof(Int128)); // Perform unaligned read
313+
result = AddInt128(result, input);
309314
}
310315

311316
return result;

src/tests/Interop/PInvoke/Int128/UInt128Native.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,15 @@ extern "C" DLL_EXPORT UInt128 STDMETHODCALLTYPE GetUInt128(uint64_t upper, uint6
3535
return result;
3636
}
3737

38-
extern "C" DLL_EXPORT void STDMETHODCALLTYPE GetUInt128Out(uint64_t upper, uint64_t lower, UInt128* pValue)
38+
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 */)
3939
{
4040
UInt128 value = GetUInt128(upper, lower);
41-
*pValue = value;
41+
memcpy(pValue, &value, sizeof(value)); // Perform unaligned write
4242
}
4343

4444
extern "C" DLL_EXPORT const UInt128* STDMETHODCALLTYPE GetUInt128Ptr(uint64_t upper, uint64_t lower)
4545
{
46-
GetUInt128Out(upper, lower, &UInt128Value);
46+
GetUInt128Out(upper, lower, (char*)&UInt128Value);
4747
return &UInt128Value;
4848
}
4949

@@ -62,13 +62,15 @@ extern "C" DLL_EXPORT UInt128 STDMETHODCALLTYPE AddUInt128(UInt128 lhs, UInt128
6262
return result;
6363
}
6464

65-
extern "C" DLL_EXPORT UInt128 STDMETHODCALLTYPE AddUInt128s(const UInt128* pValues, uint32_t count)
65+
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)
6666
{
6767
UInt128 result = {};
6868

6969
for (uint32_t i = 0; i < count; i++)
7070
{
71-
result = AddUInt128(result, pValues[i]);
71+
UInt128 input;
72+
memcpy(&input, pValues + (sizeof(UInt128) * i), sizeof(UInt128)); // Perform unaligned read
73+
result = AddUInt128(result, input);
7274
}
7375

7476
return result;

0 commit comments

Comments
 (0)