[vm/ffi] Allow configuring the variable dimension of variable-length arrays

TEST=tests/ffi/*

CoreLibraryReviewExempt: VM only
Closes: https://github.com/dart-lang/sdk/issues/52366
Change-Id: I545a323f48d955b591cedf2dae7106d9004242e2
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-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/+/398621
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
Halil Durmus
2024-12-09 22:02:56 +00:00
committed by Commit Queue
parent 17dc16e297
commit bb483f34a3
60 changed files with 4239 additions and 575 deletions
+2 -1
View File
@@ -1,6 +1,6 @@
# Copyright (c) 2016, 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.
# BSD-style license that can be found in the LICENSE file.
import("build/config/gclient_args.gni")
import("sdk_args.gni")
@@ -258,6 +258,7 @@ if (is_fuchsia) {
"tests/ffi/function_structs_by_value_generated_args_native_leaf_test.dart",
"tests/ffi/function_structs_by_value_generated_args_native_test.dart",
"tests/ffi/function_structs_by_value_generated_args_test.dart",
"tests/ffi/function_structs_by_value_generated_compounds_sizeof_test.dart",
"tests/ffi/function_structs_by_value_generated_ret_arg_leaf_test.dart",
"tests/ffi/function_structs_by_value_generated_ret_arg_native_leaf_test.dart",
"tests/ffi/function_structs_by_value_generated_ret_arg_native_test.dart",
@@ -13365,6 +13365,17 @@ const MessageCode messageNativeClauseShouldBeAnnotation = const MessageCode(
r"""Try removing this native clause and adding @native() or @native('native-name') before the declaration.""",
);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeNegativeVariableDimension =
messageNegativeVariableDimension;
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const MessageCode messageNegativeVariableDimension = const MessageCode(
"NegativeVariableDimension",
problemMessage:
r"""The variable dimension of a variable-length array must be non-negative.""",
);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeNeverReachableSwitchDefaultError =
messageNeverReachableSwitchDefaultError;
@@ -1740,7 +1740,7 @@ FfiCode.FFI_NATIVE_MUST_BE_EXTERNAL:
since: ~2.15
notes: |-
The fix is to add the `external` keyword.
FfiCode.FFI_NATIVE_ONLY_CLASSES_EXTENDING_NATIVEFIELDWRAPPERCLASS1_CAN_BE_POINTER:
FfiCode.FFI_NATIVE_ONLY_CLASSES_EXTENDING_NATIVEFIELDWRAPPERCLASS1_CAN_BE_POINTER:
status: noFix
since: ~2.15
FfiCode.FFI_NATIVE_UNEXPECTED_NUMBER_OF_PARAMETERS:
@@ -1790,6 +1790,8 @@ FfiCode.NATIVE_FIELD_MISSING_TYPE:
status: needsEvaluation
FfiCode.NATIVE_FIELD_NOT_STATIC:
status: needsEvaluation
FfiCode.NEGATIVE_VARIABLE_DIMENSION:
status: noFix
FfiCode.NON_CONSTANT_TYPE_ARGUMENT:
status: noFix
FfiCode.NON_NATIVE_FUNCTION_TYPE_ARGUMENT_TO_POINTER:
@@ -386,6 +386,13 @@ class FfiCode extends ErrorCode {
hasPublishedDocs: true,
);
/// No parameters.
static const FfiCode NEGATIVE_VARIABLE_DIMENSION = FfiCode(
'NEGATIVE_VARIABLE_DIMENSION',
"The variable dimension of a variable-length array must be non-negative.",
correctionMessage: "Try using a value that is zero or greater.",
);
/// Parameters:
/// 0: the name of the function, method, or constructor having type arguments
static const FfiCode NON_CONSTANT_TYPE_ARGUMENT = FfiCode(
@@ -631,6 +631,7 @@ const List<ErrorCode> errorCodeValues = [
FfiCode.NATIVE_FIELD_INVALID_TYPE,
FfiCode.NATIVE_FIELD_MISSING_TYPE,
FfiCode.NATIVE_FIELD_NOT_STATIC,
FfiCode.NEGATIVE_VARIABLE_DIMENSION,
FfiCode.NON_CONSTANT_TYPE_ARGUMENT,
FfiCode.NON_NATIVE_FUNCTION_TYPE_ARGUMENT_TO_POINTER,
FfiCode.NON_POSITIVE_ARRAY_DIMENSION,
@@ -1991,28 +1991,54 @@ class FfiVerifier extends RecursiveAstVisitor<void> {
}
}
// Check dimensions are positive.
List<AstNode>? getArgumentNodes() {
var arguments = annotation.arguments?.arguments;
if (arguments != null && arguments.length == 1) {
var firstArgument = arguments[0];
if (firstArgument is ListLiteral) {
return firstArgument.elements;
}
}
return arguments;
// Check dimensions are valid.
(List<AstNode>? dimensionsNodes, AstNode? variableDimensionNode)
getArgumentNodes() {
return switch (annotation.arguments) {
// `@Array.variableMulti([..], variableDimension: ..)`
ArgumentList(
arguments: [ListLiteral dimensions, NamedExpression variableDimension]
) =>
(dimensions.elements, variableDimension.expression),
// `@Array.variableMulti([..])`
ArgumentList(arguments: [ListLiteral dimensions]) => (
dimensions.elements,
null
),
// `@Array(..)`, `@Array.variable(..)`,
// `@Array.variableWithVariableDimension(..)`
ArgumentList(arguments: NodeList<AstNode> dimensions) => (
dimensions,
null
),
_ => (null, null)
};
}
var (dimensionsNodes, variableDimensionNode) = getArgumentNodes();
AstNode errorNode = variableDimensionNode ?? annotation;
for (int i = 0; i < dimensions.length; i++) {
if (i == 0 && variableLength) {
continue; // First dimension is variable.
}
if (dimensions[i] <= 0) {
AstNode errorNode = annotation;
var argumentNodes = getArgumentNodes();
if (argumentNodes != null && argumentNodes.isNotEmpty) {
errorNode = argumentNodes[i];
if (dimensionsNodes case var dimensionsNodes?) {
if (dimensionsNodes.length > i && variableDimensionNode == null) {
var node = dimensionsNodes[i];
errorNode = node is NamedExpression ? node.expression : node;
}
}
// First dimension is variable.
if (i == 0 && variableLength) {
// Variable dimension can't be negative.
if (dimensions[0] < 0) {
_errorReporter.atNode(
errorNode,
FfiCode.NEGATIVE_VARIABLE_DIMENSION,
);
}
continue;
}
if (dimensions[i] <= 0) {
_errorReporter.atNode(
errorNode,
FfiCode.NON_POSITIVE_ARRAY_DIMENSION,
@@ -2093,8 +2119,8 @@ extension on ElementAnnotation {
assert(isArray);
var value = computeConstantValue();
var variableLength =
value?.getField('variableLength')?.toBoolValue() ?? false;
var variableDimension = value?.getField('variableDimension')?.toIntValue();
var variableLength = variableDimension != null;
// Element of `@Array.multi([1, 2, 3])`.
var listField = value?.getField('dimensions');
@@ -2105,7 +2131,10 @@ extension on ElementAnnotation {
.whereType<int>()
.toList();
if (listValues != null) {
return ([if (variableLength) 0, ...listValues], variableLength);
return (
[if (variableLength) variableDimension, ...listValues],
variableLength
);
}
}
@@ -902,20 +902,38 @@ final class DartRepresentationOf {
@Since('2.13')
final class Array<T extends NativeType> extends _Compound {
const factory Array(int dimension1,
[int dimension2,
int dimension3,
int dimension4,
int dimension5]) = _ArraySize<T>;
const factory Array(
int dimension1, [
int dimension2,
int dimension3,
int dimension4,
int dimension5,
]) = _ArraySize<T>;
const factory Array.multi(List<int> dimensions) = _ArraySize<T>.multi;
@Since('3.6')
const factory Array.variable() = _ArraySize<T>.variable;
const factory Array.variable([
int dimension2,
int dimension3,
int dimension4,
int dimension5,
]) = _ArraySize<T>.variable;
@Since('3.7')
const factory Array.variableWithVariableDimension([
int dimension1,
int dimension2,
int dimension3,
int dimension4,
int dimension5,
]) = _ArraySize<T>.variableWithVariableDimension;
@Since('3.6')
const factory Array.variableMulti(List<int> dimensions) =
_ArraySize<T>.variableMulti;
const factory Array.variableMulti(
List<int> dimensions, {
@Since('3.7') int variableDimension,
}) = _ArraySize<T>.variableMulti;
}
final class _ArraySize<T extends NativeType> implements Array<T> {
@@ -927,7 +945,7 @@ final class _ArraySize<T extends NativeType> implements Array<T> {
final List<int>? dimensions;
final bool variableLength;
final int? variableDimension;
const _ArraySize(
this.dimension1, [
@@ -936,7 +954,7 @@ final class _ArraySize<T extends NativeType> implements Array<T> {
this.dimension4,
this.dimension5,
]) : dimensions = null,
variableLength = false;
variableDimension = null;
const _ArraySize.multi(this.dimensions)
: dimension1 = null,
@@ -944,27 +962,36 @@ final class _ArraySize<T extends NativeType> implements Array<T> {
dimension3 = null,
dimension4 = null,
dimension5 = null,
variableLength = false;
static const variableLengthLength = 0;
variableDimension = null;
const _ArraySize.variable([
this.dimension2,
this.dimension3,
this.dimension4,
this.dimension5,
]) : dimension1 = variableLengthLength,
]) : dimension1 = 0,
dimensions = null,
variableLength = true;
variableDimension = 0;
const _ArraySize.variableMulti(List<int> nestedDimensions)
: dimensions = nestedDimensions,
const _ArraySize.variableWithVariableDimension([
this.dimension1,
this.dimension2,
this.dimension3,
this.dimension4,
this.dimension5,
]) : dimensions = null,
variableDimension = dimension1;
const _ArraySize.variableMulti(
List<int> nestedDimensions, {
int variableDimension = 0,
}) : dimensions = nestedDimensions,
dimension1 = null,
dimension2 = null,
dimension3 = null,
dimension4 = null,
dimension5 = null,
variableLength = true;
variableDimension = variableDimension;
}
extension StructPointer<T extends Struct> on Pointer<T> {
+73 -2
View File
@@ -20400,6 +20400,76 @@ FfiCode:
NativeCallable<Void Function(Int32)>.listener(f);
}
```
NEGATIVE_VARIABLE_DIMENSION:
problemMessage: The variable dimension of a variable-length array must be non-negative.
correctionMessage: Try using a value that is zero or greater.
hasPublishedDocs: false
comment: No parameters.
documentation: |-
#### Description
The analyzer produces this diagnostic in two cases.
The first is when the variable dimension given in an
`Array.variableWithVariableDimension` annotation is negative. The variable
dimension is the first argument in the annotation.
The second is when the variable dimension given in an
`Array.variableMulti` annotation is negative. The variable dimension is
specified in the `variableDimension` argument of the annotation.
For more information about FFI, see [C interop using dart:ffi][ffi].
#### Examples
The following code produces this diagnostic because a variable dimension
of `-1` was provided in the `Array.variableWithVariableDimension`
annotation:
```dart
import 'dart:ffi';
final class MyStruct extends Struct {
@Array.variableWithVariableDimension([!-1!])
external Array<Uint8> a0;
}
```
The following code produces this diagnostic because a variable dimension
of `-1` was provided in the `Array.variableMulti` annotation:
```dart
import 'dart:ffi';
final class MyStruct2 extends Struct {
@Array.variableMulti(variableDimension: [!-1!], [1, 2])
external Array<Array<Array<Uint8>>> a0;
}
```
#### Common fixes
Change the variable dimension with zero (`0`) or a positive number:
```dart
import 'dart:ffi';
final class MyStruct extends Struct {
@Array.variableWithVariableDimension(1)
external Array<Uint8> a0;
}
```
Change the variable dimension with zero (`0`) or a positive number:
```dart
import 'dart:ffi';
final class MyStruct2 extends Struct {
@Array.variableMulti(variableDimension: 1, [1, 2])
external Array<Array<Array<Uint8>>> a0;
}
```
NON_CONSTANT_TYPE_ARGUMENT:
problemMessage: "The type arguments to '{0}' must be known at compile time, so they can't be type parameters."
correctionMessage: Try changing the type argument to be a constant type.
@@ -20515,7 +20585,7 @@ FfiCode:
#### Example
The following code produces this diagnostic because an array dimension of
`-1` was provided:
`-8` was provided:
```dart
import 'dart:ffi';
@@ -20539,7 +20609,8 @@ FfiCode:
}
```
If this is a variable length inline array, change the annotation to `Array.variable()`:
If this is a variable length inline array, change the annotation to
`Array.variable()`:
```dart
import 'dart:ffi';
@@ -0,0 +1,204 @@
// 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.
import 'package:analyzer/src/dart/error/ffi_code.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(InlineArrayTest);
});
}
@reflectiveTest
class InlineArrayTest extends PubPackageResolutionTest {
test_array_negativeDimension() async {
await assertErrorsInCode(r'''
import 'dart:ffi';
final class MyStruct extends Struct {
@Array(-1)
external Array<Int8> arr;
}
''', [error(FfiCode.NON_POSITIVE_ARRAY_DIMENSION, 67, 2)]);
}
test_array_positiveDimension() async {
await assertNoErrorsInCode(r'''
import 'dart:ffi';
final class MyStruct extends Struct {
@Array(1)
external Array<Int8> arr;
}
''');
}
test_array_zeroDimension() async {
await assertErrorsInCode(r'''
import 'dart:ffi';
final class MyStruct extends Struct {
@Array(0)
external Array<Int8> arr;
}
''', [error(FfiCode.NON_POSITIVE_ARRAY_DIMENSION, 67, 1)]);
}
test_multi_negativeDimension() async {
await assertErrorsInCode(r'''
import 'dart:ffi';
final class MyStruct extends Struct {
@Array.multi([-2, 2])
external Array<Array<Int8>> arr;
}
''', [error(FfiCode.NON_POSITIVE_ARRAY_DIMENSION, 74, 2)]);
}
test_multi_positiveDimension() async {
await assertNoErrorsInCode(r'''
import 'dart:ffi';
final class MyStruct extends Struct {
@Array.multi([2, 2])
external Array<Array<Int8>> arr;
}
''');
}
test_multi_zeroDimension() async {
await assertErrorsInCode(r'''
import 'dart:ffi';
final class MyStruct extends Struct {
@Array.multi([0, 2])
external Array<Array<Int8>> arr;
}
''', [error(FfiCode.NON_POSITIVE_ARRAY_DIMENSION, 74, 1)]);
}
test_variable_negativeDimension() async {
await assertErrorsInCode(r'''
import 'dart:ffi';
final class MyStruct extends Struct {
@Array.variable(-1)
external Array<Array<Int8>> arr;
}
''', [error(FfiCode.NON_POSITIVE_ARRAY_DIMENSION, 76, 2)]);
}
test_variable_positiveDimension() async {
await assertNoErrorsInCode(r'''
import 'dart:ffi';
final class MyStruct extends Struct {
@Array.variable(1)
external Array<Array<Int8>> arr;
}
''');
}
test_variable_valid() async {
await assertNoErrorsInCode(r'''
import 'dart:ffi';
final class MyStruct extends Struct {
@Array.variable()
external Array<Int8> arr;
}
''');
}
test_variable_zeroDimension() async {
await assertErrorsInCode(r'''
import 'dart:ffi';
final class MyStruct extends Struct {
@Array.variable(0)
external Array<Array<Int8>> arr;
}
''', [error(FfiCode.NON_POSITIVE_ARRAY_DIMENSION, 76, 1)]);
}
test_variableMulti_negativeDimension() async {
await assertErrorsInCode(r'''
import 'dart:ffi';
final class MyStruct extends Struct {
@Array.variableMulti(variableDimension: -1, [2, 2])
external Array<Array<Array<Int8>>> arr;
}
''', [error(FfiCode.NEGATIVE_VARIABLE_DIMENSION, 100, 2)]);
}
test_variableMulti_positiveDimension() async {
await assertNoErrorsInCode(r'''
import 'dart:ffi';
final class MyStruct extends Struct {
@Array.variableMulti(variableDimension: 1, [2, 2])
external Array<Array<Array<Int8>>> arr;
}
''');
}
test_variableMulti_valid() async {
await assertNoErrorsInCode(r'''
import 'dart:ffi';
final class MyStruct extends Struct {
@Array.variableMulti([2, 2])
external Array<Array<Array<Int8>>> arr;
}
''');
}
test_variableMulti_zeroDimension() async {
await assertNoErrorsInCode(r'''
import 'dart:ffi';
final class MyStruct extends Struct {
@Array.variableMulti(variableDimension: 0, [2, 2])
external Array<Array<Array<Int8>>> arr;
}
''');
}
test_variableWithVariableDimension_negativeDimension() async {
await assertErrorsInCode(r'''
import 'dart:ffi';
final class MyStruct extends Struct {
@Array.variableWithVariableDimension(-1)
external Array<Int8> arr;
}
''', [error(FfiCode.NEGATIVE_VARIABLE_DIMENSION, 97, 2)]);
}
test_variableWithVariableDimension_positiveDimension() async {
await assertNoErrorsInCode(r'''
import 'dart:ffi';
final class MyStruct extends Struct {
@Array.variableWithVariableDimension(1)
external Array<Int8> arr;
}
''');
}
test_variableWithVariableDimension_zeroDimension() async {
await assertNoErrorsInCode(r'''
import 'dart:ffi';
final class MyStruct extends Struct {
@Array.variableWithVariableDimension(0)
external Array<Int8> arr;
}
''');
}
}
@@ -308,6 +308,7 @@ import 'extra_positional_arguments_test.dart' as extra_positional_arguments;
import 'extra_size_annotation_carray_test.dart' as extra_size_annotation_carray;
import 'extraneous_modifier_test.dart' as extraneous_modifier;
import 'ffi_address_of_cast_test.dart' as ffi_addresss_of_cast_test;
import 'ffi_array_test.dart' as ffi_array_test;
import 'ffi_async_callback_test.dart' as ffi_async_callback_test;
import 'ffi_leaf_call_must_not_use_handle_test.dart'
as ffi_leaf_call_must_not_use_handle;
@@ -1128,6 +1129,7 @@ main() {
extra_size_annotation_carray.main();
extraneous_modifier.main();
ffi_addresss_of_cast_test.main();
ffi_array_test.main();
ffi_async_callback_test.main();
ffi_leaf_call_must_not_use_handle.main();
ffi_native_test.main();
+72 -2
View File
@@ -14424,6 +14424,75 @@ final class C extends Struct {
}
```
### negative_variable_dimension
_The variable dimension of a variable-length array must be non-negative._
#### Description
The analyzer produces this diagnostic in two cases.
The first is when the variable dimension given in an
`Array.variableWithVariableDimension` annotation is negative. The variable
dimension is the first argument in the annotation.
The second is when the variable dimension given in an
`Array.variableMulti` annotation is negative. The variable dimension is
specified in the `variableDimension` argument of the annotation.
For more information about FFI, see [C interop using dart:ffi][ffi].
#### Examples
The following code produces this diagnostic because a variable dimension
of `-1` was provided in the `Array.variableWithVariableDimension`
annotation:
```dart
import 'dart:ffi';
final class MyStruct extends Struct {
@Array.variableWithVariableDimension([!-1!])
external Array<Uint8> a0;
}
```
The following code produces this diagnostic because a variable dimension
of `-1` was provided in the `Array.variableMulti` annotation:
```dart
import 'dart:ffi';
final class MyStruct2 extends Struct {
@Array.variableMulti(variableDimension: [!-1!], [1, 2])
external Array<Array<Array<Uint8>>> a0;
}
```
#### Common fixes
Change the variable dimension with zero (`0`) or a positive number:
```dart
import 'dart:ffi';
final class MyStruct extends Struct {
@Array.variableWithVariableDimension(1)
external Array<Uint8> a0;
}
```
Change the variable dimension with zero (`0`) or a positive number:
```dart
import 'dart:ffi';
final class MyStruct2 extends Struct {
@Array.variableMulti(variableDimension: 1, [1, 2])
external Array<Array<Array<Uint8>>> a0;
}
```
### new_with_undefined_constructor_default
_The class '{0}' doesn't have an unnamed constructor._
@@ -15718,7 +15787,7 @@ For more information about FFI, see [C interop using dart:ffi][ffi].
#### Example
The following code produces this diagnostic because an array dimension of
`-1` was provided:
`-8` was provided:
```dart
import 'dart:ffi';
@@ -15742,7 +15811,8 @@ final class MyStruct extends Struct {
}
```
If this is a variable length inline array, change the annotation to `Array.variable()`:
If this is a variable length inline array, change the annotation to
`Array.variable()`:
```dart
import 'dart:ffi';
+1
View File
@@ -780,6 +780,7 @@ NamedMixinOverride/analyzerCode: Fail
NamedMixinOverride/example: Fail
NamedParametersInExtensionTypeDeclaration/analyzerCode: Fail
NativeClauseShouldBeAnnotation/example: Fail
NegativeVariableDimension/analyzerCode: Fail
NeverReachableSwitchDefaultError/analyzerCode: Fail
NeverReachableSwitchDefaultError/example: Fail
NeverReachableSwitchDefaultWarning/analyzerCode: Fail
+5
View File
@@ -5432,6 +5432,11 @@ NonNullAwareSpreadIsNull:
<int>[...null];
}
NegativeVariableDimension:
# Used by dart:ffi
problemMessage: "The variable dimension of a variable-length array must be non-negative."
external: test/ffi_test.dart
NonPositiveArrayDimensions:
# Used by dart:ffi
problemMessage: "Array dimensions must be positive numbers."
@@ -9,9 +9,9 @@ final class StructInlineArray extends ffi::Struct {
synthetic constructor •() → self::StructInlineArray
: super ffi::Struct::•()
;
@#C4
@#C3
external get a0() → ffi::Array<ffi::Uint8>;
@#C4
@#C3
external set a0(synthesized ffi::Array<ffi::Uint8> #externalFieldValue) → void;
}
static method main() → dynamic {}
@@ -19,8 +19,7 @@ static method main() → dynamic {}
constants {
#C1 = 8
#C2 = null
#C3 = false
#C4 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C1, dimension2:#C2, dimension3:#C2, dimension4:#C2, dimension5:#C2, dimensions:#C2, variableLength:#C3}
#C3 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C1, dimension2:#C2, dimension3:#C2, dimension4:#C2, dimension5:#C2, dimensions:#C2, variableDimension:#C2}
}
@@ -9,9 +9,9 @@ final class StructInlineArray extends ffi::Struct {
synthetic constructor •() → self::StructInlineArray
: super ffi::Struct::•()
;
@#C4
@#C3
external get a0() → ffi::Array<ffi::Uint8>;
@#C4
@#C3
external set a0(synthesized ffi::Array<ffi::Uint8> #externalFieldValue) → void;
}
static method main() → dynamic {}
@@ -19,8 +19,7 @@ static method main() → dynamic {}
constants {
#C1 = 8
#C2 = null
#C3 = false
#C4 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C1, dimension2:#C2, dimension3:#C2, dimension4:#C2, dimension5:#C2, dimensions:#C2, variableLength:#C3}
#C3 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C1, dimension2:#C2, dimension3:#C2, dimension4:#C2, dimension5:#C2, dimensions:#C2, variableDimension:#C2}
}
@@ -18,6 +18,6 @@ static method main() → dynamic
Extra constant evaluation status:
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///ffi_struct_inline_array.dart:10:4 -> InstanceConstant(const _ArraySize<NativeType>{_ArraySize.dimension1: 8, _ArraySize.dimension2: null, _ArraySize.dimension3: null, _ArraySize.dimension4: null, _ArraySize.dimension5: null, _ArraySize.dimensions: null, _ArraySize.variableLength: false})
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///ffi_struct_inline_array.dart:10:4 -> InstanceConstant(const _ArraySize<NativeType>{_ArraySize.dimension1: 8, _ArraySize.dimension2: null, _ArraySize.dimension3: null, _ArraySize.dimension4: null, _ArraySize.dimension5: null, _ArraySize.dimensions: null, _ArraySize.variableLength: false})
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///ffi_struct_inline_array.dart:10:4 -> InstanceConstant(const _ArraySize<NativeType>{_ArraySize.dimension1: 8, _ArraySize.dimension2: null, _ArraySize.dimension3: null, _ArraySize.dimension4: null, _ArraySize.dimension5: null, _ArraySize.dimensions: null, _ArraySize.variableDimension: null})
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///ffi_struct_inline_array.dart:10:4 -> InstanceConstant(const _ArraySize<NativeType>{_ArraySize.dimension1: 8, _ArraySize.dimension2: null, _ArraySize.dimension3: null, _ArraySize.dimension4: null, _ArraySize.dimension5: null, _ArraySize.dimensions: null, _ArraySize.variableDimension: null})
Extra constant evaluation: evaluated: 2, effectively constant: 2
@@ -7,7 +7,7 @@ import "dart:typed_data" as typ;
import "dart:ffi";
import "package:ffi/ffi.dart";
@#C8
@#C9
final class StructInlineArray extends ffi::Struct {
synthetic constructor •() → self::StructInlineArray
: super ffi::Struct::•()
@@ -15,22 +15,22 @@ final class StructInlineArray extends ffi::Struct {
constructor #fromTypedDataBase(synthesized core::Object #typedDataBase, synthesized core::int #offsetInBytes) → self::StructInlineArray
: super ffi::Struct::_fromTypedDataBase(#typedDataBase, #offsetInBytes)
;
@#C10
@#C11
constructor #fromTypedData(synthesized typ::TypedData #typedData, synthesized core::int #offset, synthesized core::int #sizeInBytes) → self::StructInlineArray
: super ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
;
@#C12
@#C10
@#C11
get a0() → ffi::Array<ffi::Uint8>
return new ffi::Array::_<ffi::Uint8>(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::StructInlineArray::a0#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C3, #C13);
return new ffi::Array::_<ffi::Uint8>(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::StructInlineArray::a0#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C3, #C4, #C13);
@#C12
@#C10
@#C11
set a0(synthesized ffi::Array<ffi::Uint8> #externalFieldValue) → void
return ffi::_memCopy(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::StructInlineArray::a0#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #externalFieldValue.{ffi::_Compound::_typedDataBase}{core::Object}, #externalFieldValue.{ffi::_Compound::_offsetInBytes}{core::int}, #C14.{core::List::[]}(ffi::_abi()){(core::int) → core::int});
@#C10
@#C11
static get a0#offsetOf() → core::int
return #C16.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C10
@#C11
static get #sizeOf() → core::int
return #C14.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
}
@@ -40,15 +40,15 @@ constants {
#C1 = "vm:ffi:struct-fields"
#C2 = TypeLiteralConstant(ffi::Uint8)
#C3 = 8
#C4 = ffi::_FfiInlineArray {elementType:#C2, length:#C3}
#C5 = <core::Type>[#C4]
#C6 = null
#C7 = ffi::_FfiStructLayout {fieldTypes:#C5, packing:#C6}
#C8 = core::pragma {name:#C1, options:#C7}
#C9 = "vm:prefer-inline"
#C10 = core::pragma {name:#C9, options:#C6}
#C11 = false
#C12 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C3, dimension2:#C6, dimension3:#C6, dimension4:#C6, dimension5:#C6, dimensions:#C6, variableLength:#C11}
#C4 = false
#C5 = ffi::_FfiInlineArray {elementType:#C2, length:#C3, variableLength:#C4}
#C6 = <core::Type>[#C5]
#C7 = null
#C8 = ffi::_FfiStructLayout {fieldTypes:#C6, packing:#C7}
#C9 = core::pragma {name:#C1, options:#C8}
#C10 = "vm:prefer-inline"
#C11 = core::pragma {name:#C10, options:#C7}
#C12 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C3, dimension2:#C7, dimension3:#C7, dimension4:#C7, dimension5:#C7, dimensions:#C7, variableDimension:#C7}
#C13 = <core::int>[]
#C14 = <core::int>[#C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3]
#C15 = 0
@@ -10,26 +10,25 @@ final class StructInlineArrayMultiDimensional extends ffi::Struct {
synthetic constructor •() → self::StructInlineArrayMultiDimensional
: super ffi::Struct::•()
;
@#C4
@#C3
external get a0() → ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>>;
@#C4
@#C3
external set a0(synthesized ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>> #externalFieldValue) → void;
}
static method main() → dynamic {
final ffi::Pointer<self::StructInlineArrayMultiDimensional> pointer = ffi::AllocatorAlloc|call<self::StructInlineArrayMultiDimensional>(#C5);
final ffi::Pointer<self::StructInlineArrayMultiDimensional> pointer = ffi::AllocatorAlloc|call<self::StructInlineArrayMultiDimensional>(#C4);
final self::StructInlineArrayMultiDimensional struct = ffi::StructPointer|get#ref<self::StructInlineArrayMultiDimensional>(pointer);
final ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>> array = struct.{self::StructInlineArrayMultiDimensional::a0}{ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>>};
final ffi::Array<ffi::Array<ffi::Uint8>> subArray = ffi::ArrayArray|[]<ffi::Array<ffi::Uint8>>(array, 0);
ffi::ArrayArray|[]=<ffi::Array<ffi::Uint8>>(array, 1, subArray);
#C5.{all::CallocAllocator::free}(pointer){(ffi::Pointer<ffi::NativeType>) → void};
#C4.{all::CallocAllocator::free}(pointer){(ffi::Pointer<ffi::NativeType>) → void};
}
constants {
#C1 = 2
#C2 = null
#C3 = false
#C4 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C1, dimension2:#C1, dimension3:#C1, dimension4:#C2, dimension5:#C2, dimensions:#C2, variableLength:#C3}
#C5 = all::CallocAllocator {}
#C3 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C1, dimension2:#C1, dimension3:#C1, dimension4:#C2, dimension5:#C2, dimensions:#C2, variableDimension:#C2}
#C4 = all::CallocAllocator {}
}
@@ -10,26 +10,25 @@ final class StructInlineArrayMultiDimensional extends ffi::Struct {
synthetic constructor •() → self::StructInlineArrayMultiDimensional
: super ffi::Struct::•()
;
@#C4
@#C3
external get a0() → ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>>;
@#C4
@#C3
external set a0(synthesized ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>> #externalFieldValue) → void;
}
static method main() → dynamic {
final ffi::Pointer<self::StructInlineArrayMultiDimensional> pointer = ffi::AllocatorAlloc|call<self::StructInlineArrayMultiDimensional>(#C5);
final ffi::Pointer<self::StructInlineArrayMultiDimensional> pointer = ffi::AllocatorAlloc|call<self::StructInlineArrayMultiDimensional>(#C4);
final self::StructInlineArrayMultiDimensional struct = ffi::StructPointer|get#ref<self::StructInlineArrayMultiDimensional>(pointer);
final ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>> array = struct.{self::StructInlineArrayMultiDimensional::a0}{ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>>};
final ffi::Array<ffi::Array<ffi::Uint8>> subArray = ffi::ArrayArray|[]<ffi::Array<ffi::Uint8>>(array, 0);
ffi::ArrayArray|[]=<ffi::Array<ffi::Uint8>>(array, 1, subArray);
#C5.{all::CallocAllocator::free}(pointer){(ffi::Pointer<ffi::NativeType>) → void};
#C4.{all::CallocAllocator::free}(pointer){(ffi::Pointer<ffi::NativeType>) → void};
}
constants {
#C1 = 2
#C2 = null
#C3 = false
#C4 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C1, dimension2:#C1, dimension3:#C1, dimension4:#C2, dimension5:#C2, dimensions:#C2, variableLength:#C3}
#C5 = all::CallocAllocator {}
#C3 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C1, dimension2:#C1, dimension3:#C1, dimension4:#C2, dimension5:#C2, dimensions:#C2, variableDimension:#C2}
#C4 = all::CallocAllocator {}
}
@@ -18,6 +18,6 @@ static method main() → dynamic
Extra constant evaluation status:
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///ffi_struct_inline_array_multi_dimensional.dart:10:4 -> InstanceConstant(const _ArraySize<NativeType>{_ArraySize.dimension1: 2, _ArraySize.dimension2: 2, _ArraySize.dimension3: 2, _ArraySize.dimension4: null, _ArraySize.dimension5: null, _ArraySize.dimensions: null, _ArraySize.variableLength: false})
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///ffi_struct_inline_array_multi_dimensional.dart:10:4 -> InstanceConstant(const _ArraySize<NativeType>{_ArraySize.dimension1: 2, _ArraySize.dimension2: 2, _ArraySize.dimension3: 2, _ArraySize.dimension4: null, _ArraySize.dimension5: null, _ArraySize.dimensions: null, _ArraySize.variableLength: false})
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///ffi_struct_inline_array_multi_dimensional.dart:10:4 -> InstanceConstant(const _ArraySize<NativeType>{_ArraySize.dimension1: 2, _ArraySize.dimension2: 2, _ArraySize.dimension3: 2, _ArraySize.dimension4: null, _ArraySize.dimension5: null, _ArraySize.dimensions: null, _ArraySize.variableDimension: null})
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///ffi_struct_inline_array_multi_dimensional.dart:10:4 -> InstanceConstant(const _ArraySize<NativeType>{_ArraySize.dimension1: 2, _ArraySize.dimension2: 2, _ArraySize.dimension3: 2, _ArraySize.dimension4: null, _ArraySize.dimension5: null, _ArraySize.dimensions: null, _ArraySize.variableDimension: null})
Extra constant evaluation: evaluated: 2, effectively constant: 2
@@ -8,7 +8,7 @@ import "package:ffi/src/allocation.dart" as all;
import "dart:ffi";
import "package:ffi/ffi.dart";
@#C8
@#C9
final class StructInlineArrayMultiDimensional extends ffi::Struct {
synthetic constructor •() → self::StructInlineArrayMultiDimensional
: super ffi::Struct::•()
@@ -16,22 +16,22 @@ final class StructInlineArrayMultiDimensional extends ffi::Struct {
constructor #fromTypedDataBase(synthesized core::Object #typedDataBase, synthesized core::int #offsetInBytes) → self::StructInlineArrayMultiDimensional
: super ffi::Struct::_fromTypedDataBase(#typedDataBase, #offsetInBytes)
;
@#C10
@#C11
constructor #fromTypedData(synthesized typ::TypedData #typedData, synthesized core::int #offset, synthesized core::int #sizeInBytes) → self::StructInlineArrayMultiDimensional
: super ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
;
@#C13
@#C10
@#C11
get a0() → ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>>
return new ffi::Array::_<ffi::Array<ffi::Array<ffi::Uint8>>>(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::StructInlineArrayMultiDimensional::a0#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C11, #C14);
return new ffi::Array::_<ffi::Array<ffi::Array<ffi::Uint8>>>(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::StructInlineArrayMultiDimensional::a0#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C12, #C4, #C14);
@#C13
@#C10
@#C11
set a0(synthesized ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>> #externalFieldValue) → void
return ffi::_memCopy(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::StructInlineArrayMultiDimensional::a0#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #externalFieldValue.{ffi::_Compound::_typedDataBase}{core::Object}, #externalFieldValue.{ffi::_Compound::_offsetInBytes}{core::int}, #C15.{core::List::[]}(ffi::_abi()){(core::int) → core::int});
@#C10
@#C11
static get a0#offsetOf() → core::int
return #C17.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C10
@#C11
static get #sizeOf() → core::int
return #C15.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
}
@@ -46,7 +46,7 @@ static method main() → dynamic {
synthesized core::int #singleElementSize = #C19;
synthesized core::int #elementSize = #singleElementSize.{core::num::*}(#array.{ffi::Array::_nestedDimensionsFlattened}{core::int}){(core::num) → core::num};
synthesized core::int #offset = #elementSize.{core::num::*}(#index){(core::num) → core::num};
} =>new ffi::Array::_<ffi::Array<ffi::Uint8>>(#array.{ffi::_Compound::_typedDataBase}{core::Object}, #array.{ffi::_Compound::_offsetInBytes}{core::int}.{core::num::+}(#offset){(core::num) → core::num}, #array.{ffi::Array::_nestedDimensionsFirst}{core::int}, #array.{ffi::Array::_nestedDimensionsRest}{core::List<core::int>});
} =>new ffi::Array::_<ffi::Array<ffi::Uint8>>(#array.{ffi::_Compound::_typedDataBase}{core::Object}, #array.{ffi::_Compound::_offsetInBytes}{core::int}.{core::num::+}(#offset){(core::num) → core::num}, #array.{ffi::Array::_nestedDimensionsFirst}{core::int}, #array.{ffi::Array::_variableLength}{core::bool}, #array.{ffi::Array::_nestedDimensionsRest}{core::List<core::int>});
block {
synthesized ffi::Array<dynamic> #array = array!;
synthesized core::int #index = 1!;
@@ -63,17 +63,17 @@ constants {
#C1 = "vm:ffi:struct-fields"
#C2 = TypeLiteralConstant(ffi::Uint8)
#C3 = 8
#C4 = ffi::_FfiInlineArray {elementType:#C2, length:#C3}
#C5 = <core::Type>[#C4]
#C6 = null
#C7 = ffi::_FfiStructLayout {fieldTypes:#C5, packing:#C6}
#C8 = core::pragma {name:#C1, options:#C7}
#C9 = "vm:prefer-inline"
#C10 = core::pragma {name:#C9, options:#C6}
#C11 = 2
#C12 = false
#C13 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C11, dimension2:#C11, dimension3:#C11, dimension4:#C6, dimension5:#C6, dimensions:#C6, variableLength:#C12}
#C14 = <core::int>[#C11, #C11]
#C4 = false
#C5 = ffi::_FfiInlineArray {elementType:#C2, length:#C3, variableLength:#C4}
#C6 = <core::Type>[#C5]
#C7 = null
#C8 = ffi::_FfiStructLayout {fieldTypes:#C6, packing:#C7}
#C9 = core::pragma {name:#C1, options:#C8}
#C10 = "vm:prefer-inline"
#C11 = core::pragma {name:#C10, options:#C7}
#C12 = 2
#C13 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C12, dimension2:#C12, dimension3:#C12, dimension4:#C7, dimension5:#C7, dimensions:#C7, variableDimension:#C7}
#C14 = <core::int>[#C12, #C12]
#C15 = <core::int>[#C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3]
#C16 = 0
#C17 = <core::int>[#C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16]
@@ -84,7 +84,7 @@ constants {
Extra constant evaluation status:
Evaluated: NullCheck @ org-dartlang-testcase:///ffi_struct_inline_array_multi_dimensional.dart:18:25 -> IntConstant(0)
Evaluated: NullCheck @ org-dartlang-testcase:///ffi_struct_inline_array_multi_dimensional.dart:19:8 -> IntConstant(1)
Extra constant evaluation: evaluated: 91, effectively constant: 2
Extra constant evaluation: evaluated: 93, effectively constant: 2
Constructor coverage from constants:
@@ -14,6 +14,7 @@ import 'package:front_end/src/codes/cfe_codes.dart'
messageFfiLeafCallMustNotReturnHandle,
messageFfiLeafCallMustNotTakeHandle,
messageFfiVariableLengthArrayNotLast,
messageNegativeVariableDimension,
messageNonPositiveArrayDimensions,
templateFfiSizeAnnotation,
templateFfiSizeAnnotationDimensions,
@@ -224,7 +225,7 @@ class FfiTransformer extends Transformer {
final Field arraySizeDimension4Field;
final Field arraySizeDimension5Field;
final Field arraySizeDimensionsField;
final Field arraySizeVariableLengthField;
final Field arraySizeVariableDimensionField;
final Class pointerClass;
final Class compoundClass;
final Class structClass;
@@ -241,6 +242,7 @@ class FfiTransformer extends Transformer {
final Class ffiInlineArrayClass;
final Field ffiInlineArrayElementTypeField;
final Field ffiInlineArrayLengthField;
final Field ffiInlineArrayVariableLengthField;
final Class packedClass;
final Field packedMemberAlignmentField;
final Procedure allocateMethod;
@@ -286,6 +288,7 @@ class FfiTransformer extends Transformer {
final Field compoundTypedDataBaseField;
final Field compoundOffsetInBytesField;
final Field arraySizeField;
final Field arrayVariableLengthField;
final Field arrayNestedDimensionsField;
final Procedure arrayCheckIndex;
final Procedure arrayNestedDimensionsFlattened;
@@ -415,8 +418,8 @@ class FfiTransformer extends Transformer {
index.getField('dart:ffi', '_ArraySize', 'dimension5'),
arraySizeDimensionsField =
index.getField('dart:ffi', '_ArraySize', 'dimensions'),
arraySizeVariableLengthField =
index.getField('dart:ffi', '_ArraySize', 'variableLength'),
arraySizeVariableDimensionField =
index.getField('dart:ffi', '_ArraySize', 'variableDimension'),
pointerClass = index.getClass('dart:ffi', 'Pointer'),
compoundClass = index.getClass('dart:ffi', '_Compound'),
structClass = index.getClass('dart:ffi', 'Struct'),
@@ -442,6 +445,8 @@ class FfiTransformer extends Transformer {
index.getField('dart:ffi', '_FfiInlineArray', 'elementType'),
ffiInlineArrayLengthField =
index.getField('dart:ffi', '_FfiInlineArray', 'length'),
ffiInlineArrayVariableLengthField =
index.getField('dart:ffi', '_FfiInlineArray', 'variableLength'),
packedClass = index.getClass('dart:ffi', 'Packed'),
packedMemberAlignmentField =
index.getField('dart:ffi', 'Packed', 'memberAlignment'),
@@ -458,6 +463,8 @@ class FfiTransformer extends Transformer {
compoundOffsetInBytesField =
index.getField('dart:ffi', '_Compound', '_offsetInBytes'),
arraySizeField = index.getField('dart:ffi', 'Array', '_size'),
arrayVariableLengthField =
index.getField('dart:ffi', 'Array', '_variableLength'),
arrayNestedDimensionsField =
index.getField('dart:ffi', 'Array', '_nestedDimensions'),
arrayCheckIndex =
@@ -1025,10 +1032,19 @@ class FfiTransformer extends Transformer {
node.fileUri,
);
}
return dimensions; // Variable length single dimension.
}
for (var dimension in dimensions) {
if (dimension <= 0) {
for (var i = 0; i < dimensions.length; i++) {
// First dimension is variable.
if (i == 0 && variableLength) {
// Variable dimension can't be negative.
if (dimensions[0] < 0) {
diagnosticReporter.report(messageNegativeVariableDimension,
node.fileOffset, node.name.text.length, node.fileUri);
}
continue;
}
if (dimensions[i] <= 0) {
diagnosticReporter.report(messageNonPositiveArrayDimensions,
node.fileOffset, node.name.text.length, node.fileUri);
success = false;
@@ -1062,18 +1078,18 @@ class FfiTransformer extends Transformer {
/// Reads the dimensions from a constant instance of `_ArraySize`.
(List<int>, bool) _arraySize(InstanceConstant constant) {
final variableLength =
(constant.fieldValues[arraySizeVariableLengthField.fieldReference]
as BoolConstant)
.value;
final variableDimension =
constant.fieldValues[arraySizeVariableDimensionField.fieldReference];
final variableLength = variableDimension is IntConstant;
final dimensions =
constant.fieldValues[arraySizeDimensionsField.fieldReference];
if (dimensions != null) {
if (dimensions is ListConstant) {
final result =
dimensions.entries.whereType<IntConstant>().map((e) => e.value);
return ([if (variableLength) 0, ...result], variableLength);
}
if (dimensions is ListConstant) {
final result =
dimensions.entries.whereType<IntConstant>().map((e) => e.value);
return (
[if (variableLength) variableDimension.value, ...result],
variableLength,
);
}
final dimensionFields = [
arraySizeDimension1Field,
@@ -683,6 +683,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
final sizeAnnotations = getArraySizeAnnotations(m).toList();
if (sizeAnnotations.length == 1) {
final arrayDimensions = sizeAnnotations.single.$1;
final variableLength = sizeAnnotations.single.$2;
if (this.arrayDimensions(dartType) == arrayDimensions.length) {
final elementType = arraySingleElementType(dartType);
if (elementType is! InterfaceType) {
@@ -691,7 +692,8 @@ class _FfiDefinitionTransformer extends FfiTransformer {
} else {
type = NativeTypeCfe(this, dartType,
compoundCache: compoundCache,
arrayDimensions: arrayDimensions);
arrayDimensions: arrayDimensions,
variableLength: variableLength);
}
} else {
type = InvalidNativeTypeCfe("Invalid array dimensions.");
@@ -903,7 +905,12 @@ class _FfiDefinitionTransformer extends FfiTransformer {
fieldType.fieldValues[ffiInlineArrayLengthField.fieldReference]
as IntConstant;
final arrayLength = arrayLengthConstant.value;
members.add(ArrayNativeTypeCfe(singleElementType, arrayLength));
final variableLengthConstant = fieldType
.fieldValues[ffiInlineArrayVariableLengthField.fieldReference]
as BoolConstant;
final variableLength = variableLengthConstant.value;
members.add(
ArrayNativeTypeCfe(singleElementType, arrayLength, variableLength));
}
}
if (compoundClass.superclass == structClass) {
@@ -767,7 +767,8 @@ class FfiNativeTransformer extends FfiTransformer {
final dimensions = ensureArraySizeAnnotation(node, ffiType, false);
return (
ffiType,
NativeTypeCfe.withoutLayout(this, dartType, arrayDimensions: dimensions)
NativeTypeCfe.withoutLayout(this, dartType,
arrayDimensions: dimensions, variableLength: false)
);
}
@@ -22,13 +22,14 @@ sealed class NativeTypeCfe {
FfiTransformer transformer,
DartType dartType, {
List<int>? arrayDimensions,
bool? variableLength,
}) {
if (transformer.isStructOrUnionSubtype(dartType)) {
return ReferencedCompoundSubtypeCfe(
(dartType as InterfaceType).classNode);
} else {
return NativeTypeCfe(transformer, dartType,
arrayDimensions: arrayDimensions);
arrayDimensions: arrayDimensions, variableLength: variableLength);
}
}
@@ -36,6 +37,7 @@ sealed class NativeTypeCfe {
FfiTransformer transformer,
DartType dartType, {
List<int>? arrayDimensions,
bool? variableLength,
Map<Class, NativeTypeCfe> compoundCache = const {},
bool alreadyInAbiSpecificType = false,
}) {
@@ -62,13 +64,17 @@ sealed class NativeTypeCfe {
if (arrayDimensions.isEmpty) {
throw "Must have a size for this array dimension.";
}
if (variableLength == null) {
throw "Must have variable length for ArrayType.";
}
final elementType = transformer.arraySingleElementType(dartType);
final elementCfeType =
NativeTypeCfe(transformer, elementType, compoundCache: compoundCache);
final elementCfeType = NativeTypeCfe(transformer, elementType,
compoundCache: compoundCache, variableLength: variableLength);
if (elementCfeType is InvalidNativeTypeCfe) {
return elementCfeType;
}
return ArrayNativeTypeCfe.multi(elementCfeType, arrayDimensions);
return ArrayNativeTypeCfe.multi(
elementCfeType, arrayDimensions, variableLength);
}
if (transformer.isAbiSpecificIntegerSubtype(dartType)) {
final clazz = (dartType as InterfaceType).classNode;
@@ -741,17 +747,21 @@ class ReferencedCompoundSubtypeCfe extends NativeTypeCfe
class ArrayNativeTypeCfe extends NativeTypeCfe {
final NativeTypeCfe elementType;
final int length;
final bool variableLength;
ArrayNativeTypeCfe(this.elementType, this.length) : super._();
ArrayNativeTypeCfe(this.elementType, this.length, this.variableLength)
: super._();
factory ArrayNativeTypeCfe.multi(
NativeTypeCfe elementType, List<int> dimensions) {
NativeTypeCfe elementType, List<int> dimensions, bool variableLength) {
if (dimensions.length == 1) {
return ArrayNativeTypeCfe(elementType, dimensions.single);
return ArrayNativeTypeCfe(elementType, dimensions.single, variableLength);
}
return ArrayNativeTypeCfe(
ArrayNativeTypeCfe.multi(elementType, dimensions.sublist(1)),
ArrayNativeTypeCfe.multi(
elementType, dimensions.sublist(1), variableLength),
dimensions.first,
variableLength,
);
}
@@ -798,7 +808,9 @@ class ArrayNativeTypeCfe extends NativeTypeCfe {
transformer.ffiInlineArrayElementTypeField.fieldReference:
singleElementType.generateConstant(transformer),
transformer.ffiInlineArrayLengthField.fieldReference:
IntConstant(dimensionsFlattened)
IntConstant(dimensionsFlattened),
transformer.ffiInlineArrayVariableLengthField.fieldReference:
BoolConstant(variableLength),
},
);
@@ -830,6 +842,7 @@ class ArrayNativeTypeCfe extends NativeTypeCfe {
typedDataBase,
offsetInBytes,
ConstantExpression(IntConstant(length)),
ConstantExpression(BoolConstant(variableLength)),
transformer.intListConstantExpression(
nestedDimensions, Nullability.nonNullable)
],
@@ -1217,6 +1217,13 @@ mixin _FfiUseSiteTransformer on FfiTransformer {
arrayNestedDimensionsFirst.name,
interfaceTarget: arrayNestedDimensionsFirst,
resultType: arrayNestedDimensionsFirst.getterType),
InstanceGet(
InstanceAccessKind.Instance,
VariableGet(arrayVar),
arrayVariableLengthField.name,
interfaceTarget: arrayVariableLengthField,
resultType: arrayVariableLengthField.type,
),
InstanceGet(InstanceAccessKind.Instance, VariableGet(arrayVar),
arrayNestedDimensionsRest.name,
interfaceTarget: arrayNestedDimensionsRest,
@@ -46,7 +46,7 @@ final class WCharStruct extends ffi::Struct {
static get #sizeOf() → core::int
return #C22.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
}
@#C27
@#C28
final class WCharArrayStruct extends ffi::Struct {
constructor #fromTypedDataBase([@vm.inferred-arg-type.metadata=dart.ffi::Pointer] synthesized core::Object #typedDataBase) → self::WCharArrayStruct
: super ffi::Struct::_fromTypedDataBase(#typedDataBase)
@@ -56,7 +56,7 @@ final class WCharArrayStruct extends ffi::Struct {
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3]
@#C10
get a0() → ffi::Array<self::WChar>
return new ffi::Array::_<self::WChar>([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] this.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] [@vm.inferred-type.metadata=dart.core::_Smi (value: 0)] self::WCharArrayStruct::a0#offsetOf.{core::num::+}([@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C23, #C28);
return new ffi::Array::_<self::WChar>([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] this.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] [@vm.inferred-type.metadata=dart.core::_Smi (value: 0)] self::WCharArrayStruct::a0#offsetOf.{core::num::+}([@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C23, #C24, #C29);
[@vm.inferred-return-type.metadata=dart.core::_Smi (value: 0)]
[@vm.unboxing-info.metadata=()->i]
@@ -68,7 +68,7 @@ final class WCharArrayStruct extends ffi::Struct {
[@vm.unboxing-info.metadata=()->i]
@#C10
static get #sizeOf() → core::int
return #C31.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
return #C32.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
}
class _DummyAllocator extends core::Object implements ffi::Allocator /*hasConstConstructor*/ {
@@ -100,35 +100,35 @@ static method testSizeOf() → void {
[@vm.inferred-return-type.metadata=dart.core::Null? (value: null)]
static method testStoreLoad() → void {
final ffi::Pointer<self::WChar> p = let final core::int #t1 = [@vm.inferred-type.metadata=dart.core::_Smi] self::WChar::#sizeOf in [@vm.direct-call.metadata=#lib::_DummyAllocator.allocate] [@vm.inferred-type.metadata=dart.ffi::Pointer (skip check)] #C32.{ffi::Allocator::allocate}<self::WChar>(){(core::int, {alignment: core::int?}) → ffi::Pointer<self::WChar>};
final ffi::Pointer<self::WChar> p = let final core::int #t1 = [@vm.inferred-type.metadata=dart.core::_Smi] self::WChar::#sizeOf in [@vm.direct-call.metadata=#lib::_DummyAllocator.allocate] [@vm.inferred-type.metadata=dart.ffi::Pointer (skip check)] #C33.{ffi::Allocator::allocate}<self::WChar>(){(core::int, {alignment: core::int?}) → ffi::Pointer<self::WChar>};
ffi::_storeAbiSpecificInt<self::WChar>(p, #C19, 10);
core::print([@vm.inferred-type.metadata=int] ffi::_loadAbiSpecificInt<self::WChar>(p, #C19));
[@vm.direct-call.metadata=#lib::_DummyAllocator.free] [@vm.inferred-type.metadata=!? (skip check)] #C32.{self::_DummyAllocator::free}(){(ffi::Pointer<ffi::NativeType>) → void};
[@vm.direct-call.metadata=#lib::_DummyAllocator.free] [@vm.inferred-type.metadata=!? (skip check)] #C33.{self::_DummyAllocator::free}(){(ffi::Pointer<ffi::NativeType>) → void};
}
[@vm.inferred-return-type.metadata=dart.core::Null? (value: null)]
static method testStoreLoadIndexed() → void {
final ffi::Pointer<self::WChar> p = let final core::num #t2 = [@vm.direct-call.metadata=dart.core::_IntegerImplementation.*] [@vm.inferred-type.metadata=int (skip check)] 2.{core::num::*}([@vm.inferred-type.metadata=dart.core::_Smi] self::WChar::#sizeOf){(core::num) → core::num} in [@vm.direct-call.metadata=#lib::_DummyAllocator.allocate] [@vm.inferred-type.metadata=dart.ffi::Pointer (skip check)] #C32.{ffi::Allocator::allocate}<self::WChar>(){(core::int, {alignment: core::int?}) → ffi::Pointer<self::WChar>};
final ffi::Pointer<self::WChar> p = let final core::num #t2 = [@vm.direct-call.metadata=dart.core::_IntegerImplementation.*] [@vm.inferred-type.metadata=int (skip check)] 2.{core::num::*}([@vm.inferred-type.metadata=dart.core::_Smi] self::WChar::#sizeOf){(core::num) → core::num} in [@vm.direct-call.metadata=#lib::_DummyAllocator.allocate] [@vm.inferred-type.metadata=dart.ffi::Pointer (skip check)] #C33.{ffi::Allocator::allocate}<self::WChar>(){(core::int, {alignment: core::int?}) → ffi::Pointer<self::WChar>};
ffi::_storeAbiSpecificIntAtIndex<self::WChar>(p, #C19, 0, 10);
ffi::_storeAbiSpecificIntAtIndex<self::WChar>(p, #C19, 1, 3);
core::print([@vm.inferred-type.metadata=int] ffi::_loadAbiSpecificIntAtIndex<self::WChar>(p, #C19, 0));
core::print([@vm.inferred-type.metadata=int] ffi::_loadAbiSpecificIntAtIndex<self::WChar>(p, #C19, 1));
[@vm.direct-call.metadata=#lib::_DummyAllocator.free] [@vm.inferred-type.metadata=!? (skip check)] #C32.{self::_DummyAllocator::free}(){(ffi::Pointer<ffi::NativeType>) → void};
[@vm.direct-call.metadata=#lib::_DummyAllocator.free] [@vm.inferred-type.metadata=!? (skip check)] #C33.{self::_DummyAllocator::free}(){(ffi::Pointer<ffi::NativeType>) → void};
}
[@vm.inferred-return-type.metadata=dart.core::Null? (value: null)]
static method testStruct() → void {
final ffi::Pointer<self::WCharStruct> p = let final core::int #t3 = [@vm.inferred-type.metadata=dart.core::_Smi] self::WCharStruct::#sizeOf in [@vm.direct-call.metadata=#lib::_DummyAllocator.allocate] [@vm.inferred-type.metadata=dart.ffi::Pointer (skip check)] #C32.{ffi::Allocator::allocate}<self::WCharStruct>(){(core::int, {alignment: core::int?}) → ffi::Pointer<self::WCharStruct>};
final ffi::Pointer<self::WCharStruct> p = let final core::int #t3 = [@vm.inferred-type.metadata=dart.core::_Smi] self::WCharStruct::#sizeOf in [@vm.direct-call.metadata=#lib::_DummyAllocator.allocate] [@vm.inferred-type.metadata=dart.ffi::Pointer (skip check)] #C33.{ffi::Allocator::allocate}<self::WCharStruct>(){(core::int, {alignment: core::int?}) → ffi::Pointer<self::WCharStruct>};
[@vm.direct-call.metadata=#lib::WCharStruct.a0] [@vm.inferred-type.metadata=!? (skip check)] new self::WCharStruct::#fromTypedDataBase(_in::unsafeCast<ffi::Pointer<self::WCharStruct>>(p)).{self::WCharStruct::a0} = 1;
core::print([@vm.direct-call.metadata=#lib::WCharStruct.a0] [@vm.inferred-type.metadata=int] new self::WCharStruct::#fromTypedDataBase(_in::unsafeCast<ffi::Pointer<self::WCharStruct>>(p)).{self::WCharStruct::a0}{core::int});
[@vm.direct-call.metadata=#lib::WCharStruct.a0] [@vm.inferred-type.metadata=!? (skip check)] new self::WCharStruct::#fromTypedDataBase(_in::unsafeCast<ffi::Pointer<self::WCharStruct>>(p)).{self::WCharStruct::a0} = 2;
core::print([@vm.direct-call.metadata=#lib::WCharStruct.a0] [@vm.inferred-type.metadata=int] new self::WCharStruct::#fromTypedDataBase(_in::unsafeCast<ffi::Pointer<self::WCharStruct>>(p)).{self::WCharStruct::a0}{core::int});
[@vm.direct-call.metadata=#lib::_DummyAllocator.free] [@vm.inferred-type.metadata=!? (skip check)] #C32.{self::_DummyAllocator::free}(){(ffi::Pointer<ffi::NativeType>) → void};
[@vm.direct-call.metadata=#lib::_DummyAllocator.free] [@vm.inferred-type.metadata=!? (skip check)] #C33.{self::_DummyAllocator::free}(){(ffi::Pointer<ffi::NativeType>) → void};
}
[@vm.inferred-return-type.metadata=dart.core::Null? (value: null)]
static method testInlineArray() → void {
final ffi::Pointer<self::WCharArrayStruct> p = let final core::int #t4 = [@vm.inferred-type.metadata=dart.core::_Smi] self::WCharArrayStruct::#sizeOf in [@vm.direct-call.metadata=#lib::_DummyAllocator.allocate] [@vm.inferred-type.metadata=dart.ffi::Pointer (skip check)] #C32.{ffi::Allocator::allocate}<self::WCharArrayStruct>(){(core::int, {alignment: core::int?}) → ffi::Pointer<self::WCharArrayStruct>};
final ffi::Pointer<self::WCharArrayStruct> p = let final core::int #t4 = [@vm.inferred-type.metadata=dart.core::_Smi] self::WCharArrayStruct::#sizeOf in [@vm.direct-call.metadata=#lib::_DummyAllocator.allocate] [@vm.inferred-type.metadata=dart.ffi::Pointer (skip check)] #C33.{ffi::Allocator::allocate}<self::WCharArrayStruct>(){(core::int, {alignment: core::int?}) → ffi::Pointer<self::WCharArrayStruct>};
final ffi::Array<self::WChar> array = [@vm.direct-call.metadata=#lib::WCharArrayStruct.a0] [@vm.inferred-type.metadata=dart.ffi::Array<#lib::WChar>] new self::WCharArrayStruct::#fromTypedDataBase(_in::unsafeCast<ffi::Pointer<self::WCharArrayStruct>>(p)).{self::WCharArrayStruct::a0}{ffi::Array<self::WChar>};
for (core::int i = 0; [@vm.direct-call.metadata=dart.core::_IntegerImplementation.<] [@vm.inferred-type.metadata=dart.core::bool (skip check)] i.{core::num::<}(100){(core::num) → core::bool}; i = [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}(1){(core::num) → core::int}) {
block {
@@ -144,7 +144,7 @@ static method testInlineArray() → void {
[@vm.direct-call.metadata=dart.ffi::Array._checkIndex] [@vm.inferred-type.metadata=!? (skip check)] #array.{ffi::Array::_checkIndex}(#index){(core::int) → void};
} =>[@vm.inferred-type.metadata=int] ffi::_loadAbiSpecificIntAtIndex<self::WChar>([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] #array.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] #array.{ffi::_Compound::_offsetInBytes}{core::int}, #index));
}
[@vm.direct-call.metadata=#lib::_DummyAllocator.free] [@vm.inferred-type.metadata=!? (skip check)] #C32.{self::_DummyAllocator::free}(){(ffi::Pointer<ffi::NativeType>) → void};
[@vm.direct-call.metadata=#lib::_DummyAllocator.free] [@vm.inferred-type.metadata=!? (skip check)] #C33.{self::_DummyAllocator::free}(){(ffi::Pointer<ffi::NativeType>) → void};
}
constants {
#C1 = "vm:ffi:abi-specific-mapping"
@@ -170,13 +170,14 @@ constants {
#C21 = 8
#C22 = <core::int>[#C21, #C21, #C21, #C21, #C21, #C21, #C21, #C21, #C21, #C21, #C21, #C21, #C21, #C21, #C21, #C21, #C21, #C21, #C21, #C11, #C11, #C11]
#C23 = 100
#C24 = ffi::_FfiInlineArray {elementType:#C15, length:#C23}
#C25 = <core::Type>[#C24]
#C26 = ffi::_FfiStructLayout {fieldTypes:#C25, packing:#C9}
#C27 = core::pragma {name:#C14, options:#C26}
#C28 = <core::int>[]
#C29 = 400
#C30 = 200
#C31 = <core::int>[#C29, #C29, #C29, #C29, #C29, #C29, #C29, #C29, #C29, #C29, #C29, #C29, #C29, #C29, #C29, #C29, #C29, #C29, #C29, #C30, #C30, #C30]
#C32 = self::_DummyAllocator {}
#C24 = false
#C25 = ffi::_FfiInlineArray {elementType:#C15, length:#C23, variableLength:#C24}
#C26 = <core::Type>[#C25]
#C27 = ffi::_FfiStructLayout {fieldTypes:#C26, packing:#C9}
#C28 = core::pragma {name:#C14, options:#C27}
#C29 = <core::int>[]
#C30 = 400
#C31 = 200
#C32 = <core::int>[#C30, #C30, #C30, #C30, #C30, #C30, #C30, #C30, #C30, #C30, #C30, #C30, #C30, #C30, #C30, #C30, #C30, #C30, #C30, #C31, #C31, #C31]
#C33 = self::_DummyAllocator {}
}
@@ -54,7 +54,7 @@ final class WCharStruct extends ffi::Struct {
static get #sizeOf() → core::int
return #C77.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
}
@#C82
@#C83
final class WCharArrayStruct extends ffi::Struct {
synthetic constructor •() → self::WCharArrayStruct
: super ffi::Struct::•()
@@ -69,7 +69,7 @@ final class WCharArrayStruct extends ffi::Struct {
@#C84
@#C67
get a0() → ffi::Array<self::WChar>
return new ffi::Array::_<self::WChar>(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::WCharArrayStruct::a0#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C78, #C85);
return new ffi::Array::_<self::WChar>(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::WCharArrayStruct::a0#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C78, #C79, #C85);
@#C84
@#C67
set a0(synthesized ffi::Array<self::WChar> #externalFieldValue) → void
@@ -224,12 +224,12 @@ constants {
#C76 = 8
#C77 = <core::int>[#C76, #C76, #C76, #C76, #C76, #C76, #C76, #C76, #C76, #C76, #C76, #C76, #C76, #C76, #C76, #C76, #C76, #C76, #C76, #C41, #C41, #C41]
#C78 = 100
#C79 = ffi::_FfiInlineArray {elementType:#C70, length:#C78}
#C80 = <core::Type>[#C79]
#C81 = ffi::_FfiStructLayout {fieldTypes:#C80, packing:#C66}
#C82 = core::pragma {name:#C69, options:#C81}
#C83 = false
#C84 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C78, dimension2:#C66, dimension3:#C66, dimension4:#C66, dimension5:#C66, dimensions:#C66, variableLength:#C83}
#C79 = false
#C80 = ffi::_FfiInlineArray {elementType:#C70, length:#C78, variableLength:#C79}
#C81 = <core::Type>[#C80]
#C82 = ffi::_FfiStructLayout {fieldTypes:#C81, packing:#C66}
#C83 = core::pragma {name:#C69, options:#C82}
#C84 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C78, dimension2:#C66, dimension3:#C66, dimension4:#C66, dimension5:#C66, dimensions:#C66, variableDimension:#C66}
#C85 = <core::int>[]
#C86 = 400
#C87 = 200
@@ -46,7 +46,7 @@ final class IncompleteStruct extends ffi::Struct {
static get #sizeOf() → core::int
return [@vm.inferred-type.metadata=dart.core::_Smi (value: 8)] ffi::_checkAbiSpecificIntegerMapping<core::int>(#C19.{core::List::[]}(ffi::_abi()){(core::int) → core::int?});
}
@#C24
@#C25
final class IncompleteArrayStruct extends ffi::Struct {
constructor #fromTypedDataBase([@vm.inferred-arg-type.metadata=dart.ffi::Pointer] synthesized core::Object #typedDataBase) → self::IncompleteArrayStruct
: super ffi::Struct::_fromTypedDataBase(#typedDataBase)
@@ -56,7 +56,7 @@ final class IncompleteArrayStruct extends ffi::Struct {
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3]
@#C8
get a0() → ffi::Array<self::Incomplete>
return new ffi::Array::_<self::Incomplete>([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] this.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] [@vm.inferred-type.metadata=dart.core::_Smi (value: 0)] self::IncompleteArrayStruct::a0#offsetOf.{core::num::+}([@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C20, #C25);
return new ffi::Array::_<self::Incomplete>([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] this.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] [@vm.inferred-type.metadata=dart.core::_Smi (value: 0)] self::IncompleteArrayStruct::a0#offsetOf.{core::num::+}([@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C20, #C21, #C26);
[@vm.inferred-return-type.metadata=dart.core::_Smi (value: 0)]
[@vm.unboxing-info.metadata=()->i]
@@ -68,7 +68,7 @@ final class IncompleteArrayStruct extends ffi::Struct {
[@vm.unboxing-info.metadata=()->i]
@#C8
static get #sizeOf() → core::int
return [@vm.inferred-type.metadata=dart.core::_Smi (value: 400)] ffi::_checkAbiSpecificIntegerMapping<core::int>(#C27.{core::List::[]}(ffi::_abi()){(core::int) → core::int?});
return [@vm.inferred-type.metadata=dart.core::_Smi (value: 400)] ffi::_checkAbiSpecificIntegerMapping<core::int>(#C28.{core::List::[]}(ffi::_abi()){(core::int) → core::int?});
}
class _DummyAllocator extends core::Object implements ffi::Allocator /*hasConstConstructor*/ {
@@ -100,35 +100,35 @@ static method testSizeOf() → void {
[@vm.inferred-return-type.metadata=dart.core::Null? (value: null)]
static method testStoreLoad() → void {
final ffi::Pointer<self::Incomplete> p = let final core::int #t1 = [@vm.inferred-type.metadata=dart.core::_Smi (value: 4)] self::Incomplete::#sizeOf in [@vm.direct-call.metadata=#lib::_DummyAllocator.allocate] [@vm.inferred-type.metadata=dart.ffi::Pointer (skip check)] #C28.{ffi::Allocator::allocate}<self::Incomplete>(){(core::int, {alignment: core::int?}) → ffi::Pointer<self::Incomplete>};
final ffi::Pointer<self::Incomplete> p = let final core::int #t1 = [@vm.inferred-type.metadata=dart.core::_Smi (value: 4)] self::Incomplete::#sizeOf in [@vm.direct-call.metadata=#lib::_DummyAllocator.allocate] [@vm.inferred-type.metadata=dart.ffi::Pointer (skip check)] #C29.{ffi::Allocator::allocate}<self::Incomplete>(){(core::int, {alignment: core::int?}) → ffi::Pointer<self::Incomplete>};
ffi::_storeAbiSpecificInt<self::Incomplete>(p, #C16, 10);
core::print([@vm.inferred-type.metadata=int] ffi::_loadAbiSpecificInt<self::Incomplete>(p, #C16));
[@vm.direct-call.metadata=#lib::_DummyAllocator.free] [@vm.inferred-type.metadata=!? (skip check)] #C28.{self::_DummyAllocator::free}(){(ffi::Pointer<ffi::NativeType>) → void};
[@vm.direct-call.metadata=#lib::_DummyAllocator.free] [@vm.inferred-type.metadata=!? (skip check)] #C29.{self::_DummyAllocator::free}(){(ffi::Pointer<ffi::NativeType>) → void};
}
[@vm.inferred-return-type.metadata=dart.core::Null? (value: null)]
static method testStoreLoadIndexed() → void {
final ffi::Pointer<self::Incomplete> p = let final core::num #t2 = [@vm.direct-call.metadata=dart.core::_IntegerImplementation.*] [@vm.inferred-type.metadata=int (skip check)] 2.{core::num::*}([@vm.inferred-type.metadata=dart.core::_Smi (value: 4)] self::Incomplete::#sizeOf){(core::num) → core::num} in [@vm.direct-call.metadata=#lib::_DummyAllocator.allocate] [@vm.inferred-type.metadata=dart.ffi::Pointer (skip check)] #C28.{ffi::Allocator::allocate}<self::Incomplete>(){(core::int, {alignment: core::int?}) → ffi::Pointer<self::Incomplete>};
final ffi::Pointer<self::Incomplete> p = let final core::num #t2 = [@vm.direct-call.metadata=dart.core::_IntegerImplementation.*] [@vm.inferred-type.metadata=int (skip check)] 2.{core::num::*}([@vm.inferred-type.metadata=dart.core::_Smi (value: 4)] self::Incomplete::#sizeOf){(core::num) → core::num} in [@vm.direct-call.metadata=#lib::_DummyAllocator.allocate] [@vm.inferred-type.metadata=dart.ffi::Pointer (skip check)] #C29.{ffi::Allocator::allocate}<self::Incomplete>(){(core::int, {alignment: core::int?}) → ffi::Pointer<self::Incomplete>};
ffi::_storeAbiSpecificIntAtIndex<self::Incomplete>(p, #C16, 0, 10);
ffi::_storeAbiSpecificIntAtIndex<self::Incomplete>(p, #C16, 1, 3);
core::print([@vm.inferred-type.metadata=int] ffi::_loadAbiSpecificIntAtIndex<self::Incomplete>(p, #C16, 0));
core::print([@vm.inferred-type.metadata=int] ffi::_loadAbiSpecificIntAtIndex<self::Incomplete>(p, #C16, 1));
[@vm.direct-call.metadata=#lib::_DummyAllocator.free] [@vm.inferred-type.metadata=!? (skip check)] #C28.{self::_DummyAllocator::free}(){(ffi::Pointer<ffi::NativeType>) → void};
[@vm.direct-call.metadata=#lib::_DummyAllocator.free] [@vm.inferred-type.metadata=!? (skip check)] #C29.{self::_DummyAllocator::free}(){(ffi::Pointer<ffi::NativeType>) → void};
}
[@vm.inferred-return-type.metadata=dart.core::Null? (value: null)]
static method testStruct() → void {
final ffi::Pointer<self::IncompleteStruct> p = let final core::int #t3 = [@vm.inferred-type.metadata=dart.core::_Smi (value: 8)] self::IncompleteStruct::#sizeOf in [@vm.direct-call.metadata=#lib::_DummyAllocator.allocate] [@vm.inferred-type.metadata=dart.ffi::Pointer (skip check)] #C28.{ffi::Allocator::allocate}<self::IncompleteStruct>(){(core::int, {alignment: core::int?}) → ffi::Pointer<self::IncompleteStruct>};
final ffi::Pointer<self::IncompleteStruct> p = let final core::int #t3 = [@vm.inferred-type.metadata=dart.core::_Smi (value: 8)] self::IncompleteStruct::#sizeOf in [@vm.direct-call.metadata=#lib::_DummyAllocator.allocate] [@vm.inferred-type.metadata=dart.ffi::Pointer (skip check)] #C29.{ffi::Allocator::allocate}<self::IncompleteStruct>(){(core::int, {alignment: core::int?}) → ffi::Pointer<self::IncompleteStruct>};
[@vm.direct-call.metadata=#lib::IncompleteStruct.a0] [@vm.inferred-type.metadata=!? (skip check)] new self::IncompleteStruct::#fromTypedDataBase(_in::unsafeCast<ffi::Pointer<self::IncompleteStruct>>(p)).{self::IncompleteStruct::a0} = 1;
core::print([@vm.direct-call.metadata=#lib::IncompleteStruct.a0] [@vm.inferred-type.metadata=int] new self::IncompleteStruct::#fromTypedDataBase(_in::unsafeCast<ffi::Pointer<self::IncompleteStruct>>(p)).{self::IncompleteStruct::a0}{core::int});
[@vm.direct-call.metadata=#lib::IncompleteStruct.a0] [@vm.inferred-type.metadata=!? (skip check)] new self::IncompleteStruct::#fromTypedDataBase(_in::unsafeCast<ffi::Pointer<self::IncompleteStruct>>(p)).{self::IncompleteStruct::a0} = 2;
core::print([@vm.direct-call.metadata=#lib::IncompleteStruct.a0] [@vm.inferred-type.metadata=int] new self::IncompleteStruct::#fromTypedDataBase(_in::unsafeCast<ffi::Pointer<self::IncompleteStruct>>(p)).{self::IncompleteStruct::a0}{core::int});
[@vm.direct-call.metadata=#lib::_DummyAllocator.free] [@vm.inferred-type.metadata=!? (skip check)] #C28.{self::_DummyAllocator::free}(){(ffi::Pointer<ffi::NativeType>) → void};
[@vm.direct-call.metadata=#lib::_DummyAllocator.free] [@vm.inferred-type.metadata=!? (skip check)] #C29.{self::_DummyAllocator::free}(){(ffi::Pointer<ffi::NativeType>) → void};
}
[@vm.inferred-return-type.metadata=dart.core::Null? (value: null)]
static method testInlineArray() → void {
final ffi::Pointer<self::IncompleteArrayStruct> p = let final core::int #t4 = [@vm.inferred-type.metadata=dart.core::_Smi (value: 400)] self::IncompleteArrayStruct::#sizeOf in [@vm.direct-call.metadata=#lib::_DummyAllocator.allocate] [@vm.inferred-type.metadata=dart.ffi::Pointer (skip check)] #C28.{ffi::Allocator::allocate}<self::IncompleteArrayStruct>(){(core::int, {alignment: core::int?}) → ffi::Pointer<self::IncompleteArrayStruct>};
final ffi::Pointer<self::IncompleteArrayStruct> p = let final core::int #t4 = [@vm.inferred-type.metadata=dart.core::_Smi (value: 400)] self::IncompleteArrayStruct::#sizeOf in [@vm.direct-call.metadata=#lib::_DummyAllocator.allocate] [@vm.inferred-type.metadata=dart.ffi::Pointer (skip check)] #C29.{ffi::Allocator::allocate}<self::IncompleteArrayStruct>(){(core::int, {alignment: core::int?}) → ffi::Pointer<self::IncompleteArrayStruct>};
final ffi::Array<self::Incomplete> array = [@vm.direct-call.metadata=#lib::IncompleteArrayStruct.a0] [@vm.inferred-type.metadata=dart.ffi::Array<#lib::Incomplete>] new self::IncompleteArrayStruct::#fromTypedDataBase(_in::unsafeCast<ffi::Pointer<self::IncompleteArrayStruct>>(p)).{self::IncompleteArrayStruct::a0}{ffi::Array<self::Incomplete>};
for (core::int i = 0; [@vm.direct-call.metadata=dart.core::_IntegerImplementation.<] [@vm.inferred-type.metadata=dart.core::bool (skip check)] i.{core::num::<}(100){(core::num) → core::bool}; i = [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}(1){(core::num) → core::int}) {
block {
@@ -144,7 +144,7 @@ static method testInlineArray() → void {
[@vm.direct-call.metadata=dart.ffi::Array._checkIndex] [@vm.inferred-type.metadata=!? (skip check)] #array.{ffi::Array::_checkIndex}(#index){(core::int) → void};
} =>[@vm.inferred-type.metadata=int] ffi::_loadAbiSpecificIntAtIndex<self::Incomplete>([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] #array.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] #array.{ffi::_Compound::_offsetInBytes}{core::int}, #index));
}
[@vm.direct-call.metadata=#lib::_DummyAllocator.free] [@vm.inferred-type.metadata=!? (skip check)] #C28.{self::_DummyAllocator::free}(){(ffi::Pointer<ffi::NativeType>) → void};
[@vm.direct-call.metadata=#lib::_DummyAllocator.free] [@vm.inferred-type.metadata=!? (skip check)] #C29.{self::_DummyAllocator::free}(){(ffi::Pointer<ffi::NativeType>) → void};
}
constants {
#C1 = "vm:ffi:abi-specific-mapping"
@@ -167,12 +167,13 @@ constants {
#C18 = 8
#C19 = <core::int?>[#C2, #C2, #C2, #C2, #C2, #C2, #C2, #C2, #C2, #C2, #C2, #C18, #C18, #C18, #C18, #C2, #C2, #C2, #C2, #C2, #C2, #C2]
#C20 = 100
#C21 = ffi::_FfiInlineArray {elementType:#C12, length:#C20}
#C22 = <core::Type>[#C21]
#C23 = ffi::_FfiStructLayout {fieldTypes:#C22, packing:#C2}
#C24 = core::pragma {name:#C11, options:#C23}
#C25 = <core::int>[]
#C26 = 400
#C27 = <core::int?>[#C2, #C2, #C2, #C2, #C2, #C2, #C2, #C2, #C2, #C2, #C2, #C26, #C26, #C26, #C26, #C2, #C2, #C2, #C2, #C2, #C2, #C2]
#C28 = self::_DummyAllocator {}
#C21 = false
#C22 = ffi::_FfiInlineArray {elementType:#C12, length:#C20, variableLength:#C21}
#C23 = <core::Type>[#C22]
#C24 = ffi::_FfiStructLayout {fieldTypes:#C23, packing:#C2}
#C25 = core::pragma {name:#C11, options:#C24}
#C26 = <core::int>[]
#C27 = 400
#C28 = <core::int?>[#C2, #C2, #C2, #C2, #C2, #C2, #C2, #C2, #C2, #C2, #C2, #C27, #C27, #C27, #C27, #C2, #C2, #C2, #C2, #C2, #C2, #C2]
#C29 = self::_DummyAllocator {}
}
@@ -54,7 +54,7 @@ final class IncompleteStruct extends ffi::Struct {
static get #sizeOf() → core::int
return ffi::_checkAbiSpecificIntegerMapping<core::int>(#C40.{core::List::[]}(ffi::_abi()){(core::int) → core::int?});
}
@#C45
@#C46
final class IncompleteArrayStruct extends ffi::Struct {
synthetic constructor •() → self::IncompleteArrayStruct
: super ffi::Struct::•()
@@ -69,7 +69,7 @@ final class IncompleteArrayStruct extends ffi::Struct {
@#C47
@#C29
get a0() → ffi::Array<self::Incomplete>
return new ffi::Array::_<self::Incomplete>(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::IncompleteArrayStruct::a0#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C41, #C48);
return new ffi::Array::_<self::Incomplete>(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::IncompleteArrayStruct::a0#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C41, #C42, #C48);
@#C47
@#C29
set a0(synthesized ffi::Array<self::Incomplete> #externalFieldValue) → void
@@ -187,12 +187,12 @@ constants {
#C39 = 8
#C40 = <core::int?>[#C23, #C23, #C23, #C23, #C23, #C23, #C23, #C23, #C23, #C23, #C23, #C39, #C39, #C39, #C39, #C23, #C23, #C23, #C23, #C23, #C23, #C23]
#C41 = 100
#C42 = ffi::_FfiInlineArray {elementType:#C33, length:#C41}
#C43 = <core::Type>[#C42]
#C44 = ffi::_FfiStructLayout {fieldTypes:#C43, packing:#C23}
#C45 = core::pragma {name:#C32, options:#C44}
#C46 = false
#C47 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C41, dimension2:#C23, dimension3:#C23, dimension4:#C23, dimension5:#C23, dimensions:#C23, variableLength:#C46}
#C42 = false
#C43 = ffi::_FfiInlineArray {elementType:#C33, length:#C41, variableLength:#C42}
#C44 = <core::Type>[#C43]
#C45 = ffi::_FfiStructLayout {fieldTypes:#C44, packing:#C23}
#C46 = core::pragma {name:#C32, options:#C45}
#C47 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C41, dimension2:#C23, dimension3:#C23, dimension4:#C23, dimension5:#C23, dimensions:#C23, variableDimension:#C23}
#C48 = <core::int>[]
#C49 = 400
#C50 = <core::int?>[#C23, #C23, #C23, #C23, #C23, #C23, #C23, #C23, #C23, #C23, #C23, #C49, #C49, #C49, #C49, #C23, #C23, #C23, #C23, #C23, #C23, #C23]
@@ -6,7 +6,7 @@ import "dart:typed_data" as typ;
import "dart:ffi";
@#C10
@#C11
final class MyStruct extends ffi::Struct {
constructor #fromTypedDataBase([@vm.inferred-arg-type.metadata=dart.typed_data::_Uint8List] synthesized core::Object #typedDataBase) → self::MyStruct
: super ffi::Struct::_fromTypedDataBase(#typedDataBase)
@@ -14,47 +14,47 @@ final class MyStruct extends ffi::Struct {
[@vm.inferred-return-type.metadata=dart.ffi::Array<dart.ffi::Int8>]
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]
@#C12
@#C13
get array() → ffi::Array<ffi::Int8>
return new ffi::Array::_<ffi::Int8>([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] this.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] self::MyStruct::array#offsetOf.{core::num::+}([@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C3, #C13);
return new ffi::Array::_<ffi::Int8>([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] this.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] self::MyStruct::array#offsetOf.{core::num::+}([@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C3, #C4, #C14);
[@vm.inferred-return-type.metadata=dart.ffi::Array<dart.ffi::UnsignedLong>]
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:2]
@#C12
@#C13
get array2() → ffi::Array<ffi::UnsignedLong>
return new ffi::Array::_<ffi::UnsignedLong>([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] this.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] [@vm.inferred-type.metadata=dart.core::_Smi] self::MyStruct::array2#offsetOf.{core::num::+}([@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C3, #C13);
return new ffi::Array::_<ffi::UnsignedLong>([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] this.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] [@vm.inferred-type.metadata=dart.core::_Smi] self::MyStruct::array2#offsetOf.{core::num::+}([@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C3, #C4, #C14);
[@vm.inferred-return-type.metadata=dart.core::_Smi (value: 0)]
[@vm.unboxing-info.metadata=()->i]
@#C12
@#C13
static get a#offsetOf() → core::int
return #C15.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
return #C16.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
[@vm.inferred-return-type.metadata=dart.core::_Smi (value: 1)]
[@vm.unboxing-info.metadata=()->i]
@#C12
@#C13
static get b#offsetOf() → core::int
return #C17.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
return #C18.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
[@vm.inferred-return-type.metadata=dart.core::_Smi (value: 2)]
[@vm.unboxing-info.metadata=()->i]
@#C12
@#C13
static get array#offsetOf() → core::int
return #C19.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
return #C20.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
[@vm.inferred-return-type.metadata=dart.core::_Smi]
[@vm.unboxing-info.metadata=()->i]
@#C12
@#C13
static get array2#offsetOf() → core::int
return #C22.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
return #C23.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
[@vm.inferred-return-type.metadata=dart.core::_Smi]
[@vm.unboxing-info.metadata=()->i]
@#C12
@#C13
static get #sizeOf() → core::int
return #C25.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
return #C26.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
}
@#C28
@#C29
final class MyUnion extends ffi::Union {
constructor #fromTypedDataBase([@vm.inferred-arg-type.metadata=dart.typed_data::_Uint8List] synthesized core::Object #typedDataBase) → self::MyUnion
: super ffi::Union::_fromTypedDataBase(#typedDataBase)
@@ -62,9 +62,9 @@ final class MyUnion extends ffi::Union {
[@vm.inferred-return-type.metadata=dart.core::_Smi (value: 1)]
[@vm.unboxing-info.metadata=()->i]
@#C12
@#C13
static get #sizeOf() → core::int
return #C17.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
return #C18.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
}
[@vm.inferred-return-type.metadata=dart.core::Null? (value: null)]
@@ -79,53 +79,54 @@ static method main() → void {
self::myNative#CC(myUnion, myUnion);
self::myNative#CC( block {
synthesized ffi::_Compound pointer#value = [@vm.direct-call.metadata=#lib::MyStruct.array] [@vm.inferred-type.metadata=dart.ffi::Array<dart.ffi::Int8>] myStruct.{self::MyStruct::array}{ffi::Array<ffi::Int8>};
} =>new ffi::_Compound::_fromTypedDataBase([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] pointer#value.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+??] [@vm.inferred-type.metadata=int (skip check)] [@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] pointer#value.{ffi::_Compound::_offsetInBytes}{core::int}.{core::num::+}([@vm.direct-call.metadata=dart.core::_IntegerImplementation.*] [@vm.inferred-type.metadata=int (skip check)] #C16.{core::num::*}(3){(core::num) → core::num}){(core::num) → core::num}), block {
} =>new ffi::_Compound::_fromTypedDataBase([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] pointer#value.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+??] [@vm.inferred-type.metadata=int (skip check)] [@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] pointer#value.{ffi::_Compound::_offsetInBytes}{core::int}.{core::num::+}([@vm.direct-call.metadata=dart.core::_IntegerImplementation.*] [@vm.inferred-type.metadata=int (skip check)] #C17.{core::num::*}(3){(core::num) → core::num}){(core::num) → core::num}), block {
synthesized ffi::_Compound pointer2#value = [@vm.direct-call.metadata=#lib::MyStruct.array] [@vm.inferred-type.metadata=dart.ffi::Array<dart.ffi::Int8>] myStruct.{self::MyStruct::array}{ffi::Array<ffi::Int8>};
} =>new ffi::_Compound::_fromTypedDataBase([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] pointer2#value.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+??] [@vm.inferred-type.metadata=int (skip check)] [@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] pointer2#value.{ffi::_Compound::_offsetInBytes}{core::int}.{core::num::+}([@vm.direct-call.metadata=dart.core::_IntegerImplementation.*] [@vm.inferred-type.metadata=int (skip check)] #C16.{core::num::*}(4){(core::num) → core::num}){(core::num) → core::num}));
} =>new ffi::_Compound::_fromTypedDataBase([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] pointer2#value.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+??] [@vm.inferred-type.metadata=int (skip check)] [@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] pointer2#value.{ffi::_Compound::_offsetInBytes}{core::int}.{core::num::+}([@vm.direct-call.metadata=dart.core::_IntegerImplementation.*] [@vm.inferred-type.metadata=int (skip check)] #C17.{core::num::*}(4){(core::num) → core::num}){(core::num) → core::num}));
self::myNative#CC( block {
synthesized ffi::_Compound pointer#value = [@vm.direct-call.metadata=#lib::MyStruct.array2] [@vm.inferred-type.metadata=dart.ffi::Array<dart.ffi::UnsignedLong>] myStruct.{self::MyStruct::array2}{ffi::Array<ffi::UnsignedLong>};
} =>new ffi::_Compound::_fromTypedDataBase([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] pointer#value.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+??] [@vm.inferred-type.metadata=int (skip check)] [@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] pointer#value.{ffi::_Compound::_offsetInBytes}{core::int}.{core::num::+}([@vm.direct-call.metadata=dart.core::_IntegerImplementation.*] [@vm.inferred-type.metadata=int (skip check)] [@vm.inferred-type.metadata=dart.core::_Smi] ffi::UnsignedLong::#sizeOf.{core::num::*}(3){(core::num) → core::num}){(core::num) → core::num}), block {
synthesized ffi::_Compound pointer2#value = [@vm.direct-call.metadata=#lib::MyStruct.array2] [@vm.inferred-type.metadata=dart.ffi::Array<dart.ffi::UnsignedLong>] myStruct.{self::MyStruct::array2}{ffi::Array<ffi::UnsignedLong>};
} =>new ffi::_Compound::_fromTypedDataBase([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] pointer2#value.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+??] [@vm.inferred-type.metadata=int (skip check)] [@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] pointer2#value.{ffi::_Compound::_offsetInBytes}{core::int}.{core::num::+}([@vm.direct-call.metadata=dart.core::_IntegerImplementation.*] [@vm.inferred-type.metadata=int (skip check)] [@vm.inferred-type.metadata=dart.core::_Smi] ffi::UnsignedLong::#sizeOf.{core::num::*}(4){(core::num) → core::num}){(core::num) → core::num}));
}
@#C34
@#C36
@#C35
@#C37
external static method myNative#CC([@vm.inferred-arg-type.metadata=!] ffi::_Compound pointer, [@vm.inferred-arg-type.metadata=!] ffi::_Compound pointer2) → void;
constants {
#C1 = "vm:ffi:struct-fields"
#C2 = TypeLiteralConstant(ffi::Int8)
#C3 = 10
#C4 = ffi::_FfiInlineArray {elementType:#C2, length:#C3}
#C5 = TypeLiteralConstant(ffi::UnsignedLong)
#C6 = ffi::_FfiInlineArray {elementType:#C5, length:#C3}
#C7 = <core::Type>[#C2, #C2, #C4, #C6]
#C8 = null
#C9 = ffi::_FfiStructLayout {fieldTypes:#C7, packing:#C8}
#C10 = core::pragma {name:#C1, options:#C9}
#C11 = "vm:prefer-inline"
#C12 = core::pragma {name:#C11, options:#C8}
#C13 = <core::int>[]
#C14 = 0
#C15 = <core::int>[#C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14]
#C16 = 1
#C17 = <core::int>[#C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16]
#C18 = 2
#C19 = <core::int>[#C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18]
#C20 = 12
#C21 = 16
#C22 = <core::int>[#C20, #C21, #C20, #C21, #C21, #C21, #C21, #C21, #C20, #C21, #C21, #C20, #C21, #C20, #C21, #C20, #C21, #C21, #C21, #C20, #C20, #C20]
#C23 = 52
#C24 = 96
#C25 = <core::int>[#C23, #C24, #C23, #C24, #C24, #C24, #C24, #C24, #C23, #C24, #C24, #C23, #C24, #C23, #C24, #C23, #C24, #C24, #C24, #C23, #C23, #C23]
#C26 = <core::Type>[#C2, #C2]
#C27 = ffi::_FfiStructLayout {fieldTypes:#C26, packing:#C8}
#C28 = core::pragma {name:#C1, options:#C27}
#C29 = "cfe:ffi:native-marker"
#C30 = "myNative"
#C31 = "#lib"
#C32 = true
#C33 = ffi::Native<(ffi::Pointer<ffi::Void>, ffi::Pointer<ffi::Void>) → ffi::Void> {symbol:#C30, assetId:#C31, isLeaf:#C32}
#C34 = core::pragma {name:#C29, options:#C33}
#C35 = "vm:ffi:native"
#C36 = core::pragma {name:#C35, options:#C33}
#C4 = false
#C5 = ffi::_FfiInlineArray {elementType:#C2, length:#C3, variableLength:#C4}
#C6 = TypeLiteralConstant(ffi::UnsignedLong)
#C7 = ffi::_FfiInlineArray {elementType:#C6, length:#C3, variableLength:#C4}
#C8 = <core::Type>[#C2, #C2, #C5, #C7]
#C9 = null
#C10 = ffi::_FfiStructLayout {fieldTypes:#C8, packing:#C9}
#C11 = core::pragma {name:#C1, options:#C10}
#C12 = "vm:prefer-inline"
#C13 = core::pragma {name:#C12, options:#C9}
#C14 = <core::int>[]
#C15 = 0
#C16 = <core::int>[#C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15]
#C17 = 1
#C18 = <core::int>[#C17, #C17, #C17, #C17, #C17, #C17, #C17, #C17, #C17, #C17, #C17, #C17, #C17, #C17, #C17, #C17, #C17, #C17, #C17, #C17, #C17, #C17]
#C19 = 2
#C20 = <core::int>[#C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19]
#C21 = 12
#C22 = 16
#C23 = <core::int>[#C21, #C22, #C21, #C22, #C22, #C22, #C22, #C22, #C21, #C22, #C22, #C21, #C22, #C21, #C22, #C21, #C22, #C22, #C22, #C21, #C21, #C21]
#C24 = 52
#C25 = 96
#C26 = <core::int>[#C24, #C25, #C24, #C25, #C25, #C25, #C25, #C25, #C24, #C25, #C25, #C24, #C25, #C24, #C25, #C24, #C25, #C25, #C25, #C24, #C24, #C24]
#C27 = <core::Type>[#C2, #C2]
#C28 = ffi::_FfiStructLayout {fieldTypes:#C27, packing:#C9}
#C29 = core::pragma {name:#C1, options:#C28}
#C30 = "cfe:ffi:native-marker"
#C31 = "myNative"
#C32 = "#lib"
#C33 = true
#C34 = ffi::Native<(ffi::Pointer<ffi::Void>, ffi::Pointer<ffi::Void>) → ffi::Void> {symbol:#C31, assetId:#C32, isLeaf:#C33}
#C35 = core::pragma {name:#C30, options:#C34}
#C36 = "vm:ffi:native"
#C37 = core::pragma {name:#C36, options:#C34}
}
@@ -6,7 +6,7 @@ import "dart:typed_data" as typ;
import "dart:ffi";
@#C10
@#C11
final class MyStruct extends ffi::Struct {
synthetic constructor •() → self::MyStruct
: super ffi::Struct::•()
@@ -14,55 +14,55 @@ final class MyStruct extends ffi::Struct {
constructor #fromTypedDataBase(synthesized core::Object #typedDataBase, synthesized core::int #offsetInBytes) → self::MyStruct
: super ffi::Struct::_fromTypedDataBase(#typedDataBase, #offsetInBytes)
;
@#C12
@#C13
constructor #fromTypedData(synthesized typ::TypedData #typedData, synthesized core::int #offset, synthesized core::int #sizeInBytes) → self::MyStruct
: super ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
;
@#C14
@#C13
@#C12
get a() → core::int
return ffi::_loadInt8(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyStruct::a#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num});
@#C14
@#C13
@#C12
set a(synthesized core::int #externalFieldValue) → void
return ffi::_storeInt8(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyStruct::a#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #externalFieldValue);
@#C14
@#C13
@#C12
get b() → core::int
return ffi::_loadInt8(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyStruct::b#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num});
@#C14
@#C13
@#C12
set b(synthesized core::int #externalFieldValue) → void
return ffi::_storeInt8(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyStruct::b#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #externalFieldValue);
@#C15
@#C12
@#C13
get array() → ffi::Array<ffi::Int8>
return new ffi::Array::_<ffi::Int8>(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyStruct::array#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C3, #C16);
return new ffi::Array::_<ffi::Int8>(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyStruct::array#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C3, #C4, #C16);
@#C15
@#C12
@#C13
set array(synthesized ffi::Array<ffi::Int8> #externalFieldValue) → void
return ffi::_memCopy(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyStruct::array#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #externalFieldValue.{ffi::_Compound::_typedDataBase}{core::Object}, #externalFieldValue.{ffi::_Compound::_offsetInBytes}{core::int}, #C17.{core::List::[]}(ffi::_abi()){(core::int) → core::int});
@#C15
@#C12
@#C13
get array2() → ffi::Array<ffi::UnsignedLong>
return new ffi::Array::_<ffi::UnsignedLong>(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyStruct::array2#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C3, #C16);
return new ffi::Array::_<ffi::UnsignedLong>(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyStruct::array2#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C3, #C4, #C16);
@#C15
@#C12
@#C13
set array2(synthesized ffi::Array<ffi::UnsignedLong> #externalFieldValue) → void
return ffi::_memCopy(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyStruct::array2#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #externalFieldValue.{ffi::_Compound::_typedDataBase}{core::Object}, #externalFieldValue.{ffi::_Compound::_offsetInBytes}{core::int}, #C20.{core::List::[]}(ffi::_abi()){(core::int) → core::int});
@#C12
@#C13
static get a#offsetOf() → core::int
return #C22.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C12
@#C13
static get b#offsetOf() → core::int
return #C24.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C12
@#C13
static get array#offsetOf() → core::int
return #C26.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C12
@#C13
static get array2#offsetOf() → core::int
return #C29.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C12
@#C13
static get #sizeOf() → core::int
return #C32.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
}
@@ -74,33 +74,33 @@ final class MyUnion extends ffi::Union {
constructor #fromTypedDataBase(synthesized core::Object #typedDataBase, synthesized core::int #offsetInBytes) → self::MyUnion
: super ffi::Union::_fromTypedDataBase(#typedDataBase, #offsetInBytes)
;
@#C12
@#C13
constructor #fromTypedData(synthesized typ::TypedData #typedData, synthesized core::int #offset, synthesized core::int #sizeInBytes) → self::MyUnion
: super ffi::Union::_fromTypedData(#typedData, #offset, #sizeInBytes)
;
@#C14
@#C13
@#C12
get a() → core::int
return ffi::_loadInt8(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyUnion::a#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num});
@#C14
@#C13
@#C12
set a(synthesized core::int #externalFieldValue) → void
return ffi::_storeInt8(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyUnion::a#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #externalFieldValue);
@#C14
@#C13
@#C12
get b() → core::int
return ffi::_loadInt8(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyUnion::b#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num});
@#C14
@#C13
@#C12
set b(synthesized core::int #externalFieldValue) → void
return ffi::_storeInt8(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyUnion::b#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #externalFieldValue);
@#C12
@#C13
static get a#offsetOf() → core::int
return #C22.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C12
@#C13
static get b#offsetOf() → core::int
return #C22.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C12
@#C13
static get #sizeOf() → core::int
return #C24.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
}
@@ -134,18 +134,18 @@ constants {
#C1 = "vm:ffi:struct-fields"
#C2 = TypeLiteralConstant(ffi::Int8)
#C3 = 10
#C4 = ffi::_FfiInlineArray {elementType:#C2, length:#C3}
#C5 = TypeLiteralConstant(ffi::UnsignedLong)
#C6 = ffi::_FfiInlineArray {elementType:#C5, length:#C3}
#C7 = <core::Type>[#C2, #C2, #C4, #C6]
#C8 = null
#C9 = ffi::_FfiStructLayout {fieldTypes:#C7, packing:#C8}
#C10 = core::pragma {name:#C1, options:#C9}
#C11 = "vm:prefer-inline"
#C12 = core::pragma {name:#C11, options:#C8}
#C13 = ffi::Int8 {}
#C14 = false
#C15 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C3, dimension2:#C8, dimension3:#C8, dimension4:#C8, dimension5:#C8, dimensions:#C8, variableLength:#C14}
#C4 = false
#C5 = ffi::_FfiInlineArray {elementType:#C2, length:#C3, variableLength:#C4}
#C6 = TypeLiteralConstant(ffi::UnsignedLong)
#C7 = ffi::_FfiInlineArray {elementType:#C6, length:#C3, variableLength:#C4}
#C8 = <core::Type>[#C2, #C2, #C5, #C7]
#C9 = null
#C10 = ffi::_FfiStructLayout {fieldTypes:#C8, packing:#C9}
#C11 = core::pragma {name:#C1, options:#C10}
#C12 = "vm:prefer-inline"
#C13 = core::pragma {name:#C12, options:#C9}
#C14 = ffi::Int8 {}
#C15 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C3, dimension2:#C9, dimension3:#C9, dimension4:#C9, dimension5:#C9, dimensions:#C9, variableDimension:#C9}
#C16 = <core::int>[]
#C17 = <core::int>[#C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3]
#C18 = 40
@@ -164,7 +164,7 @@ constants {
#C31 = 96
#C32 = <core::int>[#C30, #C31, #C30, #C31, #C31, #C31, #C31, #C31, #C30, #C31, #C31, #C30, #C31, #C30, #C31, #C30, #C31, #C31, #C31, #C30, #C30, #C30]
#C33 = <core::Type>[#C2, #C2]
#C34 = ffi::_FfiStructLayout {fieldTypes:#C33, packing:#C8}
#C34 = ffi::_FfiStructLayout {fieldTypes:#C33, packing:#C9}
#C35 = core::pragma {name:#C1, options:#C34}
#C36 = "cfe:ffi:native-marker"
#C37 = "myNative"
@@ -6,7 +6,7 @@ import "dart:typed_data" as typ;
import "dart:ffi";
@#C8
@#C9
final class MyStruct extends ffi::Struct {
constructor #fromTypedDataBase([@vm.inferred-arg-type.metadata=dart.typed_data::_Uint8List] synthesized core::Object #typedDataBase) → self::MyStruct
: super ffi::Struct::_fromTypedDataBase(#typedDataBase)
@@ -14,23 +14,23 @@ final class MyStruct extends ffi::Struct {
[@vm.inferred-return-type.metadata=dart.ffi::Array<dart.ffi::Int8>]
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]
@#C10
@#C11
get a() → ffi::Array<ffi::Int8>
return new ffi::Array::_<ffi::Int8>([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] this.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] [@vm.inferred-type.metadata=dart.core::_Smi (value: 0)] self::MyStruct::a#offsetOf.{core::num::+}([@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C3, #C11);
return new ffi::Array::_<ffi::Int8>([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] this.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] [@vm.inferred-type.metadata=dart.core::_Smi (value: 0)] self::MyStruct::a#offsetOf.{core::num::+}([@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C3, #C4, #C12);
[@vm.inferred-return-type.metadata=dart.core::_Smi (value: 0)]
[@vm.unboxing-info.metadata=()->i]
@#C10
@#C11
static get a#offsetOf() → core::int
return #C13.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
return #C14.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
[@vm.inferred-return-type.metadata=dart.core::_Smi (value: 10)]
[@vm.unboxing-info.metadata=()->i]
@#C10
@#C11
static get #sizeOf() → core::int
return #C14.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
return #C15.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
}
@#C17
@#C18
final class MyUnion extends ffi::Union {
constructor #fromTypedDataBase([@vm.inferred-arg-type.metadata=dart.typed_data::_Uint8List] synthesized core::Object #typedDataBase) → self::MyUnion
: super ffi::Union::_fromTypedDataBase(#typedDataBase)
@@ -38,9 +38,9 @@ final class MyUnion extends ffi::Union {
[@vm.inferred-return-type.metadata=dart.core::_Smi (value: 1)]
[@vm.unboxing-info.metadata=()->i]
@#C10
@#C11
static get #sizeOf() → core::int
return #C19.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
return #C20.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
}
[@vm.inferred-return-type.metadata=dart.core::Null? (value: null)]
@@ -51,49 +51,50 @@ static method main() → void {
self::myNative2#C(myUnion);
self::myNative3#C([@vm.direct-call.metadata=#lib::MyStruct.a] [@vm.inferred-type.metadata=dart.ffi::Array<dart.ffi::Int8>] myStruct.{self::MyStruct::a}{ffi::Array<ffi::Int8>});
}
@#C25
@#C27
@#C26
@#C28
external static method myNative#C([@vm.inferred-arg-type.metadata=#lib::MyStruct] ffi::_Compound pointer) → void;
@#C30
@#C31
@#C32
external static method myNative2#C([@vm.inferred-arg-type.metadata=#lib::MyUnion] ffi::_Compound pointer) → void;
@#C34
@#C35
@#C36
external static method myNative3#C([@vm.inferred-arg-type.metadata=dart.ffi::Array<dart.ffi::Int8>] ffi::_Compound pointer) → void;
constants {
#C1 = "vm:ffi:struct-fields"
#C2 = TypeLiteralConstant(ffi::Int8)
#C3 = 10
#C4 = ffi::_FfiInlineArray {elementType:#C2, length:#C3}
#C5 = <core::Type>[#C4]
#C6 = null
#C7 = ffi::_FfiStructLayout {fieldTypes:#C5, packing:#C6}
#C8 = core::pragma {name:#C1, options:#C7}
#C9 = "vm:prefer-inline"
#C10 = core::pragma {name:#C9, options:#C6}
#C11 = <core::int>[]
#C12 = 0
#C13 = <core::int>[#C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12]
#C14 = <core::int>[#C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3]
#C15 = <core::Type>[#C2]
#C16 = ffi::_FfiStructLayout {fieldTypes:#C15, packing:#C6}
#C17 = core::pragma {name:#C1, options:#C16}
#C18 = 1
#C19 = <core::int>[#C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18]
#C20 = "cfe:ffi:native-marker"
#C21 = "myNative"
#C22 = "#lib"
#C23 = true
#C24 = ffi::Native<(ffi::Pointer<self::MyStruct>) → ffi::Void> {symbol:#C21, assetId:#C22, isLeaf:#C23}
#C25 = core::pragma {name:#C20, options:#C24}
#C26 = "vm:ffi:native"
#C27 = core::pragma {name:#C26, options:#C24}
#C28 = "myNative2"
#C29 = ffi::Native<(ffi::Pointer<self::MyUnion>) → ffi::Void> {symbol:#C28, assetId:#C22, isLeaf:#C23}
#C30 = core::pragma {name:#C20, options:#C29}
#C31 = core::pragma {name:#C26, options:#C29}
#C32 = "myNative3"
#C33 = ffi::Native<(ffi::Pointer<ffi::Int8>) → ffi::Void> {symbol:#C32, assetId:#C22, isLeaf:#C23}
#C34 = core::pragma {name:#C20, options:#C33}
#C35 = core::pragma {name:#C26, options:#C33}
#C4 = false
#C5 = ffi::_FfiInlineArray {elementType:#C2, length:#C3, variableLength:#C4}
#C6 = <core::Type>[#C5]
#C7 = null
#C8 = ffi::_FfiStructLayout {fieldTypes:#C6, packing:#C7}
#C9 = core::pragma {name:#C1, options:#C8}
#C10 = "vm:prefer-inline"
#C11 = core::pragma {name:#C10, options:#C7}
#C12 = <core::int>[]
#C13 = 0
#C14 = <core::int>[#C13, #C13, #C13, #C13, #C13, #C13, #C13, #C13, #C13, #C13, #C13, #C13, #C13, #C13, #C13, #C13, #C13, #C13, #C13, #C13, #C13, #C13]
#C15 = <core::int>[#C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3]
#C16 = <core::Type>[#C2]
#C17 = ffi::_FfiStructLayout {fieldTypes:#C16, packing:#C7}
#C18 = core::pragma {name:#C1, options:#C17}
#C19 = 1
#C20 = <core::int>[#C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19]
#C21 = "cfe:ffi:native-marker"
#C22 = "myNative"
#C23 = "#lib"
#C24 = true
#C25 = ffi::Native<(ffi::Pointer<self::MyStruct>) → ffi::Void> {symbol:#C22, assetId:#C23, isLeaf:#C24}
#C26 = core::pragma {name:#C21, options:#C25}
#C27 = "vm:ffi:native"
#C28 = core::pragma {name:#C27, options:#C25}
#C29 = "myNative2"
#C30 = ffi::Native<(ffi::Pointer<self::MyUnion>) → ffi::Void> {symbol:#C29, assetId:#C23, isLeaf:#C24}
#C31 = core::pragma {name:#C21, options:#C30}
#C32 = core::pragma {name:#C27, options:#C30}
#C33 = "myNative3"
#C34 = ffi::Native<(ffi::Pointer<ffi::Int8>) → ffi::Void> {symbol:#C33, assetId:#C23, isLeaf:#C24}
#C35 = core::pragma {name:#C21, options:#C34}
#C36 = core::pragma {name:#C27, options:#C34}
}
@@ -6,7 +6,7 @@ import "dart:typed_data" as typ;
import "dart:ffi";
@#C8
@#C9
final class MyStruct extends ffi::Struct {
synthetic constructor •() → self::MyStruct
: super ffi::Struct::•()
@@ -14,22 +14,22 @@ final class MyStruct extends ffi::Struct {
constructor #fromTypedDataBase(synthesized core::Object #typedDataBase, synthesized core::int #offsetInBytes) → self::MyStruct
: super ffi::Struct::_fromTypedDataBase(#typedDataBase, #offsetInBytes)
;
@#C10
@#C11
constructor #fromTypedData(synthesized typ::TypedData #typedData, synthesized core::int #offset, synthesized core::int #sizeInBytes) → self::MyStruct
: super ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
;
@#C12
@#C10
@#C11
get a() → ffi::Array<ffi::Int8>
return new ffi::Array::_<ffi::Int8>(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyStruct::a#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C3, #C13);
return new ffi::Array::_<ffi::Int8>(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyStruct::a#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C3, #C4, #C13);
@#C12
@#C10
@#C11
set a(synthesized ffi::Array<ffi::Int8> #externalFieldValue) → void
return ffi::_memCopy(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyStruct::a#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #externalFieldValue.{ffi::_Compound::_typedDataBase}{core::Object}, #externalFieldValue.{ffi::_Compound::_offsetInBytes}{core::int}, #C14.{core::List::[]}(ffi::_abi()){(core::int) → core::int});
@#C10
@#C11
static get a#offsetOf() → core::int
return #C16.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C10
@#C11
static get #sizeOf() → core::int
return #C14.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
}
@@ -41,22 +41,22 @@ final class MyUnion extends ffi::Union {
constructor #fromTypedDataBase(synthesized core::Object #typedDataBase, synthesized core::int #offsetInBytes) → self::MyUnion
: super ffi::Union::_fromTypedDataBase(#typedDataBase, #offsetInBytes)
;
@#C10
@#C11
constructor #fromTypedData(synthesized typ::TypedData #typedData, synthesized core::int #offset, synthesized core::int #sizeInBytes) → self::MyUnion
: super ffi::Union::_fromTypedData(#typedData, #offset, #sizeInBytes)
;
@#C20
@#C10
@#C11
get a() → core::int
return ffi::_loadInt8(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyUnion::a#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num});
@#C20
@#C10
@#C11
set a(synthesized core::int #externalFieldValue) → void
return ffi::_storeInt8(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyUnion::a#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #externalFieldValue);
@#C10
@#C11
static get a#offsetOf() → core::int
return #C16.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C10
@#C11
static get #sizeOf() → core::int
return #C22.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
}
@@ -89,21 +89,21 @@ constants {
#C1 = "vm:ffi:struct-fields"
#C2 = TypeLiteralConstant(ffi::Int8)
#C3 = 10
#C4 = ffi::_FfiInlineArray {elementType:#C2, length:#C3}
#C5 = <core::Type>[#C4]
#C6 = null
#C7 = ffi::_FfiStructLayout {fieldTypes:#C5, packing:#C6}
#C8 = core::pragma {name:#C1, options:#C7}
#C9 = "vm:prefer-inline"
#C10 = core::pragma {name:#C9, options:#C6}
#C11 = false
#C12 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C3, dimension2:#C6, dimension3:#C6, dimension4:#C6, dimension5:#C6, dimensions:#C6, variableLength:#C11}
#C4 = false
#C5 = ffi::_FfiInlineArray {elementType:#C2, length:#C3, variableLength:#C4}
#C6 = <core::Type>[#C5]
#C7 = null
#C8 = ffi::_FfiStructLayout {fieldTypes:#C6, packing:#C7}
#C9 = core::pragma {name:#C1, options:#C8}
#C10 = "vm:prefer-inline"
#C11 = core::pragma {name:#C10, options:#C7}
#C12 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C3, dimension2:#C7, dimension3:#C7, dimension4:#C7, dimension5:#C7, dimensions:#C7, variableDimension:#C7}
#C13 = <core::int>[]
#C14 = <core::int>[#C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3]
#C15 = 0
#C16 = <core::int>[#C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15]
#C17 = <core::Type>[#C2]
#C18 = ffi::_FfiStructLayout {fieldTypes:#C17, packing:#C6}
#C18 = ffi::_FfiStructLayout {fieldTypes:#C17, packing:#C7}
#C19 = core::pragma {name:#C1, options:#C18}
#C20 = ffi::Int8 {}
#C21 = 1
@@ -6,7 +6,7 @@ import "dart:typed_data" as typ;
import "dart:ffi";
@#C10
@#C11
final class MyStruct extends ffi::Struct {
constructor #fromTypedDataBase([@vm.inferred-arg-type.metadata=dart.typed_data::_Uint8List] synthesized core::Object #typedDataBase) → self::MyStruct
: super ffi::Struct::_fromTypedDataBase(#typedDataBase)
@@ -14,47 +14,47 @@ final class MyStruct extends ffi::Struct {
[@vm.inferred-return-type.metadata=dart.ffi::Array<dart.ffi::Int8>]
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]
@#C12
@#C13
get array() → ffi::Array<ffi::Int8>
return new ffi::Array::_<ffi::Int8>([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] this.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] self::MyStruct::array#offsetOf.{core::num::+}([@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C3, #C13);
return new ffi::Array::_<ffi::Int8>([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] this.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] self::MyStruct::array#offsetOf.{core::num::+}([@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C3, #C4, #C14);
[@vm.inferred-return-type.metadata=dart.ffi::Array<dart.ffi::UnsignedLong>]
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:2]
@#C12
@#C13
get array2() → ffi::Array<ffi::UnsignedLong>
return new ffi::Array::_<ffi::UnsignedLong>([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] this.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] [@vm.inferred-type.metadata=dart.core::_Smi] self::MyStruct::array2#offsetOf.{core::num::+}([@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C3, #C13);
return new ffi::Array::_<ffi::UnsignedLong>([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] this.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] [@vm.inferred-type.metadata=dart.core::_Smi] self::MyStruct::array2#offsetOf.{core::num::+}([@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C3, #C4, #C14);
[@vm.inferred-return-type.metadata=dart.core::_Smi (value: 0)]
[@vm.unboxing-info.metadata=()->i]
@#C12
@#C13
static get a#offsetOf() → core::int
return #C15.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
return #C16.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
[@vm.inferred-return-type.metadata=dart.core::_Smi (value: 1)]
[@vm.unboxing-info.metadata=()->i]
@#C12
@#C13
static get b#offsetOf() → core::int
return #C17.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
return #C18.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
[@vm.inferred-return-type.metadata=dart.core::_Smi (value: 2)]
[@vm.unboxing-info.metadata=()->i]
@#C12
@#C13
static get array#offsetOf() → core::int
return #C19.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
return #C20.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
[@vm.inferred-return-type.metadata=dart.core::_Smi]
[@vm.unboxing-info.metadata=()->i]
@#C12
@#C13
static get array2#offsetOf() → core::int
return #C22.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
return #C23.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
[@vm.inferred-return-type.metadata=dart.core::_Smi]
[@vm.unboxing-info.metadata=()->i]
@#C12
@#C13
static get #sizeOf() → core::int
return #C25.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
return #C26.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
}
@#C28
@#C29
final class MyUnion extends ffi::Union {
constructor #fromTypedDataBase([@vm.inferred-arg-type.metadata=dart.typed_data::_Uint8List] synthesized core::Object #typedDataBase) → self::MyUnion
: super ffi::Union::_fromTypedDataBase(#typedDataBase)
@@ -62,9 +62,9 @@ final class MyUnion extends ffi::Union {
[@vm.inferred-return-type.metadata=dart.core::_Smi (value: 1)]
[@vm.unboxing-info.metadata=()->i]
@#C12
@#C13
static get #sizeOf() → core::int
return #C17.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
return #C18.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
}
[@vm.inferred-return-type.metadata=dart.core::Null? (value: null)]
@@ -79,53 +79,54 @@ static method main() → void {
self::myNative#CC(myUnion, myUnion);
self::myNative#CC( block {
synthesized ffi::_Compound pointer#value = [@vm.direct-call.metadata=#lib::MyStruct.array] [@vm.inferred-type.metadata=dart.ffi::Array<dart.ffi::Int8>] myStruct.{self::MyStruct::array}{ffi::Array<ffi::Int8>};
} =>new ffi::_Compound::_fromTypedDataBase([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] pointer#value.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+??] [@vm.inferred-type.metadata=int (skip check)] [@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] pointer#value.{ffi::_Compound::_offsetInBytes}{core::int}.{core::num::+}([@vm.direct-call.metadata=dart.core::_IntegerImplementation.*] [@vm.inferred-type.metadata=int (skip check)] #C16.{core::num::*}(3){(core::num) → core::num}){(core::num) → core::num}), block {
} =>new ffi::_Compound::_fromTypedDataBase([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] pointer#value.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+??] [@vm.inferred-type.metadata=int (skip check)] [@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] pointer#value.{ffi::_Compound::_offsetInBytes}{core::int}.{core::num::+}([@vm.direct-call.metadata=dart.core::_IntegerImplementation.*] [@vm.inferred-type.metadata=int (skip check)] #C17.{core::num::*}(3){(core::num) → core::num}){(core::num) → core::num}), block {
synthesized ffi::_Compound pointer2#value = [@vm.direct-call.metadata=#lib::MyStruct.array] [@vm.inferred-type.metadata=dart.ffi::Array<dart.ffi::Int8>] myStruct.{self::MyStruct::array}{ffi::Array<ffi::Int8>};
} =>new ffi::_Compound::_fromTypedDataBase([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] pointer2#value.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+??] [@vm.inferred-type.metadata=int (skip check)] [@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] pointer2#value.{ffi::_Compound::_offsetInBytes}{core::int}.{core::num::+}([@vm.direct-call.metadata=dart.core::_IntegerImplementation.*] [@vm.inferred-type.metadata=int (skip check)] #C16.{core::num::*}(4){(core::num) → core::num}){(core::num) → core::num}));
} =>new ffi::_Compound::_fromTypedDataBase([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] pointer2#value.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+??] [@vm.inferred-type.metadata=int (skip check)] [@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] pointer2#value.{ffi::_Compound::_offsetInBytes}{core::int}.{core::num::+}([@vm.direct-call.metadata=dart.core::_IntegerImplementation.*] [@vm.inferred-type.metadata=int (skip check)] #C17.{core::num::*}(4){(core::num) → core::num}){(core::num) → core::num}));
self::myNative#CC( block {
synthesized ffi::_Compound pointer#value = [@vm.direct-call.metadata=#lib::MyStruct.array2] [@vm.inferred-type.metadata=dart.ffi::Array<dart.ffi::UnsignedLong>] myStruct.{self::MyStruct::array2}{ffi::Array<ffi::UnsignedLong>};
} =>new ffi::_Compound::_fromTypedDataBase([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] pointer#value.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+??] [@vm.inferred-type.metadata=int (skip check)] [@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] pointer#value.{ffi::_Compound::_offsetInBytes}{core::int}.{core::num::+}([@vm.direct-call.metadata=dart.core::_IntegerImplementation.*] [@vm.inferred-type.metadata=int (skip check)] [@vm.inferred-type.metadata=dart.core::_Smi] ffi::UnsignedLong::#sizeOf.{core::num::*}(3){(core::num) → core::num}){(core::num) → core::num}), block {
synthesized ffi::_Compound pointer2#value = [@vm.direct-call.metadata=#lib::MyStruct.array2] [@vm.inferred-type.metadata=dart.ffi::Array<dart.ffi::UnsignedLong>] myStruct.{self::MyStruct::array2}{ffi::Array<ffi::UnsignedLong>};
} =>new ffi::_Compound::_fromTypedDataBase([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] pointer2#value.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+??] [@vm.inferred-type.metadata=int (skip check)] [@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] pointer2#value.{ffi::_Compound::_offsetInBytes}{core::int}.{core::num::+}([@vm.direct-call.metadata=dart.core::_IntegerImplementation.*] [@vm.inferred-type.metadata=int (skip check)] [@vm.inferred-type.metadata=dart.core::_Smi] ffi::UnsignedLong::#sizeOf.{core::num::*}(4){(core::num) → core::num}){(core::num) → core::num}));
}
@#C34
@#C36
@#C35
@#C37
external static method myNative#CC([@vm.inferred-arg-type.metadata=!] ffi::_Compound pointer, [@vm.inferred-arg-type.metadata=!] ffi::_Compound pointer2) → void;
constants {
#C1 = "vm:ffi:struct-fields"
#C2 = TypeLiteralConstant(ffi::Int8)
#C3 = 10
#C4 = ffi::_FfiInlineArray {elementType:#C2, length:#C3}
#C5 = TypeLiteralConstant(ffi::UnsignedLong)
#C6 = ffi::_FfiInlineArray {elementType:#C5, length:#C3}
#C7 = <core::Type>[#C2, #C2, #C4, #C6]
#C8 = null
#C9 = ffi::_FfiStructLayout {fieldTypes:#C7, packing:#C8}
#C10 = core::pragma {name:#C1, options:#C9}
#C11 = "vm:prefer-inline"
#C12 = core::pragma {name:#C11, options:#C8}
#C13 = <core::int>[]
#C14 = 0
#C15 = <core::int>[#C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14]
#C16 = 1
#C17 = <core::int>[#C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16]
#C18 = 2
#C19 = <core::int>[#C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18]
#C20 = 12
#C21 = 16
#C22 = <core::int>[#C20, #C21, #C20, #C21, #C21, #C21, #C21, #C21, #C20, #C21, #C21, #C20, #C21, #C20, #C21, #C20, #C21, #C21, #C21, #C20, #C20, #C20]
#C23 = 52
#C24 = 96
#C25 = <core::int>[#C23, #C24, #C23, #C24, #C24, #C24, #C24, #C24, #C23, #C24, #C24, #C23, #C24, #C23, #C24, #C23, #C24, #C24, #C24, #C23, #C23, #C23]
#C26 = <core::Type>[#C2, #C2]
#C27 = ffi::_FfiStructLayout {fieldTypes:#C26, packing:#C8}
#C28 = core::pragma {name:#C1, options:#C27}
#C29 = "cfe:ffi:native-marker"
#C30 = "myNative"
#C31 = "#lib"
#C32 = true
#C33 = ffi::Native<(ffi::Pointer<ffi::Int8>, ffi::Pointer<ffi::Int8>) → ffi::Void> {symbol:#C30, assetId:#C31, isLeaf:#C32}
#C34 = core::pragma {name:#C29, options:#C33}
#C35 = "vm:ffi:native"
#C36 = core::pragma {name:#C35, options:#C33}
#C4 = false
#C5 = ffi::_FfiInlineArray {elementType:#C2, length:#C3, variableLength:#C4}
#C6 = TypeLiteralConstant(ffi::UnsignedLong)
#C7 = ffi::_FfiInlineArray {elementType:#C6, length:#C3, variableLength:#C4}
#C8 = <core::Type>[#C2, #C2, #C5, #C7]
#C9 = null
#C10 = ffi::_FfiStructLayout {fieldTypes:#C8, packing:#C9}
#C11 = core::pragma {name:#C1, options:#C10}
#C12 = "vm:prefer-inline"
#C13 = core::pragma {name:#C12, options:#C9}
#C14 = <core::int>[]
#C15 = 0
#C16 = <core::int>[#C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15, #C15]
#C17 = 1
#C18 = <core::int>[#C17, #C17, #C17, #C17, #C17, #C17, #C17, #C17, #C17, #C17, #C17, #C17, #C17, #C17, #C17, #C17, #C17, #C17, #C17, #C17, #C17, #C17]
#C19 = 2
#C20 = <core::int>[#C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19, #C19]
#C21 = 12
#C22 = 16
#C23 = <core::int>[#C21, #C22, #C21, #C22, #C22, #C22, #C22, #C22, #C21, #C22, #C22, #C21, #C22, #C21, #C22, #C21, #C22, #C22, #C22, #C21, #C21, #C21]
#C24 = 52
#C25 = 96
#C26 = <core::int>[#C24, #C25, #C24, #C25, #C25, #C25, #C25, #C25, #C24, #C25, #C25, #C24, #C25, #C24, #C25, #C24, #C25, #C25, #C25, #C24, #C24, #C24]
#C27 = <core::Type>[#C2, #C2]
#C28 = ffi::_FfiStructLayout {fieldTypes:#C27, packing:#C9}
#C29 = core::pragma {name:#C1, options:#C28}
#C30 = "cfe:ffi:native-marker"
#C31 = "myNative"
#C32 = "#lib"
#C33 = true
#C34 = ffi::Native<(ffi::Pointer<ffi::Int8>, ffi::Pointer<ffi::Int8>) → ffi::Void> {symbol:#C31, assetId:#C32, isLeaf:#C33}
#C35 = core::pragma {name:#C30, options:#C34}
#C36 = "vm:ffi:native"
#C37 = core::pragma {name:#C36, options:#C34}
}
@@ -6,7 +6,7 @@ import "dart:typed_data" as typ;
import "dart:ffi";
@#C10
@#C11
final class MyStruct extends ffi::Struct {
synthetic constructor •() → self::MyStruct
: super ffi::Struct::•()
@@ -14,55 +14,55 @@ final class MyStruct extends ffi::Struct {
constructor #fromTypedDataBase(synthesized core::Object #typedDataBase, synthesized core::int #offsetInBytes) → self::MyStruct
: super ffi::Struct::_fromTypedDataBase(#typedDataBase, #offsetInBytes)
;
@#C12
@#C13
constructor #fromTypedData(synthesized typ::TypedData #typedData, synthesized core::int #offset, synthesized core::int #sizeInBytes) → self::MyStruct
: super ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
;
@#C14
@#C13
@#C12
get a() → core::int
return ffi::_loadInt8(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyStruct::a#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num});
@#C14
@#C13
@#C12
set a(synthesized core::int #externalFieldValue) → void
return ffi::_storeInt8(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyStruct::a#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #externalFieldValue);
@#C14
@#C13
@#C12
get b() → core::int
return ffi::_loadInt8(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyStruct::b#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num});
@#C14
@#C13
@#C12
set b(synthesized core::int #externalFieldValue) → void
return ffi::_storeInt8(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyStruct::b#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #externalFieldValue);
@#C15
@#C12
@#C13
get array() → ffi::Array<ffi::Int8>
return new ffi::Array::_<ffi::Int8>(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyStruct::array#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C3, #C16);
return new ffi::Array::_<ffi::Int8>(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyStruct::array#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C3, #C4, #C16);
@#C15
@#C12
@#C13
set array(synthesized ffi::Array<ffi::Int8> #externalFieldValue) → void
return ffi::_memCopy(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyStruct::array#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #externalFieldValue.{ffi::_Compound::_typedDataBase}{core::Object}, #externalFieldValue.{ffi::_Compound::_offsetInBytes}{core::int}, #C17.{core::List::[]}(ffi::_abi()){(core::int) → core::int});
@#C15
@#C12
@#C13
get array2() → ffi::Array<ffi::UnsignedLong>
return new ffi::Array::_<ffi::UnsignedLong>(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyStruct::array2#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C3, #C16);
return new ffi::Array::_<ffi::UnsignedLong>(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyStruct::array2#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C3, #C4, #C16);
@#C15
@#C12
@#C13
set array2(synthesized ffi::Array<ffi::UnsignedLong> #externalFieldValue) → void
return ffi::_memCopy(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyStruct::array2#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #externalFieldValue.{ffi::_Compound::_typedDataBase}{core::Object}, #externalFieldValue.{ffi::_Compound::_offsetInBytes}{core::int}, #C20.{core::List::[]}(ffi::_abi()){(core::int) → core::int});
@#C12
@#C13
static get a#offsetOf() → core::int
return #C22.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C12
@#C13
static get b#offsetOf() → core::int
return #C24.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C12
@#C13
static get array#offsetOf() → core::int
return #C26.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C12
@#C13
static get array2#offsetOf() → core::int
return #C29.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C12
@#C13
static get #sizeOf() → core::int
return #C32.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
}
@@ -74,33 +74,33 @@ final class MyUnion extends ffi::Union {
constructor #fromTypedDataBase(synthesized core::Object #typedDataBase, synthesized core::int #offsetInBytes) → self::MyUnion
: super ffi::Union::_fromTypedDataBase(#typedDataBase, #offsetInBytes)
;
@#C12
@#C13
constructor #fromTypedData(synthesized typ::TypedData #typedData, synthesized core::int #offset, synthesized core::int #sizeInBytes) → self::MyUnion
: super ffi::Union::_fromTypedData(#typedData, #offset, #sizeInBytes)
;
@#C14
@#C13
@#C12
get a() → core::int
return ffi::_loadInt8(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyUnion::a#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num});
@#C14
@#C13
@#C12
set a(synthesized core::int #externalFieldValue) → void
return ffi::_storeInt8(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyUnion::a#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #externalFieldValue);
@#C14
@#C13
@#C12
get b() → core::int
return ffi::_loadInt8(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyUnion::b#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num});
@#C14
@#C13
@#C12
set b(synthesized core::int #externalFieldValue) → void
return ffi::_storeInt8(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyUnion::b#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #externalFieldValue);
@#C12
@#C13
static get a#offsetOf() → core::int
return #C22.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C12
@#C13
static get b#offsetOf() → core::int
return #C22.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C12
@#C13
static get #sizeOf() → core::int
return #C24.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
}
@@ -134,18 +134,18 @@ constants {
#C1 = "vm:ffi:struct-fields"
#C2 = TypeLiteralConstant(ffi::Int8)
#C3 = 10
#C4 = ffi::_FfiInlineArray {elementType:#C2, length:#C3}
#C5 = TypeLiteralConstant(ffi::UnsignedLong)
#C6 = ffi::_FfiInlineArray {elementType:#C5, length:#C3}
#C7 = <core::Type>[#C2, #C2, #C4, #C6]
#C8 = null
#C9 = ffi::_FfiStructLayout {fieldTypes:#C7, packing:#C8}
#C10 = core::pragma {name:#C1, options:#C9}
#C11 = "vm:prefer-inline"
#C12 = core::pragma {name:#C11, options:#C8}
#C13 = ffi::Int8 {}
#C14 = false
#C15 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C3, dimension2:#C8, dimension3:#C8, dimension4:#C8, dimension5:#C8, dimensions:#C8, variableLength:#C14}
#C4 = false
#C5 = ffi::_FfiInlineArray {elementType:#C2, length:#C3, variableLength:#C4}
#C6 = TypeLiteralConstant(ffi::UnsignedLong)
#C7 = ffi::_FfiInlineArray {elementType:#C6, length:#C3, variableLength:#C4}
#C8 = <core::Type>[#C2, #C2, #C5, #C7]
#C9 = null
#C10 = ffi::_FfiStructLayout {fieldTypes:#C8, packing:#C9}
#C11 = core::pragma {name:#C1, options:#C10}
#C12 = "vm:prefer-inline"
#C13 = core::pragma {name:#C12, options:#C9}
#C14 = ffi::Int8 {}
#C15 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C3, dimension2:#C9, dimension3:#C9, dimension4:#C9, dimension5:#C9, dimensions:#C9, variableDimension:#C9}
#C16 = <core::int>[]
#C17 = <core::int>[#C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3, #C3]
#C18 = 40
@@ -164,7 +164,7 @@ constants {
#C31 = 96
#C32 = <core::int>[#C30, #C31, #C30, #C31, #C31, #C31, #C31, #C31, #C30, #C31, #C31, #C30, #C31, #C30, #C31, #C30, #C31, #C31, #C31, #C30, #C30, #C30]
#C33 = <core::Type>[#C2, #C2]
#C34 = ffi::_FfiStructLayout {fieldTypes:#C33, packing:#C8}
#C34 = ffi::_FfiStructLayout {fieldTypes:#C33, packing:#C9}
#C35 = core::pragma {name:#C1, options:#C34}
#C36 = "cfe:ffi:native-marker"
#C37 = "myNative"
@@ -16,6 +16,26 @@ final class Vec2d extends Struct {
external double y;
}
final class MyStruct extends Struct {
@Array.variable()
external Array<Uint8> array;
}
final class MyStruct2 extends Struct {
@Array.variableWithVariableDimension(1)
external Array<Uint8> array;
}
final class MyStruct3 extends Struct {
@Array.variableMulti([1, 2])
external Array<Array<Array<Uint8>>> array;
}
final class MyStruct4 extends Struct {
@Array.variableMulti(variableDimension: 1, [1, 2])
external Array<Array<Array<Uint8>>> array;
}
final class MyUnion extends Union {
external Vec2d vector;
external Pointer<Vec2d> indirectVector;
@@ -86,7 +86,7 @@ static get union() → self::MyUnion
[@vm.inferred-return-type.metadata=dart.ffi::Array<dart.ffi::Array<dart.ffi::Array<dart.ffi::Double>>>]
@#C35
static get manyNumbers() → ffi::Array<ffi::Array<ffi::Array<ffi::Double>>>
return new ffi::Array::_<ffi::Array<ffi::Array<ffi::Double>>>([@vm.inferred-type.metadata=dart.ffi::Pointer] ffi::Native::_addressOf<ffi::Array<ffi::Array<ffi::Array<ffi::Double>>>>(#C34), #C9, #C36, #C39);
return new ffi::Array::_<ffi::Array<ffi::Array<ffi::Double>>>([@vm.inferred-type.metadata=dart.ffi::Pointer] ffi::Native::_addressOf<ffi::Array<ffi::Array<ffi::Array<ffi::Double>>>>(#C34), #C9, #C36, #C21, #C39);
static set manyNumbers([@vm.inferred-arg-type.metadata=dart.ffi::Array<dart.ffi::Array<dart.ffi::Array<dart.ffi::Double>>>] synthesized ffi::Array<ffi::Array<ffi::Array<ffi::Double>>> #externalFieldValue) → void
ffi::_memCopy([@vm.inferred-type.metadata=dart.ffi::Pointer] ffi::Native::_addressOf<ffi::Array<ffi::Array<ffi::Array<ffi::Double>>>>(#C34), #C9, [@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] #externalFieldValue.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] #externalFieldValue.{ffi::_Compound::_offsetInBytes}{core::int}, #C41.{core::List::[]}(ffi::_abi()){(core::int) → core::int});
@@ -111,13 +111,13 @@ static method main() → void {
synthesized core::int #singleElementSize = #C11;
synthesized core::int #elementSize = [@vm.direct-call.metadata=dart.core::_IntegerImplementation.*] [@vm.inferred-type.metadata=int (skip check)] #singleElementSize.{core::num::*}([@vm.direct-call.metadata=dart.ffi::Array._nestedDimensionsFlattened] [@vm.inferred-type.metadata=int] #array.{ffi::Array::_nestedDimensionsFlattened}{core::int}){(core::num) → core::num};
synthesized core::int #offset = [@vm.direct-call.metadata=dart.core::_IntegerImplementation.*] [@vm.inferred-type.metadata=int (skip check)] #elementSize.{core::num::*}(#index){(core::num) → core::num};
} =>new ffi::Array::_<ffi::Array<ffi::Double>>([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] #array.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+??] [@vm.inferred-type.metadata=int (skip check)] [@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] #array.{ffi::_Compound::_offsetInBytes}{core::int}.{core::num::+}(#offset){(core::num) → core::num}, [@vm.direct-call.metadata=dart.ffi::Array._nestedDimensionsFirst] [@vm.inferred-type.metadata=int] #array.{ffi::Array::_nestedDimensionsFirst}{core::int}, [@vm.direct-call.metadata=dart.ffi::Array._nestedDimensionsRest] [@vm.inferred-type.metadata=!] #array.{ffi::Array::_nestedDimensionsRest}{core::List<core::int>}));
} =>new ffi::Array::_<ffi::Array<ffi::Double>>([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] #array.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+??] [@vm.inferred-type.metadata=int (skip check)] [@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] #array.{ffi::_Compound::_offsetInBytes}{core::int}.{core::num::+}(#offset){(core::num) → core::num}, [@vm.direct-call.metadata=dart.ffi::Array._nestedDimensionsFirst] [@vm.inferred-type.metadata=int] #array.{ffi::Array::_nestedDimensionsFirst}{core::int}, [@vm.direct-call.metadata=dart.ffi::Array._variableLength] [@vm.inferred-type.metadata=dart.core::bool] #array.{ffi::Array::_variableLength}{core::bool}, [@vm.direct-call.metadata=dart.ffi::Array._nestedDimensionsRest] [@vm.inferred-type.metadata=!] #array.{ffi::Array::_nestedDimensionsRest}{core::List<core::int>}));
synthesized core::int #index = _in::unsafeCast<core::int>(1);
[@vm.direct-call.metadata=dart.ffi::Array._checkIndex] [@vm.inferred-type.metadata=!? (skip check)] #array.{ffi::Array::_checkIndex}(#index){(core::int) → void};
synthesized core::int #singleElementSize = #C11;
synthesized core::int #elementSize = [@vm.direct-call.metadata=dart.core::_IntegerImplementation.*] [@vm.inferred-type.metadata=int (skip check)] #singleElementSize.{core::num::*}([@vm.direct-call.metadata=dart.ffi::Array._nestedDimensionsFlattened] [@vm.inferred-type.metadata=int] #array.{ffi::Array::_nestedDimensionsFlattened}{core::int}){(core::num) → core::num};
synthesized core::int #offset = [@vm.direct-call.metadata=dart.core::_IntegerImplementation.*] [@vm.inferred-type.metadata=int (skip check)] #elementSize.{core::num::*}(#index){(core::num) → core::num};
} =>new ffi::Array::_<ffi::Double>([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] #array.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+??] [@vm.inferred-type.metadata=int (skip check)] [@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] #array.{ffi::_Compound::_offsetInBytes}{core::int}.{core::num::+}(#offset){(core::num) → core::num}, [@vm.direct-call.metadata=dart.ffi::Array._nestedDimensionsFirst] [@vm.inferred-type.metadata=int] #array.{ffi::Array::_nestedDimensionsFirst}{core::int}, [@vm.direct-call.metadata=dart.ffi::Array._nestedDimensionsRest] [@vm.inferred-type.metadata=!] #array.{ffi::Array::_nestedDimensionsRest}{core::List<core::int>}), 2, 123.45);
} =>new ffi::Array::_<ffi::Double>([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] #array.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+??] [@vm.inferred-type.metadata=int (skip check)] [@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] #array.{ffi::_Compound::_offsetInBytes}{core::int}.{core::num::+}(#offset){(core::num) → core::num}, [@vm.direct-call.metadata=dart.ffi::Array._nestedDimensionsFirst] [@vm.inferred-type.metadata=int] #array.{ffi::Array::_nestedDimensionsFirst}{core::int}, [@vm.direct-call.metadata=dart.ffi::Array._variableLength] [@vm.inferred-type.metadata=dart.core::bool] #array.{ffi::Array::_variableLength}{core::bool}, [@vm.direct-call.metadata=dart.ffi::Array._nestedDimensionsRest] [@vm.inferred-type.metadata=!] #array.{ffi::Array::_nestedDimensionsRest}{core::List<core::int>}), 2, 123.45);
self::manyNumbers = wholeArray;
ffi::DoubleArray|[]=( block {
synthesized ffi::Array<dynamic> #array = _in::unsafeCast<ffi::Array<ffi::Array<ffi::Double>>>( block {
@@ -127,13 +127,13 @@ static method main() → void {
synthesized core::int #singleElementSize = #C11;
synthesized core::int #elementSize = [@vm.direct-call.metadata=dart.core::_IntegerImplementation.*] [@vm.inferred-type.metadata=int (skip check)] #singleElementSize.{core::num::*}([@vm.direct-call.metadata=dart.ffi::Array._nestedDimensionsFlattened] [@vm.inferred-type.metadata=int] #array.{ffi::Array::_nestedDimensionsFlattened}{core::int}){(core::num) → core::num};
synthesized core::int #offset = [@vm.direct-call.metadata=dart.core::_IntegerImplementation.*] [@vm.inferred-type.metadata=int (skip check)] #elementSize.{core::num::*}(#index){(core::num) → core::num};
} =>new ffi::Array::_<ffi::Array<ffi::Double>>([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] #array.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+??] [@vm.inferred-type.metadata=int (skip check)] [@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] #array.{ffi::_Compound::_offsetInBytes}{core::int}.{core::num::+}(#offset){(core::num) → core::num}, [@vm.direct-call.metadata=dart.ffi::Array._nestedDimensionsFirst] [@vm.inferred-type.metadata=int] #array.{ffi::Array::_nestedDimensionsFirst}{core::int}, [@vm.direct-call.metadata=dart.ffi::Array._nestedDimensionsRest] [@vm.inferred-type.metadata=!] #array.{ffi::Array::_nestedDimensionsRest}{core::List<core::int>}));
} =>new ffi::Array::_<ffi::Array<ffi::Double>>([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] #array.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+??] [@vm.inferred-type.metadata=int (skip check)] [@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] #array.{ffi::_Compound::_offsetInBytes}{core::int}.{core::num::+}(#offset){(core::num) → core::num}, [@vm.direct-call.metadata=dart.ffi::Array._nestedDimensionsFirst] [@vm.inferred-type.metadata=int] #array.{ffi::Array::_nestedDimensionsFirst}{core::int}, [@vm.direct-call.metadata=dart.ffi::Array._variableLength] [@vm.inferred-type.metadata=dart.core::bool] #array.{ffi::Array::_variableLength}{core::bool}, [@vm.direct-call.metadata=dart.ffi::Array._nestedDimensionsRest] [@vm.inferred-type.metadata=!] #array.{ffi::Array::_nestedDimensionsRest}{core::List<core::int>}));
synthesized core::int #index = _in::unsafeCast<core::int>(0);
[@vm.direct-call.metadata=dart.ffi::Array._checkIndex] [@vm.inferred-type.metadata=!? (skip check)] #array.{ffi::Array::_checkIndex}(#index){(core::int) → void};
synthesized core::int #singleElementSize = #C11;
synthesized core::int #elementSize = [@vm.direct-call.metadata=dart.core::_IntegerImplementation.*] [@vm.inferred-type.metadata=int (skip check)] #singleElementSize.{core::num::*}([@vm.direct-call.metadata=dart.ffi::Array._nestedDimensionsFlattened] [@vm.inferred-type.metadata=int] #array.{ffi::Array::_nestedDimensionsFlattened}{core::int}){(core::num) → core::num};
synthesized core::int #offset = [@vm.direct-call.metadata=dart.core::_IntegerImplementation.*] [@vm.inferred-type.metadata=int (skip check)] #elementSize.{core::num::*}(#index){(core::num) → core::num};
} =>new ffi::Array::_<ffi::Double>([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] #array.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+??] [@vm.inferred-type.metadata=int (skip check)] [@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] #array.{ffi::_Compound::_offsetInBytes}{core::int}.{core::num::+}(#offset){(core::num) → core::num}, [@vm.direct-call.metadata=dart.ffi::Array._nestedDimensionsFirst] [@vm.inferred-type.metadata=int] #array.{ffi::Array::_nestedDimensionsFirst}{core::int}, [@vm.direct-call.metadata=dart.ffi::Array._nestedDimensionsRest] [@vm.inferred-type.metadata=!] #array.{ffi::Array::_nestedDimensionsRest}{core::List<core::int>}), 0, 54.321);
} =>new ffi::Array::_<ffi::Double>([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] #array.{ffi::_Compound::_typedDataBase}{core::Object}, [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+??] [@vm.inferred-type.metadata=int (skip check)] [@vm.direct-call.metadata=dart.ffi::_Compound._offsetInBytes] [@vm.inferred-type.metadata=int?] #array.{ffi::_Compound::_offsetInBytes}{core::int}.{core::num::+}(#offset){(core::num) → core::num}, [@vm.direct-call.metadata=dart.ffi::Array._nestedDimensionsFirst] [@vm.inferred-type.metadata=int] #array.{ffi::Array::_nestedDimensionsFirst}{core::int}, [@vm.direct-call.metadata=dart.ffi::Array._variableLength] [@vm.inferred-type.metadata=dart.core::bool] #array.{ffi::Array::_variableLength}{core::bool}, [@vm.direct-call.metadata=dart.ffi::Array._nestedDimensionsRest] [@vm.inferred-type.metadata=!] #array.{ffi::Array::_nestedDimensionsRest}{core::List<core::int>}), 0, 54.321);
}
constants {
#C1 = "vm:ffi:struct-fields"
@@ -44,7 +44,115 @@ final class Vec2d extends ffi::Struct {
static get #sizeOf() → core::int
return #C15.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
}
@#C20
@#C21
final class MyStruct extends ffi::Struct {
synthetic constructor •() → self::MyStruct
: super ffi::Struct::•()
;
constructor #fromTypedDataBase(synthesized core::Object #typedDataBase, synthesized core::int #offsetInBytes) → self::MyStruct
: super ffi::Struct::_fromTypedDataBase(#typedDataBase, #offsetInBytes)
;
@#C8
constructor #fromTypedData(synthesized typ::TypedData #typedData, synthesized core::int #offset, synthesized core::int #sizeInBytes) → self::MyStruct
: super ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
;
@#C22
@#C8
get array() → ffi::Array<ffi::Uint8>
return new ffi::Array::_<ffi::Uint8>(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyStruct::array#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C10, #C17, #C23);
@#C22
@#C8
set array(synthesized ffi::Array<ffi::Uint8> #externalFieldValue) → void
return ffi::_memCopy(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyStruct::array#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #externalFieldValue.{ffi::_Compound::_typedDataBase}{core::Object}, #externalFieldValue.{ffi::_Compound::_offsetInBytes}{core::int}, #C11.{core::List::[]}(ffi::_abi()){(core::int) → core::int});
@#C8
static get array#offsetOf() → core::int
return #C11.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C8
static get #sizeOf() → core::int
return #C11.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
}
@#C28
final class MyStruct2 extends ffi::Struct {
synthetic constructor •() → self::MyStruct2
: super ffi::Struct::•()
;
constructor #fromTypedDataBase(synthesized core::Object #typedDataBase, synthesized core::int #offsetInBytes) → self::MyStruct2
: super ffi::Struct::_fromTypedDataBase(#typedDataBase, #offsetInBytes)
;
@#C8
constructor #fromTypedData(synthesized typ::TypedData #typedData, synthesized core::int #offset, synthesized core::int #sizeInBytes) → self::MyStruct2
: super ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
;
@#C29
@#C8
get array() → ffi::Array<ffi::Uint8>
return new ffi::Array::_<ffi::Uint8>(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyStruct2::array#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C24, #C17, #C23);
@#C29
@#C8
set array(synthesized ffi::Array<ffi::Uint8> #externalFieldValue) → void
return ffi::_memCopy(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyStruct2::array#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #externalFieldValue.{ffi::_Compound::_typedDataBase}{core::Object}, #externalFieldValue.{ffi::_Compound::_offsetInBytes}{core::int}, #C30.{core::List::[]}(ffi::_abi()){(core::int) → core::int});
@#C8
static get array#offsetOf() → core::int
return #C11.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C8
static get #sizeOf() → core::int
return #C30.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
}
@#C21
final class MyStruct3 extends ffi::Struct {
synthetic constructor •() → self::MyStruct3
: super ffi::Struct::•()
;
constructor #fromTypedDataBase(synthesized core::Object #typedDataBase, synthesized core::int #offsetInBytes) → self::MyStruct3
: super ffi::Struct::_fromTypedDataBase(#typedDataBase, #offsetInBytes)
;
@#C8
constructor #fromTypedData(synthesized typ::TypedData #typedData, synthesized core::int #offset, synthesized core::int #sizeInBytes) → self::MyStruct3
: super ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
;
@#C33
@#C8
get array() → ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>>
return new ffi::Array::_<ffi::Array<ffi::Array<ffi::Uint8>>>(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyStruct3::array#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C10, #C17, #C32);
@#C33
@#C8
set array(synthesized ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>> #externalFieldValue) → void
return ffi::_memCopy(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyStruct3::array#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #externalFieldValue.{ffi::_Compound::_typedDataBase}{core::Object}, #externalFieldValue.{ffi::_Compound::_offsetInBytes}{core::int}, #C11.{core::List::[]}(ffi::_abi()){(core::int) → core::int});
@#C8
static get array#offsetOf() → core::int
return #C11.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C8
static get #sizeOf() → core::int
return #C11.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
}
@#C37
final class MyStruct4 extends ffi::Struct {
synthetic constructor •() → self::MyStruct4
: super ffi::Struct::•()
;
constructor #fromTypedDataBase(synthesized core::Object #typedDataBase, synthesized core::int #offsetInBytes) → self::MyStruct4
: super ffi::Struct::_fromTypedDataBase(#typedDataBase, #offsetInBytes)
;
@#C8
constructor #fromTypedData(synthesized typ::TypedData #typedData, synthesized core::int #offset, synthesized core::int #sizeInBytes) → self::MyStruct4
: super ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
;
@#C38
@#C8
get array() → ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>>
return new ffi::Array::_<ffi::Array<ffi::Array<ffi::Uint8>>>(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyStruct4::array#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #C24, #C17, #C32);
@#C38
@#C8
set array(synthesized ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>> #externalFieldValue) → void
return ffi::_memCopy(this.{ffi::_Compound::_typedDataBase}{core::Object}, self::MyStruct4::array#offsetOf.{core::num::+}(this.{ffi::_Compound::_offsetInBytes}{core::int}){(core::num) → core::num}, #externalFieldValue.{ffi::_Compound::_typedDataBase}{core::Object}, #externalFieldValue.{ffi::_Compound::_offsetInBytes}{core::int}, #C39.{core::List::[]}(ffi::_abi()){(core::int) → core::int});
@#C8
static get array#offsetOf() → core::int
return #C11.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C8
static get #sizeOf() → core::int
return #C39.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
}
@#C44
final class MyUnion extends ffi::Union {
synthetic constructor •() → self::MyUnion
: super ffi::Union::•()
@@ -78,36 +186,36 @@ final class MyUnion extends ffi::Union {
static get #sizeOf() → core::int
return #C15.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
}
@#C26
@#C50
static get aString() → ffi::Pointer<ffi::Char>
return ffi::_loadPointer<ffi::Char>(ffi::Native::_addressOf<ffi::Pointer<ffi::Char>>(#C25), #C10);
return ffi::_loadPointer<ffi::Char>(ffi::Native::_addressOf<ffi::Pointer<ffi::Char>>(#C49), #C10);
static set aString(synthesized ffi::Pointer<ffi::Char> #externalFieldValue) → void
ffi::_storePointer<ffi::Char>(ffi::Native::_addressOf<ffi::Pointer<ffi::Char>>(#C25), #C10, #externalFieldValue);
@#C29
ffi::_storePointer<ffi::Char>(ffi::Native::_addressOf<ffi::Pointer<ffi::Char>>(#C49), #C10, #externalFieldValue);
@#C53
static get anInt() → core::int
return ffi::_loadInt32(ffi::Native::_addressOf<ffi::Int32>(#C28), #C10);
return ffi::_loadInt32(ffi::Native::_addressOf<ffi::Int32>(#C52), #C10);
static set anInt(synthesized core::int #externalFieldValue) → void
ffi::_storeInt32(ffi::Native::_addressOf<ffi::Int32>(#C28), #C10, #externalFieldValue);
@#C32
ffi::_storeInt32(ffi::Native::_addressOf<ffi::Int32>(#C52), #C10, #externalFieldValue);
@#C56
static get anotherInt() → core::int
return ffi::_loadAbiSpecificInt<ffi::Int>(ffi::Native::_addressOf<ffi::Int>(#C31), #C10);
return ffi::_loadAbiSpecificInt<ffi::Int>(ffi::Native::_addressOf<ffi::Int>(#C55), #C10);
static set anotherInt(synthesized core::int #externalFieldValue) → void
ffi::_storeAbiSpecificInt<ffi::Int>(ffi::Native::_addressOf<ffi::Int>(#C31), #C10, #externalFieldValue);
@#C35
ffi::_storeAbiSpecificInt<ffi::Int>(ffi::Native::_addressOf<ffi::Int>(#C55), #C10, #externalFieldValue);
@#C59
static get vector() → self::Vec2d
return new self::Vec2d::#fromTypedDataBase(ffi::Native::_addressOf<self::Vec2d>(#C34), #C10);
@#C38
return new self::Vec2d::#fromTypedDataBase(ffi::Native::_addressOf<self::Vec2d>(#C58), #C10);
@#C62
static get union() → self::MyUnion
return new self::MyUnion::#fromTypedDataBase(ffi::Native::_addressOf<self::MyUnion>(#C37), #C10);
return new self::MyUnion::#fromTypedDataBase(ffi::Native::_addressOf<self::MyUnion>(#C61), #C10);
static set union(synthesized self::MyUnion #externalFieldValue) → void
ffi::_memCopy(ffi::Native::_addressOf<self::MyUnion>(#C37), #C10, #externalFieldValue.{ffi::_Compound::_typedDataBase}{core::Object}, #externalFieldValue.{ffi::_Compound::_offsetInBytes}{core::int}, self::MyUnion::#sizeOf);
@#C42
@#C45
ffi::_memCopy(ffi::Native::_addressOf<self::MyUnion>(#C61), #C10, #externalFieldValue.{ffi::_Compound::_typedDataBase}{core::Object}, #externalFieldValue.{ffi::_Compound::_offsetInBytes}{core::int}, self::MyUnion::#sizeOf);
@#C64
@#C67
static get manyNumbers() → ffi::Array<ffi::Array<ffi::Array<ffi::Double>>>
return new ffi::Array::_<ffi::Array<ffi::Array<ffi::Double>>>(ffi::Native::_addressOf<ffi::Array<ffi::Array<ffi::Array<ffi::Double>>>>(#C44), #C10, #C39, #C46);
@#C42
return new ffi::Array::_<ffi::Array<ffi::Array<ffi::Double>>>(ffi::Native::_addressOf<ffi::Array<ffi::Array<ffi::Array<ffi::Double>>>>(#C66), #C10, #C24, #C48, #C68);
@#C64
static set manyNumbers(synthesized ffi::Array<ffi::Array<ffi::Array<ffi::Double>>> #externalFieldValue) → void
ffi::_memCopy(ffi::Native::_addressOf<ffi::Array<ffi::Array<ffi::Array<ffi::Double>>>>(#C44), #C10, #externalFieldValue.{ffi::_Compound::_typedDataBase}{core::Object}, #externalFieldValue.{ffi::_Compound::_offsetInBytes}{core::int}, #C48.{core::List::[]}(ffi::_abi()){(core::int) → core::int});
ffi::_memCopy(ffi::Native::_addressOf<ffi::Array<ffi::Array<ffi::Array<ffi::Double>>>>(#C66), #C10, #externalFieldValue.{ffi::_Compound::_typedDataBase}{core::Object}, #externalFieldValue.{ffi::_Compound::_offsetInBytes}{core::int}, #C70.{core::List::[]}(ffi::_abi()){(core::int) → core::int});
static method main() → void {
core::print("first char of string: ${ffi::_loadAbiSpecificInt<ffi::Char>(self::aString, #C10)}");
core::print("global int: {${self::anInt}}");
@@ -115,10 +223,10 @@ static method main() → void {
self::anInt = self::anInt.{core::num::+}(1){(core::num) → core::int};
final self::Vec2d vec = self::vector;
core::print("(${vec.{self::Vec2d::x}{core::double}}, ${vec.{self::Vec2d::y}{core::double}})");
self::union.{self::MyUnion::indirectVector} = ffi::Native::_addressOf<self::Vec2d>(#C34);
core::print(ffi::Native::_addressOf<ffi::Int>(#C31));
core::print(ffi::Native::_addressOf<self::Vec2d>(#C34));
core::print(ffi::Native::_addressOf<self::MyUnion>(#C37));
self::union.{self::MyUnion::indirectVector} = ffi::Native::_addressOf<self::Vec2d>(#C58);
core::print(ffi::Native::_addressOf<ffi::Int>(#C55));
core::print(ffi::Native::_addressOf<self::Vec2d>(#C58));
core::print(ffi::Native::_addressOf<self::MyUnion>(#C61));
final ffi::Array<ffi::Array<ffi::Array<ffi::Double>>> wholeArray = self::manyNumbers;
ffi::DoubleArray|[]=( block {
synthesized ffi::Array<dynamic> #array = ( block {
@@ -128,13 +236,13 @@ static method main() → void {
synthesized core::int #singleElementSize = #C12;
synthesized core::int #elementSize = #singleElementSize.{core::num::*}(#array.{ffi::Array::_nestedDimensionsFlattened}{core::int}){(core::num) → core::num};
synthesized core::int #offset = #elementSize.{core::num::*}(#index){(core::num) → core::num};
} =>new ffi::Array::_<ffi::Array<ffi::Double>>(#array.{ffi::_Compound::_typedDataBase}{core::Object}, #array.{ffi::_Compound::_offsetInBytes}{core::int}.{core::num::+}(#offset){(core::num) → core::num}, #array.{ffi::Array::_nestedDimensionsFirst}{core::int}, #array.{ffi::Array::_nestedDimensionsRest}{core::List<core::int>}))!;
} =>new ffi::Array::_<ffi::Array<ffi::Double>>(#array.{ffi::_Compound::_typedDataBase}{core::Object}, #array.{ffi::_Compound::_offsetInBytes}{core::int}.{core::num::+}(#offset){(core::num) → core::num}, #array.{ffi::Array::_nestedDimensionsFirst}{core::int}, #array.{ffi::Array::_variableLength}{core::bool}, #array.{ffi::Array::_nestedDimensionsRest}{core::List<core::int>}))!;
synthesized core::int #index = 1!;
#array.{ffi::Array::_checkIndex}(#index){(core::int) → void};
synthesized core::int #singleElementSize = #C12;
synthesized core::int #elementSize = #singleElementSize.{core::num::*}(#array.{ffi::Array::_nestedDimensionsFlattened}{core::int}){(core::num) → core::num};
synthesized core::int #offset = #elementSize.{core::num::*}(#index){(core::num) → core::num};
} =>new ffi::Array::_<ffi::Double>(#array.{ffi::_Compound::_typedDataBase}{core::Object}, #array.{ffi::_Compound::_offsetInBytes}{core::int}.{core::num::+}(#offset){(core::num) → core::num}, #array.{ffi::Array::_nestedDimensionsFirst}{core::int}, #array.{ffi::Array::_nestedDimensionsRest}{core::List<core::int>}), 2, 123.45);
} =>new ffi::Array::_<ffi::Double>(#array.{ffi::_Compound::_typedDataBase}{core::Object}, #array.{ffi::_Compound::_offsetInBytes}{core::int}.{core::num::+}(#offset){(core::num) → core::num}, #array.{ffi::Array::_nestedDimensionsFirst}{core::int}, #array.{ffi::Array::_variableLength}{core::bool}, #array.{ffi::Array::_nestedDimensionsRest}{core::List<core::int>}), 2, 123.45);
self::manyNumbers = wholeArray;
ffi::DoubleArray|[]=( block {
synthesized ffi::Array<dynamic> #array = ( block {
@@ -144,13 +252,13 @@ static method main() → void {
synthesized core::int #singleElementSize = #C12;
synthesized core::int #elementSize = #singleElementSize.{core::num::*}(#array.{ffi::Array::_nestedDimensionsFlattened}{core::int}){(core::num) → core::num};
synthesized core::int #offset = #elementSize.{core::num::*}(#index){(core::num) → core::num};
} =>new ffi::Array::_<ffi::Array<ffi::Double>>(#array.{ffi::_Compound::_typedDataBase}{core::Object}, #array.{ffi::_Compound::_offsetInBytes}{core::int}.{core::num::+}(#offset){(core::num) → core::num}, #array.{ffi::Array::_nestedDimensionsFirst}{core::int}, #array.{ffi::Array::_nestedDimensionsRest}{core::List<core::int>}))!;
} =>new ffi::Array::_<ffi::Array<ffi::Double>>(#array.{ffi::_Compound::_typedDataBase}{core::Object}, #array.{ffi::_Compound::_offsetInBytes}{core::int}.{core::num::+}(#offset){(core::num) → core::num}, #array.{ffi::Array::_nestedDimensionsFirst}{core::int}, #array.{ffi::Array::_variableLength}{core::bool}, #array.{ffi::Array::_nestedDimensionsRest}{core::List<core::int>}))!;
synthesized core::int #index = 0!;
#array.{ffi::Array::_checkIndex}(#index){(core::int) → void};
synthesized core::int #singleElementSize = #C12;
synthesized core::int #elementSize = #singleElementSize.{core::num::*}(#array.{ffi::Array::_nestedDimensionsFlattened}{core::int}){(core::num) → core::num};
synthesized core::int #offset = #elementSize.{core::num::*}(#index){(core::num) → core::num};
} =>new ffi::Array::_<ffi::Double>(#array.{ffi::_Compound::_typedDataBase}{core::Object}, #array.{ffi::_Compound::_offsetInBytes}{core::int}.{core::num::+}(#offset){(core::num) → core::num}, #array.{ffi::Array::_nestedDimensionsFirst}{core::int}, #array.{ffi::Array::_nestedDimensionsRest}{core::List<core::int>}), 0, 54.321);
} =>new ffi::Array::_<ffi::Double>(#array.{ffi::_Compound::_typedDataBase}{core::Object}, #array.{ffi::_Compound::_offsetInBytes}{core::int}.{core::num::+}(#offset){(core::num) → core::num}, #array.{ffi::Array::_nestedDimensionsFirst}{core::int}, #array.{ffi::Array::_variableLength}{core::bool}, #array.{ffi::Array::_nestedDimensionsRest}{core::List<core::int>}), 0, 54.321);
}
constants {
#C1 = "vm:ffi:struct-fields"
@@ -168,37 +276,59 @@ constants {
#C13 = <core::int>[#C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12]
#C14 = 16
#C15 = <core::int>[#C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14, #C14]
#C16 = TypeLiteralConstant(self::Vec2d)
#C17 = TypeLiteralConstant(ffi::Pointer<core::Object>)
#C18 = <core::Type>[#C16, #C17]
#C19 = ffi::_FfiStructLayout {fieldTypes:#C18, packing:#C4}
#C20 = core::pragma {name:#C1, options:#C19}
#C21 = "cfe:ffi:native-marker"
#C22 = "aString"
#C23 = "#lib"
#C24 = false
#C25 = ffi::Native<ffi::Pointer<ffi::Char>> {symbol:#C22, assetId:#C23, isLeaf:#C24}
#C26 = core::pragma {name:#C21, options:#C25}
#C27 = "anInt"
#C28 = ffi::Native<ffi::Int32> {symbol:#C27, assetId:#C23, isLeaf:#C24}
#C29 = core::pragma {name:#C21, options:#C28}
#C30 = "anotherInt"
#C31 = ffi::Native<ffi::Int> {symbol:#C30, assetId:#C23, isLeaf:#C24}
#C32 = core::pragma {name:#C21, options:#C31}
#C33 = "vector"
#C34 = ffi::Native<self::Vec2d> {symbol:#C33, assetId:#C23, isLeaf:#C24}
#C35 = core::pragma {name:#C21, options:#C34}
#C36 = "union"
#C37 = ffi::Native<self::MyUnion> {symbol:#C36, assetId:#C23, isLeaf:#C24}
#C38 = core::pragma {name:#C21, options:#C37}
#C39 = 1
#C40 = 2
#C41 = 3
#C42 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C39, dimension2:#C40, dimension3:#C41, dimension4:#C4, dimension5:#C4, dimensions:#C4, variableLength:#C24}
#C43 = "manyNumbers"
#C44 = ffi::Native<ffi::Array<ffi::Array<ffi::Array<ffi::Double>>>> {symbol:#C43, assetId:#C23, isLeaf:#C24}
#C45 = core::pragma {name:#C21, options:#C44}
#C46 = <core::int>[#C40, #C41]
#C47 = 48
#C48 = <core::int>[#C47, #C47, #C47, #C47, #C47, #C47, #C47, #C47, #C47, #C47, #C47, #C47, #C47, #C47, #C47, #C47, #C47, #C47, #C47, #C47, #C47, #C47]
#C16 = TypeLiteralConstant(ffi::Uint8)
#C17 = true
#C18 = ffi::_FfiInlineArray {elementType:#C16, length:#C10, variableLength:#C17}
#C19 = <core::Type>[#C18]
#C20 = ffi::_FfiStructLayout {fieldTypes:#C19, packing:#C4}
#C21 = core::pragma {name:#C1, options:#C20}
#C22 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C10, dimension2:#C4, dimension3:#C4, dimension4:#C4, dimension5:#C4, dimensions:#C4, variableDimension:#C10}
#C23 = <core::int>[]
#C24 = 1
#C25 = ffi::_FfiInlineArray {elementType:#C16, length:#C24, variableLength:#C17}
#C26 = <core::Type>[#C25]
#C27 = ffi::_FfiStructLayout {fieldTypes:#C26, packing:#C4}
#C28 = core::pragma {name:#C1, options:#C27}
#C29 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C24, dimension2:#C4, dimension3:#C4, dimension4:#C4, dimension5:#C4, dimensions:#C4, variableDimension:#C24}
#C30 = <core::int>[#C24, #C24, #C24, #C24, #C24, #C24, #C24, #C24, #C24, #C24, #C24, #C24, #C24, #C24, #C24, #C24, #C24, #C24, #C24, #C24, #C24, #C24]
#C31 = 2
#C32 = <core::int>[#C24, #C31]
#C33 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C4, dimension2:#C4, dimension3:#C4, dimension4:#C4, dimension5:#C4, dimensions:#C32, variableDimension:#C10}
#C34 = ffi::_FfiInlineArray {elementType:#C16, length:#C31, variableLength:#C17}
#C35 = <core::Type>[#C34]
#C36 = ffi::_FfiStructLayout {fieldTypes:#C35, packing:#C4}
#C37 = core::pragma {name:#C1, options:#C36}
#C38 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C4, dimension2:#C4, dimension3:#C4, dimension4:#C4, dimension5:#C4, dimensions:#C32, variableDimension:#C24}
#C39 = <core::int>[#C31, #C31, #C31, #C31, #C31, #C31, #C31, #C31, #C31, #C31, #C31, #C31, #C31, #C31, #C31, #C31, #C31, #C31, #C31, #C31, #C31, #C31]
#C40 = TypeLiteralConstant(self::Vec2d)
#C41 = TypeLiteralConstant(ffi::Pointer<core::Object>)
#C42 = <core::Type>[#C40, #C41]
#C43 = ffi::_FfiStructLayout {fieldTypes:#C42, packing:#C4}
#C44 = core::pragma {name:#C1, options:#C43}
#C45 = "cfe:ffi:native-marker"
#C46 = "aString"
#C47 = "#lib"
#C48 = false
#C49 = ffi::Native<ffi::Pointer<ffi::Char>> {symbol:#C46, assetId:#C47, isLeaf:#C48}
#C50 = core::pragma {name:#C45, options:#C49}
#C51 = "anInt"
#C52 = ffi::Native<ffi::Int32> {symbol:#C51, assetId:#C47, isLeaf:#C48}
#C53 = core::pragma {name:#C45, options:#C52}
#C54 = "anotherInt"
#C55 = ffi::Native<ffi::Int> {symbol:#C54, assetId:#C47, isLeaf:#C48}
#C56 = core::pragma {name:#C45, options:#C55}
#C57 = "vector"
#C58 = ffi::Native<self::Vec2d> {symbol:#C57, assetId:#C47, isLeaf:#C48}
#C59 = core::pragma {name:#C45, options:#C58}
#C60 = "union"
#C61 = ffi::Native<self::MyUnion> {symbol:#C60, assetId:#C47, isLeaf:#C48}
#C62 = core::pragma {name:#C45, options:#C61}
#C63 = 3
#C64 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C24, dimension2:#C31, dimension3:#C63, dimension4:#C4, dimension5:#C4, dimensions:#C4, variableDimension:#C4}
#C65 = "manyNumbers"
#C66 = ffi::Native<ffi::Array<ffi::Array<ffi::Array<ffi::Double>>>> {symbol:#C65, assetId:#C47, isLeaf:#C48}
#C67 = core::pragma {name:#C45, options:#C66}
#C68 = <core::int>[#C31, #C63]
#C69 = 48
#C70 = <core::int>[#C69, #C69, #C69, #C69, #C69, #C69, #C69, #C69, #C69, #C69, #C69, #C69, #C69, #C69, #C69, #C69, #C69, #C69, #C69, #C69, #C69, #C69]
}
@@ -1238,10 +1238,6 @@ struct Struct3BytesPackedIntCopy {
};
#pragma pack(pop)
DART_EXPORT uint64_t SizeOfStruct3BytesPackedInt() {
return sizeof(Struct3BytesPackedIntCopy);
}
// Define ssize_t for Windows as intptr_t.
#if defined(_WIN32)
typedef intptr_t ssize_t;
File diff suppressed because it is too large Load Diff
+13 -1
View File
@@ -488,7 +488,7 @@ static const NativeType* CompoundFromPragma(Zone* zone,
.Equals(Symbols::FfiStructLayoutArray()));
const auto& struct_layout_array_fields =
Array::Handle(zone, struct_layout_array_class.fields());
ASSERT(struct_layout_array_fields.Length() == 2);
ASSERT(struct_layout_array_fields.Length() == 3);
const auto& element_type_field =
Field::Handle(zone, Field::RawCast(struct_layout_array_fields.At(0)));
ASSERT(String::Handle(zone, element_type_field.UserVisibleName())
@@ -505,6 +505,18 @@ static const NativeType* CompoundFromPragma(Zone* zone,
if (*error != nullptr) {
return nullptr;
}
#if defined(DEBUG)
const auto& variable_length_field =
Field::Handle(zone, Field::RawCast(struct_layout_array_fields.At(2)));
ASSERT(String::Handle(zone, variable_length_field.UserVisibleName())
.Equals(Symbols::VariableLength()));
const auto& variable_length = Bool::Handle(
zone, Bool::RawCast(field_instance.GetField(variable_length_field)));
ASSERT(variable_length.value() == true ||
variable_length.value() == false);
#endif
const auto field_native_type =
new (zone) NativeArrayType(*element_type, length.Value());
field_native_types.Add(field_native_type);
+1
View File
@@ -281,6 +281,7 @@ class ObjectPointerVisitor;
V(Value, "value") \
V(Values, "values") \
V(VarArgs, "VarArgs") \
V(VariableLength, "variableLength") \
V(WeakArray, "WeakArray") \
V(WeakSerializationReference, "WeakSerializationReference") \
V(_AsyncStarStreamController, "_AsyncStarStreamController") \
+12 -5
View File
@@ -332,9 +332,16 @@ final class _NativeCallableListener<T extends Function>
@patch
@pragma("vm:entry-point")
final class Array<T extends NativeType> extends _Compound {
/// The size of the current dimension.
///
/// This is variable if [_variableLength] is true.
@pragma("vm:entry-point")
final int _size;
/// Whether the current dimension is variable.
@pragma("vm:entry-point")
final bool _variableLength;
@pragma("vm:entry-point")
final List<int> _nestedDimensions;
@@ -347,6 +354,7 @@ final class Array<T extends NativeType> extends _Compound {
super._typedDataBase,
super._offsetInBytes,
this._size,
this._variableLength,
this._nestedDimensions,
) : super._fromTypedDataBase();
@@ -362,13 +370,9 @@ final class Array<T extends NativeType> extends _Compound {
List<int> get _nestedDimensionsRest =>
_nestedDimensionsRestCache ??= _nestedDimensions.sublist(1);
static const _variableLengthLength = 0;
@pragma('vm:prefer-inline')
void _checkIndex(int index) {
if (_size == _variableLengthLength) {
return;
}
if (_variableLength) return;
if (index < 0 || index >= _size) {
throw RangeError.range(index, 0, _size - 1);
}
@@ -1520,6 +1524,9 @@ final class _ArraySize<T extends NativeType> implements Array<T> {
int get _size => throw UnsupportedError('_ArraySize._size');
bool get _variableLength =>
throw UnsupportedError('_ArraySize._variableLength');
Object get _typedDataBase =>
throw UnsupportedError('_ArraySize._typedDataBase');
@@ -45,6 +45,9 @@ final class _FfiInlineArray {
@pragma("vm:entry-point")
@pragma("wasm:entry-point")
final int length;
@pragma("vm:entry-point")
@pragma("wasm:entry-point")
final bool variableLength;
const _FfiInlineArray(this.elementType, this.length);
const _FfiInlineArray(this.elementType, this.length, this.variableLength);
}
+88 -34
View File
@@ -157,7 +157,7 @@ final class Array<T extends NativeType> extends _Compound {
/// }
/// ```
///
/// The variable lenght is always the outermost dimension of the array.
/// The variable length is always the outermost dimension of the array.
///
/// ```dart
/// import 'dart:ffi';
@@ -195,6 +195,51 @@ final class Array<T extends NativeType> extends _Compound {
int dimension5,
]) = _ArraySize<T>.variable;
/// Annotation to specify a variable length [Array] with a configurable
/// variable dimension ([dimension1]) in [Struct]s.
///
/// Can only be used on the last field of a struct. When [dimension1] is set
/// to a value greater than zero (`0`), the last field of the struct is taken
/// into account in [sizeOf] and [AllocatorAlloc.call]. This is particularly
/// useful when working with Windows APIs, where most structs with variable
/// length arrays are defined to have an initial dimension of one (`1`).
///
/// ```dart
/// import 'dart:ffi';
/// import 'package:ffi/ffi.dart';
///
/// final class MyStruct extends Struct {
/// @Size()
/// external int length;
///
/// @Array.variableWithVariableDimension(1)
/// external Array<Uint8> inlineArray;
///
/// static Pointer<MyStruct> allocate(Allocator allocator, int length) {
/// final lengthInBytes = sizeOf<MyStruct>() + sizeOf<Uint8>() * (length - 1);
/// final result = allocator.allocate<MyStruct>(lengthInBytes);
/// result.ref.length = length;
/// return result;
/// }
/// }
///
/// void main() {
/// final myStruct = MyStruct.allocate(calloc, 10);
/// }
/// ```
///
/// The variable length is always the outermost dimension of the array.
///
/// Do not invoke in normal code.
@Since('3.7')
const factory Array.variableWithVariableDimension([
int dimension1,
int dimension2,
int dimension3,
int dimension4,
int dimension5,
]) = _ArraySize<T>.variableWithVariableDimension;
/// Annotation to a variable length [Array] in [Struct]s.
///
/// ```dart
@@ -204,17 +249,29 @@ final class Array<T extends NativeType> extends _Compound {
/// }
///
/// final class MyStruct2 extends Struct {
/// @Array.variableMulti(variableDimension: 1, [2, 2, 2])
/// external Array<Array<Array<Array<Uint8>>>> fourDimensionalInlineArray;
/// }
///
/// final class MyStruct3 extends Struct {
/// @Array.variableMulti([2, 2, 2, 2, 2, 2, 2])
/// external Array<Array<Array<Array<Array<Array<Array<Array<Uint8>>>>>>>> eightDimensionalInlineArray;
/// }
/// ```
///
/// The variable lenght is always the outermost dimension of the array.
/// The variable length is always the outermost dimension of the array.
///
/// [variableDimension] is the outermost dimension of the variable length
/// array (defaults to zero (`0`)). When [variableDimension] is set to a value
/// greater than zero (`0`), the last field of the struct is taken into
/// account in [sizeOf] and [AllocatorAlloc.call].
///
/// Do not invoke in normal code.
@Since('3.6')
const factory Array.variableMulti(List<int> dimensions) =
_ArraySize<T>.variableMulti;
const factory Array.variableMulti(
List<int> dimensions, {
@Since('3.7') int variableDimension,
}) = _ArraySize<T>.variableMulti;
}
final class _ArraySize<T extends NativeType> implements Array<T> {
@@ -226,9 +283,9 @@ final class _ArraySize<T extends NativeType> implements Array<T> {
final List<int>? dimensions;
// When `true`, [dimension1] is [variableLengthLength], or [dimensions]
// should be prepended with [variableLengthLength].
final bool variableLength;
// When non-null, [dimension1] is equal to this value, or [dimensions] should
// be prepended with this value.
final int? variableDimension;
const _ArraySize(
this.dimension1, [
@@ -237,7 +294,7 @@ final class _ArraySize<T extends NativeType> implements Array<T> {
this.dimension4,
this.dimension5,
]) : dimensions = null,
variableLength = false;
variableDimension = null;
const _ArraySize.multi(this.dimensions)
: dimension1 = null,
@@ -245,40 +302,37 @@ final class _ArraySize<T extends NativeType> implements Array<T> {
dimension3 = null,
dimension4 = null,
dimension5 = null,
variableLength = false;
// Inline arrays in C of length 0 are undefined.
//
// GNU uses 0 to signal variable length arrays.
// https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
//
// Some Windows APIs use an inline array length of 1 for variable length
// inline arrays.
// https://devblogs.microsoft.com/oldnewthing/20040826-00/?p=38043
// However, this is perfectly valid C code.
//
// We follow the GNU standard here. This follows the behavior of structs
// with variable length arrays when malloc'ed and passed by value (the
// variable length array is ignored).
static const variableLengthLength = 0;
variableDimension = null;
const _ArraySize.variable([
this.dimension2,
this.dimension3,
this.dimension4,
this.dimension5,
]) : dimension1 = variableLengthLength,
]) : dimension1 = 0,
dimensions = null,
variableLength = true;
variableDimension = 0;
const _ArraySize.variableMulti(List<int> nestedDimensions)
: dimensions = nestedDimensions, // Should be `[0, ...nestedDimensions]`.
dimension1 = null,
dimension2 = null,
dimension3 = null,
dimension4 = null,
dimension5 = null,
variableLength = true;
const _ArraySize.variableWithVariableDimension([
this.dimension1,
this.dimension2,
this.dimension3,
this.dimension4,
this.dimension5,
]) : dimensions = null,
variableDimension = dimension1;
const _ArraySize.variableMulti(
List<int> nestedDimensions, {
int variableDimension = 0,
}) : // Should be `[variableDimension, ...nestedDimensions]`.
dimensions = nestedDimensions,
dimension1 = null,
dimension2 = null,
dimension3 = null,
dimension4 = null,
dimension5 = null,
variableDimension = variableDimension;
}
/// Extension on [Pointer] specialized for the type argument [NativeFunction].
@@ -580,6 +580,14 @@ final testCases = [
),
noChecks,
),
CallbackTest.withCheck(
"PassPointerStructInlineArrayVariable2",
Pointer.fromFunction<PassPointerStructInlineArrayVariable2Type>(
passPointerStructInlineArrayVariable2,
0,
),
noChecks,
),
CallbackTest.withCheck(
"ReturnStruct1ByteInt",
Pointer.fromFunction<ReturnStruct1ByteIntType>(returnStruct1ByteInt),
@@ -8629,6 +8637,59 @@ int passPointerStructInlineArrayVariableAlign(
return result;
}
typedef PassPointerStructInlineArrayVariable2Type =
Int64 Function(Pointer<StructInlineArrayVariable2>);
// Global variables to be able to test inputs after callback returned.
Pointer<StructInlineArrayVariable2> passPointerStructInlineArrayVariable2_a0 =
nullptr;
// Result variable also global, so we can delete it after the callback.
int passPointerStructInlineArrayVariable2Result = 0;
int passPointerStructInlineArrayVariable2CalculateResult() {
int result = 0;
result += passPointerStructInlineArrayVariable2_a0.ref.a0;
result += passPointerStructInlineArrayVariable2_a0.ref.a1[0];
result += passPointerStructInlineArrayVariable2_a0.ref.a1[1];
result += passPointerStructInlineArrayVariable2_a0.ref.a1[2];
result += passPointerStructInlineArrayVariable2_a0.ref.a1[3];
result += passPointerStructInlineArrayVariable2_a0.ref.a1[4];
result += passPointerStructInlineArrayVariable2_a0.ref.a1[5];
result += passPointerStructInlineArrayVariable2_a0.ref.a1[6];
result += passPointerStructInlineArrayVariable2_a0.ref.a1[7];
result += passPointerStructInlineArrayVariable2_a0.ref.a1[8];
result += passPointerStructInlineArrayVariable2_a0.ref.a1[9];
passPointerStructInlineArrayVariable2Result = result;
return result;
}
/// Variable length array with variable dimension of 1.
int passPointerStructInlineArrayVariable2(
Pointer<StructInlineArrayVariable2> a0,
) {
print("passPointerStructInlineArrayVariable2(${a0})");
// Possibly throw.
if (a0.ref.a0 == 42 || a0.ref.a0 == 84) {
print("throwing!");
throw Exception(
"PassPointerStructInlineArrayVariable2 throwing on purpose!",
);
}
passPointerStructInlineArrayVariable2_a0 = a0;
final result = passPointerStructInlineArrayVariable2CalculateResult();
print("result = $result");
return result;
}
typedef ReturnStruct1ByteIntType = Struct1ByteInt Function(Int8);
// Global variables to be able to test inputs after callback returned.
@@ -620,6 +620,14 @@ final testCases = [
),
noChecks,
),
CallbackTest.withCheck(
"PassPointerStructInlineArrayVariable2",
NativeCallable<PassPointerStructInlineArrayVariable2Type>.isolateLocal(
passPointerStructInlineArrayVariable2,
exceptionalReturn: 0,
),
noChecks,
),
CallbackTest.withCheck(
"ReturnStruct1ByteInt",
NativeCallable<ReturnStruct1ByteIntType>.isolateLocal(returnStruct1ByteInt),
@@ -8677,6 +8685,59 @@ int passPointerStructInlineArrayVariableAlign(
return result;
}
typedef PassPointerStructInlineArrayVariable2Type =
Int64 Function(Pointer<StructInlineArrayVariable2>);
// Global variables to be able to test inputs after callback returned.
Pointer<StructInlineArrayVariable2> passPointerStructInlineArrayVariable2_a0 =
nullptr;
// Result variable also global, so we can delete it after the callback.
int passPointerStructInlineArrayVariable2Result = 0;
int passPointerStructInlineArrayVariable2CalculateResult() {
int result = 0;
result += passPointerStructInlineArrayVariable2_a0.ref.a0;
result += passPointerStructInlineArrayVariable2_a0.ref.a1[0];
result += passPointerStructInlineArrayVariable2_a0.ref.a1[1];
result += passPointerStructInlineArrayVariable2_a0.ref.a1[2];
result += passPointerStructInlineArrayVariable2_a0.ref.a1[3];
result += passPointerStructInlineArrayVariable2_a0.ref.a1[4];
result += passPointerStructInlineArrayVariable2_a0.ref.a1[5];
result += passPointerStructInlineArrayVariable2_a0.ref.a1[6];
result += passPointerStructInlineArrayVariable2_a0.ref.a1[7];
result += passPointerStructInlineArrayVariable2_a0.ref.a1[8];
result += passPointerStructInlineArrayVariable2_a0.ref.a1[9];
passPointerStructInlineArrayVariable2Result = result;
return result;
}
/// Variable length array with variable dimension of 1.
int passPointerStructInlineArrayVariable2(
Pointer<StructInlineArrayVariable2> a0,
) {
print("passPointerStructInlineArrayVariable2(${a0})");
// Possibly throw.
if (a0.ref.a0 == 42 || a0.ref.a0 == 84) {
print("throwing!");
throw Exception(
"PassPointerStructInlineArrayVariable2 throwing on purpose!",
);
}
passPointerStructInlineArrayVariable2_a0 = a0;
final result = passPointerStructInlineArrayVariable2CalculateResult();
print("result = $result");
return result;
}
typedef ReturnStruct1ByteIntType = Struct1ByteInt Function(Int8);
// Global variables to be able to test inputs after callback returned.
@@ -95,6 +95,7 @@ void main() {
testPassPointerStruct12BytesHomogeneousInt32Leaf();
testPassPointerStructInlineArrayVariableLeaf();
testPassPointerStructInlineArrayVariableAlignLeaf();
testPassPointerStructInlineArrayVariable2Leaf();
}
}
@@ -6149,3 +6150,36 @@ void testPassPointerStructInlineArrayVariableAlignLeaf() {
calloc.free(a0);
}
final passPointerStructInlineArrayVariable2Leaf = ffiTestFunctions
.lookupFunction<
Int64 Function(Pointer<StructInlineArrayVariable2>),
int Function(Pointer<StructInlineArrayVariable2>)
>("PassPointerStructInlineArrayVariable2", isLeaf: true);
/// Variable length array with variable dimension of 1.
void testPassPointerStructInlineArrayVariable2Leaf() {
final a0 = calloc.allocate<StructInlineArrayVariable2>(
sizeOf<StructInlineArrayVariable2>() + 9 * sizeOf<Uint8>(),
);
a0.ref.a0 = 1;
a0.ref.a1[0] = 2;
a0.ref.a1[1] = 3;
a0.ref.a1[2] = 4;
a0.ref.a1[3] = 5;
a0.ref.a1[4] = 6;
a0.ref.a1[5] = 7;
a0.ref.a1[6] = 8;
a0.ref.a1[7] = 9;
a0.ref.a1[8] = 10;
a0.ref.a1[9] = 11;
final result = passPointerStructInlineArrayVariable2Leaf(a0);
print("result = $result");
Expect.equals(66, result);
calloc.free(a0);
}
@@ -98,6 +98,7 @@ void main() {
testPassPointerStruct12BytesHomogeneousInt32NativeLeaf();
testPassPointerStructInlineArrayVariableNativeLeaf();
testPassPointerStructInlineArrayVariableAlignNativeLeaf();
testPassPointerStructInlineArrayVariable2NativeLeaf();
}
}
@@ -6204,3 +6205,38 @@ void testPassPointerStructInlineArrayVariableAlignNativeLeaf() {
calloc.free(a0);
}
@Native<Int64 Function(Pointer<StructInlineArrayVariable2>)>(
symbol: 'PassPointerStructInlineArrayVariable2',
isLeaf: true,
)
external int passPointerStructInlineArrayVariable2NativeLeaf(
Pointer<StructInlineArrayVariable2> a0,
);
/// Variable length array with variable dimension of 1.
void testPassPointerStructInlineArrayVariable2NativeLeaf() {
final a0 = calloc.allocate<StructInlineArrayVariable2>(
sizeOf<StructInlineArrayVariable2>() + 9 * sizeOf<Uint8>(),
);
a0.ref.a0 = 1;
a0.ref.a1[0] = 2;
a0.ref.a1[1] = 3;
a0.ref.a1[2] = 4;
a0.ref.a1[3] = 5;
a0.ref.a1[4] = 6;
a0.ref.a1[5] = 7;
a0.ref.a1[6] = 8;
a0.ref.a1[7] = 9;
a0.ref.a1[8] = 10;
a0.ref.a1[9] = 11;
final result = passPointerStructInlineArrayVariable2NativeLeaf(a0);
print("result = $result");
Expect.equals(66, result);
calloc.free(a0);
}
@@ -98,6 +98,7 @@ void main() {
testPassPointerStruct12BytesHomogeneousInt32Native();
testPassPointerStructInlineArrayVariableNative();
testPassPointerStructInlineArrayVariableAlignNative();
testPassPointerStructInlineArrayVariable2Native();
}
}
@@ -6163,3 +6164,37 @@ void testPassPointerStructInlineArrayVariableAlignNative() {
calloc.free(a0);
}
@Native<Int64 Function(Pointer<StructInlineArrayVariable2>)>(
symbol: 'PassPointerStructInlineArrayVariable2',
)
external int passPointerStructInlineArrayVariable2Native(
Pointer<StructInlineArrayVariable2> a0,
);
/// Variable length array with variable dimension of 1.
void testPassPointerStructInlineArrayVariable2Native() {
final a0 = calloc.allocate<StructInlineArrayVariable2>(
sizeOf<StructInlineArrayVariable2>() + 9 * sizeOf<Uint8>(),
);
a0.ref.a0 = 1;
a0.ref.a1[0] = 2;
a0.ref.a1[1] = 3;
a0.ref.a1[2] = 4;
a0.ref.a1[3] = 5;
a0.ref.a1[4] = 6;
a0.ref.a1[5] = 7;
a0.ref.a1[6] = 8;
a0.ref.a1[7] = 9;
a0.ref.a1[8] = 10;
a0.ref.a1[9] = 11;
final result = passPointerStructInlineArrayVariable2Native(a0);
print("result = $result");
Expect.equals(66, result);
calloc.free(a0);
}
@@ -95,6 +95,7 @@ void main() {
testPassPointerStruct12BytesHomogeneousInt32();
testPassPointerStructInlineArrayVariable();
testPassPointerStructInlineArrayVariableAlign();
testPassPointerStructInlineArrayVariable2();
}
}
@@ -6094,3 +6095,35 @@ void testPassPointerStructInlineArrayVariableAlign() {
calloc.free(a0);
}
final passPointerStructInlineArrayVariable2 = ffiTestFunctions.lookupFunction<
Int64 Function(Pointer<StructInlineArrayVariable2>),
int Function(Pointer<StructInlineArrayVariable2>)
>("PassPointerStructInlineArrayVariable2");
/// Variable length array with variable dimension of 1.
void testPassPointerStructInlineArrayVariable2() {
final a0 = calloc.allocate<StructInlineArrayVariable2>(
sizeOf<StructInlineArrayVariable2>() + 9 * sizeOf<Uint8>(),
);
a0.ref.a0 = 1;
a0.ref.a1[0] = 2;
a0.ref.a1[1] = 3;
a0.ref.a1[2] = 4;
a0.ref.a1[3] = 5;
a0.ref.a1[4] = 6;
a0.ref.a1[5] = 7;
a0.ref.a1[6] = 8;
a0.ref.a1[7] = 9;
a0.ref.a1[8] = 10;
a0.ref.a1[9] = 11;
final result = passPointerStructInlineArrayVariable2(a0);
print("result = $result");
Expect.equals(66, result);
calloc.free(a0);
}
@@ -1305,3 +1305,33 @@ final class StructInlineArrayVariableAlign extends Struct {
String toString() => "(${a0}, ${a1})";
}
final class StructInlineArrayVariable2 extends Struct {
@Uint32()
external int a0;
@Array.variableWithVariableDimension(1)
external Array<Uint8> a1;
String toString() => "(${a0}, ${a1})";
}
final class StructInlineArrayVariableNested2 extends Struct {
@Uint32()
external int a0;
@Array.variableWithVariableDimension(1, 2, 2)
external Array<Array<Array<Uint8>>> a1;
String toString() => "(${a0}, ${a1})";
}
final class StructInlineArrayVariableNestedDeep2 extends Struct {
@Uint32()
external int a0;
@Array.variableMulti(variableDimension: 1, [2, 2, 2, 2, 2, 2])
external Array<Array<Array<Array<Array<Array<Array<Uint8>>>>>>> a1;
String toString() => "(${a0}, ${a1})";
}
File diff suppressed because it is too large Load Diff
+20 -8
View File
@@ -245,8 +245,7 @@ class Member {
String get cStructField {
String postFix = "";
if (type is FixedLengthArrayType) {
final dimensions = (type as FixedLengthArrayType).dimensions;
if (type case FixedLengthArrayType(:final dimensions)) {
postFix =
"[${dimensions.map((d) => d == 0 ? '' : d.toString()).join("][")}]";
}
@@ -488,24 +487,35 @@ class FixedLengthArrayType extends CType {
}
class VariableLengthArrayType extends FixedLengthArrayType {
VariableLengthArrayType(CType elementType) : super(elementType, 0);
VariableLengthArrayType(CType elementType, {this.variableDimension = 0})
: super(elementType, variableDimension);
factory VariableLengthArrayType.multi(
CType elementType,
List<int> fixedDimensions,
) {
List<int> fixedDimensions, {
int variableDimension = 0,
}) {
final nestedArray = FixedLengthArrayType.multi(
elementType,
fixedDimensions,
);
return VariableLengthArrayType(nestedArray);
return VariableLengthArrayType(
nestedArray,
variableDimension: variableDimension,
);
}
final int variableDimension;
String get dartStructFieldAnnotation {
if (dimensions.length > 5) {
return "@Array.variableMulti([${dimensions.skip(1).join(", ")}])";
return variableDimension > 0
? "@Array.variableMulti(variableDimension: $variableDimension, [${dimensions.skip(1).join(", ")}])"
: "@Array.variableMulti([${dimensions.skip(1).join(", ")}])";
}
return "@Array.variable(${dimensions.skip(1).join(", ")})";
return variableDimension > 0
? "@Array.variableWithVariableDimension($variableDimension, ${dimensions.skip(1).join(", ")})"
: "@Array.variable(${dimensions.skip(1).join(", ")})";
}
}
@@ -614,6 +624,8 @@ class FunctionType extends CType {
}
} else if (returnValue is UnionType && arguments.length == 1) {
return "Return${returnValue.dartCType}";
} else if (returnValue == uint64 && arguments.isEmpty) {
result = "SizeOf${reason}";
} else {
result = "Uncategorized";
}
@@ -11,6 +11,12 @@ final functions = [
...functionsReturnArgument,
];
/// Functions that return the size of each compound.
final functionsCompoundSizeOf = [
for (final compound in compounds)
FunctionType(const [], uint64, compound.name),
];
/// Functions that pass structs as arguments.
final functionsStructArguments = [
FunctionType(List.filled(10, struct1byteInt), int64, """
@@ -475,6 +481,12 @@ Variable length array""",
Variable length array with variable length element having more alignment than
the rest of the struct.""",
),
FunctionType(
[PointerType(structVariableLengthArray5)],
int64,
"""
Variable length array with variable dimension of 1.""",
),
];
/// Functions that return a struct by value.
@@ -748,6 +760,9 @@ final compounds = [
structVariableLengthArray2,
structVariableLengthArray3,
structVariableLengthArray4,
structVariableLengthArray5,
structVariableLengthArray6,
structVariableLengthArray7,
];
/// Function signatures for variadic argument tests.
@@ -1160,3 +1175,25 @@ final structVariableLengthArray4 = StructType.override([
uint8,
VariableLengthArrayType(uint32),
], "InlineArrayVariableAlign");
final structVariableLengthArray5 = StructType.override([
uint32,
VariableLengthArrayType(uint8, variableDimension: 1),
], "InlineArrayVariable2");
final structVariableLengthArray6 = StructType.override([
uint32,
VariableLengthArrayType.multi(uint8, [2, 2], variableDimension: 1),
], "InlineArrayVariableNested2");
final structVariableLengthArray7 = StructType.override([
uint32,
VariableLengthArrayType.multi(uint8, [
2,
2,
2,
2,
2,
2,
], variableDimension: 1),
], "InlineArrayVariableNestedDeep2");
@@ -9,9 +9,13 @@ import 'c_types.dart';
import 'structs_by_value_tests_configuration.dart';
import 'utils.dart';
/// The test type determines how to convert the arguments into return values
/// such that the caller knows what to check.
/// Defines the type of test, detailing how arguments are handled and return
/// values are generated for validation.
enum TestType {
/// Tested by comparing the sizes of compounds using Dart's `sizeOf` and C++'s
/// `sizeof`.
compoundSizeOf,
/// Tested by getting all the individual fields out of the structs and
/// summing their values.
structArguments,
@@ -41,6 +45,9 @@ extension on FunctionType {
return TestType.structReturn;
}
}
if (returnValue == uint64 && arguments.isEmpty) {
return TestType.compoundSizeOf;
}
// No structs, sum the arguments as well.
return TestType.structArguments;
@@ -344,8 +351,11 @@ extension on CType {
case StructType _:
final lastMember = pointerTo.memberTypes.last;
final String extraBytes = switch (lastMember) {
VariableLengthArrayType _ =>
'+ $_variableLengthLength * sizeOf<${lastMember.elementType.dartCType}>()',
VariableLengthArrayType(:final variableDimension) =>
variableDimension > 0
? '+ ${_variableLengthLength - variableDimension} * sizeOf<${lastMember.elementType.dartCType}>()'
: '+ $_variableLengthLength * sizeOf<${lastMember.elementType.dartCType}>()',
_ => '',
};
return '''
@@ -753,6 +763,13 @@ extension on FunctionType {
String expects;
switch (testType) {
case TestType.compoundSizeOf:
// Check against sizeOf.
expects = returnValue.dartExpectsStatements(
"sizeOf<$reason>()",
"result",
);
break;
case TestType.structArguments:
// Check against sum value.
final expectedResult = a.sumValue(returnValue as FundamentalType);
@@ -772,6 +789,12 @@ extension on FunctionType {
var namePostfix = isNative ? "Native" : "";
namePostfix += isLeaf ? "Leaf" : "";
final docs =
testType == TestType.compoundSizeOf
? '''
/// Tests that the Dart [sizeOf] returns the same value as the C++ `sizeof` for
/// [$reason].'''
: reason.makeDartDocComment();
return """
${isNative ? '''
@@ -782,7 +805,7 @@ final $dartName$namePostfix =
ffiTestFunctions.lookupFunction<$dartCType, $dartType>(
"$cName"${isLeaf ? ", isLeaf:true" : ""});
'''}
${reason.makeDartDocComment()}
$docs
void $dartTestName$namePostfix() {
${arguments.dartAllocateStatements()}
${assignValues}
@@ -817,6 +840,8 @@ ${assignValues}
}
switch (testType) {
case TestType.compoundSizeOf:
throw UnsupportedError("Unsupported test type: $testType");
case TestType.structArguments:
// Sum all input values.
@@ -868,6 +893,8 @@ ${arguments.addToResultStatements(true, '${dartName}_')}
String afterCallbackExpects = "";
String afterCallbackFrees = "";
switch (testType) {
case TestType.compoundSizeOf:
throw UnsupportedError("Unsupported test type: $testType");
case TestType.structArguments:
// Check that the input structs are still available.
// Check against sum value.
@@ -1043,6 +1070,11 @@ Future<void> ${dartName}AfterCallback() async {
returnStatement = 'return result % 2 != 0;';
}
switch (testType) {
case TestType.compoundSizeOf:
body = """
$returnValueType result = sizeof($reason);
""";
break;
case TestType.structArguments:
body = """
$returnValueType result = 0;
@@ -1085,9 +1117,12 @@ $varArgUnpackArguments
""";
}
final docs =
testType == TestType.compoundSizeOf
? "// Used for testing the size of $reason."
: "// Used for testing structs and unions by value.\n${reason.makeCComment()}";
return """
// Used for testing structs and unions by value.
${reason.makeCComment()}
$docs
DART_EXPORT ${returnValue.cType} $cName($argumentString) {
$varArgsUnpack
@@ -1120,6 +1155,8 @@ $varArgsUnpack
String expects = "";
String expectsZero = "";
switch (testType) {
case TestType.compoundSizeOf:
throw UnsupportedError("Unsupported test type: $testType");
case TestType.structArguments:
// Check against sum value.
final returnValue_ = returnValue as FundamentalType;
@@ -1254,6 +1291,38 @@ Future<void> writeDartCompounds() async {
await runProcess(Platform.resolvedExecutable, ["format", path]);
}
String compoundsSizeOfTestPath() =>
Platform.script
.resolve(
"../../ffi/function_structs_by_value_generated_compounds_sizeof_test.dart",
)
.toFilePath();
Future<void> writeDartCompoundsSizeOfTest(List<FunctionType> functions) async {
final StringBuffer buffer = StringBuffer();
buffer.write(headerDartCallTest(copyrightYear: 2024));
final forceDlOpen = '''
// Force dlopen so @Native lookups in DynamicLibrary.process() succeed.
dlopenGlobalPlatformSpecific('ffi_test_functions');
''';
buffer.write("""
void main() {
$forceDlOpen
${functions.map((e) => "${e.dartTestName}NativeLeaf();").join("\n ")}
}
""");
buffer.writeAll(
functions.map((e) => e.dartCallCode(isLeaf: true, isNative: true)),
);
final path = compoundsSizeOfTestPath();
await File(path).writeAsString(buffer.toString());
await runProcess(Platform.resolvedExecutable, ["format", path]);
}
headerDartCallTest({required int copyrightYear, String vmFlags = ''}) {
if (vmFlags.length != 0 && !vmFlags.endsWith(' ')) {
vmFlags += ' ';
@@ -1403,7 +1472,7 @@ Future<void> writeDartCallbackTest(
buffer.write("""
final testCases = [
${functions.map((e) => e.dartCallbackTestConstructor(isNativeCallable: isNativeCallable)).join("\n")}
${functions.map((e) => e.dartCallbackTestConstructor(isNativeCallable: isNativeCallable)).join()}
];
""");
@@ -1482,9 +1551,13 @@ Future<void> writeDartNativeCallableListenerTest(
if (isAsync) {
functions = functions.where((f) => !f.arguments.containsPointers).toList();
}
final constructors = functions
.map((e) => e.dartNativeCallableListenerTestConstructor(isAsync: isAsync))
.join("\n");
final constructors =
functions
.map(
(e) =>
e.dartNativeCallableListenerTestConstructor(isAsync: isAsync),
)
.join();
buffer.write("""
final testCases = [
@@ -1515,6 +1588,7 @@ Future<void> writeC() async {
buffer.write(headerC(copyrightYear: 2020, generatorPath: generatorPath));
buffer.writeAll(compounds.map((e) => e.cDefinition));
buffer.writeAll(functionsCompoundSizeOf.map((e) => e.cCallCode));
buffer.writeAll(functions.map((e) => e.cCallCode));
buffer.writeAll(functions.map((e) => e.cCallbackCode));
buffer.writeAll(functions.map((e) => e.cAsyncCallbackCode));
@@ -1563,6 +1637,7 @@ void main(List<String> arguments) async {
await Future.wait([
writeDartCompounds(),
writeDartCompoundsSizeOfTest(functionsCompoundSizeOf),
for (bool isLeaf in [false, true]) ...[
for (bool isNative in [false, true]) ...[
writeDartCallTest(
@@ -16,6 +16,9 @@ void main() {
testInlineArray();
testInlineArrayNested();
testInlineArrayNestedDeep();
testInlineArray2();
testInlineArrayNested2();
testInlineArrayNestedDeep2();
testSizeOf();
}
@@ -79,6 +82,67 @@ void testInlineArrayNestedDeep() {
Expect.equals(45, sum);
}
void testInlineArray2() {
const length = 10;
final lengthInBytes =
sizeOf<StructInlineArrayVariable2>() + sizeOf<Uint8>() * (length - 1);
final pointer = calloc.allocate<StructInlineArrayVariable2>(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 testInlineArrayNested2() {
const length = 10;
final lengthInBytes =
sizeOf<StructInlineArrayVariableNested2>() +
sizeOf<Uint8>() * (length - 1) * 2 * 2;
final pointer = calloc.allocate<StructInlineArrayVariableNested2>(
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 testInlineArrayNestedDeep2() {
const length = 10;
final lengthInBytes =
sizeOf<StructInlineArrayVariableNestedDeep2>() +
sizeOf<Uint8>() * (length - 1) * 2 * 2 * 2 * 2 * 2 * 2;
final pointer = calloc.allocate<StructInlineArrayVariableNestedDeep2>(
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;
@@ -88,11 +152,56 @@ final class Foo2 extends Struct {
@Int8()
external int field0;
@Array<Uint32>.variable()
@Array.variable()
external Array<Uint32> field1;
}
final class Foo3 extends Struct {
@Int8()
external int field0;
@Array.variableMulti([2, 2])
external Array<Array<Array<Uint32>>> field1;
}
final class Foo4 extends Struct {
@Int8()
external int field0;
@Array.variableWithVariableDimension(0)
external Array<Uint32> field1;
}
final class Foo5 extends Struct {
@Int8()
external int field0;
@Array.variableWithVariableDimension(1)
external Array<Uint32> field1;
}
final class Foo6 extends Struct {
@Int8()
external int field0;
@Array.variableMulti(variableDimension: 0, [2, 2])
external Array<Array<Array<Uint32>>> field1;
}
final class Foo7 extends Struct {
@Int8()
external int field0;
@Array.variableMulti(variableDimension: 1, [2, 2])
external Array<Array<Array<Uint32>>> field1;
}
void testSizeOf() {
Expect.equals(1, sizeOf<Foo>());
Expect.equals(4, sizeOf<Foo2>());
Expect.equals(4, sizeOf<Foo3>());
Expect.equals(4, sizeOf<Foo4>());
Expect.equals(8, sizeOf<Foo5>());
Expect.equals(4, sizeOf<Foo6>());
Expect.equals(20, sizeOf<Foo7>());
}
@@ -517,6 +517,13 @@ final testCases = [
),
noChecksAsync,
),
AsyncCallbackTest(
"PassPointerStructInlineArrayVariable2",
Pointer.fromFunction<PassPointerStructInlineArrayVariable2Type>(
passPointerStructInlineArrayVariable2,
),
noChecksAsync,
),
AsyncCallbackTest(
"ReturnStruct1ByteInt",
Pointer.fromFunction<ReturnStruct1ByteIntType>(returnStruct1ByteInt),
@@ -5696,6 +5703,42 @@ Future<void> passPointerStructInlineArrayVariableAlignAfterCallback() async {
Expect.approxEquals(66, result);
}
typedef PassPointerStructInlineArrayVariable2Type =
Void Function(Pointer<StructInlineArrayVariable2>);
// Global variable that stores the result.
final PassPointerStructInlineArrayVariable2Result = Completer<double>();
/// Variable length array with variable dimension of 1.
void passPointerStructInlineArrayVariable2(
Pointer<StructInlineArrayVariable2> a0,
) {
print("passPointerStructInlineArrayVariable2(${a0})");
double result = 0;
result += a0.ref.a0;
result += a0.ref.a1[0];
result += a0.ref.a1[1];
result += a0.ref.a1[2];
result += a0.ref.a1[3];
result += a0.ref.a1[4];
result += a0.ref.a1[5];
result += a0.ref.a1[6];
result += a0.ref.a1[7];
result += a0.ref.a1[8];
result += a0.ref.a1[9];
print("result = $result");
PassPointerStructInlineArrayVariable2Result.complete(result);
}
Future<void> passPointerStructInlineArrayVariable2AfterCallback() async {
final result = await PassPointerStructInlineArrayVariable2Result.future;
print("after callback result = $result");
Expect.approxEquals(66, result);
}
typedef ReturnStruct1ByteIntType = Void Function(Int8);
// Global variable that stores the result.
@@ -121,3 +121,41 @@ final class TestStruct12 extends Struct {
bool get a1 => true;
set a1(bool value) {}
}
final class TestStruct13 extends Struct {
@Array.variableWithVariableDimension(-1)
// ^^
// [analyzer] COMPILE_TIME_ERROR.NEGATIVE_VARIABLE_DIMENSION
external Array<Uint8> a0;
// ^^
// [cfe] The variable dimension of a variable-length array must be non-negative.
}
final class TestStruct14 extends Struct {
@Array.variableWithVariableDimension(0)
external Array<Uint8> a0;
}
final class TestStruct15 extends Struct {
@Array.variableWithVariableDimension(1)
external Array<Uint8> a0;
}
final class TestStruct16 extends Struct {
@Array.variableMulti(variableDimension: -1, [1, 2])
// ^^
// [analyzer] COMPILE_TIME_ERROR.NEGATIVE_VARIABLE_DIMENSION
external Array<Array<Array<Uint8>>> a0;
// ^^
// [cfe] The variable dimension of a variable-length array must be non-negative.
}
final class TestStruct17 extends Struct {
@Array.variableMulti(variableDimension: 0, [1, 2])
external Array<Array<Array<Uint8>>> a0;
}
final class TestStruct18 extends Struct {
@Array.variableMulti(variableDimension: 1, [1, 2])
external Array<Array<Array<Uint8>>> a0;
}