[test/ffi] Add struct stack alignment test

A smoke test to exercise alignment of structs with various field types
to see how they are aligned on the stack. Only contains small structs
because most ABIs only pass structs less than 16 bytes on the stack.

Especially tests iOS64, where `AlignOf(struct{float32;float32;}) == 4`
but `AlignOf(struct{int32;int32;}) == 8` due to the special treatment
of homogenous floats in the arm64 ABI combined with iOS decision to not
align everything on the stack to at least word size.

Test tested on iOS64 through Flutter.

structs_by_value_tests_configuration.dart is the only non-generated
file.

The tests are tested in the dependent CL. Tests are ignored in status
file and are un-ignored in dependent CL.

Tests for https://github.com/dart-lang/sdk/issues/36730.

Change-Id: I6ec4523208db740b8ea3f8a4ab1e5717f1088467
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/170691
Commit-Queue: Daco Harkes <dacoharkes@google.com>
Auto-Submit: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
This commit is contained in:
Daco Harkes 2020-11-06 13:54:23 +00:00 committed by commit-bot@chromium.org
parent d54e2bb568
commit 6101e4653b
7 changed files with 1457 additions and 0 deletions

View file

@ -2386,6 +2386,131 @@ DART_EXPORT double PassStruct40BytesHomogeneousDoubleStruct4BytesHomo(
return result;
}
// Used for testing structs by value.
// Test alignment and padding of 16 byte int within struct.
DART_EXPORT double PassInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int(
int32_t a0,
int32_t a1,
int32_t a2,
int32_t a3,
int32_t a4,
int32_t a5,
int32_t a6,
int32_t a7,
double a8,
double a9,
double a10,
double a11,
double a12,
double a13,
double a14,
double a15,
int64_t a16,
int8_t a17,
Struct1ByteInt a18,
int64_t a19,
int8_t a20,
Struct4BytesHomogeneousInt16 a21,
int64_t a22,
int8_t a23,
Struct8BytesInt a24,
int64_t a25,
int8_t a26,
Struct8BytesHomogeneousFloat a27,
int64_t a28,
int8_t a29,
Struct8BytesMixed a30,
int64_t a31,
int8_t a32,
StructAlignmentInt16 a33,
int64_t a34,
int8_t a35,
StructAlignmentInt32 a36,
int64_t a37,
int8_t a38,
StructAlignmentInt64 a39) {
std::cout << "PassInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int"
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
<< ", " << a5 << ", " << a6 << ", " << a7 << ", " << a8 << ", "
<< a9 << ", " << a10 << ", " << a11 << ", " << a12 << ", " << a13
<< ", " << a14 << ", " << a15 << ", " << a16 << ", "
<< static_cast<int>(a17) << ", (" << static_cast<int>(a18.a0)
<< "), " << a19 << ", " << static_cast<int>(a20) << ", (" << a21.a0
<< ", " << a21.a1 << "), " << a22 << ", " << static_cast<int>(a23)
<< ", (" << a24.a0 << ", " << a24.a1 << ", " << a24.a2 << "), "
<< a25 << ", " << static_cast<int>(a26) << ", (" << a27.a0 << ", "
<< a27.a1 << "), " << a28 << ", " << static_cast<int>(a29) << ", ("
<< a30.a0 << ", " << a30.a1 << ", " << a30.a2 << "), " << a31
<< ", " << static_cast<int>(a32) << ", ("
<< static_cast<int>(a33.a0) << ", " << a33.a1 << ", "
<< static_cast<int>(a33.a2) << "), " << a34 << ", "
<< static_cast<int>(a35) << ", (" << static_cast<int>(a36.a0)
<< ", " << a36.a1 << ", " << static_cast<int>(a36.a2) << "), "
<< a37 << ", " << static_cast<int>(a38) << ", ("
<< static_cast<int>(a39.a0) << ", " << a39.a1 << ", "
<< static_cast<int>(a39.a2) << "))"
<< "\n";
double result = 0;
result += a0;
result += a1;
result += a2;
result += a3;
result += a4;
result += a5;
result += a6;
result += a7;
result += a8;
result += a9;
result += a10;
result += a11;
result += a12;
result += a13;
result += a14;
result += a15;
result += a16;
result += a17;
result += a18.a0;
result += a19;
result += a20;
result += a21.a0;
result += a21.a1;
result += a22;
result += a23;
result += a24.a0;
result += a24.a1;
result += a24.a2;
result += a25;
result += a26;
result += a27.a0;
result += a27.a1;
result += a28;
result += a29;
result += a30.a0;
result += a30.a1;
result += a30.a2;
result += a31;
result += a32;
result += a33.a0;
result += a33.a1;
result += a33.a2;
result += a34;
result += a35;
result += a36.a0;
result += a36.a1;
result += a36.a2;
result += a37;
result += a38;
result += a39.a0;
result += a39.a1;
result += a39.a2;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs by value.
// Test alignment and padding of 16 byte int within struct.
DART_EXPORT int64_t PassStructAlignmentInt16(StructAlignmentInt16 a0) {
@ -6357,6 +6482,196 @@ DART_EXPORT intptr_t TestPassStruct40BytesHomogeneousDoubleStruct4BytesHomo(
return 0;
}
// Used for testing structs by value.
// Test alignment and padding of 16 byte int within struct.
DART_EXPORT intptr_t TestPassInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int(
// NOLINTNEXTLINE(whitespace/parens)
double (*f)(int32_t a0,
int32_t a1,
int32_t a2,
int32_t a3,
int32_t a4,
int32_t a5,
int32_t a6,
int32_t a7,
double a8,
double a9,
double a10,
double a11,
double a12,
double a13,
double a14,
double a15,
int64_t a16,
int8_t a17,
Struct1ByteInt a18,
int64_t a19,
int8_t a20,
Struct4BytesHomogeneousInt16 a21,
int64_t a22,
int8_t a23,
Struct8BytesInt a24,
int64_t a25,
int8_t a26,
Struct8BytesHomogeneousFloat a27,
int64_t a28,
int8_t a29,
Struct8BytesMixed a30,
int64_t a31,
int8_t a32,
StructAlignmentInt16 a33,
int64_t a34,
int8_t a35,
StructAlignmentInt32 a36,
int64_t a37,
int8_t a38,
StructAlignmentInt64 a39)) {
int32_t a0;
int32_t a1;
int32_t a2;
int32_t a3;
int32_t a4;
int32_t a5;
int32_t a6;
int32_t a7;
double a8;
double a9;
double a10;
double a11;
double a12;
double a13;
double a14;
double a15;
int64_t a16;
int8_t a17;
Struct1ByteInt a18;
int64_t a19;
int8_t a20;
Struct4BytesHomogeneousInt16 a21;
int64_t a22;
int8_t a23;
Struct8BytesInt a24;
int64_t a25;
int8_t a26;
Struct8BytesHomogeneousFloat a27;
int64_t a28;
int8_t a29;
Struct8BytesMixed a30;
int64_t a31;
int8_t a32;
StructAlignmentInt16 a33;
int64_t a34;
int8_t a35;
StructAlignmentInt32 a36;
int64_t a37;
int8_t a38;
StructAlignmentInt64 a39;
a0 = -1;
a1 = 2;
a2 = -3;
a3 = 4;
a4 = -5;
a5 = 6;
a6 = -7;
a7 = 8;
a8 = -9.0;
a9 = 10.0;
a10 = -11.0;
a11 = 12.0;
a12 = -13.0;
a13 = 14.0;
a14 = -15.0;
a15 = 16.0;
a16 = -17;
a17 = 18;
a18.a0 = -19;
a19 = 20;
a20 = -21;
a21.a0 = 22;
a21.a1 = -23;
a22 = 24;
a23 = -25;
a24.a0 = 26;
a24.a1 = -27;
a24.a2 = 28;
a25 = -29;
a26 = 30;
a27.a0 = -31.0;
a27.a1 = 32.0;
a28 = -33;
a29 = 34;
a30.a0 = -35.0;
a30.a1 = 36;
a30.a2 = -37;
a31 = 38;
a32 = -39;
a33.a0 = 40;
a33.a1 = -41;
a33.a2 = 42;
a34 = -43;
a35 = 44;
a36.a0 = -45;
a36.a1 = 46;
a36.a2 = -47;
a37 = 48;
a38 = -49;
a39.a0 = 50;
a39.a1 = -51;
a39.a2 = 52;
std::cout << "Calling TestPassInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int("
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
<< ", " << a5 << ", " << a6 << ", " << a7 << ", " << a8 << ", "
<< a9 << ", " << a10 << ", " << a11 << ", " << a12 << ", " << a13
<< ", " << a14 << ", " << a15 << ", " << a16 << ", "
<< static_cast<int>(a17) << ", (" << static_cast<int>(a18.a0)
<< "), " << a19 << ", " << static_cast<int>(a20) << ", (" << a21.a0
<< ", " << a21.a1 << "), " << a22 << ", " << static_cast<int>(a23)
<< ", (" << a24.a0 << ", " << a24.a1 << ", " << a24.a2 << "), "
<< a25 << ", " << static_cast<int>(a26) << ", (" << a27.a0 << ", "
<< a27.a1 << "), " << a28 << ", " << static_cast<int>(a29) << ", ("
<< a30.a0 << ", " << a30.a1 << ", " << a30.a2 << "), " << a31
<< ", " << static_cast<int>(a32) << ", ("
<< static_cast<int>(a33.a0) << ", " << a33.a1 << ", "
<< static_cast<int>(a33.a2) << "), " << a34 << ", "
<< static_cast<int>(a35) << ", (" << static_cast<int>(a36.a0)
<< ", " << a36.a1 << ", " << static_cast<int>(a36.a2) << "), "
<< a37 << ", " << static_cast<int>(a38) << ", ("
<< static_cast<int>(a39.a0) << ", " << a39.a1 << ", "
<< static_cast<int>(a39.a2) << "))"
<< ")\n";
double result =
f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15,
a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29,
a30, a31, a32, a33, a34, a35, a36, a37, a38, a39);
std::cout << "result = " << result << "\n";
CHECK_APPROX(26.0, result);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14,
a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27,
a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14,
a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27,
a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs by value.
// Test alignment and padding of 16 byte int within struct.
DART_EXPORT intptr_t TestPassStructAlignmentInt16(

View file

@ -171,6 +171,12 @@ final testCases = [
PassStruct40BytesHomogeneousDoubleStruct4BytesHomoType>(
passStruct40BytesHomogeneousDoubleStruct4BytesHomo, 0.0),
passStruct40BytesHomogeneousDoubleStruct4BytesHomoAfterCallback),
CallbackTest.withCheck(
"PassInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int",
Pointer.fromFunction<
PassInt32x8Doublex8Int64Int8Struct1ByteIntInt64IntType>(
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int, 0.0),
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64IntAfterCallback),
CallbackTest.withCheck(
"PassStructAlignmentInt16",
Pointer.fromFunction<PassStructAlignmentInt16Type>(
@ -3704,6 +3710,277 @@ void passStruct40BytesHomogeneousDoubleStruct4BytesHomoAfterCallback() {
Expect.approxEquals(-5.0, result);
}
typedef PassInt32x8Doublex8Int64Int8Struct1ByteIntInt64IntType
= Double Function(
Int32,
Int32,
Int32,
Int32,
Int32,
Int32,
Int32,
Int32,
Double,
Double,
Double,
Double,
Double,
Double,
Double,
Double,
Int64,
Int8,
Struct1ByteInt,
Int64,
Int8,
Struct4BytesHomogeneousInt16,
Int64,
Int8,
Struct8BytesInt,
Int64,
Int8,
Struct8BytesHomogeneousFloat,
Int64,
Int8,
Struct8BytesMixed,
Int64,
Int8,
StructAlignmentInt16,
Int64,
Int8,
StructAlignmentInt32,
Int64,
Int8,
StructAlignmentInt64);
// Global variables to be able to test inputs after callback returned.
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a0 = 0;
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a1 = 0;
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a2 = 0;
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a3 = 0;
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a4 = 0;
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a5 = 0;
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a6 = 0;
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a7 = 0;
double passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a8 = 0.0;
double passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a9 = 0.0;
double passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a10 = 0.0;
double passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a11 = 0.0;
double passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a12 = 0.0;
double passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a13 = 0.0;
double passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a14 = 0.0;
double passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a15 = 0.0;
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a16 = 0;
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a17 = 0;
Struct1ByteInt passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a18 =
Struct1ByteInt();
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a19 = 0;
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a20 = 0;
Struct4BytesHomogeneousInt16
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a21 =
Struct4BytesHomogeneousInt16();
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a22 = 0;
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a23 = 0;
Struct8BytesInt passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a24 =
Struct8BytesInt();
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a25 = 0;
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a26 = 0;
Struct8BytesHomogeneousFloat
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a27 =
Struct8BytesHomogeneousFloat();
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a28 = 0;
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a29 = 0;
Struct8BytesMixed passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a30 =
Struct8BytesMixed();
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a31 = 0;
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a32 = 0;
StructAlignmentInt16 passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a33 =
StructAlignmentInt16();
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a34 = 0;
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a35 = 0;
StructAlignmentInt32 passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a36 =
StructAlignmentInt32();
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a37 = 0;
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a38 = 0;
StructAlignmentInt64 passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a39 =
StructAlignmentInt64();
// Result variable also global, so we can delete it after the callback.
double passInt32x8Doublex8Int64Int8Struct1ByteIntInt64IntResult = 0.0;
double passInt32x8Doublex8Int64Int8Struct1ByteIntInt64IntCalculateResult() {
double result = 0;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a0;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a1;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a2;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a3;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a4;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a5;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a6;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a7;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a8;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a9;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a10;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a11;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a12;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a13;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a14;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a15;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a16;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a17;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a18.a0;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a19;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a20;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a21.a0;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a21.a1;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a22;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a23;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a24.a0;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a24.a1;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a24.a2;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a25;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a26;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a27.a0;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a27.a1;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a28;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a29;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a30.a0;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a30.a1;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a30.a2;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a31;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a32;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a33.a0;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a33.a1;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a33.a2;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a34;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a35;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a36.a0;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a36.a1;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a36.a2;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a37;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a38;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a39.a0;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a39.a1;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a39.a2;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64IntResult = result;
return result;
}
/// Test alignment and padding of 16 byte int within struct.
double passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int(
int a0,
int a1,
int a2,
int a3,
int a4,
int a5,
int a6,
int a7,
double a8,
double a9,
double a10,
double a11,
double a12,
double a13,
double a14,
double a15,
int a16,
int a17,
Struct1ByteInt a18,
int a19,
int a20,
Struct4BytesHomogeneousInt16 a21,
int a22,
int a23,
Struct8BytesInt a24,
int a25,
int a26,
Struct8BytesHomogeneousFloat a27,
int a28,
int a29,
Struct8BytesMixed a30,
int a31,
int a32,
StructAlignmentInt16 a33,
int a34,
int a35,
StructAlignmentInt32 a36,
int a37,
int a38,
StructAlignmentInt64 a39) {
print(
"passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9}, ${a10}, ${a11}, ${a12}, ${a13}, ${a14}, ${a15}, ${a16}, ${a17}, ${a18}, ${a19}, ${a20}, ${a21}, ${a22}, ${a23}, ${a24}, ${a25}, ${a26}, ${a27}, ${a28}, ${a29}, ${a30}, ${a31}, ${a32}, ${a33}, ${a34}, ${a35}, ${a36}, ${a37}, ${a38}, ${a39})");
// In legacy mode, possibly return null.
// In both nnbd and legacy mode, possibly throw.
if (a0 == 42 || a0 == 84) {
print("throwing!");
throw Exception(
"PassInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int throwing on purpuse!");
}
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a0 = a0;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a1 = a1;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a2 = a2;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a3 = a3;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a4 = a4;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a5 = a5;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a6 = a6;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a7 = a7;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a8 = a8;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a9 = a9;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a10 = a10;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a11 = a11;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a12 = a12;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a13 = a13;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a14 = a14;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a15 = a15;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a16 = a16;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a17 = a17;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a18 = a18;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a19 = a19;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a20 = a20;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a21 = a21;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a22 = a22;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a23 = a23;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a24 = a24;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a25 = a25;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a26 = a26;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a27 = a27;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a28 = a28;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a29 = a29;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a30 = a30;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a31 = a31;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a32 = a32;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a33 = a33;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a34 = a34;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a35 = a35;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a36 = a36;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a37 = a37;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a38 = a38;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a39 = a39;
final result =
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64IntCalculateResult();
print("result = $result");
return result;
}
void passInt32x8Doublex8Int64Int8Struct1ByteIntInt64IntAfterCallback() {
final result =
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64IntCalculateResult();
print("after callback result = $result");
Expect.approxEquals(26.0, result);
}
typedef PassStructAlignmentInt16Type = Int64 Function(StructAlignmentInt16);
// Global variables to be able to test inputs after callback returned.

View file

@ -48,6 +48,7 @@ void main() {
testPassDoublex6Struct16BytesMixedx4Int32();
testPassInt32x4Struct16BytesMixedx4Double();
testPassStruct40BytesHomogeneousDoubleStruct4BytesHomo();
testPassInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int();
testPassStructAlignmentInt16();
testPassStructAlignmentInt32();
testPassStructAlignmentInt64();
@ -3357,6 +3358,245 @@ void testPassStruct40BytesHomogeneousDoubleStruct4BytesHomo() {
free(a2.addressOf);
}
final passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int =
ffiTestFunctions.lookupFunction<
Double Function(
Int32,
Int32,
Int32,
Int32,
Int32,
Int32,
Int32,
Int32,
Double,
Double,
Double,
Double,
Double,
Double,
Double,
Double,
Int64,
Int8,
Struct1ByteInt,
Int64,
Int8,
Struct4BytesHomogeneousInt16,
Int64,
Int8,
Struct8BytesInt,
Int64,
Int8,
Struct8BytesHomogeneousFloat,
Int64,
Int8,
Struct8BytesMixed,
Int64,
Int8,
StructAlignmentInt16,
Int64,
Int8,
StructAlignmentInt32,
Int64,
Int8,
StructAlignmentInt64),
double Function(
int,
int,
int,
int,
int,
int,
int,
int,
double,
double,
double,
double,
double,
double,
double,
double,
int,
int,
Struct1ByteInt,
int,
int,
Struct4BytesHomogeneousInt16,
int,
int,
Struct8BytesInt,
int,
int,
Struct8BytesHomogeneousFloat,
int,
int,
Struct8BytesMixed,
int,
int,
StructAlignmentInt16,
int,
int,
StructAlignmentInt32,
int,
int,
StructAlignmentInt64)>("PassInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int");
/// Test alignment and padding of 16 byte int within struct.
void testPassInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int() {
int a0;
int a1;
int a2;
int a3;
int a4;
int a5;
int a6;
int a7;
double a8;
double a9;
double a10;
double a11;
double a12;
double a13;
double a14;
double a15;
int a16;
int a17;
Struct1ByteInt a18 = allocate<Struct1ByteInt>().ref;
int a19;
int a20;
Struct4BytesHomogeneousInt16 a21 =
allocate<Struct4BytesHomogeneousInt16>().ref;
int a22;
int a23;
Struct8BytesInt a24 = allocate<Struct8BytesInt>().ref;
int a25;
int a26;
Struct8BytesHomogeneousFloat a27 =
allocate<Struct8BytesHomogeneousFloat>().ref;
int a28;
int a29;
Struct8BytesMixed a30 = allocate<Struct8BytesMixed>().ref;
int a31;
int a32;
StructAlignmentInt16 a33 = allocate<StructAlignmentInt16>().ref;
int a34;
int a35;
StructAlignmentInt32 a36 = allocate<StructAlignmentInt32>().ref;
int a37;
int a38;
StructAlignmentInt64 a39 = allocate<StructAlignmentInt64>().ref;
a0 = -1;
a1 = 2;
a2 = -3;
a3 = 4;
a4 = -5;
a5 = 6;
a6 = -7;
a7 = 8;
a8 = -9.0;
a9 = 10.0;
a10 = -11.0;
a11 = 12.0;
a12 = -13.0;
a13 = 14.0;
a14 = -15.0;
a15 = 16.0;
a16 = -17;
a17 = 18;
a18.a0 = -19;
a19 = 20;
a20 = -21;
a21.a0 = 22;
a21.a1 = -23;
a22 = 24;
a23 = -25;
a24.a0 = 26;
a24.a1 = -27;
a24.a2 = 28;
a25 = -29;
a26 = 30;
a27.a0 = -31.0;
a27.a1 = 32.0;
a28 = -33;
a29 = 34;
a30.a0 = -35.0;
a30.a1 = 36;
a30.a2 = -37;
a31 = 38;
a32 = -39;
a33.a0 = 40;
a33.a1 = -41;
a33.a2 = 42;
a34 = -43;
a35 = 44;
a36.a0 = -45;
a36.a1 = 46;
a36.a2 = -47;
a37 = 48;
a38 = -49;
a39.a0 = 50;
a39.a1 = -51;
a39.a2 = 52;
final result = passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int(
a0,
a1,
a2,
a3,
a4,
a5,
a6,
a7,
a8,
a9,
a10,
a11,
a12,
a13,
a14,
a15,
a16,
a17,
a18,
a19,
a20,
a21,
a22,
a23,
a24,
a25,
a26,
a27,
a28,
a29,
a30,
a31,
a32,
a33,
a34,
a35,
a36,
a37,
a38,
a39);
print("result = $result");
Expect.approxEquals(26.0, result);
free(a18.addressOf);
free(a21.addressOf);
free(a24.addressOf);
free(a27.addressOf);
free(a30.addressOf);
free(a33.addressOf);
free(a36.addressOf);
free(a39.addressOf);
}
final passStructAlignmentInt16 = ffiTestFunctions.lookupFunction<
Int64 Function(StructAlignmentInt16),
int Function(StructAlignmentInt16)>("PassStructAlignmentInt16");

View file

@ -188,6 +188,58 @@ The double will be backfilled into the xmm register."""),
"""
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,

View file

@ -171,6 +171,12 @@ final testCases = [
PassStruct40BytesHomogeneousDoubleStruct4BytesHomoType>(
passStruct40BytesHomogeneousDoubleStruct4BytesHomo, 0.0),
passStruct40BytesHomogeneousDoubleStruct4BytesHomoAfterCallback),
CallbackTest.withCheck(
"PassInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int",
Pointer.fromFunction<
PassInt32x8Doublex8Int64Int8Struct1ByteIntInt64IntType>(
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int, 0.0),
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64IntAfterCallback),
CallbackTest.withCheck(
"PassStructAlignmentInt16",
Pointer.fromFunction<PassStructAlignmentInt16Type>(
@ -3816,6 +3822,281 @@ void passStruct40BytesHomogeneousDoubleStruct4BytesHomoAfterCallback() {
Expect.approxEquals(-5.0, result);
}
typedef PassInt32x8Doublex8Int64Int8Struct1ByteIntInt64IntType
= Double Function(
Int32,
Int32,
Int32,
Int32,
Int32,
Int32,
Int32,
Int32,
Double,
Double,
Double,
Double,
Double,
Double,
Double,
Double,
Int64,
Int8,
Struct1ByteInt,
Int64,
Int8,
Struct4BytesHomogeneousInt16,
Int64,
Int8,
Struct8BytesInt,
Int64,
Int8,
Struct8BytesHomogeneousFloat,
Int64,
Int8,
Struct8BytesMixed,
Int64,
Int8,
StructAlignmentInt16,
Int64,
Int8,
StructAlignmentInt32,
Int64,
Int8,
StructAlignmentInt64);
// Global variables to be able to test inputs after callback returned.
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a0 = 0;
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a1 = 0;
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a2 = 0;
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a3 = 0;
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a4 = 0;
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a5 = 0;
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a6 = 0;
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a7 = 0;
double passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a8 = 0.0;
double passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a9 = 0.0;
double passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a10 = 0.0;
double passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a11 = 0.0;
double passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a12 = 0.0;
double passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a13 = 0.0;
double passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a14 = 0.0;
double passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a15 = 0.0;
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a16 = 0;
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a17 = 0;
Struct1ByteInt passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a18 =
Struct1ByteInt();
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a19 = 0;
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a20 = 0;
Struct4BytesHomogeneousInt16
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a21 =
Struct4BytesHomogeneousInt16();
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a22 = 0;
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a23 = 0;
Struct8BytesInt passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a24 =
Struct8BytesInt();
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a25 = 0;
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a26 = 0;
Struct8BytesHomogeneousFloat
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a27 =
Struct8BytesHomogeneousFloat();
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a28 = 0;
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a29 = 0;
Struct8BytesMixed passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a30 =
Struct8BytesMixed();
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a31 = 0;
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a32 = 0;
StructAlignmentInt16 passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a33 =
StructAlignmentInt16();
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a34 = 0;
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a35 = 0;
StructAlignmentInt32 passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a36 =
StructAlignmentInt32();
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a37 = 0;
int passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a38 = 0;
StructAlignmentInt64 passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a39 =
StructAlignmentInt64();
// Result variable also global, so we can delete it after the callback.
double passInt32x8Doublex8Int64Int8Struct1ByteIntInt64IntResult = 0.0;
double passInt32x8Doublex8Int64Int8Struct1ByteIntInt64IntCalculateResult() {
double result = 0;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a0;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a1;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a2;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a3;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a4;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a5;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a6;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a7;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a8;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a9;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a10;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a11;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a12;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a13;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a14;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a15;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a16;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a17;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a18.a0;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a19;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a20;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a21.a0;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a21.a1;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a22;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a23;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a24.a0;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a24.a1;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a24.a2;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a25;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a26;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a27.a0;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a27.a1;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a28;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a29;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a30.a0;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a30.a1;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a30.a2;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a31;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a32;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a33.a0;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a33.a1;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a33.a2;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a34;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a35;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a36.a0;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a36.a1;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a36.a2;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a37;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a38;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a39.a0;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a39.a1;
result += passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a39.a2;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64IntResult = result;
return result;
}
/// Test alignment and padding of 16 byte int within struct.
double passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int(
int a0,
int a1,
int a2,
int a3,
int a4,
int a5,
int a6,
int a7,
double a8,
double a9,
double a10,
double a11,
double a12,
double a13,
double a14,
double a15,
int a16,
int a17,
Struct1ByteInt a18,
int a19,
int a20,
Struct4BytesHomogeneousInt16 a21,
int a22,
int a23,
Struct8BytesInt a24,
int a25,
int a26,
Struct8BytesHomogeneousFloat a27,
int a28,
int a29,
Struct8BytesMixed a30,
int a31,
int a32,
StructAlignmentInt16 a33,
int a34,
int a35,
StructAlignmentInt32 a36,
int a37,
int a38,
StructAlignmentInt64 a39) {
print(
"passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9}, ${a10}, ${a11}, ${a12}, ${a13}, ${a14}, ${a15}, ${a16}, ${a17}, ${a18}, ${a19}, ${a20}, ${a21}, ${a22}, ${a23}, ${a24}, ${a25}, ${a26}, ${a27}, ${a28}, ${a29}, ${a30}, ${a31}, ${a32}, ${a33}, ${a34}, ${a35}, ${a36}, ${a37}, ${a38}, ${a39})");
// In legacy mode, possibly return null.
if (a0 == 84) {
print("returning null!");
return null;
}
// In both nnbd and legacy mode, possibly throw.
if (a0 == 42 || a0 == 84) {
print("throwing!");
throw Exception(
"PassInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int throwing on purpuse!");
}
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a0 = a0;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a1 = a1;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a2 = a2;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a3 = a3;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a4 = a4;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a5 = a5;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a6 = a6;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a7 = a7;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a8 = a8;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a9 = a9;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a10 = a10;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a11 = a11;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a12 = a12;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a13 = a13;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a14 = a14;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a15 = a15;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a16 = a16;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a17 = a17;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a18 = a18;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a19 = a19;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a20 = a20;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a21 = a21;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a22 = a22;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a23 = a23;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a24 = a24;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a25 = a25;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a26 = a26;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a27 = a27;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a28 = a28;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a29 = a29;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a30 = a30;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a31 = a31;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a32 = a32;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a33 = a33;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a34 = a34;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a35 = a35;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a36 = a36;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a37 = a37;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a38 = a38;
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int_a39 = a39;
final result =
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64IntCalculateResult();
print("result = $result");
return result;
}
void passInt32x8Doublex8Int64Int8Struct1ByteIntInt64IntAfterCallback() {
final result =
passInt32x8Doublex8Int64Int8Struct1ByteIntInt64IntCalculateResult();
print("after callback result = $result");
Expect.approxEquals(26.0, result);
}
typedef PassStructAlignmentInt16Type = Int64 Function(StructAlignmentInt16);
// Global variables to be able to test inputs after callback returned.

View file

@ -48,6 +48,7 @@ void main() {
testPassDoublex6Struct16BytesMixedx4Int32();
testPassInt32x4Struct16BytesMixedx4Double();
testPassStruct40BytesHomogeneousDoubleStruct4BytesHomo();
testPassInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int();
testPassStructAlignmentInt16();
testPassStructAlignmentInt32();
testPassStructAlignmentInt64();
@ -3357,6 +3358,245 @@ void testPassStruct40BytesHomogeneousDoubleStruct4BytesHomo() {
free(a2.addressOf);
}
final passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int =
ffiTestFunctions.lookupFunction<
Double Function(
Int32,
Int32,
Int32,
Int32,
Int32,
Int32,
Int32,
Int32,
Double,
Double,
Double,
Double,
Double,
Double,
Double,
Double,
Int64,
Int8,
Struct1ByteInt,
Int64,
Int8,
Struct4BytesHomogeneousInt16,
Int64,
Int8,
Struct8BytesInt,
Int64,
Int8,
Struct8BytesHomogeneousFloat,
Int64,
Int8,
Struct8BytesMixed,
Int64,
Int8,
StructAlignmentInt16,
Int64,
Int8,
StructAlignmentInt32,
Int64,
Int8,
StructAlignmentInt64),
double Function(
int,
int,
int,
int,
int,
int,
int,
int,
double,
double,
double,
double,
double,
double,
double,
double,
int,
int,
Struct1ByteInt,
int,
int,
Struct4BytesHomogeneousInt16,
int,
int,
Struct8BytesInt,
int,
int,
Struct8BytesHomogeneousFloat,
int,
int,
Struct8BytesMixed,
int,
int,
StructAlignmentInt16,
int,
int,
StructAlignmentInt32,
int,
int,
StructAlignmentInt64)>("PassInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int");
/// Test alignment and padding of 16 byte int within struct.
void testPassInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int() {
int a0;
int a1;
int a2;
int a3;
int a4;
int a5;
int a6;
int a7;
double a8;
double a9;
double a10;
double a11;
double a12;
double a13;
double a14;
double a15;
int a16;
int a17;
Struct1ByteInt a18 = allocate<Struct1ByteInt>().ref;
int a19;
int a20;
Struct4BytesHomogeneousInt16 a21 =
allocate<Struct4BytesHomogeneousInt16>().ref;
int a22;
int a23;
Struct8BytesInt a24 = allocate<Struct8BytesInt>().ref;
int a25;
int a26;
Struct8BytesHomogeneousFloat a27 =
allocate<Struct8BytesHomogeneousFloat>().ref;
int a28;
int a29;
Struct8BytesMixed a30 = allocate<Struct8BytesMixed>().ref;
int a31;
int a32;
StructAlignmentInt16 a33 = allocate<StructAlignmentInt16>().ref;
int a34;
int a35;
StructAlignmentInt32 a36 = allocate<StructAlignmentInt32>().ref;
int a37;
int a38;
StructAlignmentInt64 a39 = allocate<StructAlignmentInt64>().ref;
a0 = -1;
a1 = 2;
a2 = -3;
a3 = 4;
a4 = -5;
a5 = 6;
a6 = -7;
a7 = 8;
a8 = -9.0;
a9 = 10.0;
a10 = -11.0;
a11 = 12.0;
a12 = -13.0;
a13 = 14.0;
a14 = -15.0;
a15 = 16.0;
a16 = -17;
a17 = 18;
a18.a0 = -19;
a19 = 20;
a20 = -21;
a21.a0 = 22;
a21.a1 = -23;
a22 = 24;
a23 = -25;
a24.a0 = 26;
a24.a1 = -27;
a24.a2 = 28;
a25 = -29;
a26 = 30;
a27.a0 = -31.0;
a27.a1 = 32.0;
a28 = -33;
a29 = 34;
a30.a0 = -35.0;
a30.a1 = 36;
a30.a2 = -37;
a31 = 38;
a32 = -39;
a33.a0 = 40;
a33.a1 = -41;
a33.a2 = 42;
a34 = -43;
a35 = 44;
a36.a0 = -45;
a36.a1 = 46;
a36.a2 = -47;
a37 = 48;
a38 = -49;
a39.a0 = 50;
a39.a1 = -51;
a39.a2 = 52;
final result = passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int(
a0,
a1,
a2,
a3,
a4,
a5,
a6,
a7,
a8,
a9,
a10,
a11,
a12,
a13,
a14,
a15,
a16,
a17,
a18,
a19,
a20,
a21,
a22,
a23,
a24,
a25,
a26,
a27,
a28,
a29,
a30,
a31,
a32,
a33,
a34,
a35,
a36,
a37,
a38,
a39);
print("result = $result");
Expect.approxEquals(26.0, result);
free(a18.addressOf);
free(a21.addressOf);
free(a24.addressOf);
free(a27.addressOf);
free(a30.addressOf);
free(a33.addressOf);
free(a36.addressOf);
free(a39.addressOf);
}
final passStructAlignmentInt16 = ffiTestFunctions.lookupFunction<
Int64 Function(StructAlignmentInt16),
int Function(StructAlignmentInt16)>("PassStructAlignmentInt16");

View file

@ -188,6 +188,58 @@ The double will be backfilled into the xmm register."""),
"""
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,