40094c8cfd
Enables passing inner pointers to typed data in FFI leaf calls. This works for typed data's in the Dart heap, external typed datas (constructed from `Pointer.asTypedList`), and typed data views. Notable implementation details: 1. The Dart signature is used in the Marshaller now. This means it needs to keep track of whether there's a pointer argument in the signature (`asFunction`) or not (`@Native`). 2. Unwrapping is done in `FfiCallInstr::EmitNativeCode` before moving the arguments to their native location. This ensures we can use the assembler logic to load the `TypedDataBase::data` field. 3. The `XXXList` user visible classes don't have predefined cids. So the implementation uses symbols for comparison. 4. The type checking logic takes `isLeaf` as input to reject typed data. This leads to an error message about the type not accepted. Alternatively, we could consider adding an error message that specifically says the function should be leaf. 5. To cover all calling convention variants, tests are generated with up to 20 arguments. TEST=pkg/analyzer/test/src/diagnostics/ffi_unwrap_typed_data_test.dart TEST=tests/ffi/unwrap_typeddata_generated_native_test.dart TEST=tests/ffi/unwrap_typeddata_generated_test.dart TEST=tests/ffi/vmspecific_static_checks_typeddata_test.dart Closes: https://github.com/dart-lang/sdk/issues/44589 Change-Id: Ia78f18bf3238d42ac6882929b441f6dc432fcefe Cq-Include-Trybots: luci.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-arm-try,vm-ffi-android-debug-arm64c-try,vm-ffi-qemu-linux-release-arm-try,vm-ffi-qemu-linux-release-riscv64-try,vm-fuchsia-release-x64-try,vm-kernel-linux-debug-x64-try,vm-kernel-precomp-linux-release-x64-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/+/338620 Commit-Queue: Daco Harkes <dacoharkes@google.com> Reviewed-by: Martin Kustermann <kustermann@google.com>
108 lines
3.2 KiB
Dart
108 lines
3.2 KiB
Dart
// 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.
|
|
|
|
import 'dart:io';
|
|
|
|
extension TestGeneratorStringExtension on String {
|
|
String upperCaseFirst() => "${this[0].toUpperCase()}${this.substring(1)}";
|
|
|
|
String lowerCaseFirst() => "${this[0].toLowerCase()}${this.substring(1)}";
|
|
|
|
String makeCComment() => "// " + split("\n").join("\n// ");
|
|
|
|
String makeDartDocComment() => "/// " + split("\n").join("\n/// ");
|
|
|
|
String limitTo(int length) {
|
|
if (this.length > length) {
|
|
return substring(0, length);
|
|
}
|
|
return this;
|
|
}
|
|
|
|
String trimCouts() => replaceAll('" << "', '').replaceAll('"<< "', '');
|
|
}
|
|
|
|
Future<void> runProcess(String executable, List<String> arguments) async {
|
|
final commandString = [executable, ...arguments].join(' ');
|
|
stdout.writeln('Running `$commandString`.');
|
|
final process = await Process.start(
|
|
executable,
|
|
arguments,
|
|
runInShell: true,
|
|
includeParentEnvironment: true,
|
|
).then((process) {
|
|
process.stdout.forEach(stdout.add);
|
|
process.stderr.forEach(stderr.add);
|
|
return process;
|
|
});
|
|
final exitCode = await process.exitCode;
|
|
if (exitCode != 0) {
|
|
final message = 'Command `$commandString` failed with exit code $exitCode.';
|
|
stderr.writeln(message);
|
|
throw Exception(message);
|
|
}
|
|
stdout.writeln('Command `$commandString` done.');
|
|
}
|
|
|
|
String headerCommon({
|
|
required int copyrightYear,
|
|
required String generatorPath,
|
|
}) {
|
|
final year = copyrightYear;
|
|
return """
|
|
// Copyright (c) $year, 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.
|
|
//
|
|
// This file has been automatically generated. Please do not edit it manually.
|
|
// Generated by $generatorPath.""";
|
|
}
|
|
|
|
String headerC({
|
|
required int copyrightYear,
|
|
required String generatorPath,
|
|
}) {
|
|
return """
|
|
${headerCommon(copyrightYear: copyrightYear, generatorPath: generatorPath)}
|
|
|
|
#include <stdarg.h>
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <sys/types.h>
|
|
|
|
#include <cmath>
|
|
#include <iostream>
|
|
#include <limits>
|
|
|
|
#if defined(_WIN32)
|
|
#define DART_EXPORT extern "C" __declspec(dllexport)
|
|
#else
|
|
#define DART_EXPORT \\
|
|
extern "C" __attribute__((visibility("default"))) __attribute((used))
|
|
#endif
|
|
|
|
namespace dart {
|
|
|
|
#define CHECK(X) \\
|
|
if (!(X)) { \\
|
|
fprintf(stderr, "%s\\n", "Check failed: " #X); \\
|
|
return 1; \\
|
|
}
|
|
|
|
#define CHECK_EQ(X, Y) CHECK((X) == (Y))
|
|
|
|
// Works for positive, negative and zero.
|
|
#define CHECK_APPROX(EXPECTED, ACTUAL) \\
|
|
CHECK(((EXPECTED * 0.99) <= (ACTUAL) && (EXPECTED * 1.01) >= (ACTUAL)) || \\
|
|
((EXPECTED * 0.99) >= (ACTUAL) && (EXPECTED * 1.01) <= (ACTUAL)))
|
|
|
|
""";
|
|
}
|
|
|
|
const footerC = """
|
|
|
|
} // namespace dart
|
|
""";
|