// Copyright (c) 2021, 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. // // SharedObjects=ffi_test_functions // NOTE: There is no `test/ffi_2/...` version of this test since annotations // with type arguments isn't supported in that version of Dart. import 'dart:ffi'; import 'package:expect/expect.dart'; import 'dylib_utils.dart'; final nativeLib = dlopenPlatformSpecific('ffi_test_functions'); final getRootLibraryUrl = nativeLib .lookupFunction('GetRootLibraryUrl'); final setFfiNativeResolverForTest = nativeLib .lookupFunction('SetFfiNativeResolverForTest'); @FfiNative('ReturnIntPtr') external int returnIntPtr(int x); @FfiNative('ReturnIntPtr', isLeaf: true) external int returnIntPtrLeaf(int x); @FfiNative('IsThreadInGenerated') external int isThreadInGenerated(); @FfiNative('IsThreadInGenerated', isLeaf: true) external int isThreadInGeneratedLeaf(); // Error: FFI leaf call must not have Handle return type. @FfiNative("foo", isLeaf: true) //# 01: compile-time error external Object foo(); //# 01: compile-time error // Error: FFI leaf call must not have Handle argument types. @FfiNative("bar", isLeaf: true) //# 02: compile-time error external void bar(Object); //# 02: compile-time error class Classy { @FfiNative('ReturnIntPtr') external static int returnIntPtrStatic(int x); // Error: FfiNative annotations can only be used on static functions. @FfiNative('ReturnIntPtr') //# 03: compile-time error external int returnIntPtrMethod(int x); //# 03: compile-time error } // Regression test: Ensure same-name FfiNative functions don't collide in the // top-level namespace, but instead live under their parent (Library, Class). class A { @FfiNative('nop') external static void foo(); } class B { @FfiNative('nop') external static void foo(); } void main() { // Register test resolver for top-level functions above. final root_lib_url = getRootLibraryUrl(); setFfiNativeResolverForTest(root_lib_url); // Test we can call FfiNative functions. Expect.equals(123, returnIntPtr(123)); Expect.equals(123, returnIntPtrLeaf(123)); Expect.equals(123, Classy.returnIntPtrStatic(123)); // Test FfiNative leaf calls remain in generated code. // Regular calls should transition generated -> native. Expect.equals(0, isThreadInGenerated()); // Leaf calls should remain in generated state. Expect.equals(1, isThreadInGeneratedLeaf()); }