commit | 4b66657b984d41c34250e1e7b80030fcfb6a82a8 | [log] [tgz] |
---|---|---|
author | Daco Harkes <dacoharkes@google.com> | Thu Apr 25 10:06:16 2024 +0000 |
committer | Commit Queue <dart-scoped@luci-project-accounts.iam.gserviceaccount.com> | Thu Apr 25 10:06:16 2024 +0000 |
tree | 9b74d2eb0cd706182ce24a1eaa4f7fe2bb43bac7 | |
parent | 8c1475c6c26f47ccba46f62afbd7d8599a992464 [diff] |
[vm/ffi] `address` of operator for FFI leaf calls During FFI leaf calls, the Dart GC will not run. This means that we can pass pointers into `TypedData` to FFI calls that take `Pointer` arguments. After this CL, we have three types of arguments that can flow into `Pointer` argument in an FFI call: * `Pointer`. * `TypedData`: Any typed data including views. * `_Compound`: A TypedData/Pointer and an offset in bytes. The is only possible for `@Native external` functions, `asFunction` does not support passing in `TypedData`. (See related GitHub issues for discussion. TLDR: FFIgen should generate bindings without config.) `.address` expressions on `TypedData` and `Array` elements do _not_ introduce bounds checks, even though `TypedData` and `Array` have bounds information. E.g. `ffiNative(Uint8List(10)[20].address)` does not throw. Implementation details: The CFE analyzes call-sites to `@Native external` functions. If the arguments are `.address` expressions, it transforms the call site to pass the compound or `TypedData`. If an additional offset needs to be applied, the CFE constructs a new `_Compound` with the correct offset in bytes. The CFE then also creates a new `@Native external` function which have `TypedData`s and `_Compound`s parameters. To avoid name clashes, these functions are postfixed with `#` and `P`, `T`, or `C` for each Pointer parameter. TEST=pkg/vm/testcases/transformations/ffi/address_of_* In the VM, `TypedData` arguments are passed as tagged values, and the address is loaded inside the `FfiCallInstr`. `_Compound` arguments turn into two IL definitions, one for the `TypedDataBase` (tagged), and one for the offset in bytes (unboxed). The address is then loaded inside the `FfiCallInstr` and the offset in bytes is applied. Adding the offset in bytes required an extra temp register for ia32. Also, it uncovered that the temp register in arm32 was conflicting with the argument registers. However, TMP should suffice instead. TEST=tests/ffi/address_of_array_generated_test.dart TEST=tests/ffi/address_of_struct_generated_test.dart TEST=tests/ffi/address_of_typeddata_generated_test.dart Closes: https://github.com/dart-lang/sdk/issues/44589 Closes: https://github.com/dart-lang/sdk/issues/54771 CoreLibraryReviewExempt: VM only, unsupported in dart2wasm Change-Id: I01fb428cfd6f9096a34689c2819c124a8003cb6b Cq-Include-Trybots: dart/try:vm-aot-android-release-arm64c-try,vm-aot-android-release-arm_x64-try,vm-aot-linux-debug-x64-try,vm-aot-linux-debug-x64c-try,vm-aot-mac-release-arm64-try,vm-aot-mac-release-x64-try,vm-aot-obfuscate-linux-release-x64-try,vm-aot-optimization-level-linux-release-x64-try,vm-aot-win-debug-arm64-try,vm-aot-win-debug-x64c-try,vm-aot-win-release-x64-try,vm-appjit-linux-debug-x64-try,vm-asan-linux-release-x64-try,vm-checked-mac-release-arm64-try,vm-eager-optimization-linux-release-ia32-try,vm-eager-optimization-linux-release-x64-try,vm-ffi-android-debug-arm64c-try,vm-ffi-qemu-linux-release-arm-try,vm-ffi-qemu-linux-release-riscv64-try,vm-linux-debug-ia32-try,vm-linux-debug-x64-try,vm-linux-debug-x64c-try,vm-mac-debug-arm64-try,vm-mac-debug-x64-try,vm-msan-linux-release-x64-try,vm-reload-linux-debug-x64-try,vm-reload-rollback-linux-debug-x64-try,vm-ubsan-linux-release-x64-try,vm-win-debug-arm64-try,vm-win-debug-x64-try,vm-win-debug-x64c-try,vm-win-release-ia32-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/360882 Reviewed-by: Jens Johansen <jensj@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Reviewed-by: Martin Kustermann <kustermann@google.com> Commit-Queue: Daco Harkes <dacoharkes@google.com> Reviewed-by: Tess Strickland <sstrickl@google.com> Reviewed-by: Lasse Nielsen <lrn@google.com>
Dart is:
Approachable: Develop with a strongly typed programming language that is consistent, concise, and offers modern language features like null safety and patterns.
Portable: Compile to ARM, x64, or RISC-V machine code for mobile, desktop, and backend. Compile to JavaScript or WebAssembly for the web.
Productive: Make changes iteratively: use hot reload to see the result instantly in your running app. Diagnose app issues using DevTools.
Dart's flexible compiler technology lets you run Dart code in different ways, depending on your target platform and goals:
Dart Native: For programs targeting devices (mobile, desktop, server, and more), Dart Native includes both a Dart VM with JIT (just-in-time) compilation and an AOT (ahead-of-time) compiler for producing machine code.
Dart Web: For programs targeting the web, Dart Web includes both a development time compiler (dartdevc) and a production time compiler (dart2js).
Dart is free and open source.
See LICENSE and PATENT_GRANT.
Visit dart.dev to learn more about the language, tools, and to find codelabs.
Browse pub.dev for more packages and libraries contributed by the community and the Dart team.
Our API reference documentation is published at api.dart.dev, based on the stable release. (We also publish docs from our beta and dev channels, as well as from the primary development branch).
If you want to build Dart yourself, here is a guide to getting the source, preparing your machine to build the SDK, and building.
There are more documents on our wiki.
The easiest way to contribute to Dart is to file issues.
You can also contribute patches, as described in Contributing.
Future plans for Dart are included in the combined Dart and Flutter roadmap on the Flutter wiki.