Files
sdk/tests/ffi/inline_array_variable_length_test.dart
T
Daco Harkes 965234ccbe [vm/ffi] Variable length inline arrays
Adds a new `@Array.variable()` to specify that the last element of
structs is a variable length inline array.

This CL does not add any checks for passing structs with variable
length inline arrays by value or directly calling them with
`AllocatorAlloc.call`. Instead, the implementation defaults to what
C does, allocate as if there are 0 elements in the variable length
inline array.

TEST=tests/ffi/*

CoreLibraryReviewExempt: VM only
Closes: https://github.com/dart-lang/sdk/issues/55964
Change-Id: I524d8a1d710b1a744b392e05fa884908c3ff1f12
Cq-Include-Trybots: dart/try:vm-aot-android-release-arm64c-try,vm-aot-android-release-arm_x64-try,vm-aot-asan-linux-release-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-msan-linux-release-x64-try,vm-aot-obfuscate-linux-release-x64-try,vm-aot-optimization-level-linux-release-x64-try,vm-aot-tsan-linux-release-x64-try,vm-aot-ubsan-linux-release-x64-try,vm-aot-win-debug-arm64-try,vm-aot-win-debug-x64-try,vm-aot-win-debug-x64c-try,vm-appjit-linux-debug-x64-try,vm-asan-linux-release-arm64-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-arm64-try,vm-fuchsia-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-arm64-try,vm-msan-linux-release-x64-try,vm-reload-linux-debug-x64-try,vm-reload-rollback-linux-debug-x64-try,vm-tsan-linux-release-arm64-try,vm-tsan-linux-release-x64-try,vm-ubsan-linux-release-arm64-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/+/371960
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Lasse Nielsen <lrn@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
2024-08-06 07:50:49 +00:00

95 lines
2.3 KiB
Dart

// Copyright (c) 2024, 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
import 'dart:ffi';
import "package:expect/expect.dart";
import 'package:ffi/ffi.dart';
// Reuse compound definitions.
import 'function_structs_by_value_generated_compounds.dart';
void main() {
testInlineArray();
testInlineArrayNested();
testInlineArrayNestedDeep();
testSizeOf();
}
void testInlineArray() {
const length = 10;
final lengthInBytes =
sizeOf<StructInlineArrayVariable>() + sizeOf<Uint8>() * length;
final pointer = calloc.allocate<StructInlineArrayVariable>(lengthInBytes);
pointer.ref.a0 = length;
final struct = pointer.ref;
for (int i = 0; i < length; i++) {
struct.a1[i] = i;
}
var sum = 0;
for (int i = 0; i < length; i++) {
sum += struct.a1[i];
}
calloc.free(pointer);
Expect.equals(45, sum);
}
void testInlineArrayNested() {
const length = 10;
final lengthInBytes = sizeOf<StructInlineArrayVariableNested>() +
sizeOf<Uint8>() * length * 2 * 2;
final pointer =
calloc.allocate<StructInlineArrayVariableNested>(lengthInBytes);
pointer.ref.a0 = length;
final struct = pointer.ref;
for (int i = 0; i < length; i++) {
struct.a1[i][0][0] = i;
}
var sum = 0;
for (int i = 0; i < length; i++) {
sum += struct.a1[i][0][0];
}
calloc.free(pointer);
Expect.equals(45, sum);
}
void testInlineArrayNestedDeep() {
const length = 10;
final lengthInBytes = sizeOf<StructInlineArrayVariableNestedDeep>() +
sizeOf<Uint8>() * length * 2 * 2 * 2 * 2 * 2 * 2;
final pointer =
calloc.allocate<StructInlineArrayVariableNestedDeep>(lengthInBytes);
pointer.ref.a0 = length;
final struct = pointer.ref;
for (int i = 0; i < length; i++) {
struct.a1[i][0][0][1][1][0][0] = i;
}
var sum = 0;
for (int i = 0; i < length; i++) {
sum += struct.a1[i][0][0][1][1][0][0];
}
calloc.free(pointer);
Expect.equals(45, sum);
}
final class Foo extends Struct {
@Int8()
external int field0;
}
final class Foo2 extends Struct {
@Int8()
external int field0;
@Array<Uint32>.variable()
external Array<Uint32> field1;
}
void testSizeOf() {
Expect.equals(1, sizeOf<Foo>());
Expect.equals(4, sizeOf<Foo2>());
}