// 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= // VMOptions=--stacktrace-every=100 // VMOptions=--use-slow-path // VMOptions=--use-slow-path --stacktrace-every=100 // VMOptions=--dwarf_stack_traces --no-retain_function_objects --no-retain_code_objects // VMOptions=--test_il_serialization // VMOptions=--profiler --profile_vm=true // VMOptions=--profiler --profile_vm=false // 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 + 1)..value = 1337; typedef NullPointersType = Pointer Function(Pointer); Pointer nullPointers(Pointer ptr) => (ptr + 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()); }