mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 08:24:39 +00:00
[vm/ffi] Update tests to cover MacOS arm64 after-struct alignment
Expands the test PassStruct9BytesPackedMixedx10DoubleInt32 to see how the second integer is allocated. Updates runtime/vm/compiler/ffi/unit_tests/structPacked to have the same signature. Fixes the structs by value test generator to output // @dart 2.9 for legacy mode. Deletes the copy of the test generator from tests/ffi, the copy did not run in legacy mode. TEST=only test changes Change-Id: I65b7db56225a8e7963493dbccc2f296faca6fee1 Cq-Include-Trybots: luci.dart.try:vm-kernel-mac-release-arm64-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/202968 Reviewed-by: Tess Strickland <sstrickl@google.com>
This commit is contained in:
parent
a9f08a75a2
commit
ddafaa0775
|
@ -170,8 +170,7 @@ DART_EXPORT intptr_t TakeMaxUint8x10(uint8_t a,
|
|||
<< static_cast<int>(d) << ", " << static_cast<int>(e) << ", "
|
||||
<< static_cast<int>(f) << ", " << static_cast<int>(g) << ", "
|
||||
<< static_cast<int>(h) << ", " << static_cast<int>(i) << ", "
|
||||
<< static_cast<int>(j) << ", "
|
||||
<< ")\n";
|
||||
<< static_cast<int>(j) << ")\n";
|
||||
return (a == 0xff && b == 0xff && c == 0xff && d == 0xff && e == 0xff &&
|
||||
f == 0xff && g == 0xff && h == 0xff && i == 0xff && j == 0xff)
|
||||
? 1
|
||||
|
|
|
@ -4231,7 +4231,7 @@ DART_EXPORT int64_t PassStruct8BytesPackedIntx10(Struct8BytesPackedInt a0,
|
|||
// Used for testing structs and unions by value.
|
||||
// Struct with mis-aligned member.
|
||||
// Tests backfilling of CPU and FPU registers.
|
||||
DART_EXPORT double PassStruct9BytesPackedMixedx10DoubleInt32(
|
||||
DART_EXPORT double PassStruct9BytesPackedMixedx10DoubleInt32x2(
|
||||
Struct9BytesPackedMixed a0,
|
||||
Struct9BytesPackedMixed a1,
|
||||
Struct9BytesPackedMixed a2,
|
||||
|
@ -4243,8 +4243,9 @@ DART_EXPORT double PassStruct9BytesPackedMixedx10DoubleInt32(
|
|||
Struct9BytesPackedMixed a8,
|
||||
Struct9BytesPackedMixed a9,
|
||||
double a10,
|
||||
int32_t a11) {
|
||||
std::cout << "PassStruct9BytesPackedMixedx10DoubleInt32"
|
||||
int32_t a11,
|
||||
int32_t a12) {
|
||||
std::cout << "PassStruct9BytesPackedMixedx10DoubleInt32x2"
|
||||
<< "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << "), ("
|
||||
<< static_cast<int>(a1.a0) << ", " << a1.a1 << "), ("
|
||||
<< static_cast<int>(a2.a0) << ", " << a2.a1 << "), ("
|
||||
|
@ -4255,7 +4256,7 @@ DART_EXPORT double PassStruct9BytesPackedMixedx10DoubleInt32(
|
|||
<< static_cast<int>(a7.a0) << ", " << a7.a1 << "), ("
|
||||
<< static_cast<int>(a8.a0) << ", " << a8.a1 << "), ("
|
||||
<< static_cast<int>(a9.a0) << ", " << a9.a1 << "), " << a10 << ", "
|
||||
<< a11 << ")"
|
||||
<< a11 << ", " << a12 << ")"
|
||||
<< "\n";
|
||||
|
||||
double result = 0;
|
||||
|
@ -4282,6 +4283,7 @@ DART_EXPORT double PassStruct9BytesPackedMixedx10DoubleInt32(
|
|||
result += a9.a1;
|
||||
result += a10;
|
||||
result += a11;
|
||||
result += a12;
|
||||
|
||||
std::cout << "result = " << result << "\n";
|
||||
|
||||
|
@ -11492,7 +11494,7 @@ DART_EXPORT intptr_t TestPassStruct8BytesPackedIntx10(
|
|||
// Used for testing structs and unions by value.
|
||||
// Struct with mis-aligned member.
|
||||
// Tests backfilling of CPU and FPU registers.
|
||||
DART_EXPORT intptr_t TestPassStruct9BytesPackedMixedx10DoubleInt32(
|
||||
DART_EXPORT intptr_t TestPassStruct9BytesPackedMixedx10DoubleInt32x2(
|
||||
// NOLINTNEXTLINE(whitespace/parens)
|
||||
double (*f)(Struct9BytesPackedMixed a0,
|
||||
Struct9BytesPackedMixed a1,
|
||||
|
@ -11505,7 +11507,8 @@ DART_EXPORT intptr_t TestPassStruct9BytesPackedMixedx10DoubleInt32(
|
|||
Struct9BytesPackedMixed a8,
|
||||
Struct9BytesPackedMixed a9,
|
||||
double a10,
|
||||
int32_t a11)) {
|
||||
int32_t a11,
|
||||
int32_t a12)) {
|
||||
Struct9BytesPackedMixed a0;
|
||||
Struct9BytesPackedMixed a1;
|
||||
Struct9BytesPackedMixed a2;
|
||||
|
@ -11518,6 +11521,7 @@ DART_EXPORT intptr_t TestPassStruct9BytesPackedMixedx10DoubleInt32(
|
|||
Struct9BytesPackedMixed a9;
|
||||
double a10;
|
||||
int32_t a11;
|
||||
int32_t a12;
|
||||
|
||||
a0.a0 = 1;
|
||||
a0.a1 = 2.0;
|
||||
|
@ -11541,8 +11545,9 @@ DART_EXPORT intptr_t TestPassStruct9BytesPackedMixedx10DoubleInt32(
|
|||
a9.a1 = 20.0;
|
||||
a10 = -21.0;
|
||||
a11 = 22;
|
||||
a12 = -23;
|
||||
|
||||
std::cout << "Calling TestPassStruct9BytesPackedMixedx10DoubleInt32("
|
||||
std::cout << "Calling TestPassStruct9BytesPackedMixedx10DoubleInt32x2("
|
||||
<< "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << "), ("
|
||||
<< static_cast<int>(a1.a0) << ", " << a1.a1 << "), ("
|
||||
<< static_cast<int>(a2.a0) << ", " << a2.a1 << "), ("
|
||||
|
@ -11553,26 +11558,26 @@ DART_EXPORT intptr_t TestPassStruct9BytesPackedMixedx10DoubleInt32(
|
|||
<< static_cast<int>(a7.a0) << ", " << a7.a1 << "), ("
|
||||
<< static_cast<int>(a8.a0) << ", " << a8.a1 << "), ("
|
||||
<< static_cast<int>(a9.a0) << ", " << a9.a1 << "), " << a10 << ", "
|
||||
<< a11 << ")"
|
||||
<< a11 << ", " << a12 << ")"
|
||||
<< ")\n";
|
||||
|
||||
double result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
|
||||
double result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12);
|
||||
|
||||
std::cout << "result = " << result << "\n";
|
||||
|
||||
CHECK_APPROX(211.0, result);
|
||||
CHECK_APPROX(188.0, result);
|
||||
|
||||
// Pass argument that will make the Dart callback throw.
|
||||
a0.a0 = 42;
|
||||
|
||||
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
|
||||
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12);
|
||||
|
||||
CHECK_APPROX(0.0, result);
|
||||
|
||||
// Pass argument that will make the Dart callback return null.
|
||||
a0.a0 = 84;
|
||||
|
||||
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
|
||||
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12);
|
||||
|
||||
CHECK_APPROX(0.0, result);
|
||||
|
||||
|
|
|
@ -494,6 +494,7 @@ UNIT_TEST_CASE_WITH_ZONE(NativeCallingConvention_struct8bytesPackedx10) {
|
|||
// See the *.expect in ./unit_tests for this behavior.
|
||||
UNIT_TEST_CASE_WITH_ZONE(NativeCallingConvention_structPacked) {
|
||||
const auto& int8_type = *new (Z) NativePrimitiveType(kInt8);
|
||||
const auto& int32_type = *new (Z) NativePrimitiveType(kInt32);
|
||||
const auto& double_type = *new (Z) NativePrimitiveType(kDouble);
|
||||
|
||||
auto& member_types = *new (Z) NativeTypes(Z, 2);
|
||||
|
@ -504,13 +505,22 @@ UNIT_TEST_CASE_WITH_ZONE(NativeCallingConvention_structPacked) {
|
|||
EXPECT_EQ(9, struct_type.SizeInBytes());
|
||||
EXPECT(struct_type.ContainsUnalignedMembers());
|
||||
|
||||
auto& arguments = *new (Z) NativeTypes(Z, 11);
|
||||
auto& arguments = *new (Z) NativeTypes(Z, 13);
|
||||
arguments.Add(&struct_type);
|
||||
arguments.Add(&struct_type);
|
||||
arguments.Add(&struct_type);
|
||||
arguments.Add(&struct_type);
|
||||
arguments.Add(&struct_type);
|
||||
arguments.Add(&struct_type);
|
||||
arguments.Add(&struct_type);
|
||||
arguments.Add(&struct_type);
|
||||
arguments.Add(&struct_type);
|
||||
arguments.Add(&struct_type);
|
||||
arguments.Add(&int8_type); // Backfilling int registers.
|
||||
arguments.Add(&double_type); // Backfilling float registers.
|
||||
arguments.Add(&int32_type); // Backfilling int registers.
|
||||
arguments.Add(&int32_type); // Backfilling int registers.
|
||||
|
||||
RunSignatureTest(Z, "structPacked", arguments, struct_type);
|
||||
RunSignatureTest(Z, "structPacked", arguments, double_type);
|
||||
}
|
||||
|
||||
// The union is only 5 bytes because it's members are packed.
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
M(r0 int64, r1 int64) Struct(size: 9)
|
||||
M(r2 int64, r3 int64) Struct(size: 9)
|
||||
r4 int8
|
||||
M(r4 int64, r5 int64) Struct(size: 9)
|
||||
M(r6 int64, r7 int64) Struct(size: 9)
|
||||
S+0 Struct(size: 9)
|
||||
S+16 Struct(size: 9)
|
||||
S+32 Struct(size: 9)
|
||||
S+48 Struct(size: 9)
|
||||
S+64 Struct(size: 9)
|
||||
S+80 Struct(size: 9)
|
||||
v0 double
|
||||
S+96 int32
|
||||
S+104 int32
|
||||
=>
|
||||
M(r0 int64, r1 int64) Struct(size: 9)
|
||||
v0 double
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
M(r0 int64, r1 int64) Struct(size: 9)
|
||||
M(r2 int64, r3 int64) Struct(size: 9)
|
||||
r4 int32[int8]
|
||||
M(r4 int64, r5 int64) Struct(size: 9)
|
||||
M(r6 int64, r7 int64) Struct(size: 9)
|
||||
S+0 Struct(size: 9)
|
||||
S+16 Struct(size: 9)
|
||||
S+32 Struct(size: 9)
|
||||
S+48 Struct(size: 9)
|
||||
S+64 Struct(size: 9)
|
||||
S+80 Struct(size: 9)
|
||||
v0 double
|
||||
S+92 int32
|
||||
S+96 int32
|
||||
=>
|
||||
M(r0 int64, r1 int64) Struct(size: 9)
|
||||
v0 double
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
M(r0 int64, r1 int64) Struct(size: 9)
|
||||
M(r2 int64, r3 int64) Struct(size: 9)
|
||||
r4 int8
|
||||
M(r4 int64, r5 int64) Struct(size: 9)
|
||||
M(r6 int64, r7 int64) Struct(size: 9)
|
||||
S+0 Struct(size: 9)
|
||||
S+16 Struct(size: 9)
|
||||
S+32 Struct(size: 9)
|
||||
S+48 Struct(size: 9)
|
||||
S+64 Struct(size: 9)
|
||||
S+80 Struct(size: 9)
|
||||
v0 double
|
||||
S+96 int32
|
||||
S+104 int32
|
||||
=>
|
||||
M(r0 int64, r1 int64) Struct(size: 9)
|
||||
v0 double
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
M(r0 int64, r1 int64) Struct(size: 9)
|
||||
M(r2 int64, r3 int64) Struct(size: 9)
|
||||
r4 int8
|
||||
M(r4 int64, r5 int64) Struct(size: 9)
|
||||
M(r6 int64, r7 int64) Struct(size: 9)
|
||||
S+0 Struct(size: 9)
|
||||
S+16 Struct(size: 9)
|
||||
S+32 Struct(size: 9)
|
||||
S+48 Struct(size: 9)
|
||||
S+64 Struct(size: 9)
|
||||
S+80 Struct(size: 9)
|
||||
v0 double
|
||||
S+92 int32
|
||||
S+96 int32
|
||||
=>
|
||||
M(r0 int64, r1 int64) Struct(size: 9)
|
||||
v0 double
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
M(r1 int32, r2 int32, r3 int32) Struct(size: 9)
|
||||
M(S+0 int32, S+4 int32, S+8 int32) Struct(size: 9)
|
||||
S+12 int32[int8]
|
||||
S+16 double
|
||||
M(r0 int32, r1 int32, r2 int32) Struct(size: 9)
|
||||
M(r3 int32, S+0 int32, S+4 int32) Struct(size: 9)
|
||||
M(S+8 int32, S+12 int32, S+16 int32) Struct(size: 9)
|
||||
M(S+20 int32, S+24 int32, S+28 int32) Struct(size: 9)
|
||||
M(S+32 int32, S+36 int32, S+40 int32) Struct(size: 9)
|
||||
M(S+44 int32, S+48 int32, S+52 int32) Struct(size: 9)
|
||||
M(S+56 int32, S+60 int32, S+64 int32) Struct(size: 9)
|
||||
M(S+68 int32, S+72 int32, S+76 int32) Struct(size: 9)
|
||||
M(S+80 int32, S+84 int32, S+88 int32) Struct(size: 9)
|
||||
M(S+92 int32, S+96 int32, S+100 int32) Struct(size: 9)
|
||||
S+104 double
|
||||
S+112 int32
|
||||
S+116 int32
|
||||
=>
|
||||
P(r0 uint32) Struct(size: 9)
|
||||
(r0, r1) int64[double]
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
M(r1 int32, r2 int32, r3 int32) Struct(size: 9)
|
||||
M(S+0 int32, S+4 int32, S+8 int32) Struct(size: 9)
|
||||
S+12 int32[int8]
|
||||
M(r0 int32, r1 int32, r2 int32) Struct(size: 9)
|
||||
M(r3 int32, S+0 int32, S+4 int32) Struct(size: 9)
|
||||
M(S+8 int32, S+12 int32, S+16 int32) Struct(size: 9)
|
||||
M(S+20 int32, S+24 int32, S+28 int32) Struct(size: 9)
|
||||
M(S+32 int32, S+36 int32, S+40 int32) Struct(size: 9)
|
||||
M(S+44 int32, S+48 int32, S+52 int32) Struct(size: 9)
|
||||
M(S+56 int32, S+60 int32, S+64 int32) Struct(size: 9)
|
||||
M(S+68 int32, S+72 int32, S+76 int32) Struct(size: 9)
|
||||
M(S+80 int32, S+84 int32, S+88 int32) Struct(size: 9)
|
||||
M(S+92 int32, S+96 int32, S+100 int32) Struct(size: 9)
|
||||
d0 double
|
||||
S+104 int32
|
||||
S+108 int32
|
||||
=>
|
||||
P(r0 uint32) Struct(size: 9)
|
||||
q0 double
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
M(r1 int32, r2 int32, r3 int32) Struct(size: 9)
|
||||
M(S+0 int32, S+4 int32, S+8 int32) Struct(size: 9)
|
||||
S+12 int32[int8]
|
||||
M(r0 int32, r1 int32, r2 int32) Struct(size: 9)
|
||||
M(r3 int32, S+0 int32, S+4 int32) Struct(size: 9)
|
||||
M(S+8 int32, S+12 int32, S+16 int32) Struct(size: 9)
|
||||
M(S+20 int32, S+24 int32, S+28 int32) Struct(size: 9)
|
||||
M(S+32 int32, S+36 int32, S+40 int32) Struct(size: 9)
|
||||
M(S+44 int32, S+48 int32, S+52 int32) Struct(size: 9)
|
||||
M(S+56 int32, S+60 int32, S+64 int32) Struct(size: 9)
|
||||
M(S+68 int32, S+72 int32, S+76 int32) Struct(size: 9)
|
||||
M(S+80 int32, S+84 int32, S+88 int32) Struct(size: 9)
|
||||
M(S+92 int32, S+96 int32, S+100 int32) Struct(size: 9)
|
||||
d0 double
|
||||
S+104 int32
|
||||
S+108 int32
|
||||
=>
|
||||
P(r0 uint32) Struct(size: 9)
|
||||
q0 double
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
S+4 Struct(size: 9)
|
||||
S+16 Struct(size: 9)
|
||||
S+28 int32[int8]
|
||||
S+32 double
|
||||
S+0 Struct(size: 9)
|
||||
S+12 Struct(size: 9)
|
||||
S+24 Struct(size: 9)
|
||||
S+36 Struct(size: 9)
|
||||
S+48 Struct(size: 9)
|
||||
S+60 Struct(size: 9)
|
||||
S+72 Struct(size: 9)
|
||||
S+84 Struct(size: 9)
|
||||
S+96 Struct(size: 9)
|
||||
S+108 Struct(size: 9)
|
||||
S+120 double
|
||||
S+128 int32
|
||||
S+132 int32
|
||||
=>
|
||||
P(S+0 uint32, ret:eax uint32) Struct(size: 9)
|
||||
xmm0 double
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
S+4 Struct(size: 9)
|
||||
S+16 Struct(size: 9)
|
||||
S+28 int32[int8]
|
||||
S+32 double
|
||||
S+0 Struct(size: 9)
|
||||
S+12 Struct(size: 9)
|
||||
S+24 Struct(size: 9)
|
||||
S+36 Struct(size: 9)
|
||||
S+48 Struct(size: 9)
|
||||
S+60 Struct(size: 9)
|
||||
S+72 Struct(size: 9)
|
||||
S+84 Struct(size: 9)
|
||||
S+96 Struct(size: 9)
|
||||
S+108 Struct(size: 9)
|
||||
S+120 double
|
||||
S+128 int32
|
||||
S+132 int32
|
||||
=>
|
||||
P(S+0 uint32, ret:eax uint32) Struct(size: 9)
|
||||
xmm0 double
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
S+4 Struct(size: 9)
|
||||
S+16 Struct(size: 9)
|
||||
S+28 int32[int8]
|
||||
S+32 double
|
||||
S+0 Struct(size: 9)
|
||||
S+12 Struct(size: 9)
|
||||
S+24 Struct(size: 9)
|
||||
S+36 Struct(size: 9)
|
||||
S+48 Struct(size: 9)
|
||||
S+60 Struct(size: 9)
|
||||
S+72 Struct(size: 9)
|
||||
S+84 Struct(size: 9)
|
||||
S+96 Struct(size: 9)
|
||||
S+108 Struct(size: 9)
|
||||
S+120 double
|
||||
S+128 int32
|
||||
S+132 int32
|
||||
=>
|
||||
P(S+0 uint32, ret:eax uint32) Struct(size: 9)
|
||||
xmm0 double
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
S+0 Struct(size: 9)
|
||||
S+16 Struct(size: 9)
|
||||
rsi int32[int8]
|
||||
S+32 Struct(size: 9)
|
||||
S+48 Struct(size: 9)
|
||||
S+64 Struct(size: 9)
|
||||
S+80 Struct(size: 9)
|
||||
S+96 Struct(size: 9)
|
||||
S+112 Struct(size: 9)
|
||||
S+128 Struct(size: 9)
|
||||
S+144 Struct(size: 9)
|
||||
xmm0 double
|
||||
rdi int32
|
||||
rsi int32
|
||||
=>
|
||||
P(rdi int64, ret:rax int64) Struct(size: 9)
|
||||
xmm0 double
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
S+0 Struct(size: 9)
|
||||
S+16 Struct(size: 9)
|
||||
rsi int32[int8]
|
||||
S+32 Struct(size: 9)
|
||||
S+48 Struct(size: 9)
|
||||
S+64 Struct(size: 9)
|
||||
S+80 Struct(size: 9)
|
||||
S+96 Struct(size: 9)
|
||||
S+112 Struct(size: 9)
|
||||
S+128 Struct(size: 9)
|
||||
S+144 Struct(size: 9)
|
||||
xmm0 double
|
||||
rdi int32
|
||||
rsi int32
|
||||
=>
|
||||
P(rdi int64, ret:rax int64) Struct(size: 9)
|
||||
xmm0 double
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
S+0 Struct(size: 9)
|
||||
S+16 Struct(size: 9)
|
||||
rsi int32[int8]
|
||||
S+32 Struct(size: 9)
|
||||
S+48 Struct(size: 9)
|
||||
S+64 Struct(size: 9)
|
||||
S+80 Struct(size: 9)
|
||||
S+96 Struct(size: 9)
|
||||
S+112 Struct(size: 9)
|
||||
S+128 Struct(size: 9)
|
||||
S+144 Struct(size: 9)
|
||||
xmm0 double
|
||||
rdi int32
|
||||
rsi int32
|
||||
=>
|
||||
P(rdi int64, ret:rax int64) Struct(size: 9)
|
||||
xmm0 double
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
P(rcx int64) Struct(size: 9)
|
||||
P(rdx int64) Struct(size: 9)
|
||||
P(r8 int64) Struct(size: 9)
|
||||
r9 int8
|
||||
S+0 double
|
||||
P(r9 int64) Struct(size: 9)
|
||||
P(S+0 int64) Struct(size: 9)
|
||||
P(S+8 int64) Struct(size: 9)
|
||||
P(S+16 int64) Struct(size: 9)
|
||||
P(S+24 int64) Struct(size: 9)
|
||||
P(S+32 int64) Struct(size: 9)
|
||||
P(S+40 int64) Struct(size: 9)
|
||||
S+48 double
|
||||
S+56 int32
|
||||
S+64 int32
|
||||
=>
|
||||
P(rcx int64, ret:rax int64) Struct(size: 9)
|
||||
xmm0 double
|
||||
|
|
|
@ -295,10 +295,10 @@ final testCases = [
|
|||
passStruct8BytesPackedIntx10, 0),
|
||||
passStruct8BytesPackedIntx10AfterCallback),
|
||||
CallbackTest.withCheck(
|
||||
"PassStruct9BytesPackedMixedx10DoubleInt32",
|
||||
Pointer.fromFunction<PassStruct9BytesPackedMixedx10DoubleInt32Type>(
|
||||
passStruct9BytesPackedMixedx10DoubleInt32, 0.0),
|
||||
passStruct9BytesPackedMixedx10DoubleInt32AfterCallback),
|
||||
"PassStruct9BytesPackedMixedx10DoubleInt32x2",
|
||||
Pointer.fromFunction<PassStruct9BytesPackedMixedx10DoubleInt32x2Type>(
|
||||
passStruct9BytesPackedMixedx10DoubleInt32x2, 0.0),
|
||||
passStruct9BytesPackedMixedx10DoubleInt32x2AfterCallback),
|
||||
CallbackTest.withCheck(
|
||||
"PassStruct5BytesPackedMixed",
|
||||
Pointer.fromFunction<PassStruct5BytesPackedMixedType>(
|
||||
|
@ -6545,7 +6545,7 @@ void passStruct8BytesPackedIntx10AfterCallback() {
|
|||
Expect.equals(1275, result);
|
||||
}
|
||||
|
||||
typedef PassStruct9BytesPackedMixedx10DoubleInt32Type = Double Function(
|
||||
typedef PassStruct9BytesPackedMixedx10DoubleInt32x2Type = Double Function(
|
||||
Struct9BytesPackedMixed,
|
||||
Struct9BytesPackedMixed,
|
||||
Struct9BytesPackedMixed,
|
||||
|
@ -6557,69 +6557,72 @@ typedef PassStruct9BytesPackedMixedx10DoubleInt32Type = Double Function(
|
|||
Struct9BytesPackedMixed,
|
||||
Struct9BytesPackedMixed,
|
||||
Double,
|
||||
Int32,
|
||||
Int32);
|
||||
|
||||
// Global variables to be able to test inputs after callback returned.
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a0 =
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32x2_a0 =
|
||||
Struct9BytesPackedMixed();
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a1 =
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32x2_a1 =
|
||||
Struct9BytesPackedMixed();
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a2 =
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32x2_a2 =
|
||||
Struct9BytesPackedMixed();
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a3 =
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32x2_a3 =
|
||||
Struct9BytesPackedMixed();
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a4 =
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32x2_a4 =
|
||||
Struct9BytesPackedMixed();
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a5 =
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32x2_a5 =
|
||||
Struct9BytesPackedMixed();
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a6 =
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32x2_a6 =
|
||||
Struct9BytesPackedMixed();
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a7 =
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32x2_a7 =
|
||||
Struct9BytesPackedMixed();
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a8 =
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32x2_a8 =
|
||||
Struct9BytesPackedMixed();
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a9 =
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32x2_a9 =
|
||||
Struct9BytesPackedMixed();
|
||||
double passStruct9BytesPackedMixedx10DoubleInt32_a10 = 0.0;
|
||||
int passStruct9BytesPackedMixedx10DoubleInt32_a11 = 0;
|
||||
double passStruct9BytesPackedMixedx10DoubleInt32x2_a10 = 0.0;
|
||||
int passStruct9BytesPackedMixedx10DoubleInt32x2_a11 = 0;
|
||||
int passStruct9BytesPackedMixedx10DoubleInt32x2_a12 = 0;
|
||||
|
||||
// Result variable also global, so we can delete it after the callback.
|
||||
double passStruct9BytesPackedMixedx10DoubleInt32Result = 0.0;
|
||||
double passStruct9BytesPackedMixedx10DoubleInt32x2Result = 0.0;
|
||||
|
||||
double passStruct9BytesPackedMixedx10DoubleInt32CalculateResult() {
|
||||
double passStruct9BytesPackedMixedx10DoubleInt32x2CalculateResult() {
|
||||
double result = 0;
|
||||
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a0.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a0.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a1.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a1.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a2.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a2.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a3.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a3.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a4.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a4.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a5.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a5.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a6.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a6.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a7.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a7.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a8.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a8.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a9.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a9.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a10;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a11;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a0.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a0.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a1.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a1.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a2.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a2.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a3.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a3.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a4.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a4.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a5.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a5.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a6.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a6.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a7.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a7.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a8.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a8.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a9.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a9.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a10;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a11;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a12;
|
||||
|
||||
passStruct9BytesPackedMixedx10DoubleInt32Result = result;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32x2Result = result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Struct with mis-aligned member.
|
||||
/// Tests backfilling of CPU and FPU registers.
|
||||
double passStruct9BytesPackedMixedx10DoubleInt32(
|
||||
double passStruct9BytesPackedMixedx10DoubleInt32x2(
|
||||
Struct9BytesPackedMixed a0,
|
||||
Struct9BytesPackedMixed a1,
|
||||
Struct9BytesPackedMixed a2,
|
||||
|
@ -6631,9 +6634,10 @@ double passStruct9BytesPackedMixedx10DoubleInt32(
|
|||
Struct9BytesPackedMixed a8,
|
||||
Struct9BytesPackedMixed a9,
|
||||
double a10,
|
||||
int a11) {
|
||||
int a11,
|
||||
int a12) {
|
||||
print(
|
||||
"passStruct9BytesPackedMixedx10DoubleInt32(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9}, ${a10}, ${a11})");
|
||||
"passStruct9BytesPackedMixedx10DoubleInt32x2(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9}, ${a10}, ${a11}, ${a12})");
|
||||
|
||||
// In legacy mode, possibly return null.
|
||||
|
||||
|
@ -6641,35 +6645,36 @@ double passStruct9BytesPackedMixedx10DoubleInt32(
|
|||
if (a0.a0 == 42 || a0.a0 == 84) {
|
||||
print("throwing!");
|
||||
throw Exception(
|
||||
"PassStruct9BytesPackedMixedx10DoubleInt32 throwing on purpose!");
|
||||
"PassStruct9BytesPackedMixedx10DoubleInt32x2 throwing on purpose!");
|
||||
}
|
||||
|
||||
passStruct9BytesPackedMixedx10DoubleInt32_a0 = a0;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32_a1 = a1;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32_a2 = a2;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32_a3 = a3;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32_a4 = a4;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32_a5 = a5;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32_a6 = a6;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32_a7 = a7;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32_a8 = a8;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32_a9 = a9;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32_a10 = a10;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32_a11 = a11;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32x2_a0 = a0;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32x2_a1 = a1;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32x2_a2 = a2;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32x2_a3 = a3;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32x2_a4 = a4;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32x2_a5 = a5;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32x2_a6 = a6;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32x2_a7 = a7;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32x2_a8 = a8;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32x2_a9 = a9;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32x2_a10 = a10;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32x2_a11 = a11;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32x2_a12 = a12;
|
||||
|
||||
final result = passStruct9BytesPackedMixedx10DoubleInt32CalculateResult();
|
||||
final result = passStruct9BytesPackedMixedx10DoubleInt32x2CalculateResult();
|
||||
|
||||
print("result = $result");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void passStruct9BytesPackedMixedx10DoubleInt32AfterCallback() {
|
||||
final result = passStruct9BytesPackedMixedx10DoubleInt32CalculateResult();
|
||||
void passStruct9BytesPackedMixedx10DoubleInt32x2AfterCallback() {
|
||||
final result = passStruct9BytesPackedMixedx10DoubleInt32x2CalculateResult();
|
||||
|
||||
print("after callback result = $result");
|
||||
|
||||
Expect.approxEquals(211.0, result);
|
||||
Expect.approxEquals(188.0, result);
|
||||
}
|
||||
|
||||
typedef PassStruct5BytesPackedMixedType = Double Function(
|
||||
|
|
|
@ -72,7 +72,7 @@ void main() {
|
|||
testPassUint8Struct4BytesInlineArrayMultiDimensionalIn();
|
||||
testPassStruct3BytesPackedIntx10();
|
||||
testPassStruct8BytesPackedIntx10();
|
||||
testPassStruct9BytesPackedMixedx10DoubleInt32();
|
||||
testPassStruct9BytesPackedMixedx10DoubleInt32x2();
|
||||
testPassStruct5BytesPackedMixed();
|
||||
testPassStructNestedAlignmentStruct5BytesPackedMixed();
|
||||
testPassStruct6BytesInlineArrayInt();
|
||||
|
@ -185,7 +185,7 @@ void main() {
|
|||
testPassUint8Struct4BytesInlineArrayMultiDimensionalInLeaf();
|
||||
testPassStruct3BytesPackedIntx10Leaf();
|
||||
testPassStruct8BytesPackedIntx10Leaf();
|
||||
testPassStruct9BytesPackedMixedx10DoubleInt32Leaf();
|
||||
testPassStruct9BytesPackedMixedx10DoubleInt32x2Leaf();
|
||||
testPassStruct5BytesPackedMixedLeaf();
|
||||
testPassStructNestedAlignmentStruct5BytesPackedMixedLeaf();
|
||||
testPassStruct6BytesInlineArrayIntLeaf();
|
||||
|
@ -5892,7 +5892,7 @@ void testPassStruct8BytesPackedIntx10() {
|
|||
calloc.free(a9Pointer);
|
||||
}
|
||||
|
||||
final passStruct9BytesPackedMixedx10DoubleInt32 =
|
||||
final passStruct9BytesPackedMixedx10DoubleInt32x2 =
|
||||
ffiTestFunctions.lookupFunction<
|
||||
Double Function(
|
||||
Struct9BytesPackedMixed,
|
||||
|
@ -5906,6 +5906,7 @@ final passStruct9BytesPackedMixedx10DoubleInt32 =
|
|||
Struct9BytesPackedMixed,
|
||||
Struct9BytesPackedMixed,
|
||||
Double,
|
||||
Int32,
|
||||
Int32),
|
||||
double Function(
|
||||
Struct9BytesPackedMixed,
|
||||
|
@ -5919,11 +5920,12 @@ final passStruct9BytesPackedMixedx10DoubleInt32 =
|
|||
Struct9BytesPackedMixed,
|
||||
Struct9BytesPackedMixed,
|
||||
double,
|
||||
int)>("PassStruct9BytesPackedMixedx10DoubleInt32");
|
||||
int,
|
||||
int)>("PassStruct9BytesPackedMixedx10DoubleInt32x2");
|
||||
|
||||
/// Struct with mis-aligned member.
|
||||
/// Tests backfilling of CPU and FPU registers.
|
||||
void testPassStruct9BytesPackedMixedx10DoubleInt32() {
|
||||
void testPassStruct9BytesPackedMixedx10DoubleInt32x2() {
|
||||
final a0Pointer = calloc<Struct9BytesPackedMixed>();
|
||||
final Struct9BytesPackedMixed a0 = a0Pointer.ref;
|
||||
final a1Pointer = calloc<Struct9BytesPackedMixed>();
|
||||
|
@ -5946,6 +5948,7 @@ void testPassStruct9BytesPackedMixedx10DoubleInt32() {
|
|||
final Struct9BytesPackedMixed a9 = a9Pointer.ref;
|
||||
double a10;
|
||||
int a11;
|
||||
int a12;
|
||||
|
||||
a0.a0 = 1;
|
||||
a0.a1 = 2.0;
|
||||
|
@ -5969,13 +5972,14 @@ void testPassStruct9BytesPackedMixedx10DoubleInt32() {
|
|||
a9.a1 = 20.0;
|
||||
a10 = -21.0;
|
||||
a11 = 22;
|
||||
a12 = -23;
|
||||
|
||||
final result = passStruct9BytesPackedMixedx10DoubleInt32(
|
||||
a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
|
||||
final result = passStruct9BytesPackedMixedx10DoubleInt32x2(
|
||||
a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12);
|
||||
|
||||
print("result = $result");
|
||||
|
||||
Expect.approxEquals(211.0, result);
|
||||
Expect.approxEquals(188.0, result);
|
||||
|
||||
calloc.free(a0Pointer);
|
||||
calloc.free(a1Pointer);
|
||||
|
@ -13390,7 +13394,7 @@ void testPassStruct8BytesPackedIntx10Leaf() {
|
|||
calloc.free(a9Pointer);
|
||||
}
|
||||
|
||||
final passStruct9BytesPackedMixedx10DoubleInt32Leaf =
|
||||
final passStruct9BytesPackedMixedx10DoubleInt32x2Leaf =
|
||||
ffiTestFunctions.lookupFunction<
|
||||
Double Function(
|
||||
Struct9BytesPackedMixed,
|
||||
|
@ -13404,6 +13408,7 @@ final passStruct9BytesPackedMixedx10DoubleInt32Leaf =
|
|||
Struct9BytesPackedMixed,
|
||||
Struct9BytesPackedMixed,
|
||||
Double,
|
||||
Int32,
|
||||
Int32),
|
||||
double Function(
|
||||
Struct9BytesPackedMixed,
|
||||
|
@ -13417,11 +13422,12 @@ final passStruct9BytesPackedMixedx10DoubleInt32Leaf =
|
|||
Struct9BytesPackedMixed,
|
||||
Struct9BytesPackedMixed,
|
||||
double,
|
||||
int)>("PassStruct9BytesPackedMixedx10DoubleInt32", isLeaf: true);
|
||||
int,
|
||||
int)>("PassStruct9BytesPackedMixedx10DoubleInt32x2", isLeaf: true);
|
||||
|
||||
/// Struct with mis-aligned member.
|
||||
/// Tests backfilling of CPU and FPU registers.
|
||||
void testPassStruct9BytesPackedMixedx10DoubleInt32Leaf() {
|
||||
void testPassStruct9BytesPackedMixedx10DoubleInt32x2Leaf() {
|
||||
final a0Pointer = calloc<Struct9BytesPackedMixed>();
|
||||
final Struct9BytesPackedMixed a0 = a0Pointer.ref;
|
||||
final a1Pointer = calloc<Struct9BytesPackedMixed>();
|
||||
|
@ -13444,6 +13450,7 @@ void testPassStruct9BytesPackedMixedx10DoubleInt32Leaf() {
|
|||
final Struct9BytesPackedMixed a9 = a9Pointer.ref;
|
||||
double a10;
|
||||
int a11;
|
||||
int a12;
|
||||
|
||||
a0.a0 = 1;
|
||||
a0.a1 = 2.0;
|
||||
|
@ -13467,13 +13474,14 @@ void testPassStruct9BytesPackedMixedx10DoubleInt32Leaf() {
|
|||
a9.a1 = 20.0;
|
||||
a10 = -21.0;
|
||||
a11 = 22;
|
||||
a12 = -23;
|
||||
|
||||
final result = passStruct9BytesPackedMixedx10DoubleInt32Leaf(
|
||||
a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
|
||||
final result = passStruct9BytesPackedMixedx10DoubleInt32x2Leaf(
|
||||
a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12);
|
||||
|
||||
print("result = $result");
|
||||
|
||||
Expect.approxEquals(211.0, result);
|
||||
Expect.approxEquals(188.0, result);
|
||||
|
||||
calloc.free(a0Pointer);
|
||||
calloc.free(a1Pointer);
|
||||
|
|
|
@ -339,7 +339,7 @@ Small struct with mis-aligned member."""),
|
|||
FunctionType(List.filled(10, struct8bytesPacked), int64, """
|
||||
Struct with mis-aligned member."""),
|
||||
FunctionType(
|
||||
[...List.filled(10, struct9bytesPacked), double_, int32],
|
||||
[...List.filled(10, struct9bytesPacked), double_, int32, int32],
|
||||
double_,
|
||||
"""
|
||||
Struct with mis-aligned member.
|
||||
|
|
|
@ -856,7 +856,14 @@ const throwExceptionValue = 42;
|
|||
/// Some value between 0 and 127 (works in every native type).
|
||||
const returnNullValue = 84;
|
||||
|
||||
const headerDartCallTest = """
|
||||
const dart2dot9 = '''
|
||||
// @dart = 2.9
|
||||
''';
|
||||
|
||||
headerDartCallTest(bool nnbd) {
|
||||
final dartVersion = nnbd ? '' : dart2dot9;
|
||||
|
||||
return """
|
||||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
@ -869,6 +876,8 @@ const headerDartCallTest = """
|
|||
// VMOptions=--use-slow-path
|
||||
// VMOptions=--use-slow-path --stacktrace-every=100
|
||||
|
||||
$dartVersion
|
||||
|
||||
import 'dart:ffi';
|
||||
|
||||
import "package:expect/expect.dart";
|
||||
|
@ -878,11 +887,12 @@ import 'dylib_utils.dart';
|
|||
|
||||
final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
|
||||
""";
|
||||
}
|
||||
|
||||
void writeDartCallTest() {
|
||||
for (bool nnbd in [true, false]) {
|
||||
final StringBuffer buffer = StringBuffer();
|
||||
buffer.write(headerDartCallTest);
|
||||
buffer.write(headerDartCallTest(nnbd));
|
||||
|
||||
buffer.write("""
|
||||
void main() {
|
||||
|
@ -909,7 +919,10 @@ String callTestPath(bool nnbd) {
|
|||
.path;
|
||||
}
|
||||
|
||||
const headerDartCallbackTest = """
|
||||
headerDartCallbackTest(bool nnbd) {
|
||||
final dartVersion = nnbd ? '' : dart2dot9;
|
||||
|
||||
return """
|
||||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
@ -922,6 +935,8 @@ const headerDartCallbackTest = """
|
|||
// VMOptions=--use-slow-path
|
||||
// VMOptions=--use-slow-path --stacktrace-every=100
|
||||
|
||||
$dartVersion
|
||||
|
||||
import 'dart:ffi';
|
||||
|
||||
import "package:expect/expect.dart";
|
||||
|
@ -942,11 +957,12 @@ void main() {
|
|||
|
||||
|
||||
""";
|
||||
}
|
||||
|
||||
void writeDartCallbackTest() {
|
||||
for (bool nnbd in [true, false]) {
|
||||
final StringBuffer buffer = StringBuffer();
|
||||
buffer.write(headerDartCallbackTest);
|
||||
buffer.write(headerDartCallbackTest(nnbd));
|
||||
|
||||
buffer.write("""
|
||||
final testCases = [
|
||||
|
|
|
@ -297,10 +297,10 @@ final testCases = [
|
|||
passStruct8BytesPackedIntx10, 0),
|
||||
passStruct8BytesPackedIntx10AfterCallback),
|
||||
CallbackTest.withCheck(
|
||||
"PassStruct9BytesPackedMixedx10DoubleInt32",
|
||||
Pointer.fromFunction<PassStruct9BytesPackedMixedx10DoubleInt32Type>(
|
||||
passStruct9BytesPackedMixedx10DoubleInt32, 0.0),
|
||||
passStruct9BytesPackedMixedx10DoubleInt32AfterCallback),
|
||||
"PassStruct9BytesPackedMixedx10DoubleInt32x2",
|
||||
Pointer.fromFunction<PassStruct9BytesPackedMixedx10DoubleInt32x2Type>(
|
||||
passStruct9BytesPackedMixedx10DoubleInt32x2, 0.0),
|
||||
passStruct9BytesPackedMixedx10DoubleInt32x2AfterCallback),
|
||||
CallbackTest.withCheck(
|
||||
"PassStruct5BytesPackedMixed",
|
||||
Pointer.fromFunction<PassStruct5BytesPackedMixedType>(
|
||||
|
@ -6755,7 +6755,7 @@ void passStruct8BytesPackedIntx10AfterCallback() {
|
|||
Expect.equals(1275, result);
|
||||
}
|
||||
|
||||
typedef PassStruct9BytesPackedMixedx10DoubleInt32Type = Double Function(
|
||||
typedef PassStruct9BytesPackedMixedx10DoubleInt32x2Type = Double Function(
|
||||
Struct9BytesPackedMixed,
|
||||
Struct9BytesPackedMixed,
|
||||
Struct9BytesPackedMixed,
|
||||
|
@ -6767,69 +6767,72 @@ typedef PassStruct9BytesPackedMixedx10DoubleInt32Type = Double Function(
|
|||
Struct9BytesPackedMixed,
|
||||
Struct9BytesPackedMixed,
|
||||
Double,
|
||||
Int32,
|
||||
Int32);
|
||||
|
||||
// Global variables to be able to test inputs after callback returned.
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a0 =
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32x2_a0 =
|
||||
Struct9BytesPackedMixed();
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a1 =
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32x2_a1 =
|
||||
Struct9BytesPackedMixed();
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a2 =
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32x2_a2 =
|
||||
Struct9BytesPackedMixed();
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a3 =
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32x2_a3 =
|
||||
Struct9BytesPackedMixed();
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a4 =
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32x2_a4 =
|
||||
Struct9BytesPackedMixed();
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a5 =
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32x2_a5 =
|
||||
Struct9BytesPackedMixed();
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a6 =
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32x2_a6 =
|
||||
Struct9BytesPackedMixed();
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a7 =
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32x2_a7 =
|
||||
Struct9BytesPackedMixed();
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a8 =
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32x2_a8 =
|
||||
Struct9BytesPackedMixed();
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a9 =
|
||||
Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32x2_a9 =
|
||||
Struct9BytesPackedMixed();
|
||||
double passStruct9BytesPackedMixedx10DoubleInt32_a10 = 0.0;
|
||||
int passStruct9BytesPackedMixedx10DoubleInt32_a11 = 0;
|
||||
double passStruct9BytesPackedMixedx10DoubleInt32x2_a10 = 0.0;
|
||||
int passStruct9BytesPackedMixedx10DoubleInt32x2_a11 = 0;
|
||||
int passStruct9BytesPackedMixedx10DoubleInt32x2_a12 = 0;
|
||||
|
||||
// Result variable also global, so we can delete it after the callback.
|
||||
double passStruct9BytesPackedMixedx10DoubleInt32Result = 0.0;
|
||||
double passStruct9BytesPackedMixedx10DoubleInt32x2Result = 0.0;
|
||||
|
||||
double passStruct9BytesPackedMixedx10DoubleInt32CalculateResult() {
|
||||
double passStruct9BytesPackedMixedx10DoubleInt32x2CalculateResult() {
|
||||
double result = 0;
|
||||
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a0.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a0.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a1.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a1.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a2.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a2.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a3.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a3.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a4.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a4.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a5.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a5.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a6.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a6.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a7.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a7.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a8.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a8.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a9.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a9.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a10;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32_a11;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a0.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a0.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a1.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a1.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a2.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a2.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a3.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a3.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a4.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a4.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a5.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a5.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a6.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a6.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a7.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a7.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a8.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a8.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a9.a0;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a9.a1;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a10;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a11;
|
||||
result += passStruct9BytesPackedMixedx10DoubleInt32x2_a12;
|
||||
|
||||
passStruct9BytesPackedMixedx10DoubleInt32Result = result;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32x2Result = result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Struct with mis-aligned member.
|
||||
/// Tests backfilling of CPU and FPU registers.
|
||||
double passStruct9BytesPackedMixedx10DoubleInt32(
|
||||
double passStruct9BytesPackedMixedx10DoubleInt32x2(
|
||||
Struct9BytesPackedMixed a0,
|
||||
Struct9BytesPackedMixed a1,
|
||||
Struct9BytesPackedMixed a2,
|
||||
|
@ -6841,9 +6844,10 @@ double passStruct9BytesPackedMixedx10DoubleInt32(
|
|||
Struct9BytesPackedMixed a8,
|
||||
Struct9BytesPackedMixed a9,
|
||||
double a10,
|
||||
int a11) {
|
||||
int a11,
|
||||
int a12) {
|
||||
print(
|
||||
"passStruct9BytesPackedMixedx10DoubleInt32(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9}, ${a10}, ${a11})");
|
||||
"passStruct9BytesPackedMixedx10DoubleInt32x2(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9}, ${a10}, ${a11}, ${a12})");
|
||||
|
||||
// In legacy mode, possibly return null.
|
||||
if (a0.a0 == 84) {
|
||||
|
@ -6855,35 +6859,36 @@ double passStruct9BytesPackedMixedx10DoubleInt32(
|
|||
if (a0.a0 == 42 || a0.a0 == 84) {
|
||||
print("throwing!");
|
||||
throw Exception(
|
||||
"PassStruct9BytesPackedMixedx10DoubleInt32 throwing on purpose!");
|
||||
"PassStruct9BytesPackedMixedx10DoubleInt32x2 throwing on purpose!");
|
||||
}
|
||||
|
||||
passStruct9BytesPackedMixedx10DoubleInt32_a0 = a0;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32_a1 = a1;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32_a2 = a2;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32_a3 = a3;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32_a4 = a4;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32_a5 = a5;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32_a6 = a6;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32_a7 = a7;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32_a8 = a8;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32_a9 = a9;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32_a10 = a10;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32_a11 = a11;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32x2_a0 = a0;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32x2_a1 = a1;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32x2_a2 = a2;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32x2_a3 = a3;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32x2_a4 = a4;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32x2_a5 = a5;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32x2_a6 = a6;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32x2_a7 = a7;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32x2_a8 = a8;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32x2_a9 = a9;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32x2_a10 = a10;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32x2_a11 = a11;
|
||||
passStruct9BytesPackedMixedx10DoubleInt32x2_a12 = a12;
|
||||
|
||||
final result = passStruct9BytesPackedMixedx10DoubleInt32CalculateResult();
|
||||
final result = passStruct9BytesPackedMixedx10DoubleInt32x2CalculateResult();
|
||||
|
||||
print("result = $result");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void passStruct9BytesPackedMixedx10DoubleInt32AfterCallback() {
|
||||
final result = passStruct9BytesPackedMixedx10DoubleInt32CalculateResult();
|
||||
void passStruct9BytesPackedMixedx10DoubleInt32x2AfterCallback() {
|
||||
final result = passStruct9BytesPackedMixedx10DoubleInt32x2CalculateResult();
|
||||
|
||||
print("after callback result = $result");
|
||||
|
||||
Expect.approxEquals(211.0, result);
|
||||
Expect.approxEquals(188.0, result);
|
||||
}
|
||||
|
||||
typedef PassStruct5BytesPackedMixedType = Double Function(
|
||||
|
|
|
@ -74,7 +74,7 @@ void main() {
|
|||
testPassUint8Struct4BytesInlineArrayMultiDimensionalIn();
|
||||
testPassStruct3BytesPackedIntx10();
|
||||
testPassStruct8BytesPackedIntx10();
|
||||
testPassStruct9BytesPackedMixedx10DoubleInt32();
|
||||
testPassStruct9BytesPackedMixedx10DoubleInt32x2();
|
||||
testPassStruct5BytesPackedMixed();
|
||||
testPassStructNestedAlignmentStruct5BytesPackedMixed();
|
||||
testPassStruct6BytesInlineArrayInt();
|
||||
|
@ -187,7 +187,7 @@ void main() {
|
|||
testPassUint8Struct4BytesInlineArrayMultiDimensionalInLeaf();
|
||||
testPassStruct3BytesPackedIntx10Leaf();
|
||||
testPassStruct8BytesPackedIntx10Leaf();
|
||||
testPassStruct9BytesPackedMixedx10DoubleInt32Leaf();
|
||||
testPassStruct9BytesPackedMixedx10DoubleInt32x2Leaf();
|
||||
testPassStruct5BytesPackedMixedLeaf();
|
||||
testPassStructNestedAlignmentStruct5BytesPackedMixedLeaf();
|
||||
testPassStruct6BytesInlineArrayIntLeaf();
|
||||
|
@ -5894,7 +5894,7 @@ void testPassStruct8BytesPackedIntx10() {
|
|||
calloc.free(a9Pointer);
|
||||
}
|
||||
|
||||
final passStruct9BytesPackedMixedx10DoubleInt32 =
|
||||
final passStruct9BytesPackedMixedx10DoubleInt32x2 =
|
||||
ffiTestFunctions.lookupFunction<
|
||||
Double Function(
|
||||
Struct9BytesPackedMixed,
|
||||
|
@ -5908,6 +5908,7 @@ final passStruct9BytesPackedMixedx10DoubleInt32 =
|
|||
Struct9BytesPackedMixed,
|
||||
Struct9BytesPackedMixed,
|
||||
Double,
|
||||
Int32,
|
||||
Int32),
|
||||
double Function(
|
||||
Struct9BytesPackedMixed,
|
||||
|
@ -5921,11 +5922,12 @@ final passStruct9BytesPackedMixedx10DoubleInt32 =
|
|||
Struct9BytesPackedMixed,
|
||||
Struct9BytesPackedMixed,
|
||||
double,
|
||||
int)>("PassStruct9BytesPackedMixedx10DoubleInt32");
|
||||
int,
|
||||
int)>("PassStruct9BytesPackedMixedx10DoubleInt32x2");
|
||||
|
||||
/// Struct with mis-aligned member.
|
||||
/// Tests backfilling of CPU and FPU registers.
|
||||
void testPassStruct9BytesPackedMixedx10DoubleInt32() {
|
||||
void testPassStruct9BytesPackedMixedx10DoubleInt32x2() {
|
||||
final a0Pointer = calloc<Struct9BytesPackedMixed>();
|
||||
final Struct9BytesPackedMixed a0 = a0Pointer.ref;
|
||||
final a1Pointer = calloc<Struct9BytesPackedMixed>();
|
||||
|
@ -5948,6 +5950,7 @@ void testPassStruct9BytesPackedMixedx10DoubleInt32() {
|
|||
final Struct9BytesPackedMixed a9 = a9Pointer.ref;
|
||||
double a10;
|
||||
int a11;
|
||||
int a12;
|
||||
|
||||
a0.a0 = 1;
|
||||
a0.a1 = 2.0;
|
||||
|
@ -5971,13 +5974,14 @@ void testPassStruct9BytesPackedMixedx10DoubleInt32() {
|
|||
a9.a1 = 20.0;
|
||||
a10 = -21.0;
|
||||
a11 = 22;
|
||||
a12 = -23;
|
||||
|
||||
final result = passStruct9BytesPackedMixedx10DoubleInt32(
|
||||
a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
|
||||
final result = passStruct9BytesPackedMixedx10DoubleInt32x2(
|
||||
a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12);
|
||||
|
||||
print("result = $result");
|
||||
|
||||
Expect.approxEquals(211.0, result);
|
||||
Expect.approxEquals(188.0, result);
|
||||
|
||||
calloc.free(a0Pointer);
|
||||
calloc.free(a1Pointer);
|
||||
|
@ -13392,7 +13396,7 @@ void testPassStruct8BytesPackedIntx10Leaf() {
|
|||
calloc.free(a9Pointer);
|
||||
}
|
||||
|
||||
final passStruct9BytesPackedMixedx10DoubleInt32Leaf =
|
||||
final passStruct9BytesPackedMixedx10DoubleInt32x2Leaf =
|
||||
ffiTestFunctions.lookupFunction<
|
||||
Double Function(
|
||||
Struct9BytesPackedMixed,
|
||||
|
@ -13406,6 +13410,7 @@ final passStruct9BytesPackedMixedx10DoubleInt32Leaf =
|
|||
Struct9BytesPackedMixed,
|
||||
Struct9BytesPackedMixed,
|
||||
Double,
|
||||
Int32,
|
||||
Int32),
|
||||
double Function(
|
||||
Struct9BytesPackedMixed,
|
||||
|
@ -13419,11 +13424,12 @@ final passStruct9BytesPackedMixedx10DoubleInt32Leaf =
|
|||
Struct9BytesPackedMixed,
|
||||
Struct9BytesPackedMixed,
|
||||
double,
|
||||
int)>("PassStruct9BytesPackedMixedx10DoubleInt32", isLeaf: true);
|
||||
int,
|
||||
int)>("PassStruct9BytesPackedMixedx10DoubleInt32x2", isLeaf: true);
|
||||
|
||||
/// Struct with mis-aligned member.
|
||||
/// Tests backfilling of CPU and FPU registers.
|
||||
void testPassStruct9BytesPackedMixedx10DoubleInt32Leaf() {
|
||||
void testPassStruct9BytesPackedMixedx10DoubleInt32x2Leaf() {
|
||||
final a0Pointer = calloc<Struct9BytesPackedMixed>();
|
||||
final Struct9BytesPackedMixed a0 = a0Pointer.ref;
|
||||
final a1Pointer = calloc<Struct9BytesPackedMixed>();
|
||||
|
@ -13446,6 +13452,7 @@ void testPassStruct9BytesPackedMixedx10DoubleInt32Leaf() {
|
|||
final Struct9BytesPackedMixed a9 = a9Pointer.ref;
|
||||
double a10;
|
||||
int a11;
|
||||
int a12;
|
||||
|
||||
a0.a0 = 1;
|
||||
a0.a1 = 2.0;
|
||||
|
@ -13469,13 +13476,14 @@ void testPassStruct9BytesPackedMixedx10DoubleInt32Leaf() {
|
|||
a9.a1 = 20.0;
|
||||
a10 = -21.0;
|
||||
a11 = 22;
|
||||
a12 = -23;
|
||||
|
||||
final result = passStruct9BytesPackedMixedx10DoubleInt32Leaf(
|
||||
a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
|
||||
final result = passStruct9BytesPackedMixedx10DoubleInt32x2Leaf(
|
||||
a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12);
|
||||
|
||||
print("result = $result");
|
||||
|
||||
Expect.approxEquals(211.0, result);
|
||||
Expect.approxEquals(188.0, result);
|
||||
|
||||
calloc.free(a0Pointer);
|
||||
calloc.free(a1Pointer);
|
||||
|
|
|
@ -1,461 +0,0 @@
|
|||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'dart:math' as math;
|
||||
|
||||
import 'utils.dart';
|
||||
|
||||
const int8 = FundamentalType(PrimitiveType.int8);
|
||||
const int16 = FundamentalType(PrimitiveType.int16);
|
||||
const int32 = FundamentalType(PrimitiveType.int32);
|
||||
const int64 = FundamentalType(PrimitiveType.int64);
|
||||
const uint8 = FundamentalType(PrimitiveType.uint8);
|
||||
const uint16 = FundamentalType(PrimitiveType.uint16);
|
||||
const uint32 = FundamentalType(PrimitiveType.uint32);
|
||||
const uint64 = FundamentalType(PrimitiveType.uint64);
|
||||
const intptr = FundamentalType(PrimitiveType.intptr);
|
||||
const float = FundamentalType(PrimitiveType.float);
|
||||
const double_ = FundamentalType(PrimitiveType.double_);
|
||||
|
||||
enum PrimitiveType {
|
||||
int8,
|
||||
int16,
|
||||
int32,
|
||||
int64,
|
||||
uint8,
|
||||
uint16,
|
||||
uint32,
|
||||
uint64,
|
||||
intptr,
|
||||
float,
|
||||
double_,
|
||||
}
|
||||
|
||||
const primitiveNames = [
|
||||
"int8",
|
||||
"int16",
|
||||
"int32",
|
||||
"int64",
|
||||
"uint8",
|
||||
"uint16",
|
||||
"uint32",
|
||||
"uint64",
|
||||
"intptr",
|
||||
"float",
|
||||
"double",
|
||||
];
|
||||
|
||||
const intptrSize = -1;
|
||||
const primitiveSizesInBytes = [1, 2, 4, 8, 1, 2, 4, 8, intptrSize, 4, 8];
|
||||
|
||||
abstract class CType {
|
||||
String get cType;
|
||||
String get dartCType;
|
||||
String get dartType;
|
||||
String get dartStructFieldAnnotation;
|
||||
|
||||
/// Has a known [size] that is the same for all architectures.
|
||||
bool get hasSize;
|
||||
|
||||
/// Get a size in bytes that is the same on all architectures.
|
||||
int get size;
|
||||
|
||||
/// All members have a floating point type.
|
||||
bool get isOnlyFloatingPoint;
|
||||
|
||||
/// All members have a integer type.
|
||||
bool get isOnlyInteger;
|
||||
|
||||
String toString() => dartCType;
|
||||
|
||||
const CType();
|
||||
}
|
||||
|
||||
class FundamentalType extends CType {
|
||||
final PrimitiveType primitive;
|
||||
|
||||
const FundamentalType(this.primitive);
|
||||
|
||||
bool get isFloatingPoint =>
|
||||
primitive == PrimitiveType.float || primitive == PrimitiveType.double_;
|
||||
bool get isInteger => !isFloatingPoint;
|
||||
bool get isOnlyFloatingPoint => isFloatingPoint;
|
||||
bool get isOnlyInteger => isInteger;
|
||||
bool get isUnsigned =>
|
||||
primitive == PrimitiveType.uint8 ||
|
||||
primitive == PrimitiveType.uint16 ||
|
||||
primitive == PrimitiveType.uint32 ||
|
||||
primitive == PrimitiveType.uint64;
|
||||
bool get isSigned => !isUnsigned;
|
||||
|
||||
String get name => primitiveNames[primitive.index];
|
||||
|
||||
String get cType => "${name}${isInteger ? "_t" : ""}";
|
||||
String get dartCType => name.upperCaseFirst();
|
||||
String get dartType => isInteger ? "int" : "double";
|
||||
String get dartStructFieldAnnotation => "@${dartCType}()";
|
||||
bool get hasSize => primitive != PrimitiveType.intptr;
|
||||
int get size {
|
||||
if (!hasSize) {
|
||||
throw "Size unknown.";
|
||||
}
|
||||
return primitiveSizesInBytes[primitive.index];
|
||||
}
|
||||
}
|
||||
|
||||
class PointerType extends CType {
|
||||
final CType pointerTo;
|
||||
|
||||
PointerType(this.pointerTo);
|
||||
|
||||
String get cType => "${pointerTo.cType}*";
|
||||
String get dartCType => "Pointer<${pointerTo.dartCType}>";
|
||||
String get dartType => "Pointer<${pointerTo.dartType}>";
|
||||
String get dartStructFieldAnnotation => "";
|
||||
bool get hasSize => false;
|
||||
int get size => throw "Size unknown";
|
||||
|
||||
bool get isOnlyFloatingPoint => false;
|
||||
bool get isOnlyInteger => true;
|
||||
}
|
||||
|
||||
/// Used to give [StructType] fields and [FunctionType] arguments names.
|
||||
class Member {
|
||||
final CType type;
|
||||
final String name;
|
||||
|
||||
Member(this.type, this.name);
|
||||
|
||||
String dartStructField(bool nnbd) {
|
||||
final modifier = nnbd ? "external" : "";
|
||||
return "${type.dartStructFieldAnnotation} $modifier ${type.dartType} $name;";
|
||||
}
|
||||
|
||||
String get cStructField {
|
||||
String postFix = "";
|
||||
if (type is FixedLengthArrayType) {
|
||||
final dimensions = (type as FixedLengthArrayType).dimensions;
|
||||
postFix = "[${dimensions.join("][")}]";
|
||||
}
|
||||
return "${type.cType} $name$postFix;";
|
||||
}
|
||||
|
||||
String toString() => "$type $name";
|
||||
}
|
||||
|
||||
List<Member> generateMemberNames(List<CType> memberTypes) {
|
||||
int index = 0;
|
||||
List<Member> result = [];
|
||||
for (final type in memberTypes) {
|
||||
result.add(Member(type, "a$index"));
|
||||
index++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
abstract class CompositeType extends CType {
|
||||
final List<Member> members;
|
||||
|
||||
/// To disambiguate same size structs.
|
||||
final String suffix;
|
||||
|
||||
/// To override names.
|
||||
final String overrideName;
|
||||
|
||||
CompositeType(List<CType> memberTypes)
|
||||
: this.members = generateMemberNames(memberTypes),
|
||||
this.suffix = "",
|
||||
this.overrideName = "";
|
||||
CompositeType.disambiguate(List<CType> memberTypes, this.suffix)
|
||||
: this.members = generateMemberNames(memberTypes),
|
||||
this.overrideName = "";
|
||||
CompositeType.override(List<CType> memberTypes, this.overrideName)
|
||||
: this.members = generateMemberNames(memberTypes),
|
||||
this.suffix = "";
|
||||
|
||||
List<CType> get memberTypes => members.map((a) => a.type).toList();
|
||||
|
||||
String get name;
|
||||
|
||||
String get cType => name;
|
||||
String get dartCType => name;
|
||||
String get dartType => name;
|
||||
String get dartStructFieldAnnotation => "";
|
||||
String get cKeyword;
|
||||
String get dartSuperClass;
|
||||
|
||||
bool get isOnlyFloatingPoint =>
|
||||
!memberTypes.map((e) => e.isOnlyFloatingPoint).contains(false);
|
||||
bool get isOnlyInteger =>
|
||||
!memberTypes.map((e) => e.isOnlyInteger).contains(false);
|
||||
|
||||
bool get isMixed => !isOnlyInteger && !isOnlyFloatingPoint;
|
||||
|
||||
bool get hasNestedStructs =>
|
||||
members.map((e) => e.type is StructType).contains(true);
|
||||
|
||||
bool get hasInlineArrays =>
|
||||
members.map((e) => e.type is FixedLengthArrayType).contains(true);
|
||||
|
||||
bool get hasMultiDimensionalInlineArrays => members
|
||||
.map((e) => e.type)
|
||||
.whereType<FixedLengthArrayType>()
|
||||
.where((e) => e.isMulti)
|
||||
.isNotEmpty;
|
||||
}
|
||||
|
||||
class StructType extends CompositeType {
|
||||
final int? packing;
|
||||
|
||||
StructType(List<CType> memberTypes, {int? this.packing}) : super(memberTypes);
|
||||
StructType.disambiguate(List<CType> memberTypes, String suffix,
|
||||
{int? this.packing})
|
||||
: super.disambiguate(memberTypes, suffix);
|
||||
StructType.override(List<CType> memberTypes, String overrideName,
|
||||
{int? this.packing})
|
||||
: super.override(memberTypes, overrideName);
|
||||
|
||||
String get cKeyword => "struct";
|
||||
String get dartSuperClass => "Struct";
|
||||
|
||||
bool get hasSize =>
|
||||
!memberTypes.map((e) => e.hasSize).contains(false) && !hasPadding;
|
||||
int get size => memberTypes.fold(0, (int acc, e) => acc + e.size);
|
||||
|
||||
bool get hasPacking => packing != null;
|
||||
|
||||
bool get hasPadding {
|
||||
if (members.length < 2) {
|
||||
return false;
|
||||
}
|
||||
if (packing == 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Rough approximation, to not redo all ABI logic here.
|
||||
return members[0].type.size < members[1].type.size;
|
||||
}
|
||||
|
||||
/// All members have the same type.
|
||||
bool get isHomogeneous => memberTypes.toSet().length == 1;
|
||||
|
||||
String get name {
|
||||
String result = dartSuperClass;
|
||||
if (overrideName != "") {
|
||||
return result + overrideName;
|
||||
}
|
||||
if (hasSize) {
|
||||
result += "${size}Byte" + (size != 1 ? "s" : "");
|
||||
}
|
||||
if (hasPacking) {
|
||||
result += "Packed";
|
||||
if (packing! > 1) {
|
||||
result += "$packing";
|
||||
}
|
||||
}
|
||||
if (hasNestedStructs) {
|
||||
result += "Nested";
|
||||
}
|
||||
if (hasInlineArrays) {
|
||||
result += "InlineArray";
|
||||
if (hasMultiDimensionalInlineArrays) {
|
||||
result += "MultiDimensional";
|
||||
}
|
||||
}
|
||||
if (members.length == 0) {
|
||||
// No suffix.
|
||||
} else if (hasPadding) {
|
||||
result += "Alignment${memberTypes[1].dartCType}";
|
||||
} else if (isHomogeneous && members.length > 1 && !hasNestedStructs) {
|
||||
result += "Homogeneous${memberTypes.first.dartCType}";
|
||||
} else if (isOnlyFloatingPoint) {
|
||||
result += "Float";
|
||||
} else if (isOnlyInteger) {
|
||||
result += "Int";
|
||||
} else {
|
||||
result += "Mixed";
|
||||
}
|
||||
result += suffix;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
class UnionType extends CompositeType {
|
||||
UnionType(List<CType> memberTypes) : super(memberTypes);
|
||||
|
||||
String get cKeyword => "union";
|
||||
String get dartSuperClass => "Union";
|
||||
|
||||
bool get hasSize => !memberTypes.map((e) => e.hasSize).contains(false);
|
||||
int get size => memberTypes.fold(0, (int acc, e) => math.max(acc, e.size));
|
||||
|
||||
String get name {
|
||||
String result = dartSuperClass;
|
||||
if (overrideName != "") {
|
||||
return result + overrideName;
|
||||
}
|
||||
if (hasSize) {
|
||||
result += "${size}Byte" + (size != 1 ? "s" : "");
|
||||
}
|
||||
if (hasNestedStructs) {
|
||||
result += "Nested";
|
||||
}
|
||||
if (hasInlineArrays) {
|
||||
result += "InlineArray";
|
||||
if (hasMultiDimensionalInlineArrays) {
|
||||
result += "MultiDimensional";
|
||||
}
|
||||
}
|
||||
if (members.length == 0) {
|
||||
// No suffix.
|
||||
} else if (isOnlyFloatingPoint) {
|
||||
result += "Float";
|
||||
} else if (isOnlyInteger) {
|
||||
result += "Int";
|
||||
} else {
|
||||
result += "Mixed";
|
||||
}
|
||||
result += suffix;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
class FixedLengthArrayType extends CType {
|
||||
final CType elementType;
|
||||
final int length;
|
||||
|
||||
FixedLengthArrayType(this.elementType, this.length);
|
||||
|
||||
factory FixedLengthArrayType.multi(CType elementType, List<int> dimensions) {
|
||||
if (dimensions.length == 1) {
|
||||
return FixedLengthArrayType(elementType, dimensions.single);
|
||||
}
|
||||
|
||||
final remainingDimensions = dimensions.sublist(1);
|
||||
final nestedArray =
|
||||
FixedLengthArrayType.multi(elementType, remainingDimensions);
|
||||
return FixedLengthArrayType(nestedArray, dimensions.first);
|
||||
}
|
||||
|
||||
String get cType => elementType.cType;
|
||||
String get dartCType => "Array<${elementType.dartCType}>";
|
||||
String get dartType => "Array<${elementType.dartCType}>";
|
||||
|
||||
String get dartStructFieldAnnotation {
|
||||
if (dimensions.length > 5) {
|
||||
return "@Array.multi([${dimensions.join(", ")}])";
|
||||
}
|
||||
return "@Array(${dimensions.join(", ")})";
|
||||
}
|
||||
|
||||
List<int> get dimensions {
|
||||
final elementType = this.elementType;
|
||||
if (elementType is FixedLengthArrayType) {
|
||||
return [length, ...elementType.dimensions];
|
||||
}
|
||||
return [length];
|
||||
}
|
||||
|
||||
bool get isMulti => elementType is FixedLengthArrayType;
|
||||
|
||||
bool get hasSize => elementType.hasSize;
|
||||
int get size => elementType.size * length;
|
||||
|
||||
bool get isOnlyFloatingPoint => elementType.isOnlyFloatingPoint;
|
||||
bool get isOnlyInteger => elementType.isOnlyInteger;
|
||||
}
|
||||
|
||||
class FunctionType extends CType {
|
||||
final List<Member> arguments;
|
||||
final CType returnValue;
|
||||
final String reason;
|
||||
|
||||
List<CType> get argumentTypes => arguments.map((a) => a.type).toList();
|
||||
|
||||
FunctionType(List<CType> argumentTypes, this.returnValue, this.reason)
|
||||
: this.arguments = generateMemberNames(argumentTypes);
|
||||
|
||||
String get cType =>
|
||||
throw "Are not represented without function or variable name in C.";
|
||||
|
||||
String get dartCType {
|
||||
final argumentsDartCType = argumentTypes.map((e) => e.dartCType).join(", ");
|
||||
return "${returnValue.dartCType} Function($argumentsDartCType)";
|
||||
}
|
||||
|
||||
String get dartType {
|
||||
final argumentsDartType = argumentTypes.map((e) => e.dartType).join(", ");
|
||||
return "${returnValue.dartType} Function($argumentsDartType)";
|
||||
}
|
||||
|
||||
String get dartStructFieldAnnotation => throw "No nested function pointers.";
|
||||
|
||||
bool get hasSize => false;
|
||||
int get size => throw "Unknown size.";
|
||||
|
||||
bool get isOnlyFloatingPoint => throw "Not implemented";
|
||||
bool get isOnlyInteger => throw "Not implemented";
|
||||
|
||||
/// Group consecutive [arguments] by same type.
|
||||
///
|
||||
/// Used for naming.
|
||||
List<List<Member>> get argumentsGrouped {
|
||||
List<List<Member>> result = [];
|
||||
for (final a in arguments) {
|
||||
if (result.isEmpty) {
|
||||
result.add([a]);
|
||||
} else if (result.last.first.type.dartCType == a.type.dartCType) {
|
||||
result.last.add(a);
|
||||
} else {
|
||||
result.add([a]);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// A suitable name based on the signature.
|
||||
String get cName {
|
||||
String result = "";
|
||||
if (arguments.containsComposites && returnValue is FundamentalType) {
|
||||
result = "Pass";
|
||||
} else if (returnValue is StructType &&
|
||||
argumentTypes.contains(returnValue)) {
|
||||
result = "ReturnStructArgument";
|
||||
} else if (returnValue is UnionType &&
|
||||
argumentTypes.contains(returnValue)) {
|
||||
result = "ReturnUnionArgument";
|
||||
} else if (returnValue is StructType) {
|
||||
if (arguments.length == (returnValue as StructType).members.length) {
|
||||
return "Return${returnValue.dartCType}";
|
||||
}
|
||||
} else if (returnValue is UnionType && arguments.length == 1) {
|
||||
return "Return${returnValue.dartCType}";
|
||||
} else {
|
||||
result = "Uncategorized";
|
||||
}
|
||||
|
||||
for (final group in argumentsGrouped) {
|
||||
result += group.first.type.dartCType;
|
||||
if (group.length > 1) {
|
||||
result += "x${group.length}";
|
||||
}
|
||||
}
|
||||
return result.limitTo(50);
|
||||
}
|
||||
|
||||
String get dartTestName => "test$cName";
|
||||
|
||||
String get dartName => cName.lowerCaseFirst();
|
||||
|
||||
/// Only valid for [TestType.structReturnArgument].
|
||||
Member get structReturnArgument =>
|
||||
arguments.firstWhere((a) => a.type == returnValue);
|
||||
}
|
||||
|
||||
extension MemberList on List<Member> {
|
||||
bool get containsComposites =>
|
||||
map((m) => m.type is CompositeType).contains(true);
|
||||
}
|
|
@ -1,812 +0,0 @@
|
|||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'c_types.dart';
|
||||
|
||||
final functions = [
|
||||
...functionsStructArguments,
|
||||
...functionsStructReturn,
|
||||
...functionsReturnArgument,
|
||||
];
|
||||
|
||||
final functionsStructArguments = [
|
||||
FunctionType(List.filled(10, struct1byteInt), int64, """
|
||||
Smallest struct with data.
|
||||
10 struct arguments will exhaust available registers."""),
|
||||
FunctionType(List.filled(10, struct3bytesInt), int64, """
|
||||
Not a multiple of word size, not a power of two.
|
||||
10 struct arguments will exhaust available registers."""),
|
||||
FunctionType(List.filled(10, struct3bytesInt2), int64, """
|
||||
Not a multiple of word size, not a power of two.
|
||||
With alignment rules taken into account size is 4 bytes.
|
||||
10 struct arguments will exhaust available registers."""),
|
||||
FunctionType(List.filled(10, struct4bytesInt), int64, """
|
||||
Exactly word size on 32-bit architectures.
|
||||
10 struct arguments will exhaust available registers."""),
|
||||
FunctionType(List.filled(10, struct7bytesInt), int64, """
|
||||
Sub word size on 64 bit architectures.
|
||||
10 struct arguments will exhaust available registers."""),
|
||||
FunctionType(List.filled(10, struct7bytesInt2), int64, """
|
||||
Sub word size on 64 bit architectures.
|
||||
With alignment rules taken into account size is 8 bytes.
|
||||
10 struct arguments will exhaust available registers."""),
|
||||
FunctionType(List.filled(10, struct8bytesInt), int64, """
|
||||
Exactly word size struct on 64bit architectures.
|
||||
10 struct arguments will exhaust available registers."""),
|
||||
FunctionType(List.filled(10, struct8bytesFloat), float, """
|
||||
Arguments passed in FP registers as long as they fit.
|
||||
10 struct arguments will exhaust available registers."""),
|
||||
FunctionType(List.filled(10, struct8BytesMixed), float, """
|
||||
On x64, arguments go in int registers because it is not only float.
|
||||
10 struct arguments will exhaust available registers."""),
|
||||
FunctionType(List.filled(10, struct9bytesInt), int64, """
|
||||
Argument is a single byte over a multiple of word size.
|
||||
10 struct arguments will exhaust available registers.
|
||||
Struct only has 1-byte aligned fields to test struct alignment itself.
|
||||
Tests upper bytes in the integer registers that are partly filled.
|
||||
Tests stack alignment of non word size stack arguments."""),
|
||||
FunctionType(List.filled(10, struct9bytesInt2), int64, """
|
||||
Argument is a single byte over a multiple of word size.
|
||||
With alignment rules taken into account size is 12 or 16 bytes.
|
||||
10 struct arguments will exhaust available registers.
|
||||
"""),
|
||||
FunctionType(List.filled(6, struct12bytesFloat), float, """
|
||||
Arguments in FPU registers on arm hardfp and arm64.
|
||||
Struct arguments will exhaust available registers, and leave some empty.
|
||||
The last argument is to test whether arguments are backfilled."""),
|
||||
FunctionType(List.filled(5, struct16bytesFloat), float, """
|
||||
On Linux x64 argument is transferred on stack because it is over 16 bytes.
|
||||
Arguments in FPU registers on arm hardfp and arm64.
|
||||
5 struct arguments will exhaust available registers."""),
|
||||
FunctionType(List.filled(10, struct16bytesMixed), double_, """
|
||||
On x64, arguments are split over FP and int registers.
|
||||
On x64, it will exhaust the integer registers with the 6th argument.
|
||||
The rest goes on the stack.
|
||||
On arm, arguments are 8 byte aligned."""),
|
||||
FunctionType(List.filled(10, struct16bytesMixed2), float, """
|
||||
On x64, arguments are split over FP and int registers.
|
||||
On x64, it will exhaust the integer registers with the 6th argument.
|
||||
The rest goes on the stack.
|
||||
On arm, arguments are 4 byte aligned."""),
|
||||
FunctionType(List.filled(10, struct17bytesInt), int64, """
|
||||
Arguments are passed as pointer to copy on arm64.
|
||||
Tests that the memory allocated for copies are rounded up to word size."""),
|
||||
FunctionType(List.filled(10, struct19bytesInt), int64, """
|
||||
The minimum alignment of this struct is only 1 byte based on its fields.
|
||||
Test that the memory backing these structs is extended to the right size.
|
||||
"""),
|
||||
FunctionType(List.filled(10, struct20bytesInt), int32, """
|
||||
Argument too big to go into integer registers on arm64.
|
||||
The arguments are passed as pointers to copies.
|
||||
The amount of arguments exhausts the number of integer registers, such that
|
||||
pointers to copies are also passed on the stack."""),
|
||||
FunctionType(
|
||||
[struct20bytesFloat],
|
||||
float,
|
||||
"""
|
||||
Argument too big to go into FPU registers in hardfp and arm64."""),
|
||||
FunctionType(List.filled(5, struct32bytesDouble), double_, """
|
||||
Arguments in FPU registers on arm64.
|
||||
5 struct arguments will exhaust available registers."""),
|
||||
FunctionType(
|
||||
[struct40bytesDouble],
|
||||
double_,
|
||||
"""
|
||||
Argument too big to go into FPU registers in arm64."""),
|
||||
FunctionType(
|
||||
[struct1024bytesInt],
|
||||
uint64,
|
||||
"""
|
||||
Test 1kb struct."""),
|
||||
FunctionType(
|
||||
[
|
||||
float,
|
||||
struct16bytesFloat,
|
||||
float,
|
||||
struct16bytesFloat,
|
||||
float,
|
||||
struct16bytesFloat,
|
||||
float,
|
||||
struct16bytesFloat,
|
||||
float
|
||||
],
|
||||
float,
|
||||
"""
|
||||
Tests the alignment of structs in FPU registers and backfilling."""),
|
||||
FunctionType(
|
||||
[
|
||||
float,
|
||||
struct32bytesDouble,
|
||||
float,
|
||||
struct32bytesDouble,
|
||||
float,
|
||||
struct32bytesDouble,
|
||||
float,
|
||||
struct32bytesDouble,
|
||||
float
|
||||
],
|
||||
double_,
|
||||
"""
|
||||
Tests the alignment of structs in FPU registers and backfilling."""),
|
||||
FunctionType(
|
||||
[
|
||||
int8,
|
||||
struct16bytesMixed,
|
||||
int8,
|
||||
struct16bytesMixed,
|
||||
int8,
|
||||
struct16bytesMixed,
|
||||
int8,
|
||||
struct16bytesMixed,
|
||||
int8
|
||||
],
|
||||
double_,
|
||||
"""
|
||||
Tests the alignment of structs in integers registers and on the stack.
|
||||
Arm32 aligns this struct at 8.
|
||||
Also, arm32 allocates the second struct partially in registers, partially
|
||||
on stack.
|
||||
Test backfilling of integer registers."""),
|
||||
FunctionType(
|
||||
[
|
||||
double_,
|
||||
double_,
|
||||
double_,
|
||||
double_,
|
||||
double_,
|
||||
double_,
|
||||
struct16bytesMixed,
|
||||
struct16bytesMixed,
|
||||
struct16bytesMixed,
|
||||
struct16bytesMixed,
|
||||
int32,
|
||||
],
|
||||
double_,
|
||||
"""
|
||||
On Linux x64, it will exhaust xmm registers first, after 6 doubles and 2
|
||||
structs. The rest of the structs will go on the stack.
|
||||
The int will be backfilled into the int register."""),
|
||||
FunctionType(
|
||||
[
|
||||
int32,
|
||||
int32,
|
||||
int32,
|
||||
int32,
|
||||
struct16bytesMixed,
|
||||
struct16bytesMixed,
|
||||
struct16bytesMixed,
|
||||
struct16bytesMixed,
|
||||
double_,
|
||||
],
|
||||
double_,
|
||||
"""
|
||||
On Linux x64, it will exhaust int registers first.
|
||||
The rest of the structs will go on the stack.
|
||||
The double will be backfilled into the xmm register."""),
|
||||
FunctionType(
|
||||
[
|
||||
struct40bytesDouble,
|
||||
struct4bytesInt,
|
||||
struct8bytesFloat,
|
||||
],
|
||||
double_,
|
||||
"""
|
||||
On various architectures, first struct is allocated on stack.
|
||||
Check that the other two arguments are allocated on registers."""),
|
||||
FunctionType(
|
||||
[
|
||||
// Exhaust integer registers on all architectures
|
||||
int32,
|
||||
int32,
|
||||
int32,
|
||||
int32,
|
||||
int32,
|
||||
int32,
|
||||
int32,
|
||||
int32,
|
||||
// Exhaust floating point registers on all architectures.
|
||||
double_,
|
||||
double_,
|
||||
double_,
|
||||
double_,
|
||||
double_,
|
||||
double_,
|
||||
double_,
|
||||
double_,
|
||||
// Pass all kinds of structs to exercise stack placement behavior.
|
||||
//
|
||||
// For all structs, align stack with int64, then align to 1-byte with
|
||||
// int8, then pass struct.
|
||||
int64,
|
||||
int8,
|
||||
struct1byteInt,
|
||||
int64,
|
||||
int8,
|
||||
struct4bytesInt,
|
||||
int64,
|
||||
int8,
|
||||
struct8bytesInt,
|
||||
int64,
|
||||
int8,
|
||||
struct8bytesFloat,
|
||||
int64,
|
||||
int8,
|
||||
struct8BytesMixed,
|
||||
int64,
|
||||
int8,
|
||||
structAlignmentInt16,
|
||||
int64,
|
||||
int8,
|
||||
structAlignmentInt32,
|
||||
int64,
|
||||
int8,
|
||||
structAlignmentInt64,
|
||||
],
|
||||
double_,
|
||||
"""
|
||||
Test alignment and padding of 16 byte int within struct."""),
|
||||
FunctionType(
|
||||
[structAlignmentInt16],
|
||||
int64,
|
||||
"""
|
||||
Test alignment and padding of 16 byte int within struct."""),
|
||||
FunctionType(
|
||||
[structAlignmentInt32],
|
||||
int64,
|
||||
"""
|
||||
Test alignment and padding of 32 byte int within struct."""),
|
||||
FunctionType(
|
||||
[structAlignmentInt64],
|
||||
int64,
|
||||
"""
|
||||
Test alignment and padding of 64 byte int within struct."""),
|
||||
FunctionType(List.filled(10, struct8bytesNestedInt), int64, """
|
||||
Simple nested struct. No alignment gaps on any architectures.
|
||||
10 arguments exhaust registers on all platforms."""),
|
||||
FunctionType(List.filled(10, struct8bytesNestedFloat), float, """
|
||||
Simple nested struct. No alignment gaps on any architectures.
|
||||
10 arguments exhaust fpu registers on all platforms."""),
|
||||
FunctionType(List.filled(10, struct8bytesNestedFloat2), float, """
|
||||
Simple nested struct. No alignment gaps on any architectures.
|
||||
10 arguments exhaust fpu registers on all platforms.
|
||||
The nesting is irregular, testing homogenous float rules on arm and arm64,
|
||||
and the fpu register usage on x64."""),
|
||||
FunctionType(List.filled(10, struct8bytesNestedMixed), double_, """
|
||||
Simple nested struct. No alignment gaps on any architectures.
|
||||
10 arguments exhaust all registers on all platforms."""),
|
||||
FunctionType(List.filled(2, struct16bytesNestedInt), int64, """
|
||||
Deeper nested struct to test recursive member access."""),
|
||||
FunctionType(List.filled(2, struct32bytesNestedInt), int64, """
|
||||
Even deeper nested struct to test recursive member access."""),
|
||||
FunctionType(
|
||||
[structNestedAlignmentInt16],
|
||||
int64,
|
||||
"""
|
||||
Test alignment and padding of nested struct with 16 byte int."""),
|
||||
FunctionType(
|
||||
[structNestedAlignmentInt32],
|
||||
int64,
|
||||
"""
|
||||
Test alignment and padding of nested struct with 32 byte int."""),
|
||||
FunctionType(
|
||||
[structNestedAlignmentInt64],
|
||||
int64,
|
||||
"""
|
||||
Test alignment and padding of nested struct with 64 byte int."""),
|
||||
FunctionType(List.filled(4, structNestedEvenBigger), double_, """
|
||||
Return big irregular struct as smoke test."""),
|
||||
FunctionType(List.filled(4, structInlineArray), int32, """
|
||||
Simple struct with inline array."""),
|
||||
FunctionType(List.filled(4, structInlineArrayIrregular), int32, """
|
||||
Irregular struct with inline array."""),
|
||||
FunctionType(
|
||||
[structInlineArray100Bytes],
|
||||
int32,
|
||||
"""
|
||||
Regular larger struct with inline array."""),
|
||||
FunctionType(List.filled(5, struct16bytesFloatInlineNested), float, """
|
||||
Arguments in FPU registers on arm hardfp and arm64.
|
||||
5 struct arguments will exhaust available registers."""),
|
||||
FunctionType(List.filled(5, struct32bytesDoubleInlineNested), double_, """
|
||||
Arguments in FPU registers on arm64.
|
||||
5 struct arguments will exhaust available registers."""),
|
||||
FunctionType(List.filled(10, struct16bytesMixedInlineNested), float, """
|
||||
On x64, arguments are split over FP and int registers.
|
||||
On x64, it will exhaust the integer registers with the 6th argument.
|
||||
The rest goes on the stack.
|
||||
On arm, arguments are 4 byte aligned."""),
|
||||
FunctionType(
|
||||
[
|
||||
uint8,
|
||||
struct32bytesInlineArrayMultiDimesional,
|
||||
uint8,
|
||||
struct8bytesInlineArrayMultiDimesional,
|
||||
uint8,
|
||||
struct8bytesInlineArrayMultiDimesional,
|
||||
uint8
|
||||
],
|
||||
uint32,
|
||||
"""
|
||||
Test multi dimensional inline array struct as argument."""),
|
||||
FunctionType(
|
||||
[uint8, structMultiDimensionalStruct, uint8],
|
||||
uint32,
|
||||
"""
|
||||
Test struct in multi dimensional inline array."""),
|
||||
FunctionType(List.filled(10, struct3bytesPacked), int64, """
|
||||
Small struct with mis-aligned member."""),
|
||||
FunctionType(List.filled(10, struct8bytesPacked), int64, """
|
||||
Struct with mis-aligned member."""),
|
||||
FunctionType(
|
||||
[...List.filled(10, struct9bytesPacked), double_, int32],
|
||||
double_,
|
||||
"""
|
||||
Struct with mis-aligned member.
|
||||
Tests backfilling of CPU and FPU registers."""),
|
||||
FunctionType(
|
||||
[struct5bytesPacked],
|
||||
double_,
|
||||
"""
|
||||
This packed struct happens to have only aligned members."""),
|
||||
FunctionType(
|
||||
[struct6bytesPacked],
|
||||
double_,
|
||||
"""
|
||||
Check alignment of packed struct in non-packed struct."""),
|
||||
FunctionType(
|
||||
[struct6bytesPacked2],
|
||||
double_,
|
||||
"""
|
||||
Check alignment of packed struct array in non-packed struct."""),
|
||||
FunctionType(
|
||||
[struct15bytesPacked],
|
||||
double_,
|
||||
"""
|
||||
Check alignment of packed struct array in non-packed struct."""),
|
||||
FunctionType(List.filled(10, union4bytesMixed), double_, """
|
||||
Check placement of mixed integer/float union."""),
|
||||
FunctionType(List.filled(10, union8bytesFloat), double_, """
|
||||
Check placement of mixed floats union."""),
|
||||
FunctionType(List.filled(10, union12bytesInt), double_, """
|
||||
Mixed-size union argument."""),
|
||||
FunctionType(List.filled(10, union16bytesFloat), double_, """
|
||||
Union with homogenous floats."""),
|
||||
FunctionType(List.filled(10, union16bytesFloat2), double_, """
|
||||
Union with homogenous floats."""),
|
||||
];
|
||||
|
||||
final functionsStructReturn = [
|
||||
FunctionType(struct1byteInt.memberTypes, struct1byteInt, """
|
||||
Smallest struct with data."""),
|
||||
FunctionType(struct3bytesInt.memberTypes, struct3bytesInt, """
|
||||
Smaller than word size return value on all architectures."""),
|
||||
FunctionType(struct3bytesInt2.memberTypes, struct3bytesInt2, """
|
||||
Smaller than word size return value on all architectures.
|
||||
With alignment rules taken into account size is 4 bytes."""),
|
||||
FunctionType(struct4bytesInt.memberTypes, struct4bytesInt, """
|
||||
Word size return value on 32 bit architectures.."""),
|
||||
FunctionType(struct7bytesInt.memberTypes, struct7bytesInt, """
|
||||
Non-wordsize return value."""),
|
||||
FunctionType(struct7bytesInt2.memberTypes, struct7bytesInt2, """
|
||||
Non-wordsize return value.
|
||||
With alignment rules taken into account size is 8 bytes."""),
|
||||
FunctionType(struct8bytesInt.memberTypes, struct8bytesInt, """
|
||||
Return value in integer registers on many architectures."""),
|
||||
FunctionType(struct8bytesFloat.memberTypes, struct8bytesFloat, """
|
||||
Return value in FP registers on many architectures."""),
|
||||
FunctionType(struct8BytesMixed.memberTypes, struct8BytesMixed, """
|
||||
Return value split over FP and integer register in x64."""),
|
||||
FunctionType(struct9bytesInt.memberTypes, struct9bytesInt, """
|
||||
The minimum alignment of this struct is only 1 byte based on its fields.
|
||||
Test that the memory backing these structs is the right size and that
|
||||
dart:ffi trampolines do not write outside this size."""),
|
||||
FunctionType(struct9bytesInt2.memberTypes, struct9bytesInt2, """
|
||||
Return value in two integer registers on x64.
|
||||
With alignment rules taken into account size is 12 or 16 bytes."""),
|
||||
FunctionType(struct12bytesFloat.memberTypes, struct12bytesFloat, """
|
||||
Return value in FPU registers, but does not use all registers on arm hardfp
|
||||
and arm64."""),
|
||||
FunctionType(struct16bytesFloat.memberTypes, struct16bytesFloat, """
|
||||
Return value in FPU registers on arm hardfp and arm64."""),
|
||||
FunctionType(struct16bytesMixed.memberTypes, struct16bytesMixed, """
|
||||
Return value split over FP and integer register in x64."""),
|
||||
FunctionType(struct16bytesMixed2.memberTypes, struct16bytesMixed2, """
|
||||
Return value split over FP and integer register in x64.
|
||||
The integer register contains half float half int."""),
|
||||
FunctionType(struct17bytesInt.memberTypes, struct17bytesInt, """
|
||||
Rerturn value returned in preallocated space passed by pointer on most ABIs.
|
||||
Is non word size on purpose, to test that structs are rounded up to word size
|
||||
on all ABIs."""),
|
||||
FunctionType(struct19bytesInt.memberTypes, struct19bytesInt, """
|
||||
The minimum alignment of this struct is only 1 byte based on its fields.
|
||||
Test that the memory backing these structs is the right size and that
|
||||
dart:ffi trampolines do not write outside this size."""),
|
||||
FunctionType(struct20bytesInt.memberTypes, struct20bytesInt, """
|
||||
Return value too big to go in cpu registers on arm64."""),
|
||||
FunctionType(struct20bytesFloat.memberTypes, struct20bytesFloat, """
|
||||
Return value too big to go in FPU registers on x64, arm hardfp and arm64."""),
|
||||
FunctionType(struct32bytesDouble.memberTypes, struct32bytesDouble, """
|
||||
Return value in FPU registers on arm64."""),
|
||||
FunctionType(struct40bytesDouble.memberTypes, struct40bytesDouble, """
|
||||
Return value too big to go in FPU registers on arm64."""),
|
||||
FunctionType(struct1024bytesInt.memberTypes, struct1024bytesInt, """
|
||||
Test 1kb struct."""),
|
||||
FunctionType(struct3bytesPacked.memberTypes, struct3bytesPacked, """
|
||||
Small struct with mis-aligned member."""),
|
||||
FunctionType(struct8bytesPacked.memberTypes, struct8bytesPacked, """
|
||||
Struct with mis-aligned member."""),
|
||||
FunctionType(struct9bytesPacked.memberTypes, struct9bytesPacked, """
|
||||
Struct with mis-aligned member.
|
||||
Tests backfilling of CPU and FPU registers."""),
|
||||
FunctionType(
|
||||
[union4bytesMixed.memberTypes.first],
|
||||
union4bytesMixed,
|
||||
"""
|
||||
Returning a mixed integer/float union."""),
|
||||
FunctionType(
|
||||
[union8bytesFloat.memberTypes.first],
|
||||
union8bytesFloat,
|
||||
"""
|
||||
Returning a floating point only union."""),
|
||||
FunctionType(
|
||||
[union12bytesInt.memberTypes.first],
|
||||
union12bytesInt,
|
||||
"""
|
||||
Returning a mixed-size union."""),
|
||||
FunctionType(
|
||||
[union16bytesFloat2.memberTypes.first],
|
||||
union16bytesFloat2,
|
||||
"""
|
||||
Returning union with homogenous floats."""),
|
||||
];
|
||||
|
||||
final functionsReturnArgument = [
|
||||
FunctionType(
|
||||
[struct1byteInt],
|
||||
struct1byteInt,
|
||||
"""
|
||||
Test that a struct passed in as argument can be returned.
|
||||
Especially for ffi callbacks.
|
||||
Struct is passed in int registers in most ABIs."""),
|
||||
FunctionType(
|
||||
[int32, int32, int32, int32, int32, int32, int32, int32, struct1byteInt],
|
||||
struct1byteInt,
|
||||
"""
|
||||
Test that a struct passed in as argument can be returned.
|
||||
Especially for ffi callbacks.
|
||||
Struct is passed on stack on all ABIs."""),
|
||||
FunctionType(
|
||||
[struct8bytesFloat],
|
||||
struct8bytesFloat,
|
||||
"""
|
||||
Test that a struct passed in as argument can be returned.
|
||||
Especially for ffi callbacks.
|
||||
Struct is passed in float registers in most ABIs."""),
|
||||
FunctionType(
|
||||
[struct20bytesInt],
|
||||
struct20bytesInt,
|
||||
"""
|
||||
On arm64, both argument and return value are passed in by pointer."""),
|
||||
FunctionType(
|
||||
[
|
||||
int32,
|
||||
int32,
|
||||
int32,
|
||||
int32,
|
||||
int32,
|
||||
int32,
|
||||
int32,
|
||||
int32,
|
||||
struct20bytesInt
|
||||
],
|
||||
struct20bytesInt,
|
||||
"""
|
||||
On arm64, both argument and return value are passed in by pointer.
|
||||
Ints exhaust registers, so that pointer is passed on stack."""),
|
||||
FunctionType(
|
||||
[structInlineArray],
|
||||
structInlineArray,
|
||||
"""
|
||||
Test returning struct with inline array."""),
|
||||
FunctionType(
|
||||
[struct16bytesFloatInlineNested],
|
||||
struct16bytesFloatInlineNested,
|
||||
"""
|
||||
Return value in FPU registers on arm hardfp and arm64."""),
|
||||
FunctionType(
|
||||
[struct32bytesDoubleInlineNested],
|
||||
struct32bytesDoubleInlineNested,
|
||||
"""
|
||||
Return value in FPU registers on arm64."""),
|
||||
FunctionType(
|
||||
[struct16bytesMixedInlineNested],
|
||||
struct16bytesMixedInlineNested,
|
||||
"""
|
||||
On x64 Linux, return value is split over FP and int registers."""),
|
||||
FunctionType(structAlignmentInt16.memberTypes, structAlignmentInt16, """
|
||||
Test alignment and padding of 16 byte int within struct."""),
|
||||
FunctionType(structAlignmentInt32.memberTypes, structAlignmentInt32, """
|
||||
Test alignment and padding of 32 byte int within struct."""),
|
||||
FunctionType(structAlignmentInt64.memberTypes, structAlignmentInt64, """
|
||||
Test alignment and padding of 64 byte int within struct."""),
|
||||
FunctionType(struct8bytesNestedInt.memberTypes, struct8bytesNestedInt, """
|
||||
Simple nested struct."""),
|
||||
FunctionType(struct8bytesNestedFloat.memberTypes, struct8bytesNestedFloat, """
|
||||
Simple nested struct with floats."""),
|
||||
FunctionType(
|
||||
struct8bytesNestedFloat2.memberTypes, struct8bytesNestedFloat2, """
|
||||
The nesting is irregular, testing homogenous float rules on arm and arm64,
|
||||
and the fpu register usage on x64."""),
|
||||
FunctionType(struct8bytesNestedMixed.memberTypes, struct8bytesNestedMixed, """
|
||||
Simple nested struct with mixed members."""),
|
||||
FunctionType(struct16bytesNestedInt.memberTypes, struct16bytesNestedInt, """
|
||||
Deeper nested struct to test recursive member access."""),
|
||||
FunctionType(struct32bytesNestedInt.memberTypes, struct32bytesNestedInt, """
|
||||
Even deeper nested struct to test recursive member access."""),
|
||||
FunctionType(
|
||||
structNestedAlignmentInt16.memberTypes, structNestedAlignmentInt16, """
|
||||
Test alignment and padding of nested struct with 16 byte int."""),
|
||||
FunctionType(
|
||||
structNestedAlignmentInt32.memberTypes, structNestedAlignmentInt32, """
|
||||
Test alignment and padding of nested struct with 32 byte int."""),
|
||||
FunctionType(
|
||||
structNestedAlignmentInt64.memberTypes, structNestedAlignmentInt64, """
|
||||
Test alignment and padding of nested struct with 64 byte int."""),
|
||||
FunctionType(structNestedEvenBigger.memberTypes, structNestedEvenBigger, """
|
||||
Return big irregular struct as smoke test."""),
|
||||
];
|
||||
|
||||
final compounds = [
|
||||
struct1byteInt,
|
||||
struct3bytesInt,
|
||||
struct3bytesInt2,
|
||||
struct4bytesInt,
|
||||
struct4bytesFloat,
|
||||
struct7bytesInt,
|
||||
struct7bytesInt2,
|
||||
struct8bytesInt,
|
||||
struct8bytesFloat,
|
||||
struct8bytesFloat2,
|
||||
struct8BytesMixed,
|
||||
struct9bytesInt,
|
||||
struct9bytesInt2,
|
||||
struct12bytesFloat,
|
||||
struct16bytesFloat,
|
||||
struct16bytesMixed,
|
||||
struct16bytesMixed2,
|
||||
struct17bytesInt,
|
||||
struct19bytesInt,
|
||||
struct20bytesInt,
|
||||
struct20bytesFloat,
|
||||
struct32bytesDouble,
|
||||
struct40bytesDouble,
|
||||
struct1024bytesInt,
|
||||
structAlignmentInt16,
|
||||
structAlignmentInt32,
|
||||
structAlignmentInt64,
|
||||
struct8bytesNestedInt,
|
||||
struct8bytesNestedFloat,
|
||||
struct8bytesNestedFloat2,
|
||||
struct8bytesNestedMixed,
|
||||
struct16bytesNestedInt,
|
||||
struct32bytesNestedInt,
|
||||
structNestedAlignmentInt16,
|
||||
structNestedAlignmentInt32,
|
||||
structNestedAlignmentInt64,
|
||||
structNestedBig,
|
||||
structNestedBigger,
|
||||
structNestedEvenBigger,
|
||||
structInlineArray,
|
||||
structInlineArrayIrregular,
|
||||
structInlineArray100Bytes,
|
||||
structInlineArrayBig,
|
||||
struct16bytesFloatInlineNested,
|
||||
struct32bytesDoubleInlineNested,
|
||||
struct16bytesMixedInlineNested,
|
||||
struct8bytesInlineArrayMultiDimesional,
|
||||
struct32bytesInlineArrayMultiDimesional,
|
||||
struct64bytesInlineArrayMultiDimesional,
|
||||
structMultiDimensionalStruct,
|
||||
struct3bytesPacked,
|
||||
struct3bytesPackedMembersAligned,
|
||||
struct5bytesPacked,
|
||||
struct6bytesPacked,
|
||||
struct6bytesPacked2,
|
||||
struct8bytesPacked,
|
||||
struct9bytesPacked,
|
||||
struct15bytesPacked,
|
||||
union4bytesMixed,
|
||||
union8bytesFloat,
|
||||
union12bytesInt,
|
||||
union16bytesFloat,
|
||||
union16bytesFloat2,
|
||||
];
|
||||
|
||||
final struct1byteInt = StructType([int8]);
|
||||
final struct3bytesInt = StructType(List.filled(3, uint8));
|
||||
final struct3bytesInt2 = StructType.disambiguate([int16, int8], "2ByteAligned");
|
||||
final struct4bytesInt = StructType([int16, int16]);
|
||||
final struct4bytesFloat = StructType([float]);
|
||||
final struct7bytesInt = StructType(List.filled(7, uint8));
|
||||
final struct7bytesInt2 =
|
||||
StructType.disambiguate([int32, int16, int8], "4ByteAligned");
|
||||
final struct8bytesInt = StructType([int16, int16, int32]);
|
||||
final struct8bytesFloat = StructType([float, float]);
|
||||
final struct8bytesFloat2 = StructType([double_]);
|
||||
final struct8BytesMixed = StructType([float, int16, int16]);
|
||||
final struct9bytesInt = StructType(List.filled(9, uint8));
|
||||
final struct9bytesInt2 =
|
||||
StructType.disambiguate([int64, int8], "4Or8ByteAligned");
|
||||
final struct12bytesFloat = StructType([float, float, float]);
|
||||
|
||||
/// The largest homogenous float that goes into FPU registers on softfp and
|
||||
/// arm64.
|
||||
final struct16bytesFloat = StructType([float, float, float, float]);
|
||||
|
||||
/// This struct will be 8 byte aligned on arm.
|
||||
final struct16bytesMixed = StructType([double_, int64]);
|
||||
|
||||
/// This struct will be 4 byte aligned on arm.
|
||||
final struct16bytesMixed2 =
|
||||
StructType.disambiguate([float, float, float, int32], "2");
|
||||
|
||||
final struct17bytesInt = StructType([int64, int64, int8]);
|
||||
|
||||
/// This struct has only 1 byte field-alignmnent requirements.
|
||||
final struct19bytesInt = StructType(List.filled(19, uint8));
|
||||
|
||||
/// The first homogenous integer struct that does not go into registers
|
||||
/// anymore on arm64.
|
||||
final struct20bytesInt = StructType([int32, int32, int32, int32, int32]);
|
||||
|
||||
/// The first homogenous float that does not go into FPU registers anymore on
|
||||
/// softfp and arm64.
|
||||
final struct20bytesFloat = StructType([float, float, float, float, float]);
|
||||
|
||||
/// Largest homogenous doubles in arm64 that goes into FPU registers.
|
||||
final struct32bytesDouble = StructType([double_, double_, double_, double_]);
|
||||
|
||||
/// The first homogenous doubles that does not go into FPU registers anymore on
|
||||
/// arm64.
|
||||
final struct40bytesDouble =
|
||||
StructType([double_, double_, double_, double_, double_]);
|
||||
|
||||
final struct1024bytesInt = StructType(List.filled(128, uint64));
|
||||
|
||||
final structAlignmentInt16 = StructType([int8, int16, int8]);
|
||||
final structAlignmentInt32 = StructType([int8, int32, int8]);
|
||||
final structAlignmentInt64 = StructType([int8, int64, int8]);
|
||||
|
||||
final struct8bytesNestedInt = StructType([struct4bytesInt, struct4bytesInt]);
|
||||
final struct8bytesNestedFloat =
|
||||
StructType([struct4bytesFloat, struct4bytesFloat]);
|
||||
final struct8bytesNestedFloat2 =
|
||||
StructType.disambiguate([struct4bytesFloat, float], "2");
|
||||
final struct8bytesNestedMixed =
|
||||
StructType([struct4bytesInt, struct4bytesFloat]);
|
||||
|
||||
final struct16bytesNestedInt =
|
||||
StructType([struct8bytesNestedInt, struct8bytesNestedInt]);
|
||||
final struct32bytesNestedInt =
|
||||
StructType([struct16bytesNestedInt, struct16bytesNestedInt]);
|
||||
|
||||
final structNestedAlignmentInt16 = StructType.disambiguate(
|
||||
List.filled(2, structAlignmentInt16), structAlignmentInt16.name);
|
||||
final structNestedAlignmentInt32 = StructType.disambiguate(
|
||||
List.filled(2, structAlignmentInt32), structAlignmentInt32.name);
|
||||
final structNestedAlignmentInt64 = StructType.disambiguate(
|
||||
List.filled(2, structAlignmentInt64), structAlignmentInt64.name);
|
||||
|
||||
final structNestedBig = StructType.override([
|
||||
uint16,
|
||||
struct8bytesNestedMixed,
|
||||
uint16,
|
||||
struct8bytesNestedFloat2,
|
||||
uint16,
|
||||
struct8bytesNestedFloat,
|
||||
uint16
|
||||
], "NestedIrregularBig");
|
||||
final structNestedBigger = StructType.override(
|
||||
[structNestedBig, struct8bytesNestedMixed, float, double_],
|
||||
"NestedIrregularBigger");
|
||||
final structNestedEvenBigger = StructType.override(
|
||||
[uint64, structNestedBigger, structNestedBigger, double_],
|
||||
"NestedIrregularEvenBigger");
|
||||
|
||||
final structInlineArray = StructType([FixedLengthArrayType(uint8, 8)]);
|
||||
|
||||
final structInlineArrayIrregular = StructType.override(
|
||||
[FixedLengthArrayType(struct3bytesInt2, 2), uint8], "InlineArrayIrregular");
|
||||
|
||||
final structInlineArray100Bytes = StructType.override(
|
||||
[FixedLengthArrayType(uint8, 100)], "InlineArray100Bytes");
|
||||
|
||||
final structInlineArrayBig = StructType.override(
|
||||
[uint32, uint32, FixedLengthArrayType(uint8, 4000)], "InlineArrayBig");
|
||||
|
||||
/// The largest homogenous float that goes into FPU registers on softfp and
|
||||
/// arm64. This time with nested structs and inline arrays.
|
||||
final struct16bytesFloatInlineNested = StructType.override([
|
||||
StructType([float]),
|
||||
FixedLengthArrayType(StructType([float]), 2),
|
||||
float,
|
||||
], "Struct16BytesHomogeneousFloat2");
|
||||
|
||||
/// The largest homogenous float that goes into FPU registers on arm64.
|
||||
/// This time with nested structs and inline arrays.
|
||||
final struct32bytesDoubleInlineNested = StructType.override([
|
||||
StructType([double_]),
|
||||
FixedLengthArrayType(StructType([double_]), 2),
|
||||
double_,
|
||||
], "Struct32BytesHomogeneousDouble2");
|
||||
|
||||
/// This struct is split over a CPU and FPU register in x64 Linux.
|
||||
/// This time with nested structs and inline arrays.
|
||||
final struct16bytesMixedInlineNested = StructType.override([
|
||||
StructType([float]),
|
||||
FixedLengthArrayType(StructType([float, int16, int16]), 1),
|
||||
FixedLengthArrayType(int16, 2),
|
||||
], "Struct16BytesMixed3");
|
||||
|
||||
final struct8bytesInlineArrayMultiDimesional = StructType([
|
||||
FixedLengthArrayType.multi(uint8, [2, 2, 2])
|
||||
]);
|
||||
|
||||
final struct32bytesInlineArrayMultiDimesional = StructType([
|
||||
FixedLengthArrayType.multi(uint8, [2, 2, 2, 2, 2])
|
||||
]);
|
||||
|
||||
final struct64bytesInlineArrayMultiDimesional = StructType([
|
||||
FixedLengthArrayType.multi(uint8, [2, 2, 2, 2, 2, 2])
|
||||
]);
|
||||
|
||||
final structMultiDimensionalStruct = StructType([
|
||||
FixedLengthArrayType.multi(struct1byteInt, [2, 2])
|
||||
]);
|
||||
|
||||
final struct3bytesPacked = StructType([int8, int16], packing: 1);
|
||||
|
||||
final struct3bytesPackedMembersAligned =
|
||||
StructType.disambiguate([int8, int16], "MembersAligned", packing: 1);
|
||||
|
||||
final struct5bytesPacked = StructType([float, uint8], packing: 1);
|
||||
|
||||
/// The float in the nested struct is not aligned.
|
||||
final struct6bytesPacked = StructType([uint8, struct5bytesPacked]);
|
||||
|
||||
/// The second element in the array has a nested misaligned int16.
|
||||
final struct6bytesPacked2 =
|
||||
StructType([FixedLengthArrayType(struct3bytesPackedMembersAligned, 2)]);
|
||||
|
||||
final struct8bytesPacked =
|
||||
StructType([uint8, uint32, uint8, uint8, uint8], packing: 1);
|
||||
|
||||
final struct9bytesPacked = StructType([uint8, double_], packing: 1);
|
||||
|
||||
/// The float in the nested struct is aligned in the first element in the
|
||||
/// inline array, but not in the subsequent ones.
|
||||
final struct15bytesPacked =
|
||||
StructType([FixedLengthArrayType(struct5bytesPacked, 3)]);
|
||||
|
||||
/// Mixed integer and float. Tests whether calling conventions put this in
|
||||
/// integer registers or not.
|
||||
final union4bytesMixed = UnionType([uint32, float]);
|
||||
|
||||
/// Different types of float. Tests whether calling conventions put this in
|
||||
/// FPU registers or not.
|
||||
final union8bytesFloat = UnionType([double_, struct8bytesFloat]);
|
||||
|
||||
/// This union has a size of 12, because of the 4-byte alignment of the first
|
||||
/// member.
|
||||
final union12bytesInt = UnionType([struct8bytesInt, struct9bytesInt]);
|
||||
|
||||
/// This union has homogenous floats of the same sizes.
|
||||
final union16bytesFloat =
|
||||
UnionType([FixedLengthArrayType(float, 4), struct16bytesFloat]);
|
||||
|
||||
/// This union has homogenous floats of different sizes.
|
||||
final union16bytesFloat2 =
|
||||
UnionType([struct8bytesFloat, struct12bytesFloat, struct16bytesFloat]);
|
File diff suppressed because it is too large
Load diff
|
@ -1,24 +0,0 @@
|
|||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
extension TestGeneratorStringExtension on String {
|
||||
String upperCaseFirst() => "${this[0].toUpperCase()}${this.substring(1)}";
|
||||
|
||||
String lowerCaseFirst() => "${this[0].toLowerCase()}${this.substring(1)}";
|
||||
|
||||
String makeCComment() => "// " + split("\n").join("\n// ");
|
||||
|
||||
String makeDartDocComment() => "/// " + split("\n").join("\n/// ");
|
||||
|
||||
String limitTo(int lenght) {
|
||||
if (this.length > lenght) {
|
||||
return substring(0, lenght);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
String trimCouts() => replaceAll('" << "', '').replaceAll('"<< "', '');
|
||||
}
|
Loading…
Reference in a new issue