Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[release/7.0] Fix issues found in recent Int128 ABI change #74460

Merged
merged 2 commits into from
Aug 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
23 changes: 14 additions & 9 deletions src/tests/Interop/PInvoke/Int128/Int128Native.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;
}

Expand All @@ -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;

Expand All @@ -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)
Expand Down Expand Up @@ -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;
Expand Down
12 changes: 7 additions & 5 deletions src/tests/Interop/PInvoke/Int128/UInt128Native.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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;
Expand Down