diff --git a/runtime/bin/ffi_test/ffi_test_functions_generated.cc b/runtime/bin/ffi_test/ffi_test_functions_generated.cc index cbb631f24e0..74f27e4229b 100644 --- a/runtime/bin/ffi_test/ffi_test_functions_generated.cc +++ b/runtime/bin/ffi_test/ffi_test_functions_generated.cc @@ -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(a17) << ", (" << static_cast(a18.a0) + << "), " << a19 << ", " << static_cast(a20) << ", (" << a21.a0 + << ", " << a21.a1 << "), " << a22 << ", " << static_cast(a23) + << ", (" << a24.a0 << ", " << a24.a1 << ", " << a24.a2 << "), " + << a25 << ", " << static_cast(a26) << ", (" << a27.a0 << ", " + << a27.a1 << "), " << a28 << ", " << static_cast(a29) << ", (" + << a30.a0 << ", " << a30.a1 << ", " << a30.a2 << "), " << a31 + << ", " << static_cast(a32) << ", (" + << static_cast(a33.a0) << ", " << a33.a1 << ", " + << static_cast(a33.a2) << "), " << a34 << ", " + << static_cast(a35) << ", (" << static_cast(a36.a0) + << ", " << a36.a1 << ", " << static_cast(a36.a2) << "), " + << a37 << ", " << static_cast(a38) << ", (" + << static_cast(a39.a0) << ", " << a39.a1 << ", " + << static_cast(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(a17) << ", (" << static_cast(a18.a0) + << "), " << a19 << ", " << static_cast(a20) << ", (" << a21.a0 + << ", " << a21.a1 << "), " << a22 << ", " << static_cast(a23) + << ", (" << a24.a0 << ", " << a24.a1 << ", " << a24.a2 << "), " + << a25 << ", " << static_cast(a26) << ", (" << a27.a0 << ", " + << a27.a1 << "), " << a28 << ", " << static_cast(a29) << ", (" + << a30.a0 << ", " << a30.a1 << ", " << a30.a2 << "), " << a31 + << ", " << static_cast(a32) << ", (" + << static_cast(a33.a0) << ", " << a33.a1 << ", " + << static_cast(a33.a2) << "), " << a34 << ", " + << static_cast(a35) << ", (" << static_cast(a36.a0) + << ", " << a36.a1 << ", " << static_cast(a36.a2) << "), " + << a37 << ", " << static_cast(a38) << ", (" + << static_cast(a39.a0) << ", " << a39.a1 << ", " + << static_cast(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( diff --git a/tests/ffi/function_callbacks_structs_by_value_generated_test.dart b/tests/ffi/function_callbacks_structs_by_value_generated_test.dart index 7985c51fab9..845ebb98578 100644 --- a/tests/ffi/function_callbacks_structs_by_value_generated_test.dart +++ b/tests/ffi/function_callbacks_structs_by_value_generated_test.dart @@ -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( @@ -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. diff --git a/tests/ffi/function_structs_by_value_generated_test.dart b/tests/ffi/function_structs_by_value_generated_test.dart index 26f48eafe8d..35936e969cc 100644 --- a/tests/ffi/function_structs_by_value_generated_test.dart +++ b/tests/ffi/function_structs_by_value_generated_test.dart @@ -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().ref; + int a19; + int a20; + Struct4BytesHomogeneousInt16 a21 = + allocate().ref; + int a22; + int a23; + Struct8BytesInt a24 = allocate().ref; + int a25; + int a26; + Struct8BytesHomogeneousFloat a27 = + allocate().ref; + int a28; + int a29; + Struct8BytesMixed a30 = allocate().ref; + int a31; + int a32; + StructAlignmentInt16 a33 = allocate().ref; + int a34; + int a35; + StructAlignmentInt32 a36 = allocate().ref; + int a37; + int a38; + StructAlignmentInt64 a39 = allocate().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"); diff --git a/tests/ffi/generator/structs_by_value_tests_configuration.dart b/tests/ffi/generator/structs_by_value_tests_configuration.dart index 5ea4cffd633..46f5108b735 100644 --- a/tests/ffi/generator/structs_by_value_tests_configuration.dart +++ b/tests/ffi/generator/structs_by_value_tests_configuration.dart @@ -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, diff --git a/tests/ffi_2/function_callbacks_structs_by_value_generated_test.dart b/tests/ffi_2/function_callbacks_structs_by_value_generated_test.dart index 76620d78cc2..38714fd91bf 100644 --- a/tests/ffi_2/function_callbacks_structs_by_value_generated_test.dart +++ b/tests/ffi_2/function_callbacks_structs_by_value_generated_test.dart @@ -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( @@ -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. diff --git a/tests/ffi_2/function_structs_by_value_generated_test.dart b/tests/ffi_2/function_structs_by_value_generated_test.dart index a548274b7e7..dfb17cd0fd5 100644 --- a/tests/ffi_2/function_structs_by_value_generated_test.dart +++ b/tests/ffi_2/function_structs_by_value_generated_test.dart @@ -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().ref; + int a19; + int a20; + Struct4BytesHomogeneousInt16 a21 = + allocate().ref; + int a22; + int a23; + Struct8BytesInt a24 = allocate().ref; + int a25; + int a26; + Struct8BytesHomogeneousFloat a27 = + allocate().ref; + int a28; + int a29; + Struct8BytesMixed a30 = allocate().ref; + int a31; + int a32; + StructAlignmentInt16 a33 = allocate().ref; + int a34; + int a35; + StructAlignmentInt32 a36 = allocate().ref; + int a37; + int a38; + StructAlignmentInt64 a39 = allocate().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"); diff --git a/tests/ffi_2/generator/structs_by_value_tests_configuration.dart b/tests/ffi_2/generator/structs_by_value_tests_configuration.dart index 5ea4cffd633..46f5108b735 100644 --- a/tests/ffi_2/generator/structs_by_value_tests_configuration.dart +++ b/tests/ffi_2/generator/structs_by_value_tests_configuration.dart @@ -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,