// 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. // Dart test program for testing dart:ffi function pointers with callbacks. // // VMOptions=--stacktrace-every=100 // VMOptions=--write-protect-code --no-dual-map-code // VMOptions=--write-protect-code --no-dual-map-code --stacktrace-every=100 // VMOptions=--use-slow-path // VMOptions=--use-slow-path --stacktrace-every=100 // VMOptions=--use-slow-path --write-protect-code --no-dual-map-code // VMOptions=--use-slow-path --write-protect-code --no-dual-map-code --stacktrace-every=100 // VMOptions=--dwarf_stack_traces --no-retain_function_objects --no-retain_code_objects // VMOptions=--test_il_serialization // VMOptions=--profiler // SharedObjects=ffi_test_functions import 'dart:ffi'; import 'callback_tests_utils.dart'; typedef SimpleAdditionType = Int32 Function(Int32, Int32); int simpleAddition(int x, int y) { print("simpleAddition($x, $y)"); return x + y; } class Foo { static int simpleAddition(int x, int y) { print("Foo.simpleAddition($x, $y)"); return x + y; } } typedef IntComputationType = Int64 Function(Int8, Int16, Int32, Int64); int intComputation(int a, int b, int c, int d) { print("intComputation($a, $b, $c, $d)"); return d - c + b - a; } typedef UintComputationType = Uint64 Function(Uint8, Uint16, Uint32, Uint64); int uintComputation(int a, int b, int c, int d) { print("uintComputation($a, $b, $c, $d)"); return d - c + b - a; } typedef SimpleMultiplyType = Double Function(Double); double simpleMultiply(double x) { print("simpleMultiply($x)"); return x * 1.337; } typedef SimpleMultiplyFloatType = Float Function(Float); double simpleMultiplyFloat(double x) { print("simpleMultiplyFloat($x)"); return x * 1.337; } typedef ManyIntsType = IntPtr Function(IntPtr, IntPtr, IntPtr, IntPtr, IntPtr, IntPtr, IntPtr, IntPtr, IntPtr, IntPtr); int manyInts( int a, int b, int c, int d, int e, int f, int g, int h, int i, int j) { print("manyInts($a, $b, $c, $d, $e, $f, $g, $h, $i, $j"); return a + b + c + d + e + f + g + h + i + j; } typedef ManyDoublesType = Double Function(Double, Double, Double, Double, Double, Double, Double, Double, Double, Double); double manyDoubles(double a, double b, double c, double d, double e, double f, double g, double h, double i, double j) { print("manyDoubles($a, $b, $c, $d, $e, $f, $g, $h, $i, $j"); return a + b + c + d + e + f + g + h + i + j; } typedef ManyArgsType = Double Function( IntPtr, Float, IntPtr, Double, IntPtr, Float, IntPtr, Double, IntPtr, Float, IntPtr, Double, IntPtr, Float, IntPtr, Double, IntPtr, Float, IntPtr, Double); double manyArgs( int _1, double _2, int _3, double _4, int _5, double _6, int _7, double _8, int _9, double _10, int _11, double _12, int _13, double _14, int _15, double _16, int _17, double _18, int _19, double _20) { print("manyArgs( $_1, $_2, $_3, $_4, $_5, $_6, $_7, $_8, $_9, $_10," + "$_11, $_12, $_13, $_14, $_15, $_16, $_17, $_18, $_19, $_20)"); return _1 + _2 + _3 + _4 + _5 + _6 + _7 + _8 + _9 + _10 + _11 + _12 + _13 + _14 + _15 + _16 + _17 + _18 + _19 + _20; } typedef StoreType = Pointer Function(Pointer); Pointer store(Pointer ptr) => ptr.elementAt(1)..value = 1337; typedef NullPointersType = Pointer Function(Pointer); Pointer nullPointers(Pointer ptr) => ptr.elementAt(1); typedef ReturnVoid = Void Function(); void returnVoid() {} void throwException() { throw "Exception."; } typedef ThrowExceptionInt = IntPtr Function(); int throwExceptionInt() { throw "Exception."; } typedef ThrowExceptionDouble = Double Function(); double throwExceptionDouble() { throw "Exception."; } typedef ThrowExceptionPointer = Pointer Function(); Pointer throwExceptionPointer() { throw "Exception."; } typedef TakeMaxUint8x10Type = IntPtr Function( Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8); int takeMaxUint8x10( int a, int b, int c, int d, int e, int f, int g, int h, int i, int j) { print("takeMaxUint8x10($a, $b, $c, $d, $e, $f, $g, $h, $i, $j)"); return a == 0xff && b == 0xff && c == 0xff && d == 0xff && e == 0xff && f == 0xff && g == 0xff && h == 0xff && i == 0xff && j == 0xff ? 1 : 0; } typedef ReturnMaxUint8Type = Uint8 Function(); int returnMaxUint8() { return 0xff; } int returnMaxUint8v2() { return 0xabcff; } final testcases = [ CallbackTest("SimpleAddition", Pointer.fromFunction(simpleAddition, 0)), CallbackTest("SimpleAddition", Pointer.fromFunction(Foo.simpleAddition, 0)), CallbackTest("IntComputation", Pointer.fromFunction(intComputation, 0)), CallbackTest("UintComputation", Pointer.fromFunction(uintComputation, 0)), CallbackTest("SimpleMultiply", Pointer.fromFunction(simpleMultiply, 0.0)), CallbackTest("SimpleMultiplyFloat", Pointer.fromFunction(simpleMultiplyFloat, 0.0)), 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)), CallbackTest("ThrowExceptionPointer", Pointer.fromFunction(throwExceptionPointer)), CallbackTest("ThrowException", Pointer.fromFunction(throwExceptionInt, 42)), CallbackTest("TakeMaxUint8x10", Pointer.fromFunction(takeMaxUint8x10, 0)), CallbackTest("ReturnMaxUint8", Pointer.fromFunction(returnMaxUint8, 0)), CallbackTest("ReturnMaxUint8", Pointer.fromFunction(returnMaxUint8v2, 0)), ]; void main() { testcases.forEach((t) => t.run()); }