diff --git a/runtime/bin/ffi_test/ffi_test_functions.cc b/runtime/bin/ffi_test/ffi_test_functions.cc index 13e67e5d65f..cc39f08a3dc 100644 --- a/runtime/bin/ffi_test/ffi_test_functions.cc +++ b/runtime/bin/ffi_test/ffi_test_functions.cc @@ -44,7 +44,7 @@ namespace dart { // int. DART_EXPORT int32_t SumPlus42(int32_t a, int32_t b) { std::cout << "SumPlus42(" << a << ", " << b << ")\n"; - int32_t retval = 42 + a + b; + const int32_t retval = 42 + a + b; std::cout << "returning " << retval << "\n"; return retval; } @@ -173,7 +173,7 @@ DART_EXPORT intptr_t TakeMaxUint8x10(uint8_t a, DART_EXPORT int64_t IntComputation(int8_t a, int16_t b, int32_t c, int64_t d) { std::cout << "IntComputation(" << static_cast(a) << ", " << b << ", " << c << ", " << d << ")\n"; - int64_t retval = d - c + b - a; + const int64_t retval = d - c + b - a; std::cout << "returning " << retval << "\n"; return retval; } @@ -194,7 +194,7 @@ DART_EXPORT int64_t UintComputation(uint8_t a, uint64_t d) { std::cout << "UintComputation(" << static_cast(a) << ", " << b << ", " << c << ", " << d << ")\n"; - uint64_t retval = d - c + b - a; + const uint64_t retval = d - c + b - a; std::cout << "returning " << retval << "\n"; return retval; } @@ -203,7 +203,7 @@ DART_EXPORT int64_t UintComputation(uint8_t a, // Used for testing pointer sized parameter and return value. DART_EXPORT intptr_t Times3(intptr_t a) { std::cout << "Times3(" << a << ")\n"; - intptr_t retval = a * 3; + const intptr_t retval = a * 3; std::cout << "returning " << retval << "\n"; return retval; } @@ -214,7 +214,7 @@ DART_EXPORT intptr_t Times3(intptr_t a) { // double. DART_EXPORT double Times1_337Double(double a) { std::cout << "Times1_337Double(" << a << ")\n"; - double retval = a * 1.337; + const double retval = a * 1.337; std::cout << "returning " << retval << "\n"; return retval; } @@ -223,7 +223,7 @@ DART_EXPORT double Times1_337Double(double a) { // Used for testing float parameter and return value. DART_EXPORT float Times1_337Float(float a) { std::cout << "Times1_337Float(" << a << ")\n"; - float retval = a * 1.337f; + const float retval = a * 1.337f; std::cout << "returning " << retval << "\n"; return retval; } @@ -244,7 +244,7 @@ DART_EXPORT intptr_t SumManyInts(intptr_t a, std::cout << "SumManyInts(" << a << ", " << b << ", " << c << ", " << d << ", " << e << ", " << f << ", " << g << ", " << h << ", " << i << ", " << j << ")\n"; - intptr_t retval = a + b + c + d + e + f + g + h + i + j; + const intptr_t retval = a + b + c + d + e + f + g + h + i + j; std::cout << "returning " << retval << "\n"; return retval; } @@ -266,7 +266,146 @@ DART_EXPORT int16_t SumManySmallInts(int8_t a, << static_cast(c) << ", " << d << ", " << static_cast(e) << ", " << f << ", " << static_cast(g) << ", " << h << ", " << static_cast(i) << ", " << j << ")\n"; - int16_t retval = a + b + c + d + e + f + g + h + i + j; + const int16_t retval = a + b + c + d + e + f + g + h + i + j; + std::cout << "returning " << retval << "\n"; + return retval; +} + +// Used for testing floating point argument backfilling on Arm32 in hardfp. +DART_EXPORT double SumFloatsAndDoubles(float a, double b, float c) { + std::cout << "SumFloatsAndDoubles(" << a << ", " << b << ", " << c << ")\n"; + const double retval = a + b + c; + std::cout << "returning " << retval << "\n"; + return retval; +} + +// Very many small integers, tests alignment on stack. +DART_EXPORT int16_t SumVeryManySmallInts(int8_t a01, + int16_t a02, + int8_t a03, + int16_t a04, + int8_t a05, + int16_t a06, + int8_t a07, + int16_t a08, + int8_t a09, + int16_t a10, + int8_t a11, + int16_t a12, + int8_t a13, + int16_t a14, + int8_t a15, + int16_t a16, + int8_t a17, + int16_t a18, + int8_t a19, + int16_t a20, + int8_t a21, + int16_t a22, + int8_t a23, + int16_t a24, + int8_t a25, + int16_t a26, + int8_t a27, + int16_t a28, + int8_t a29, + int16_t a30, + int8_t a31, + int16_t a32, + int8_t a33, + int16_t a34, + int8_t a35, + int16_t a36, + int8_t a37, + int16_t a38, + int8_t a39, + int16_t a40) { + std::cout << "SumVeryManySmallInts(" << static_cast(a01) << ", " << a02 + << ", " << static_cast(a03) << ", " << a04 << ", " + << static_cast(a05) << ", " << a06 << ", " + << static_cast(a07) << ", " << a08 << ", " + << static_cast(a09) << ", " << a10 << ", " + << static_cast(a11) << ", " << a12 << ", " + << static_cast(a13) << ", " << a14 << ", " + << static_cast(a15) << ", " << a16 << ", " + << static_cast(a17) << ", " << a18 << ", " + << static_cast(a19) << ", " << a20 << ", " + << static_cast(a21) << ", " << a22 << ", " + << static_cast(a23) << ", " << a24 << ", " + << static_cast(a25) << ", " << a26 << ", " + << static_cast(a27) << ", " << a28 << ", " + << static_cast(a29) << ", " << a30 << ", " + << static_cast(a31) << ", " << a32 << ", " + << static_cast(a33) << ", " << a34 << ", " + << static_cast(a35) << ", " << a36 << ", " + << static_cast(a37) << ", " << a38 << ", " + << static_cast(a39) << ", " << a40 << ")\n"; + const int16_t retval = a01 + a02 + a03 + a04 + a05 + a06 + a07 + a08 + a09 + + 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 + a40; + std::cout << "returning " << retval << "\n"; + return retval; +} + +// Very many floating points, tests alignment on stack, and packing in +// floating point registers in hardfp. +DART_EXPORT double SumVeryManyFloatsDoubles(float a01, + double a02, + float a03, + double a04, + float a05, + double a06, + float a07, + double a08, + float a09, + double a10, + float a11, + double a12, + float a13, + double a14, + float a15, + double a16, + float a17, + double a18, + float a19, + double a20, + float a21, + double a22, + float a23, + double a24, + float a25, + double a26, + float a27, + double a28, + float a29, + double a30, + float a31, + double a32, + float a33, + double a34, + float a35, + double a36, + float a37, + double a38, + float a39, + double a40) { + std::cout << "SumVeryManyFloatsDoubles(" << a01 << ", " << a02 << ", " << a03 + << ", " << a04 << ", " << a05 << ", " << a06 << ", " << a07 << ", " + << a08 << ", " << a09 << ", " << 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 + << ", " << a40 << ")\n"; + const double retval = a01 + a02 + a03 + a04 + a05 + a06 + a07 + a08 + a09 + + 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 + a40; std::cout << "returning " << retval << "\n"; return retval; } @@ -288,7 +427,7 @@ DART_EXPORT intptr_t SumManyIntsOdd(intptr_t a, std::cout << "SumManyInts(" << a << ", " << b << ", " << c << ", " << d << ", " << e << ", " << f << ", " << g << ", " << h << ", " << i << ", " << j << ", " << k << ")\n"; - intptr_t retval = a + b + c + d + e + f + g + h + i + j + k; + const intptr_t retval = a + b + c + d + e + f + g + h + i + j + k; std::cout << "returning " << retval << "\n"; return retval; } @@ -309,7 +448,7 @@ DART_EXPORT double SumManyDoubles(double a, std::cout << "SumManyDoubles(" << a << ", " << b << ", " << c << ", " << d << ", " << e << ", " << f << ", " << g << ", " << h << ", " << i << ", " << j << ")\n"; - double retval = a + b + c + d + e + f + g + h + i + j; + const double retval = a + b + c + d + e + f + g + h + i + j; std::cout << "returning " << retval << "\n"; return retval; } @@ -342,8 +481,8 @@ DART_EXPORT double SumManyNumbers(intptr_t a, << ", " << j << ", " << k << ", " << l << ", " << m << ", " << n << ", " << o << ", " << p << ", " << q << ", " << r << ", " << s << ", " << t << ")\n"; - double retval = a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + - p + q + r + s + t; + const double retval = a + b + c + d + e + f + g + h + i + j + k + l + m + n + + o + p + q + r + s + t; std::cout << "returning " << retval << "\n"; return retval; } @@ -581,7 +720,7 @@ DART_EXPORT void DevNullFloat(float a) { // Used for testing functions that do not take any arguments. DART_EXPORT float InventFloatValue() { std::cout << "InventFloatValue()\n"; - float retval = 1337.0f; + const float retval = 1337.0f; std::cout << "returning " << retval << "\n"; return retval; } @@ -678,6 +817,111 @@ DART_EXPORT intptr_t TestManyArgs(double (*fn)(intptr_t a, return 0; } +// Used for testing floating point argument backfilling on Arm32 in hardfp. +DART_EXPORT intptr_t TestSumFloatsAndDoubles(double (*fn)(float, + double, + float)) { + CHECK_EQ(6.0, fn(1.0, 2.0, 3.0)); + return 0; +} + +// Very many small integers, tests alignment on stack. +DART_EXPORT intptr_t TestSumVeryManySmallInts(int16_t (*fn)(int8_t, + int16_t, + int8_t, + int16_t, + int8_t, + int16_t, + int8_t, + int16_t, + int8_t, + int16_t, + int8_t, + int16_t, + int8_t, + int16_t, + int8_t, + int16_t, + int8_t, + int16_t, + int8_t, + int16_t, + int8_t, + int16_t, + int8_t, + int16_t, + int8_t, + int16_t, + int8_t, + int16_t, + int8_t, + int16_t, + int8_t, + int16_t, + int8_t, + int16_t, + int8_t, + int16_t, + int8_t, + int16_t, + int8_t, + int16_t)) { + CHECK_EQ(40 * 41 / 2, fn(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40)); + return 0; +} + +// Very many floating points, tests alignment on stack, and packing in +// floating point registers in hardfp. +DART_EXPORT intptr_t TestSumVeryManyFloatsDoubles(double (*fn)(float, + double, + float, + double, + float, + double, + float, + double, + float, + double, + float, + double, + float, + double, + float, + double, + float, + double, + float, + double, + float, + double, + float, + double, + float, + double, + float, + double, + float, + double, + float, + double, + float, + double, + float, + double, + float, + double, + float, + double)) { + CHECK_EQ(40 * 41 / 2, + fn(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, + 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, + 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0, + 35.0, 36.0, 37.0, 38.0, 39.0, 40.0)); + return 0; +} + DART_EXPORT intptr_t TestStore(int64_t* (*fn)(int64_t* a)) { int64_t p[2] = {42, 1000}; int64_t* result = fn(p); diff --git a/tests/ffi/callback_tests_utils.dart b/tests/ffi/callback_tests_utils.dart new file mode 100644 index 00000000000..ac5fdcb7337 --- /dev/null +++ b/tests/ffi/callback_tests_utils.dart @@ -0,0 +1,34 @@ +// Copyright (c) 2019, 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. + +import 'dart:ffi'; + +import 'dylib_utils.dart'; + +import "package:expect/expect.dart"; + +final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions"); + +typedef NativeCallbackTest = Int32 Function(Pointer); +typedef NativeCallbackTestFn = int Function(Pointer); + +class CallbackTest { + final String name; + final Pointer callback; + final bool skip; + + CallbackTest(this.name, this.callback, {bool skipIf: false}) + : skip = skipIf {} + + void run() { + if (skip) return; + + final NativeCallbackTestFn tester = ffiTestFunctions + .lookupFunction("Test$name"); + final int testCode = tester(callback); + if (testCode != 0) { + Expect.fail("Test $name failed."); + } + } +} diff --git a/tests/ffi/function_callbacks_many_test.dart b/tests/ffi/function_callbacks_many_test.dart index d187093f75d..c8fb5195e34 100644 --- a/tests/ffi/function_callbacks_many_test.dart +++ b/tests/ffi/function_callbacks_many_test.dart @@ -16,33 +16,7 @@ import 'dart:ffi'; -import "package:expect/expect.dart"; - -import 'dylib_utils.dart'; - -typedef NativeCallbackTest = Int32 Function(Pointer); -typedef NativeCallbackTestFn = int Function(Pointer); - -final DynamicLibrary testLibrary = dlopenPlatformSpecific("ffi_test_functions"); - -class Test { - final String name; - final Pointer callback; - final bool skip; - - Test(this.name, this.callback, {bool skipIf: false}) : skip = skipIf {} - - void run() { - if (skip) return; - - final NativeCallbackTestFn tester = testLibrary - .lookupFunction("Test$name"); - final int testCode = tester(callback); - if (testCode != 0) { - Expect.fail("Test $name failed."); - } - } -} +import 'callback_tests_utils.dart'; typedef SimpleAdditionType = Int32 Function(Int32, Int32); int simpleAddition(int x, int y) => x + y; @@ -1064,6 +1038,6 @@ void testManyCallbacks() { pointers.add(Pointer.fromFunction(simpleAddition, 999)); for (final pointer in pointers) { - Test("SimpleAddition", pointer).run(); + CallbackTest("SimpleAddition", pointer).run(); } } diff --git a/tests/ffi/function_callbacks_test.dart b/tests/ffi/function_callbacks_test.dart index 33a9fc1fc70..24ca0648d92 100644 --- a/tests/ffi/function_callbacks_test.dart +++ b/tests/ffi/function_callbacks_test.dart @@ -16,33 +16,7 @@ import 'dart:ffi'; -import "package:expect/expect.dart"; - -import 'dylib_utils.dart'; - -typedef NativeCallbackTest = Int32 Function(Pointer); -typedef NativeCallbackTestFn = int Function(Pointer); - -final DynamicLibrary testLibrary = dlopenPlatformSpecific("ffi_test_functions"); - -class Test { - final String name; - final Pointer callback; - final bool skip; - - Test(this.name, this.callback, {bool skipIf: false}) : skip = skipIf {} - - void run() { - if (skip) return; - - final NativeCallbackTestFn tester = testLibrary - .lookupFunction("Test$name"); - final int testCode = tester(callback); - if (testCode != 0) { - Expect.fail("Test $name failed."); - } - } -} +import 'callback_tests_utils.dart'; typedef SimpleAdditionType = Int32 Function(Int32, Int32); int simpleAddition(int x, int y) { @@ -212,34 +186,36 @@ int returnMaxUint8v2() { return 0xabcff; } -final List testcases = [ - Test("SimpleAddition", +final testcases = [ + CallbackTest("SimpleAddition", Pointer.fromFunction(simpleAddition, 0)), - Test("IntComputation", + CallbackTest("IntComputation", Pointer.fromFunction(intComputation, 0)), - Test("UintComputation", + CallbackTest("UintComputation", Pointer.fromFunction(uintComputation, 0)), - Test("SimpleMultiply", + CallbackTest("SimpleMultiply", Pointer.fromFunction(simpleMultiply, 0.0)), - Test("SimpleMultiplyFloat", + CallbackTest("SimpleMultiplyFloat", Pointer.fromFunction(simpleMultiplyFloat, 0.0)), - Test("ManyInts", Pointer.fromFunction(manyInts, 0)), - Test("ManyDoubles", Pointer.fromFunction(manyDoubles, 0.0)), - Test("ManyArgs", Pointer.fromFunction(manyArgs, 0.0)), - Test("Store", Pointer.fromFunction(store)), - Test("NullPointers", Pointer.fromFunction(nullPointers)), - Test("ReturnVoid", Pointer.fromFunction(returnVoid)), - Test("ThrowExceptionDouble", + CallbackTest("ManyInts", Pointer.fromFunction(manyInts, 0)), + CallbackTest( + "ManyDoubles", Pointer.fromFunction(manyDoubles, 0.0)), + CallbackTest("ManyArgs", Pointer.fromFunction(manyArgs, 0.0)), + CallbackTest("Store", Pointer.fromFunction(store)), + CallbackTest( + "NullPointers", Pointer.fromFunction(nullPointers)), + CallbackTest("ReturnVoid", Pointer.fromFunction(returnVoid)), + CallbackTest("ThrowExceptionDouble", Pointer.fromFunction(throwExceptionDouble, 42.0)), - Test("ThrowExceptionPointer", + CallbackTest("ThrowExceptionPointer", Pointer.fromFunction(throwExceptionPointer)), - Test("ThrowException", + CallbackTest("ThrowException", Pointer.fromFunction(throwExceptionInt, 42)), - Test("TakeMaxUint8x10", + CallbackTest("TakeMaxUint8x10", Pointer.fromFunction(takeMaxUint8x10, 0)), - Test("ReturnMaxUint8", + CallbackTest("ReturnMaxUint8", Pointer.fromFunction(returnMaxUint8, 0)), - Test("ReturnMaxUint8", + CallbackTest("ReturnMaxUint8", Pointer.fromFunction(returnMaxUint8v2, 0)), ]; diff --git a/tests/ffi/function_callbacks_very_many_test.dart b/tests/ffi/function_callbacks_very_many_test.dart new file mode 100644 index 00000000000..383b482199d --- /dev/null +++ b/tests/ffi/function_callbacks_very_many_test.dart @@ -0,0 +1,295 @@ +// 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 test program for testing dart:ffi function pointers with callbacks. +// +// VMOptions=--deterministic --optimization-counter-threshold=10 +// VMOptions=--enable-testing-pragmas +// VMOptions=--enable-testing-pragmas --stacktrace-every=100 +// VMOptions=--enable-testing-pragmas --write-protect-code --no-dual-map-code +// VMOptions=--enable-testing-pragmas --write-protect-code --no-dual-map-code --stacktrace-every=100 +// VMOptions=--use-slow-path --enable-testing-pragmas +// VMOptions=--use-slow-path --enable-testing-pragmas --stacktrace-every=100 +// VMOptions=--use-slow-path --enable-testing-pragmas --write-protect-code --no-dual-map-code +// VMOptions=--use-slow-path --enable-testing-pragmas --write-protect-code --no-dual-map-code --stacktrace-every=100 +// SharedObjects=ffi_test_functions + +import 'dart:ffi'; + +import 'callback_tests_utils.dart'; + +final testcases = [ + CallbackTest("SumVeryManySmallInts", + Pointer.fromFunction(sumVeryManySmallInts, 0)), + CallbackTest( + "SumVeryManyFloatsDoubles", + Pointer.fromFunction( + sumVeryManyDoubles, 0.0)), +]; + +void main() { + for (int i = 0; i < 100; ++i) { + testcases.forEach((t) => t.run()); + } +} + +int sumVeryManySmallInts( + int _1, + int _2, + int _3, + int _4, + int _5, + int _6, + int _7, + int _8, + int _9, + int _10, + int _11, + int _12, + int _13, + int _14, + int _15, + int _16, + int _17, + int _18, + int _19, + int _20, + int _21, + int _22, + int _23, + int _24, + int _25, + int _26, + int _27, + int _28, + int _29, + int _30, + int _31, + int _32, + int _33, + int _34, + int _35, + int _36, + int _37, + int _38, + int _39, + int _40) { + print("sumVeryManySmallInts(" + + "$_1, $_2, $_3, $_4, $_5, $_6, $_7, $_8, $_9, $_10, " + + "$_11, $_12, $_13, $_14, $_15, $_16, $_17, $_18, $_19, $_20, " + + "$_21, $_22, $_23, $_24, $_25, $_26, $_27, $_28, $_29, $_30, " + + "$_31, $_32, $_33, $_34, $_35, $_36, $_37, $_38, $_39, $_40)"); + return _1 + + _2 + + _3 + + _4 + + _5 + + _6 + + _7 + + _8 + + _9 + + _10 + + _11 + + _12 + + _13 + + _14 + + _15 + + _16 + + _17 + + _18 + + _19 + + _20 + + _21 + + _22 + + _23 + + _24 + + _25 + + _26 + + _27 + + _28 + + _29 + + _30 + + _31 + + _32 + + _33 + + _34 + + _35 + + _36 + + _37 + + _38 + + _39 + + _40; +} + +double sumVeryManyDoubles( + double _1, + double _2, + double _3, + double _4, + double _5, + double _6, + double _7, + double _8, + double _9, + double _10, + double _11, + double _12, + double _13, + double _14, + double _15, + double _16, + double _17, + double _18, + double _19, + double _20, + double _21, + double _22, + double _23, + double _24, + double _25, + double _26, + double _27, + double _28, + double _29, + double _30, + double _31, + double _32, + double _33, + double _34, + double _35, + double _36, + double _37, + double _38, + double _39, + double _40) { + print("sumVeryManyDoubles(" + + "$_1, $_2, $_3, $_4, $_5, $_6, $_7, $_8, $_9, $_10, " + + "$_11, $_12, $_13, $_14, $_15, $_16, $_17, $_18, $_19, $_20, " + + "$_21, $_22, $_23, $_24, $_25, $_26, $_27, $_28, $_29, $_30, " + + "$_31, $_32, $_33, $_34, $_35, $_36, $_37, $_38, $_39, $_40)"); + return _1 + + _2 + + _3 + + _4 + + _5 + + _6 + + _7 + + _8 + + _9 + + _10 + + _11 + + _12 + + _13 + + _14 + + _15 + + _16 + + _17 + + _18 + + _19 + + _20 + + _21 + + _22 + + _23 + + _24 + + _25 + + _26 + + _27 + + _28 + + _29 + + _30 + + _31 + + _32 + + _33 + + _34 + + _35 + + _36 + + _37 + + _38 + + _39 + + _40; +} + +typedef NativeVeryManyIntsOp = Int16 Function( + Int8, + Int16, + Int8, + Int16, + Int8, + Int16, + Int8, + Int16, + Int8, + Int16, + Int8, + Int16, + Int8, + Int16, + Int8, + Int16, + Int8, + Int16, + Int8, + Int16, + Int8, + Int16, + Int8, + Int16, + Int8, + Int16, + Int8, + Int16, + Int8, + Int16, + Int8, + Int16, + Int8, + Int16, + Int8, + Int16, + Int8, + Int16, + Int8, + Int16); + +typedef NativeVeryManyFloatsDoublesOp = Double Function( + Float, + Double, + Float, + Double, + Float, + Double, + Float, + Double, + Float, + Double, + Float, + Double, + Float, + Double, + Float, + Double, + Float, + Double, + Float, + Double, + Float, + Double, + Float, + Double, + Float, + Double, + Float, + Double, + Float, + Double, + Float, + Double, + Float, + Double, + Float, + Double, + Float, + Double, + Float, + Double); diff --git a/tests/ffi/function_very_many_test.dart b/tests/ffi/function_very_many_test.dart new file mode 100644 index 00000000000..80566175897 --- /dev/null +++ b/tests/ffi/function_very_many_test.dart @@ -0,0 +1,299 @@ +// 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 test program for testing dart:ffi calls argument passing. +// +// VMOptions= +// VMOptions=--deterministic --optimization-counter-threshold=10 +// VMOptions=--use-slow-path +// VMOptions=--use-slow-path --stacktrace-every=100 +// VMOptions=--write-protect-code --no-dual-map-code +// VMOptions=--write-protect-code --no-dual-map-code --use-slow-path +// VMOptions=--write-protect-code --no-dual-map-code --stacktrace-every=100 +// SharedObjects=ffi_test_functions + +import 'dart:ffi'; + +import 'dylib_utils.dart'; + +import "package:expect/expect.dart"; + +void main() { + for (int i = 0; i < 100; ++i) { + testSumVeryManySmallInts(); + testSumVeryManyFloatsDoubles(); + } +} + +final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions"); + +VeryManyIntsOp sumVeryManySmallInts = + ffiTestFunctions.lookupFunction( + "SumVeryManySmallInts"); +// Very many small integers, tests alignment on stack. +void testSumVeryManySmallInts() { + Expect.equals( + 40 * 41 / 2, + sumVeryManySmallInts( + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40)); +} + +VeryManyFloatsDoublesOp sumVeryManyFloatsDoubles = ffiTestFunctions + .lookupFunction( + "SumVeryManyFloatsDoubles"); + +// Very many floating points, tests alignment on stack, and packing in +// floating point registers in hardfp. +void testSumVeryManyFloatsDoubles() { + Expect.approxEquals( + 40.0 * 41.0 / 2.0, + sumVeryManyFloatsDoubles( + 1.0, + 2.0, + 3.0, + 4.0, + 5.0, + 6.0, + 7.0, + 8.0, + 9.0, + 10.0, + 11.0, + 12.0, + 13.0, + 14.0, + 15.0, + 16.0, + 17.0, + 18.0, + 19.0, + 20.0, + 21.0, + 22.0, + 23.0, + 24.0, + 25.0, + 26.0, + 27.0, + 28.0, + 29.0, + 30.0, + 31.0, + 32.0, + 33.0, + 34.0, + 35.0, + 36.0, + 37.0, + 38.0, + 39.0, + 40.0)); +} + +typedef NativeVeryManyIntsOp = Int16 Function( + Int8, + Int16, + Int8, + Int16, + Int8, + Int16, + Int8, + Int16, + Int8, + Int16, + Int8, + Int16, + Int8, + Int16, + Int8, + Int16, + Int8, + Int16, + Int8, + Int16, + Int8, + Int16, + Int8, + Int16, + Int8, + Int16, + Int8, + Int16, + Int8, + Int16, + Int8, + Int16, + Int8, + Int16, + Int8, + Int16, + Int8, + Int16, + Int8, + Int16); + +typedef VeryManyIntsOp = int Function( + int, + int, + int, + int, + int, + int, + int, + int, + int, + int, + int, + int, + int, + int, + int, + int, + int, + int, + int, + int, + int, + int, + int, + int, + int, + int, + int, + int, + int, + int, + int, + int, + int, + int, + int, + int, + int, + int, + int, + int); + +typedef NativeVeryManyFloatsDoublesOp = Double Function( + Float, + Double, + Float, + Double, + Float, + Double, + Float, + Double, + Float, + Double, + Float, + Double, + Float, + Double, + Float, + Double, + Float, + Double, + Float, + Double, + Float, + Double, + Float, + Double, + Float, + Double, + Float, + Double, + Float, + Double, + Float, + Double, + Float, + Double, + Float, + Double, + Float, + Double, + Float, + Double); + +typedef VeryManyFloatsDoublesOp = double Function( + double, + double, + double, + double, + double, + double, + double, + double, + double, + double, + double, + double, + double, + double, + double, + double, + double, + double, + double, + double, + double, + double, + double, + double, + double, + double, + double, + double, + double, + double, + double, + double, + double, + double, + double, + double, + double, + double, + double, + double); diff --git a/tests/ffi/hardfp_test.dart b/tests/ffi/hardfp_test.dart new file mode 100644 index 00000000000..600e26bb0ad --- /dev/null +++ b/tests/ffi/hardfp_test.dart @@ -0,0 +1,51 @@ +// 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 test program for testing dart:ffi function pointers. +// +// VMOptions= +// VMOptions=--deterministic --optimization-counter-threshold=10 +// VMOptions=--use-slow-path +// VMOptions=--use-slow-path --stacktrace-every=100 +// VMOptions=--write-protect-code --no-dual-map-code +// VMOptions=--write-protect-code --no-dual-map-code --use-slow-path +// VMOptions=--write-protect-code --no-dual-map-code --stacktrace-every=100 +// SharedObjects=ffi_test_functions + +import 'dart:ffi'; + +import "package:expect/expect.dart"; + +import 'callback_tests_utils.dart'; +import 'dylib_utils.dart'; + +void main() { + for (int i = 0; i < 100; ++i) { + testSumFloatsAndDoubles(); + testSumFloatsAndDoublesCallback(); + } +} + +DynamicLibrary ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions"); + +final sumFloatsAndDoubles = ffiTestFunctions.lookupFunction< + Double Function(Float, Double, Float), + double Function(double, double, double)>("SumFloatsAndDoubles"); + +void testSumFloatsAndDoubles() { + Expect.approxEquals(6.0, sumFloatsAndDoubles(1.0, 2.0, 3.0)); +} + +void testSumFloatsAndDoublesCallback() { + CallbackTest( + "SumFloatsAndDoubles", + Pointer.fromFunction( + sumFloatsAndDoublesDart, 0.0)) + .run(); +} + +double sumFloatsAndDoublesDart(double a, double b, double c) { + print("sumFloatsAndDoublesDart($a, $b, $c)"); + return a + b + c; +} diff --git a/tests/ffi/vmspecific_function_callbacks_exit_test.dart b/tests/ffi/vmspecific_function_callbacks_exit_test.dart index b28dea9d5fd..e7f33a214ee 100644 --- a/tests/ffi/vmspecific_function_callbacks_exit_test.dart +++ b/tests/ffi/vmspecific_function_callbacks_exit_test.dart @@ -10,41 +10,27 @@ import 'dart:io'; import 'dart:ffi'; import 'dart:isolate'; + import "package:expect/expect.dart"; + +import 'callback_tests_utils.dart'; import 'dylib_utils.dart'; -typedef NativeCallbackTest = Int32 Function(Pointer); -typedef NativeCallbackTestFn = int Function(Pointer); -final DynamicLibrary testLibrary = dlopenPlatformSpecific("ffi_test_functions"); - -class Test { - final String name; - final Pointer callback; - final bool skip; - Test(this.name, this.callback, {bool skipIf: false}) : skip = skipIf {} - void run() { - if (skip) return; - print("Test $name."); - final NativeCallbackTestFn tester = testLibrary - .lookupFunction("Test$name"); - final int testCode = tester(callback); - if (testCode != 0) { - Expect.fail("Test $name failed."); - } - } -} +final testLibrary = dlopenPlatformSpecific("ffi_test_functions"); typedef ReturnVoid = Void Function(); void returnVoid() {} testCallbackWrongThread() { print("Test CallbackWrongThread."); - Test("CallbackWrongThread", Pointer.fromFunction(returnVoid)) + CallbackTest( + "CallbackWrongThread", Pointer.fromFunction(returnVoid)) .run(); } testCallbackOutsideIsolate() { print("Test CallbackOutsideIsolate."); - Test("CallbackOutsideIsolate", Pointer.fromFunction(returnVoid)) + CallbackTest("CallbackOutsideIsolate", + Pointer.fromFunction(returnVoid)) .run(); } diff --git a/tests/ffi/vmspecific_function_callbacks_test.dart b/tests/ffi/vmspecific_function_callbacks_test.dart index 53c0119c002..99a036b93c6 100644 --- a/tests/ffi/vmspecific_function_callbacks_test.dart +++ b/tests/ffi/vmspecific_function_callbacks_test.dart @@ -20,7 +20,12 @@ import 'dart:ffi'; import 'ffi_test_helpers.dart'; -import 'function_callbacks_test.dart' show Test, testLibrary, ReturnVoid; +import 'callback_tests_utils.dart'; +import 'dylib_utils.dart'; + +typedef ReturnVoid = Void Function(); + +final testLibrary = dlopenPlatformSpecific("ffi_test_functions"); void testGC() { triggerGc(); @@ -35,9 +40,9 @@ void waitForHelper(Pointer helper) { "WaitForHelper")(helper); } -final List testcases = [ - Test("GC", Pointer.fromFunction(testGC)), - Test("UnprotectCode", +final testcases = [ + CallbackTest("GC", Pointer.fromFunction(testGC)), + CallbackTest("UnprotectCode", Pointer.fromFunction(waitForHelper)), ];