[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 # 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 # 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("build/config/gclient_args.gni")
import("sdk_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_leaf_test.dart",
"tests/ffi/function_structs_by_value_generated_args_native_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_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_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_leaf_test.dart",
"tests/ffi/function_structs_by_value_generated_ret_arg_native_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.""", 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. // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeNeverReachableSwitchDefaultError = const Code<Null> codeNeverReachableSwitchDefaultError =
messageNeverReachableSwitchDefaultError; messageNeverReachableSwitchDefaultError;
@@ -1740,7 +1740,7 @@ FfiCode.FFI_NATIVE_MUST_BE_EXTERNAL:
since: ~2.15 since: ~2.15
notes: |- notes: |-
The fix is to add the `external` keyword. 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 status: noFix
since: ~2.15 since: ~2.15
FfiCode.FFI_NATIVE_UNEXPECTED_NUMBER_OF_PARAMETERS: FfiCode.FFI_NATIVE_UNEXPECTED_NUMBER_OF_PARAMETERS:
@@ -1790,6 +1790,8 @@ FfiCode.NATIVE_FIELD_MISSING_TYPE:
status: needsEvaluation status: needsEvaluation
FfiCode.NATIVE_FIELD_NOT_STATIC: FfiCode.NATIVE_FIELD_NOT_STATIC:
status: needsEvaluation status: needsEvaluation
FfiCode.NEGATIVE_VARIABLE_DIMENSION:
status: noFix
FfiCode.NON_CONSTANT_TYPE_ARGUMENT: FfiCode.NON_CONSTANT_TYPE_ARGUMENT:
status: noFix status: noFix
FfiCode.NON_NATIVE_FUNCTION_TYPE_ARGUMENT_TO_POINTER: FfiCode.NON_NATIVE_FUNCTION_TYPE_ARGUMENT_TO_POINTER:
@@ -386,6 +386,13 @@ class FfiCode extends ErrorCode {
hasPublishedDocs: true, 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: /// Parameters:
/// 0: the name of the function, method, or constructor having type arguments /// 0: the name of the function, method, or constructor having type arguments
static const FfiCode NON_CONSTANT_TYPE_ARGUMENT = FfiCode( static const FfiCode NON_CONSTANT_TYPE_ARGUMENT = FfiCode(
@@ -631,6 +631,7 @@ const List<ErrorCode> errorCodeValues = [
FfiCode.NATIVE_FIELD_INVALID_TYPE, FfiCode.NATIVE_FIELD_INVALID_TYPE,
FfiCode.NATIVE_FIELD_MISSING_TYPE, FfiCode.NATIVE_FIELD_MISSING_TYPE,
FfiCode.NATIVE_FIELD_NOT_STATIC, FfiCode.NATIVE_FIELD_NOT_STATIC,
FfiCode.NEGATIVE_VARIABLE_DIMENSION,
FfiCode.NON_CONSTANT_TYPE_ARGUMENT, FfiCode.NON_CONSTANT_TYPE_ARGUMENT,
FfiCode.NON_NATIVE_FUNCTION_TYPE_ARGUMENT_TO_POINTER, FfiCode.NON_NATIVE_FUNCTION_TYPE_ARGUMENT_TO_POINTER,
FfiCode.NON_POSITIVE_ARRAY_DIMENSION, FfiCode.NON_POSITIVE_ARRAY_DIMENSION,
@@ -1991,28 +1991,54 @@ class FfiVerifier extends RecursiveAstVisitor<void> {
} }
} }
// Check dimensions are positive. // Check dimensions are valid.
List<AstNode>? getArgumentNodes() { (List<AstNode>? dimensionsNodes, AstNode? variableDimensionNode)
var arguments = annotation.arguments?.arguments; getArgumentNodes() {
if (arguments != null && arguments.length == 1) { return switch (annotation.arguments) {
var firstArgument = arguments[0]; // `@Array.variableMulti([..], variableDimension: ..)`
if (firstArgument is ListLiteral) { ArgumentList(
return firstArgument.elements; arguments: [ListLiteral dimensions, NamedExpression variableDimension]
} ) =>
} (dimensions.elements, variableDimension.expression),
return arguments; // `@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++) { for (int i = 0; i < dimensions.length; i++) {
if (i == 0 && variableLength) { if (dimensionsNodes case var dimensionsNodes?) {
continue; // First dimension is variable. if (dimensionsNodes.length > i && variableDimensionNode == null) {
} var node = dimensionsNodes[i];
if (dimensions[i] <= 0) { errorNode = node is NamedExpression ? node.expression : node;
AstNode errorNode = annotation;
var argumentNodes = getArgumentNodes();
if (argumentNodes != null && argumentNodes.isNotEmpty) {
errorNode = argumentNodes[i];
} }
}
// 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( _errorReporter.atNode(
errorNode, errorNode,
FfiCode.NON_POSITIVE_ARRAY_DIMENSION, FfiCode.NON_POSITIVE_ARRAY_DIMENSION,
@@ -2093,8 +2119,8 @@ extension on ElementAnnotation {
assert(isArray); assert(isArray);
var value = computeConstantValue(); var value = computeConstantValue();
var variableLength = var variableDimension = value?.getField('variableDimension')?.toIntValue();
value?.getField('variableLength')?.toBoolValue() ?? false; var variableLength = variableDimension != null;
// Element of `@Array.multi([1, 2, 3])`. // Element of `@Array.multi([1, 2, 3])`.
var listField = value?.getField('dimensions'); var listField = value?.getField('dimensions');
@@ -2105,7 +2131,10 @@ extension on ElementAnnotation {
.whereType<int>() .whereType<int>()
.toList(); .toList();
if (listValues != null) { 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') @Since('2.13')
final class Array<T extends NativeType> extends _Compound { final class Array<T extends NativeType> extends _Compound {
const factory Array(int dimension1, const factory Array(
[int dimension2, int dimension1, [
int dimension3, int dimension2,
int dimension4, int dimension3,
int dimension5]) = _ArraySize<T>; int dimension4,
int dimension5,
]) = _ArraySize<T>;
const factory Array.multi(List<int> dimensions) = _ArraySize<T>.multi; const factory Array.multi(List<int> dimensions) = _ArraySize<T>.multi;
@Since('3.6') @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') @Since('3.6')
const factory Array.variableMulti(List<int> dimensions) = const factory Array.variableMulti(
_ArraySize<T>.variableMulti; List<int> dimensions, {
@Since('3.7') int variableDimension,
}) = _ArraySize<T>.variableMulti;
} }
final class _ArraySize<T extends NativeType> implements Array<T> { 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 List<int>? dimensions;
final bool variableLength; final int? variableDimension;
const _ArraySize( const _ArraySize(
this.dimension1, [ this.dimension1, [
@@ -936,7 +954,7 @@ final class _ArraySize<T extends NativeType> implements Array<T> {
this.dimension4, this.dimension4,
this.dimension5, this.dimension5,
]) : dimensions = null, ]) : dimensions = null,
variableLength = false; variableDimension = null;
const _ArraySize.multi(this.dimensions) const _ArraySize.multi(this.dimensions)
: dimension1 = null, : dimension1 = null,
@@ -944,27 +962,36 @@ final class _ArraySize<T extends NativeType> implements Array<T> {
dimension3 = null, dimension3 = null,
dimension4 = null, dimension4 = null,
dimension5 = null, dimension5 = null,
variableLength = false; variableDimension = null;
static const variableLengthLength = 0;
const _ArraySize.variable([ const _ArraySize.variable([
this.dimension2, this.dimension2,
this.dimension3, this.dimension3,
this.dimension4, this.dimension4,
this.dimension5, this.dimension5,
]) : dimension1 = variableLengthLength, ]) : dimension1 = 0,
dimensions = null, dimensions = null,
variableLength = true; variableDimension = 0;
const _ArraySize.variableMulti(List<int> nestedDimensions) const _ArraySize.variableWithVariableDimension([
: dimensions = nestedDimensions, 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, dimension1 = null,
dimension2 = null, dimension2 = null,
dimension3 = null, dimension3 = null,
dimension4 = null, dimension4 = null,
dimension5 = null, dimension5 = null,
variableLength = true; variableDimension = variableDimension;
} }
extension StructPointer<T extends Struct> on Pointer<T> { extension StructPointer<T extends Struct> on Pointer<T> {
+73 -2
View File
@@ -20400,6 +20400,76 @@ FfiCode:
NativeCallable<Void Function(Int32)>.listener(f); 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: NON_CONSTANT_TYPE_ARGUMENT:
problemMessage: "The type arguments to '{0}' must be known at compile time, so they can't be type parameters." 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. correctionMessage: Try changing the type argument to be a constant type.
@@ -20515,7 +20585,7 @@ FfiCode:
#### Example #### Example
The following code produces this diagnostic because an array dimension of The following code produces this diagnostic because an array dimension of
`-1` was provided: `-8` was provided:
```dart ```dart
import 'dart:ffi'; 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 ```dart
import 'dart:ffi'; 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 'extra_size_annotation_carray_test.dart' as extra_size_annotation_carray;
import 'extraneous_modifier_test.dart' as extraneous_modifier; import 'extraneous_modifier_test.dart' as extraneous_modifier;
import 'ffi_address_of_cast_test.dart' as ffi_addresss_of_cast_test; 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_async_callback_test.dart' as ffi_async_callback_test;
import 'ffi_leaf_call_must_not_use_handle_test.dart' import 'ffi_leaf_call_must_not_use_handle_test.dart'
as ffi_leaf_call_must_not_use_handle; as ffi_leaf_call_must_not_use_handle;
@@ -1128,6 +1129,7 @@ main() {
extra_size_annotation_carray.main(); extra_size_annotation_carray.main();
extraneous_modifier.main(); extraneous_modifier.main();
ffi_addresss_of_cast_test.main(); ffi_addresss_of_cast_test.main();
ffi_array_test.main();
ffi_async_callback_test.main(); ffi_async_callback_test.main();
ffi_leaf_call_must_not_use_handle.main(); ffi_leaf_call_must_not_use_handle.main();
ffi_native_test.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 ### new_with_undefined_constructor_default
_The class '{0}' doesn't have an unnamed constructor._ _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 #### Example
The following code produces this diagnostic because an array dimension of The following code produces this diagnostic because an array dimension of
`-1` was provided: `-8` was provided:
```dart ```dart
import 'dart:ffi'; 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 ```dart
import 'dart:ffi'; import 'dart:ffi';
+1
View File
@@ -780,6 +780,7 @@ NamedMixinOverride/analyzerCode: Fail
NamedMixinOverride/example: Fail NamedMixinOverride/example: Fail
NamedParametersInExtensionTypeDeclaration/analyzerCode: Fail NamedParametersInExtensionTypeDeclaration/analyzerCode: Fail
NativeClauseShouldBeAnnotation/example: Fail NativeClauseShouldBeAnnotation/example: Fail
NegativeVariableDimension/analyzerCode: Fail
NeverReachableSwitchDefaultError/analyzerCode: Fail NeverReachableSwitchDefaultError/analyzerCode: Fail
NeverReachableSwitchDefaultError/example: Fail NeverReachableSwitchDefaultError/example: Fail
NeverReachableSwitchDefaultWarning/analyzerCode: Fail NeverReachableSwitchDefaultWarning/analyzerCode: Fail
+5
View File
@@ -5432,6 +5432,11 @@ NonNullAwareSpreadIsNull:
<int>[...null]; <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: NonPositiveArrayDimensions:
# Used by dart:ffi # Used by dart:ffi
problemMessage: "Array dimensions must be positive numbers." problemMessage: "Array dimensions must be positive numbers."
@@ -9,9 +9,9 @@ final class StructInlineArray extends ffi::Struct {
synthetic constructor •() → self::StructInlineArray synthetic constructor •() → self::StructInlineArray
: super ffi::Struct::•() : super ffi::Struct::•()
; ;
@#C4 @#C3
external get a0() → ffi::Array<ffi::Uint8>; external get a0() → ffi::Array<ffi::Uint8>;
@#C4 @#C3
external set a0(synthesized ffi::Array<ffi::Uint8> #externalFieldValue) → void; external set a0(synthesized ffi::Array<ffi::Uint8> #externalFieldValue) → void;
} }
static method main() → dynamic {} static method main() → dynamic {}
@@ -19,8 +19,7 @@ static method main() → dynamic {}
constants { constants {
#C1 = 8 #C1 = 8
#C2 = null #C2 = null
#C3 = false #C3 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C1, dimension2:#C2, dimension3:#C2, dimension4:#C2, dimension5:#C2, dimensions:#C2, variableDimension:#C2}
#C4 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C1, dimension2:#C2, dimension3:#C2, dimension4:#C2, dimension5:#C2, dimensions:#C2, variableLength:#C3}
} }
@@ -9,9 +9,9 @@ final class StructInlineArray extends ffi::Struct {
synthetic constructor •() → self::StructInlineArray synthetic constructor •() → self::StructInlineArray
: super ffi::Struct::•() : super ffi::Struct::•()
; ;
@#C4 @#C3
external get a0() → ffi::Array<ffi::Uint8>; external get a0() → ffi::Array<ffi::Uint8>;
@#C4 @#C3
external set a0(synthesized ffi::Array<ffi::Uint8> #externalFieldValue) → void; external set a0(synthesized ffi::Array<ffi::Uint8> #externalFieldValue) → void;
} }
static method main() → dynamic {} static method main() → dynamic {}
@@ -19,8 +19,7 @@ static method main() → dynamic {}
constants { constants {
#C1 = 8 #C1 = 8
#C2 = null #C2 = null
#C3 = false #C3 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C1, dimension2:#C2, dimension3:#C2, dimension4:#C2, dimension5:#C2, dimensions:#C2, variableDimension:#C2}
#C4 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C1, dimension2:#C2, dimension3:#C2, dimension4:#C2, dimension5:#C2, dimensions:#C2, variableLength:#C3}
} }
@@ -18,6 +18,6 @@ static method main() → dynamic
Extra constant evaluation status: 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.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.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})
Extra constant evaluation: evaluated: 2, effectively constant: 2 Extra constant evaluation: evaluated: 2, effectively constant: 2
@@ -7,7 +7,7 @@ import "dart:typed_data" as typ;
import "dart:ffi"; import "dart:ffi";
import "package:ffi/ffi.dart"; import "package:ffi/ffi.dart";
@#C8 @#C9
final class StructInlineArray extends ffi::Struct { final class StructInlineArray extends ffi::Struct {
synthetic constructor •() → self::StructInlineArray synthetic constructor •() → self::StructInlineArray
: super ffi::Struct::•() : 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 constructor #fromTypedDataBase(synthesized core::Object #typedDataBase, synthesized core::int #offsetInBytes) → self::StructInlineArray
: super ffi::Struct::_fromTypedDataBase(#typedDataBase, #offsetInBytes) : super ffi::Struct::_fromTypedDataBase(#typedDataBase, #offsetInBytes)
; ;
@#C10 @#C11
constructor #fromTypedData(synthesized typ::TypedData #typedData, synthesized core::int #offset, synthesized core::int #sizeInBytes) → self::StructInlineArray constructor #fromTypedData(synthesized typ::TypedData #typedData, synthesized core::int #offset, synthesized core::int #sizeInBytes) → self::StructInlineArray
: super ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes) : super ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
; ;
@#C12 @#C12
@#C10 @#C11
get a0() → ffi::Array<ffi::Uint8> 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 @#C12
@#C10 @#C11
set a0(synthesized ffi::Array<ffi::Uint8> #externalFieldValue) → void 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}); 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 static get a0#offsetOf() → core::int
return #C16.{core::List::[]}(ffi::_abi()){(core::int) → core::int}; return #C16.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C10 @#C11
static get #sizeOf() → core::int static get #sizeOf() → core::int
return #C14.{core::List::[]}(ffi::_abi()){(core::int) → core::int}; return #C14.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
} }
@@ -40,15 +40,15 @@ constants {
#C1 = "vm:ffi:struct-fields" #C1 = "vm:ffi:struct-fields"
#C2 = TypeLiteralConstant(ffi::Uint8) #C2 = TypeLiteralConstant(ffi::Uint8)
#C3 = 8 #C3 = 8
#C4 = ffi::_FfiInlineArray {elementType:#C2, length:#C3} #C4 = false
#C5 = <core::Type>[#C4] #C5 = ffi::_FfiInlineArray {elementType:#C2, length:#C3, variableLength:#C4}
#C6 = null #C6 = <core::Type>[#C5]
#C7 = ffi::_FfiStructLayout {fieldTypes:#C5, packing:#C6} #C7 = null
#C8 = core::pragma {name:#C1, options:#C7} #C8 = ffi::_FfiStructLayout {fieldTypes:#C6, packing:#C7}
#C9 = "vm:prefer-inline" #C9 = core::pragma {name:#C1, options:#C8}
#C10 = core::pragma {name:#C9, options:#C6} #C10 = "vm:prefer-inline"
#C11 = false #C11 = core::pragma {name:#C10, options:#C7}
#C12 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C3, dimension2:#C6, dimension3:#C6, dimension4:#C6, dimension5:#C6, dimensions:#C6, variableLength:#C11} #C12 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C3, dimension2:#C7, dimension3:#C7, dimension4:#C7, dimension5:#C7, dimensions:#C7, variableDimension:#C7}
#C13 = <core::int>[] #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] #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 #C15 = 0
@@ -10,26 +10,25 @@ final class StructInlineArrayMultiDimensional extends ffi::Struct {
synthetic constructor •() → self::StructInlineArrayMultiDimensional synthetic constructor •() → self::StructInlineArrayMultiDimensional
: super ffi::Struct::•() : super ffi::Struct::•()
; ;
@#C4 @#C3
external get a0() → ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>>; 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; external set a0(synthesized ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>> #externalFieldValue) → void;
} }
static method main() → dynamic { 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 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::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); 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); 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 { constants {
#C1 = 2 #C1 = 2
#C2 = null #C2 = null
#C3 = false #C3 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C1, dimension2:#C1, dimension3:#C1, dimension4:#C2, dimension5:#C2, dimensions:#C2, variableDimension:#C2}
#C4 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C1, dimension2:#C1, dimension3:#C1, dimension4:#C2, dimension5:#C2, dimensions:#C2, variableLength:#C3} #C4 = all::CallocAllocator {}
#C5 = all::CallocAllocator {}
} }
@@ -10,26 +10,25 @@ final class StructInlineArrayMultiDimensional extends ffi::Struct {
synthetic constructor •() → self::StructInlineArrayMultiDimensional synthetic constructor •() → self::StructInlineArrayMultiDimensional
: super ffi::Struct::•() : super ffi::Struct::•()
; ;
@#C4 @#C3
external get a0() → ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>>; 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; external set a0(synthesized ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>> #externalFieldValue) → void;
} }
static method main() → dynamic { 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 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::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); 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); 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 { constants {
#C1 = 2 #C1 = 2
#C2 = null #C2 = null
#C3 = false #C3 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C1, dimension2:#C1, dimension3:#C1, dimension4:#C2, dimension5:#C2, dimensions:#C2, variableDimension:#C2}
#C4 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C1, dimension2:#C1, dimension3:#C1, dimension4:#C2, dimension5:#C2, dimensions:#C2, variableLength:#C3} #C4 = all::CallocAllocator {}
#C5 = all::CallocAllocator {}
} }
@@ -18,6 +18,6 @@ static method main() → dynamic
Extra constant evaluation status: 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.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.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})
Extra constant evaluation: evaluated: 2, effectively constant: 2 Extra constant evaluation: evaluated: 2, effectively constant: 2
@@ -8,7 +8,7 @@ import "package:ffi/src/allocation.dart" as all;
import "dart:ffi"; import "dart:ffi";
import "package:ffi/ffi.dart"; import "package:ffi/ffi.dart";
@#C8 @#C9
final class StructInlineArrayMultiDimensional extends ffi::Struct { final class StructInlineArrayMultiDimensional extends ffi::Struct {
synthetic constructor •() → self::StructInlineArrayMultiDimensional synthetic constructor •() → self::StructInlineArrayMultiDimensional
: super ffi::Struct::•() : 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 constructor #fromTypedDataBase(synthesized core::Object #typedDataBase, synthesized core::int #offsetInBytes) → self::StructInlineArrayMultiDimensional
: super ffi::Struct::_fromTypedDataBase(#typedDataBase, #offsetInBytes) : super ffi::Struct::_fromTypedDataBase(#typedDataBase, #offsetInBytes)
; ;
@#C10 @#C11
constructor #fromTypedData(synthesized typ::TypedData #typedData, synthesized core::int #offset, synthesized core::int #sizeInBytes) → self::StructInlineArrayMultiDimensional constructor #fromTypedData(synthesized typ::TypedData #typedData, synthesized core::int #offset, synthesized core::int #sizeInBytes) → self::StructInlineArrayMultiDimensional
: super ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes) : super ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
; ;
@#C13 @#C13
@#C10 @#C11
get a0() → ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>> 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 @#C13
@#C10 @#C11
set a0(synthesized ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>> #externalFieldValue) → void 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}); 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 static get a0#offsetOf() → core::int
return #C17.{core::List::[]}(ffi::_abi()){(core::int) → core::int}; return #C17.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C10 @#C11
static get #sizeOf() → core::int static get #sizeOf() → core::int
return #C15.{core::List::[]}(ffi::_abi()){(core::int) → 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 #singleElementSize = #C19;
synthesized core::int #elementSize = #singleElementSize.{core::num::*}(#array.{ffi::Array::_nestedDimensionsFlattened}{core::int}){(core::num) → core::num}; 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}; 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 { block {
synthesized ffi::Array<dynamic> #array = array!; synthesized ffi::Array<dynamic> #array = array!;
synthesized core::int #index = 1!; synthesized core::int #index = 1!;
@@ -63,17 +63,17 @@ constants {
#C1 = "vm:ffi:struct-fields" #C1 = "vm:ffi:struct-fields"
#C2 = TypeLiteralConstant(ffi::Uint8) #C2 = TypeLiteralConstant(ffi::Uint8)
#C3 = 8 #C3 = 8
#C4 = ffi::_FfiInlineArray {elementType:#C2, length:#C3} #C4 = false
#C5 = <core::Type>[#C4] #C5 = ffi::_FfiInlineArray {elementType:#C2, length:#C3, variableLength:#C4}
#C6 = null #C6 = <core::Type>[#C5]
#C7 = ffi::_FfiStructLayout {fieldTypes:#C5, packing:#C6} #C7 = null
#C8 = core::pragma {name:#C1, options:#C7} #C8 = ffi::_FfiStructLayout {fieldTypes:#C6, packing:#C7}
#C9 = "vm:prefer-inline" #C9 = core::pragma {name:#C1, options:#C8}
#C10 = core::pragma {name:#C9, options:#C6} #C10 = "vm:prefer-inline"
#C11 = 2 #C11 = core::pragma {name:#C10, options:#C7}
#C12 = false #C12 = 2
#C13 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C11, dimension2:#C11, dimension3:#C11, dimension4:#C6, dimension5:#C6, dimensions:#C6, variableLength:#C12} #C13 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C12, dimension2:#C12, dimension3:#C12, dimension4:#C7, dimension5:#C7, dimensions:#C7, variableDimension:#C7}
#C14 = <core::int>[#C11, #C11] #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] #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 #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] #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: 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:18:25 -> IntConstant(0)
Evaluated: NullCheck @ org-dartlang-testcase:///ffi_struct_inline_array_multi_dimensional.dart:19:8 -> IntConstant(1) 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: Constructor coverage from constants:
@@ -14,6 +14,7 @@ import 'package:front_end/src/codes/cfe_codes.dart'
messageFfiLeafCallMustNotReturnHandle, messageFfiLeafCallMustNotReturnHandle,
messageFfiLeafCallMustNotTakeHandle, messageFfiLeafCallMustNotTakeHandle,
messageFfiVariableLengthArrayNotLast, messageFfiVariableLengthArrayNotLast,
messageNegativeVariableDimension,
messageNonPositiveArrayDimensions, messageNonPositiveArrayDimensions,
templateFfiSizeAnnotation, templateFfiSizeAnnotation,
templateFfiSizeAnnotationDimensions, templateFfiSizeAnnotationDimensions,
@@ -224,7 +225,7 @@ class FfiTransformer extends Transformer {
final Field arraySizeDimension4Field; final Field arraySizeDimension4Field;
final Field arraySizeDimension5Field; final Field arraySizeDimension5Field;
final Field arraySizeDimensionsField; final Field arraySizeDimensionsField;
final Field arraySizeVariableLengthField; final Field arraySizeVariableDimensionField;
final Class pointerClass; final Class pointerClass;
final Class compoundClass; final Class compoundClass;
final Class structClass; final Class structClass;
@@ -241,6 +242,7 @@ class FfiTransformer extends Transformer {
final Class ffiInlineArrayClass; final Class ffiInlineArrayClass;
final Field ffiInlineArrayElementTypeField; final Field ffiInlineArrayElementTypeField;
final Field ffiInlineArrayLengthField; final Field ffiInlineArrayLengthField;
final Field ffiInlineArrayVariableLengthField;
final Class packedClass; final Class packedClass;
final Field packedMemberAlignmentField; final Field packedMemberAlignmentField;
final Procedure allocateMethod; final Procedure allocateMethod;
@@ -286,6 +288,7 @@ class FfiTransformer extends Transformer {
final Field compoundTypedDataBaseField; final Field compoundTypedDataBaseField;
final Field compoundOffsetInBytesField; final Field compoundOffsetInBytesField;
final Field arraySizeField; final Field arraySizeField;
final Field arrayVariableLengthField;
final Field arrayNestedDimensionsField; final Field arrayNestedDimensionsField;
final Procedure arrayCheckIndex; final Procedure arrayCheckIndex;
final Procedure arrayNestedDimensionsFlattened; final Procedure arrayNestedDimensionsFlattened;
@@ -415,8 +418,8 @@ class FfiTransformer extends Transformer {
index.getField('dart:ffi', '_ArraySize', 'dimension5'), index.getField('dart:ffi', '_ArraySize', 'dimension5'),
arraySizeDimensionsField = arraySizeDimensionsField =
index.getField('dart:ffi', '_ArraySize', 'dimensions'), index.getField('dart:ffi', '_ArraySize', 'dimensions'),
arraySizeVariableLengthField = arraySizeVariableDimensionField =
index.getField('dart:ffi', '_ArraySize', 'variableLength'), index.getField('dart:ffi', '_ArraySize', 'variableDimension'),
pointerClass = index.getClass('dart:ffi', 'Pointer'), pointerClass = index.getClass('dart:ffi', 'Pointer'),
compoundClass = index.getClass('dart:ffi', '_Compound'), compoundClass = index.getClass('dart:ffi', '_Compound'),
structClass = index.getClass('dart:ffi', 'Struct'), structClass = index.getClass('dart:ffi', 'Struct'),
@@ -442,6 +445,8 @@ class FfiTransformer extends Transformer {
index.getField('dart:ffi', '_FfiInlineArray', 'elementType'), index.getField('dart:ffi', '_FfiInlineArray', 'elementType'),
ffiInlineArrayLengthField = ffiInlineArrayLengthField =
index.getField('dart:ffi', '_FfiInlineArray', 'length'), index.getField('dart:ffi', '_FfiInlineArray', 'length'),
ffiInlineArrayVariableLengthField =
index.getField('dart:ffi', '_FfiInlineArray', 'variableLength'),
packedClass = index.getClass('dart:ffi', 'Packed'), packedClass = index.getClass('dart:ffi', 'Packed'),
packedMemberAlignmentField = packedMemberAlignmentField =
index.getField('dart:ffi', 'Packed', 'memberAlignment'), index.getField('dart:ffi', 'Packed', 'memberAlignment'),
@@ -458,6 +463,8 @@ class FfiTransformer extends Transformer {
compoundOffsetInBytesField = compoundOffsetInBytesField =
index.getField('dart:ffi', '_Compound', '_offsetInBytes'), index.getField('dart:ffi', '_Compound', '_offsetInBytes'),
arraySizeField = index.getField('dart:ffi', 'Array', '_size'), arraySizeField = index.getField('dart:ffi', 'Array', '_size'),
arrayVariableLengthField =
index.getField('dart:ffi', 'Array', '_variableLength'),
arrayNestedDimensionsField = arrayNestedDimensionsField =
index.getField('dart:ffi', 'Array', '_nestedDimensions'), index.getField('dart:ffi', 'Array', '_nestedDimensions'),
arrayCheckIndex = arrayCheckIndex =
@@ -1025,10 +1032,19 @@ class FfiTransformer extends Transformer {
node.fileUri, node.fileUri,
); );
} }
return dimensions; // Variable length single dimension.
} }
for (var dimension in dimensions) { for (var i = 0; i < dimensions.length; i++) {
if (dimension <= 0) { // 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, diagnosticReporter.report(messageNonPositiveArrayDimensions,
node.fileOffset, node.name.text.length, node.fileUri); node.fileOffset, node.name.text.length, node.fileUri);
success = false; success = false;
@@ -1062,18 +1078,18 @@ class FfiTransformer extends Transformer {
/// Reads the dimensions from a constant instance of `_ArraySize`. /// Reads the dimensions from a constant instance of `_ArraySize`.
(List<int>, bool) _arraySize(InstanceConstant constant) { (List<int>, bool) _arraySize(InstanceConstant constant) {
final variableLength = final variableDimension =
(constant.fieldValues[arraySizeVariableLengthField.fieldReference] constant.fieldValues[arraySizeVariableDimensionField.fieldReference];
as BoolConstant) final variableLength = variableDimension is IntConstant;
.value;
final dimensions = final dimensions =
constant.fieldValues[arraySizeDimensionsField.fieldReference]; constant.fieldValues[arraySizeDimensionsField.fieldReference];
if (dimensions != null) { if (dimensions is ListConstant) {
if (dimensions is ListConstant) { final result =
final result = dimensions.entries.whereType<IntConstant>().map((e) => e.value);
dimensions.entries.whereType<IntConstant>().map((e) => e.value); return (
return ([if (variableLength) 0, ...result], variableLength); [if (variableLength) variableDimension.value, ...result],
} variableLength,
);
} }
final dimensionFields = [ final dimensionFields = [
arraySizeDimension1Field, arraySizeDimension1Field,
@@ -683,6 +683,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
final sizeAnnotations = getArraySizeAnnotations(m).toList(); final sizeAnnotations = getArraySizeAnnotations(m).toList();
if (sizeAnnotations.length == 1) { if (sizeAnnotations.length == 1) {
final arrayDimensions = sizeAnnotations.single.$1; final arrayDimensions = sizeAnnotations.single.$1;
final variableLength = sizeAnnotations.single.$2;
if (this.arrayDimensions(dartType) == arrayDimensions.length) { if (this.arrayDimensions(dartType) == arrayDimensions.length) {
final elementType = arraySingleElementType(dartType); final elementType = arraySingleElementType(dartType);
if (elementType is! InterfaceType) { if (elementType is! InterfaceType) {
@@ -691,7 +692,8 @@ class _FfiDefinitionTransformer extends FfiTransformer {
} else { } else {
type = NativeTypeCfe(this, dartType, type = NativeTypeCfe(this, dartType,
compoundCache: compoundCache, compoundCache: compoundCache,
arrayDimensions: arrayDimensions); arrayDimensions: arrayDimensions,
variableLength: variableLength);
} }
} else { } else {
type = InvalidNativeTypeCfe("Invalid array dimensions."); type = InvalidNativeTypeCfe("Invalid array dimensions.");
@@ -903,7 +905,12 @@ class _FfiDefinitionTransformer extends FfiTransformer {
fieldType.fieldValues[ffiInlineArrayLengthField.fieldReference] fieldType.fieldValues[ffiInlineArrayLengthField.fieldReference]
as IntConstant; as IntConstant;
final arrayLength = arrayLengthConstant.value; 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) { if (compoundClass.superclass == structClass) {
@@ -767,7 +767,8 @@ class FfiNativeTransformer extends FfiTransformer {
final dimensions = ensureArraySizeAnnotation(node, ffiType, false); final dimensions = ensureArraySizeAnnotation(node, ffiType, false);
return ( return (
ffiType, ffiType,
NativeTypeCfe.withoutLayout(this, dartType, arrayDimensions: dimensions) NativeTypeCfe.withoutLayout(this, dartType,
arrayDimensions: dimensions, variableLength: false)
); );
} }
@@ -22,13 +22,14 @@ sealed class NativeTypeCfe {
FfiTransformer transformer, FfiTransformer transformer,
DartType dartType, { DartType dartType, {
List<int>? arrayDimensions, List<int>? arrayDimensions,
bool? variableLength,
}) { }) {
if (transformer.isStructOrUnionSubtype(dartType)) { if (transformer.isStructOrUnionSubtype(dartType)) {
return ReferencedCompoundSubtypeCfe( return ReferencedCompoundSubtypeCfe(
(dartType as InterfaceType).classNode); (dartType as InterfaceType).classNode);
} else { } else {
return NativeTypeCfe(transformer, dartType, return NativeTypeCfe(transformer, dartType,
arrayDimensions: arrayDimensions); arrayDimensions: arrayDimensions, variableLength: variableLength);
} }
} }
@@ -36,6 +37,7 @@ sealed class NativeTypeCfe {
FfiTransformer transformer, FfiTransformer transformer,
DartType dartType, { DartType dartType, {
List<int>? arrayDimensions, List<int>? arrayDimensions,
bool? variableLength,
Map<Class, NativeTypeCfe> compoundCache = const {}, Map<Class, NativeTypeCfe> compoundCache = const {},
bool alreadyInAbiSpecificType = false, bool alreadyInAbiSpecificType = false,
}) { }) {
@@ -62,13 +64,17 @@ sealed class NativeTypeCfe {
if (arrayDimensions.isEmpty) { if (arrayDimensions.isEmpty) {
throw "Must have a size for this array dimension."; 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 elementType = transformer.arraySingleElementType(dartType);
final elementCfeType = final elementCfeType = NativeTypeCfe(transformer, elementType,
NativeTypeCfe(transformer, elementType, compoundCache: compoundCache); compoundCache: compoundCache, variableLength: variableLength);
if (elementCfeType is InvalidNativeTypeCfe) { if (elementCfeType is InvalidNativeTypeCfe) {
return elementCfeType; return elementCfeType;
} }
return ArrayNativeTypeCfe.multi(elementCfeType, arrayDimensions); return ArrayNativeTypeCfe.multi(
elementCfeType, arrayDimensions, variableLength);
} }
if (transformer.isAbiSpecificIntegerSubtype(dartType)) { if (transformer.isAbiSpecificIntegerSubtype(dartType)) {
final clazz = (dartType as InterfaceType).classNode; final clazz = (dartType as InterfaceType).classNode;
@@ -741,17 +747,21 @@ class ReferencedCompoundSubtypeCfe extends NativeTypeCfe
class ArrayNativeTypeCfe extends NativeTypeCfe { class ArrayNativeTypeCfe extends NativeTypeCfe {
final NativeTypeCfe elementType; final NativeTypeCfe elementType;
final int length; final int length;
final bool variableLength;
ArrayNativeTypeCfe(this.elementType, this.length) : super._(); ArrayNativeTypeCfe(this.elementType, this.length, this.variableLength)
: super._();
factory ArrayNativeTypeCfe.multi( factory ArrayNativeTypeCfe.multi(
NativeTypeCfe elementType, List<int> dimensions) { NativeTypeCfe elementType, List<int> dimensions, bool variableLength) {
if (dimensions.length == 1) { if (dimensions.length == 1) {
return ArrayNativeTypeCfe(elementType, dimensions.single); return ArrayNativeTypeCfe(elementType, dimensions.single, variableLength);
} }
return ArrayNativeTypeCfe( return ArrayNativeTypeCfe(
ArrayNativeTypeCfe.multi(elementType, dimensions.sublist(1)), ArrayNativeTypeCfe.multi(
elementType, dimensions.sublist(1), variableLength),
dimensions.first, dimensions.first,
variableLength,
); );
} }
@@ -798,7 +808,9 @@ class ArrayNativeTypeCfe extends NativeTypeCfe {
transformer.ffiInlineArrayElementTypeField.fieldReference: transformer.ffiInlineArrayElementTypeField.fieldReference:
singleElementType.generateConstant(transformer), singleElementType.generateConstant(transformer),
transformer.ffiInlineArrayLengthField.fieldReference: transformer.ffiInlineArrayLengthField.fieldReference:
IntConstant(dimensionsFlattened) IntConstant(dimensionsFlattened),
transformer.ffiInlineArrayVariableLengthField.fieldReference:
BoolConstant(variableLength),
}, },
); );
@@ -830,6 +842,7 @@ class ArrayNativeTypeCfe extends NativeTypeCfe {
typedDataBase, typedDataBase,
offsetInBytes, offsetInBytes,
ConstantExpression(IntConstant(length)), ConstantExpression(IntConstant(length)),
ConstantExpression(BoolConstant(variableLength)),
transformer.intListConstantExpression( transformer.intListConstantExpression(
nestedDimensions, Nullability.nonNullable) nestedDimensions, Nullability.nonNullable)
], ],
@@ -1217,6 +1217,13 @@ mixin _FfiUseSiteTransformer on FfiTransformer {
arrayNestedDimensionsFirst.name, arrayNestedDimensionsFirst.name,
interfaceTarget: arrayNestedDimensionsFirst, interfaceTarget: arrayNestedDimensionsFirst,
resultType: arrayNestedDimensionsFirst.getterType), resultType: arrayNestedDimensionsFirst.getterType),
InstanceGet(
InstanceAccessKind.Instance,
VariableGet(arrayVar),
arrayVariableLengthField.name,
interfaceTarget: arrayVariableLengthField,
resultType: arrayVariableLengthField.type,
),
InstanceGet(InstanceAccessKind.Instance, VariableGet(arrayVar), InstanceGet(InstanceAccessKind.Instance, VariableGet(arrayVar),
arrayNestedDimensionsRest.name, arrayNestedDimensionsRest.name,
interfaceTarget: arrayNestedDimensionsRest, interfaceTarget: arrayNestedDimensionsRest,
@@ -46,7 +46,7 @@ final class WCharStruct extends ffi::Struct {
static get #sizeOf() → core::int static get #sizeOf() → core::int
return #C22.{core::List::[]}(ffi::_abi()){(core::int) → core::int}; return #C22.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
} }
@#C27 @#C28
final class WCharArrayStruct extends ffi::Struct { final class WCharArrayStruct extends ffi::Struct {
constructor #fromTypedDataBase([@vm.inferred-arg-type.metadata=dart.ffi::Pointer] synthesized core::Object #typedDataBase) → self::WCharArrayStruct constructor #fromTypedDataBase([@vm.inferred-arg-type.metadata=dart.ffi::Pointer] synthesized core::Object #typedDataBase) → self::WCharArrayStruct
: super ffi::Struct::_fromTypedDataBase(#typedDataBase) : 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] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3]
@#C10 @#C10
get a0() → ffi::Array<self::WChar> 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.inferred-return-type.metadata=dart.core::_Smi (value: 0)]
[@vm.unboxing-info.metadata=()->i] [@vm.unboxing-info.metadata=()->i]
@@ -68,7 +68,7 @@ final class WCharArrayStruct extends ffi::Struct {
[@vm.unboxing-info.metadata=()->i] [@vm.unboxing-info.metadata=()->i]
@#C10 @#C10
static get #sizeOf() → core::int 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*/ { 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)] [@vm.inferred-return-type.metadata=dart.core::Null? (value: null)]
static method testStoreLoad() → void { 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); ffi::_storeAbiSpecificInt<self::WChar>(p, #C19, 10);
core::print([@vm.inferred-type.metadata=int] ffi::_loadAbiSpecificInt<self::WChar>(p, #C19)); 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)] [@vm.inferred-return-type.metadata=dart.core::Null? (value: null)]
static method testStoreLoadIndexed() → void { 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, 0, 10);
ffi::_storeAbiSpecificIntAtIndex<self::WChar>(p, #C19, 1, 3); 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, 0));
core::print([@vm.inferred-type.metadata=int] ffi::_loadAbiSpecificIntAtIndex<self::WChar>(p, #C19, 1)); 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)] [@vm.inferred-return-type.metadata=dart.core::Null? (value: null)]
static method testStruct() → void { 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; [@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}); 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; [@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}); 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)] [@vm.inferred-return-type.metadata=dart.core::Null? (value: null)]
static method testInlineArray() → void { 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>}; 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}) { 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 { 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.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.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 { constants {
#C1 = "vm:ffi:abi-specific-mapping" #C1 = "vm:ffi:abi-specific-mapping"
@@ -170,13 +170,14 @@ constants {
#C21 = 8 #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] #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 #C23 = 100
#C24 = ffi::_FfiInlineArray {elementType:#C15, length:#C23} #C24 = false
#C25 = <core::Type>[#C24] #C25 = ffi::_FfiInlineArray {elementType:#C15, length:#C23, variableLength:#C24}
#C26 = ffi::_FfiStructLayout {fieldTypes:#C25, packing:#C9} #C26 = <core::Type>[#C25]
#C27 = core::pragma {name:#C14, options:#C26} #C27 = ffi::_FfiStructLayout {fieldTypes:#C26, packing:#C9}
#C28 = <core::int>[] #C28 = core::pragma {name:#C14, options:#C27}
#C29 = 400 #C29 = <core::int>[]
#C30 = 200 #C30 = 400
#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] #C31 = 200
#C32 = self::_DummyAllocator {} #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 static get #sizeOf() → core::int
return #C77.{core::List::[]}(ffi::_abi()){(core::int) → core::int}; return #C77.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
} }
@#C82 @#C83
final class WCharArrayStruct extends ffi::Struct { final class WCharArrayStruct extends ffi::Struct {
synthetic constructor •() → self::WCharArrayStruct synthetic constructor •() → self::WCharArrayStruct
: super ffi::Struct::•() : super ffi::Struct::•()
@@ -69,7 +69,7 @@ final class WCharArrayStruct extends ffi::Struct {
@#C84 @#C84
@#C67 @#C67
get a0() → ffi::Array<self::WChar> 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 @#C84
@#C67 @#C67
set a0(synthesized ffi::Array<self::WChar> #externalFieldValue) → void set a0(synthesized ffi::Array<self::WChar> #externalFieldValue) → void
@@ -224,12 +224,12 @@ constants {
#C76 = 8 #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] #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 #C78 = 100
#C79 = ffi::_FfiInlineArray {elementType:#C70, length:#C78} #C79 = false
#C80 = <core::Type>[#C79] #C80 = ffi::_FfiInlineArray {elementType:#C70, length:#C78, variableLength:#C79}
#C81 = ffi::_FfiStructLayout {fieldTypes:#C80, packing:#C66} #C81 = <core::Type>[#C80]
#C82 = core::pragma {name:#C69, options:#C81} #C82 = ffi::_FfiStructLayout {fieldTypes:#C81, packing:#C66}
#C83 = false #C83 = core::pragma {name:#C69, options:#C82}
#C84 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C78, dimension2:#C66, dimension3:#C66, dimension4:#C66, dimension5:#C66, dimensions:#C66, variableLength:#C83} #C84 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C78, dimension2:#C66, dimension3:#C66, dimension4:#C66, dimension5:#C66, dimensions:#C66, variableDimension:#C66}
#C85 = <core::int>[] #C85 = <core::int>[]
#C86 = 400 #C86 = 400
#C87 = 200 #C87 = 200
@@ -46,7 +46,7 @@ final class IncompleteStruct extends ffi::Struct {
static get #sizeOf() → core::int 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?}); 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 { final class IncompleteArrayStruct extends ffi::Struct {
constructor #fromTypedDataBase([@vm.inferred-arg-type.metadata=dart.ffi::Pointer] synthesized core::Object #typedDataBase) → self::IncompleteArrayStruct constructor #fromTypedDataBase([@vm.inferred-arg-type.metadata=dart.ffi::Pointer] synthesized core::Object #typedDataBase) → self::IncompleteArrayStruct
: super ffi::Struct::_fromTypedDataBase(#typedDataBase) : 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] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3]
@#C8 @#C8
get a0() → ffi::Array<self::Incomplete> 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.inferred-return-type.metadata=dart.core::_Smi (value: 0)]
[@vm.unboxing-info.metadata=()->i] [@vm.unboxing-info.metadata=()->i]
@@ -68,7 +68,7 @@ final class IncompleteArrayStruct extends ffi::Struct {
[@vm.unboxing-info.metadata=()->i] [@vm.unboxing-info.metadata=()->i]
@#C8 @#C8
static get #sizeOf() → core::int 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*/ { 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)] [@vm.inferred-return-type.metadata=dart.core::Null? (value: null)]
static method testStoreLoad() → void { 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); ffi::_storeAbiSpecificInt<self::Incomplete>(p, #C16, 10);
core::print([@vm.inferred-type.metadata=int] ffi::_loadAbiSpecificInt<self::Incomplete>(p, #C16)); 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)] [@vm.inferred-return-type.metadata=dart.core::Null? (value: null)]
static method testStoreLoadIndexed() → void { 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, 0, 10);
ffi::_storeAbiSpecificIntAtIndex<self::Incomplete>(p, #C16, 1, 3); 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, 0));
core::print([@vm.inferred-type.metadata=int] ffi::_loadAbiSpecificIntAtIndex<self::Incomplete>(p, #C16, 1)); 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)] [@vm.inferred-return-type.metadata=dart.core::Null? (value: null)]
static method testStruct() → void { 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; [@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}); 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; [@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}); 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)] [@vm.inferred-return-type.metadata=dart.core::Null? (value: null)]
static method testInlineArray() → void { 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>}; 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}) { 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 { 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.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.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 { constants {
#C1 = "vm:ffi:abi-specific-mapping" #C1 = "vm:ffi:abi-specific-mapping"
@@ -167,12 +167,13 @@ constants {
#C18 = 8 #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] #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 #C20 = 100
#C21 = ffi::_FfiInlineArray {elementType:#C12, length:#C20} #C21 = false
#C22 = <core::Type>[#C21] #C22 = ffi::_FfiInlineArray {elementType:#C12, length:#C20, variableLength:#C21}
#C23 = ffi::_FfiStructLayout {fieldTypes:#C22, packing:#C2} #C23 = <core::Type>[#C22]
#C24 = core::pragma {name:#C11, options:#C23} #C24 = ffi::_FfiStructLayout {fieldTypes:#C23, packing:#C2}
#C25 = <core::int>[] #C25 = core::pragma {name:#C11, options:#C24}
#C26 = 400 #C26 = <core::int>[]
#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] #C27 = 400
#C28 = self::_DummyAllocator {} #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 static get #sizeOf() → core::int
return ffi::_checkAbiSpecificIntegerMapping<core::int>(#C40.{core::List::[]}(ffi::_abi()){(core::int) → core::int?}); return ffi::_checkAbiSpecificIntegerMapping<core::int>(#C40.{core::List::[]}(ffi::_abi()){(core::int) → core::int?});
} }
@#C45 @#C46
final class IncompleteArrayStruct extends ffi::Struct { final class IncompleteArrayStruct extends ffi::Struct {
synthetic constructor •() → self::IncompleteArrayStruct synthetic constructor •() → self::IncompleteArrayStruct
: super ffi::Struct::•() : super ffi::Struct::•()
@@ -69,7 +69,7 @@ final class IncompleteArrayStruct extends ffi::Struct {
@#C47 @#C47
@#C29 @#C29
get a0() → ffi::Array<self::Incomplete> 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 @#C47
@#C29 @#C29
set a0(synthesized ffi::Array<self::Incomplete> #externalFieldValue) → void set a0(synthesized ffi::Array<self::Incomplete> #externalFieldValue) → void
@@ -187,12 +187,12 @@ constants {
#C39 = 8 #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] #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 #C41 = 100
#C42 = ffi::_FfiInlineArray {elementType:#C33, length:#C41} #C42 = false
#C43 = <core::Type>[#C42] #C43 = ffi::_FfiInlineArray {elementType:#C33, length:#C41, variableLength:#C42}
#C44 = ffi::_FfiStructLayout {fieldTypes:#C43, packing:#C23} #C44 = <core::Type>[#C43]
#C45 = core::pragma {name:#C32, options:#C44} #C45 = ffi::_FfiStructLayout {fieldTypes:#C44, packing:#C23}
#C46 = false #C46 = core::pragma {name:#C32, options:#C45}
#C47 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C41, dimension2:#C23, dimension3:#C23, dimension4:#C23, dimension5:#C23, dimensions:#C23, variableLength:#C46} #C47 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C41, dimension2:#C23, dimension3:#C23, dimension4:#C23, dimension5:#C23, dimensions:#C23, variableDimension:#C23}
#C48 = <core::int>[] #C48 = <core::int>[]
#C49 = 400 #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] #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"; import "dart:ffi";
@#C10 @#C11
final class MyStruct extends ffi::Struct { final class MyStruct extends ffi::Struct {
constructor #fromTypedDataBase([@vm.inferred-arg-type.metadata=dart.typed_data::_Uint8List] synthesized core::Object #typedDataBase) → self::MyStruct constructor #fromTypedDataBase([@vm.inferred-arg-type.metadata=dart.typed_data::_Uint8List] synthesized core::Object #typedDataBase) → self::MyStruct
: super ffi::Struct::_fromTypedDataBase(#typedDataBase) : 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.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] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]
@#C12 @#C13
get array() → ffi::Array<ffi::Int8> 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.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] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:2]
@#C12 @#C13
get array2() → ffi::Array<ffi::UnsignedLong> 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.inferred-return-type.metadata=dart.core::_Smi (value: 0)]
[@vm.unboxing-info.metadata=()->i] [@vm.unboxing-info.metadata=()->i]
@#C12 @#C13
static get a#offsetOf() → core::int 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.inferred-return-type.metadata=dart.core::_Smi (value: 1)]
[@vm.unboxing-info.metadata=()->i] [@vm.unboxing-info.metadata=()->i]
@#C12 @#C13
static get b#offsetOf() → core::int 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.inferred-return-type.metadata=dart.core::_Smi (value: 2)]
[@vm.unboxing-info.metadata=()->i] [@vm.unboxing-info.metadata=()->i]
@#C12 @#C13
static get array#offsetOf() → core::int 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.inferred-return-type.metadata=dart.core::_Smi]
[@vm.unboxing-info.metadata=()->i] [@vm.unboxing-info.metadata=()->i]
@#C12 @#C13
static get array2#offsetOf() → core::int 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.inferred-return-type.metadata=dart.core::_Smi]
[@vm.unboxing-info.metadata=()->i] [@vm.unboxing-info.metadata=()->i]
@#C12 @#C13
static get #sizeOf() → core::int 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 { final class MyUnion extends ffi::Union {
constructor #fromTypedDataBase([@vm.inferred-arg-type.metadata=dart.typed_data::_Uint8List] synthesized core::Object #typedDataBase) → self::MyUnion constructor #fromTypedDataBase([@vm.inferred-arg-type.metadata=dart.typed_data::_Uint8List] synthesized core::Object #typedDataBase) → self::MyUnion
: super ffi::Union::_fromTypedDataBase(#typedDataBase) : 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.inferred-return-type.metadata=dart.core::_Smi (value: 1)]
[@vm.unboxing-info.metadata=()->i] [@vm.unboxing-info.metadata=()->i]
@#C12 @#C13
static get #sizeOf() → core::int 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)] [@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(myUnion, myUnion);
self::myNative#CC( block { 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>}; 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>}; 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 { 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>}; 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 { } =>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>}; 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})); } =>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 @#C35
@#C36 @#C37
external static method myNative#CC([@vm.inferred-arg-type.metadata=!] ffi::_Compound pointer, [@vm.inferred-arg-type.metadata=!] ffi::_Compound pointer2) → void; external static method myNative#CC([@vm.inferred-arg-type.metadata=!] ffi::_Compound pointer, [@vm.inferred-arg-type.metadata=!] ffi::_Compound pointer2) → void;
constants { constants {
#C1 = "vm:ffi:struct-fields" #C1 = "vm:ffi:struct-fields"
#C2 = TypeLiteralConstant(ffi::Int8) #C2 = TypeLiteralConstant(ffi::Int8)
#C3 = 10 #C3 = 10
#C4 = ffi::_FfiInlineArray {elementType:#C2, length:#C3} #C4 = false
#C5 = TypeLiteralConstant(ffi::UnsignedLong) #C5 = ffi::_FfiInlineArray {elementType:#C2, length:#C3, variableLength:#C4}
#C6 = ffi::_FfiInlineArray {elementType:#C5, length:#C3} #C6 = TypeLiteralConstant(ffi::UnsignedLong)
#C7 = <core::Type>[#C2, #C2, #C4, #C6] #C7 = ffi::_FfiInlineArray {elementType:#C6, length:#C3, variableLength:#C4}
#C8 = null #C8 = <core::Type>[#C2, #C2, #C5, #C7]
#C9 = ffi::_FfiStructLayout {fieldTypes:#C7, packing:#C8} #C9 = null
#C10 = core::pragma {name:#C1, options:#C9} #C10 = ffi::_FfiStructLayout {fieldTypes:#C8, packing:#C9}
#C11 = "vm:prefer-inline" #C11 = core::pragma {name:#C1, options:#C10}
#C12 = core::pragma {name:#C11, options:#C8} #C12 = "vm:prefer-inline"
#C13 = <core::int>[] #C13 = core::pragma {name:#C12, options:#C9}
#C14 = 0 #C14 = <core::int>[]
#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] #C15 = 0
#C16 = 1 #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::int>[#C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16] #C17 = 1
#C18 = 2 #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 = <core::int>[#C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18] #C19 = 2
#C20 = 12 #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 = 16 #C21 = 12
#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] #C22 = 16
#C23 = 52 #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 = 96 #C24 = 52
#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] #C25 = 96
#C26 = <core::Type>[#C2, #C2] #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 = ffi::_FfiStructLayout {fieldTypes:#C26, packing:#C8} #C27 = <core::Type>[#C2, #C2]
#C28 = core::pragma {name:#C1, options:#C27} #C28 = ffi::_FfiStructLayout {fieldTypes:#C27, packing:#C9}
#C29 = "cfe:ffi:native-marker" #C29 = core::pragma {name:#C1, options:#C28}
#C30 = "myNative" #C30 = "cfe:ffi:native-marker"
#C31 = "#lib" #C31 = "myNative"
#C32 = true #C32 = "#lib"
#C33 = ffi::Native<(ffi::Pointer<ffi::Void>, ffi::Pointer<ffi::Void>) → ffi::Void> {symbol:#C30, assetId:#C31, isLeaf:#C32} #C33 = true
#C34 = core::pragma {name:#C29, options:#C33} #C34 = ffi::Native<(ffi::Pointer<ffi::Void>, ffi::Pointer<ffi::Void>) → ffi::Void> {symbol:#C31, assetId:#C32, isLeaf:#C33}
#C35 = "vm:ffi:native" #C35 = core::pragma {name:#C30, options:#C34}
#C36 = core::pragma {name:#C35, options:#C33} #C36 = "vm:ffi:native"
#C37 = core::pragma {name:#C36, options:#C34}
} }
@@ -6,7 +6,7 @@ import "dart:typed_data" as typ;
import "dart:ffi"; import "dart:ffi";
@#C10 @#C11
final class MyStruct extends ffi::Struct { final class MyStruct extends ffi::Struct {
synthetic constructor •() → self::MyStruct synthetic constructor •() → self::MyStruct
: super ffi::Struct::•() : 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 constructor #fromTypedDataBase(synthesized core::Object #typedDataBase, synthesized core::int #offsetInBytes) → self::MyStruct
: super ffi::Struct::_fromTypedDataBase(#typedDataBase, #offsetInBytes) : super ffi::Struct::_fromTypedDataBase(#typedDataBase, #offsetInBytes)
; ;
@#C12 @#C13
constructor #fromTypedData(synthesized typ::TypedData #typedData, synthesized core::int #offset, synthesized core::int #sizeInBytes) → self::MyStruct constructor #fromTypedData(synthesized typ::TypedData #typedData, synthesized core::int #offset, synthesized core::int #sizeInBytes) → self::MyStruct
: super ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes) : super ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
; ;
@#C14
@#C13 @#C13
@#C12
get a() → core::int 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}); 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 @#C13
@#C12
set a(synthesized core::int #externalFieldValue) → void 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); 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 @#C13
@#C12
get b() → core::int 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}); 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 @#C13
@#C12
set b(synthesized core::int #externalFieldValue) → void 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); 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 @#C15
@#C12 @#C13
get array() → ffi::Array<ffi::Int8> 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 @#C15
@#C12 @#C13
set array(synthesized ffi::Array<ffi::Int8> #externalFieldValue) → void 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}); 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 @#C15
@#C12 @#C13
get array2() → ffi::Array<ffi::UnsignedLong> 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 @#C15
@#C12 @#C13
set array2(synthesized ffi::Array<ffi::UnsignedLong> #externalFieldValue) → void 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}); 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 static get a#offsetOf() → core::int
return #C22.{core::List::[]}(ffi::_abi()){(core::int) → core::int}; return #C22.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C12 @#C13
static get b#offsetOf() → core::int static get b#offsetOf() → core::int
return #C24.{core::List::[]}(ffi::_abi()){(core::int) → core::int}; return #C24.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C12 @#C13
static get array#offsetOf() → core::int static get array#offsetOf() → core::int
return #C26.{core::List::[]}(ffi::_abi()){(core::int) → core::int}; return #C26.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C12 @#C13
static get array2#offsetOf() → core::int static get array2#offsetOf() → core::int
return #C29.{core::List::[]}(ffi::_abi()){(core::int) → core::int}; return #C29.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C12 @#C13
static get #sizeOf() → core::int static get #sizeOf() → core::int
return #C32.{core::List::[]}(ffi::_abi()){(core::int) → 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 constructor #fromTypedDataBase(synthesized core::Object #typedDataBase, synthesized core::int #offsetInBytes) → self::MyUnion
: super ffi::Union::_fromTypedDataBase(#typedDataBase, #offsetInBytes) : super ffi::Union::_fromTypedDataBase(#typedDataBase, #offsetInBytes)
; ;
@#C12 @#C13
constructor #fromTypedData(synthesized typ::TypedData #typedData, synthesized core::int #offset, synthesized core::int #sizeInBytes) → self::MyUnion constructor #fromTypedData(synthesized typ::TypedData #typedData, synthesized core::int #offset, synthesized core::int #sizeInBytes) → self::MyUnion
: super ffi::Union::_fromTypedData(#typedData, #offset, #sizeInBytes) : super ffi::Union::_fromTypedData(#typedData, #offset, #sizeInBytes)
; ;
@#C14
@#C13 @#C13
@#C12
get a() → core::int 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}); 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 @#C13
@#C12
set a(synthesized core::int #externalFieldValue) → void 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); 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 @#C13
@#C12
get b() → core::int 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}); 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 @#C13
@#C12
set b(synthesized core::int #externalFieldValue) → void 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); 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 static get a#offsetOf() → core::int
return #C22.{core::List::[]}(ffi::_abi()){(core::int) → core::int}; return #C22.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C12 @#C13
static get b#offsetOf() → core::int static get b#offsetOf() → core::int
return #C22.{core::List::[]}(ffi::_abi()){(core::int) → core::int}; return #C22.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C12 @#C13
static get #sizeOf() → core::int static get #sizeOf() → core::int
return #C24.{core::List::[]}(ffi::_abi()){(core::int) → core::int}; return #C24.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
} }
@@ -134,18 +134,18 @@ constants {
#C1 = "vm:ffi:struct-fields" #C1 = "vm:ffi:struct-fields"
#C2 = TypeLiteralConstant(ffi::Int8) #C2 = TypeLiteralConstant(ffi::Int8)
#C3 = 10 #C3 = 10
#C4 = ffi::_FfiInlineArray {elementType:#C2, length:#C3} #C4 = false
#C5 = TypeLiteralConstant(ffi::UnsignedLong) #C5 = ffi::_FfiInlineArray {elementType:#C2, length:#C3, variableLength:#C4}
#C6 = ffi::_FfiInlineArray {elementType:#C5, length:#C3} #C6 = TypeLiteralConstant(ffi::UnsignedLong)
#C7 = <core::Type>[#C2, #C2, #C4, #C6] #C7 = ffi::_FfiInlineArray {elementType:#C6, length:#C3, variableLength:#C4}
#C8 = null #C8 = <core::Type>[#C2, #C2, #C5, #C7]
#C9 = ffi::_FfiStructLayout {fieldTypes:#C7, packing:#C8} #C9 = null
#C10 = core::pragma {name:#C1, options:#C9} #C10 = ffi::_FfiStructLayout {fieldTypes:#C8, packing:#C9}
#C11 = "vm:prefer-inline" #C11 = core::pragma {name:#C1, options:#C10}
#C12 = core::pragma {name:#C11, options:#C8} #C12 = "vm:prefer-inline"
#C13 = ffi::Int8 {} #C13 = core::pragma {name:#C12, options:#C9}
#C14 = false #C14 = ffi::Int8 {}
#C15 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C3, dimension2:#C8, dimension3:#C8, dimension4:#C8, dimension5:#C8, dimensions:#C8, variableLength:#C14} #C15 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C3, dimension2:#C9, dimension3:#C9, dimension4:#C9, dimension5:#C9, dimensions:#C9, variableDimension:#C9}
#C16 = <core::int>[] #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] #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 #C18 = 40
@@ -164,7 +164,7 @@ constants {
#C31 = 96 #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] #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] #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} #C35 = core::pragma {name:#C1, options:#C34}
#C36 = "cfe:ffi:native-marker" #C36 = "cfe:ffi:native-marker"
#C37 = "myNative" #C37 = "myNative"
@@ -6,7 +6,7 @@ import "dart:typed_data" as typ;
import "dart:ffi"; import "dart:ffi";
@#C8 @#C9
final class MyStruct extends ffi::Struct { final class MyStruct extends ffi::Struct {
constructor #fromTypedDataBase([@vm.inferred-arg-type.metadata=dart.typed_data::_Uint8List] synthesized core::Object #typedDataBase) → self::MyStruct constructor #fromTypedDataBase([@vm.inferred-arg-type.metadata=dart.typed_data::_Uint8List] synthesized core::Object #typedDataBase) → self::MyStruct
: super ffi::Struct::_fromTypedDataBase(#typedDataBase) : 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.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] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]
@#C10 @#C11
get a() → ffi::Array<ffi::Int8> 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.inferred-return-type.metadata=dart.core::_Smi (value: 0)]
[@vm.unboxing-info.metadata=()->i] [@vm.unboxing-info.metadata=()->i]
@#C10 @#C11
static get a#offsetOf() → core::int 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.inferred-return-type.metadata=dart.core::_Smi (value: 10)]
[@vm.unboxing-info.metadata=()->i] [@vm.unboxing-info.metadata=()->i]
@#C10 @#C11
static get #sizeOf() → core::int 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 { final class MyUnion extends ffi::Union {
constructor #fromTypedDataBase([@vm.inferred-arg-type.metadata=dart.typed_data::_Uint8List] synthesized core::Object #typedDataBase) → self::MyUnion constructor #fromTypedDataBase([@vm.inferred-arg-type.metadata=dart.typed_data::_Uint8List] synthesized core::Object #typedDataBase) → self::MyUnion
: super ffi::Union::_fromTypedDataBase(#typedDataBase) : 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.inferred-return-type.metadata=dart.core::_Smi (value: 1)]
[@vm.unboxing-info.metadata=()->i] [@vm.unboxing-info.metadata=()->i]
@#C10 @#C11
static get #sizeOf() → core::int 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)] [@vm.inferred-return-type.metadata=dart.core::Null? (value: null)]
@@ -51,49 +51,50 @@ static method main() → void {
self::myNative2#C(myUnion); 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>}); 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 @#C26
@#C27 @#C28
external static method myNative#C([@vm.inferred-arg-type.metadata=#lib::MyStruct] ffi::_Compound pointer) → void; external static method myNative#C([@vm.inferred-arg-type.metadata=#lib::MyStruct] ffi::_Compound pointer) → void;
@#C30
@#C31 @#C31
@#C32
external static method myNative2#C([@vm.inferred-arg-type.metadata=#lib::MyUnion] ffi::_Compound pointer) → void; external static method myNative2#C([@vm.inferred-arg-type.metadata=#lib::MyUnion] ffi::_Compound pointer) → void;
@#C34
@#C35 @#C35
@#C36
external static method myNative3#C([@vm.inferred-arg-type.metadata=dart.ffi::Array<dart.ffi::Int8>] ffi::_Compound pointer) → void; external static method myNative3#C([@vm.inferred-arg-type.metadata=dart.ffi::Array<dart.ffi::Int8>] ffi::_Compound pointer) → void;
constants { constants {
#C1 = "vm:ffi:struct-fields" #C1 = "vm:ffi:struct-fields"
#C2 = TypeLiteralConstant(ffi::Int8) #C2 = TypeLiteralConstant(ffi::Int8)
#C3 = 10 #C3 = 10
#C4 = ffi::_FfiInlineArray {elementType:#C2, length:#C3} #C4 = false
#C5 = <core::Type>[#C4] #C5 = ffi::_FfiInlineArray {elementType:#C2, length:#C3, variableLength:#C4}
#C6 = null #C6 = <core::Type>[#C5]
#C7 = ffi::_FfiStructLayout {fieldTypes:#C5, packing:#C6} #C7 = null
#C8 = core::pragma {name:#C1, options:#C7} #C8 = ffi::_FfiStructLayout {fieldTypes:#C6, packing:#C7}
#C9 = "vm:prefer-inline" #C9 = core::pragma {name:#C1, options:#C8}
#C10 = core::pragma {name:#C9, options:#C6} #C10 = "vm:prefer-inline"
#C11 = <core::int>[] #C11 = core::pragma {name:#C10, options:#C7}
#C12 = 0 #C12 = <core::int>[]
#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] #C13 = 0
#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] #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::Type>[#C2] #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 = ffi::_FfiStructLayout {fieldTypes:#C15, packing:#C6} #C16 = <core::Type>[#C2]
#C17 = core::pragma {name:#C1, options:#C16} #C17 = ffi::_FfiStructLayout {fieldTypes:#C16, packing:#C7}
#C18 = 1 #C18 = core::pragma {name:#C1, options:#C17}
#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] #C19 = 1
#C20 = "cfe:ffi:native-marker" #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 = "myNative" #C21 = "cfe:ffi:native-marker"
#C22 = "#lib" #C22 = "myNative"
#C23 = true #C23 = "#lib"
#C24 = ffi::Native<(ffi::Pointer<self::MyStruct>) → ffi::Void> {symbol:#C21, assetId:#C22, isLeaf:#C23} #C24 = true
#C25 = core::pragma {name:#C20, options:#C24} #C25 = ffi::Native<(ffi::Pointer<self::MyStruct>) → ffi::Void> {symbol:#C22, assetId:#C23, isLeaf:#C24}
#C26 = "vm:ffi:native" #C26 = core::pragma {name:#C21, options:#C25}
#C27 = core::pragma {name:#C26, options:#C24} #C27 = "vm:ffi:native"
#C28 = "myNative2" #C28 = core::pragma {name:#C27, options:#C25}
#C29 = ffi::Native<(ffi::Pointer<self::MyUnion>) → ffi::Void> {symbol:#C28, assetId:#C22, isLeaf:#C23} #C29 = "myNative2"
#C30 = core::pragma {name:#C20, options:#C29} #C30 = ffi::Native<(ffi::Pointer<self::MyUnion>) → ffi::Void> {symbol:#C29, assetId:#C23, isLeaf:#C24}
#C31 = core::pragma {name:#C26, options:#C29} #C31 = core::pragma {name:#C21, options:#C30}
#C32 = "myNative3" #C32 = core::pragma {name:#C27, options:#C30}
#C33 = ffi::Native<(ffi::Pointer<ffi::Int8>) → ffi::Void> {symbol:#C32, assetId:#C22, isLeaf:#C23} #C33 = "myNative3"
#C34 = core::pragma {name:#C20, options:#C33} #C34 = ffi::Native<(ffi::Pointer<ffi::Int8>) → ffi::Void> {symbol:#C33, assetId:#C23, isLeaf:#C24}
#C35 = core::pragma {name:#C26, options:#C33} #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"; import "dart:ffi";
@#C8 @#C9
final class MyStruct extends ffi::Struct { final class MyStruct extends ffi::Struct {
synthetic constructor •() → self::MyStruct synthetic constructor •() → self::MyStruct
: super ffi::Struct::•() : 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 constructor #fromTypedDataBase(synthesized core::Object #typedDataBase, synthesized core::int #offsetInBytes) → self::MyStruct
: super ffi::Struct::_fromTypedDataBase(#typedDataBase, #offsetInBytes) : super ffi::Struct::_fromTypedDataBase(#typedDataBase, #offsetInBytes)
; ;
@#C10 @#C11
constructor #fromTypedData(synthesized typ::TypedData #typedData, synthesized core::int #offset, synthesized core::int #sizeInBytes) → self::MyStruct constructor #fromTypedData(synthesized typ::TypedData #typedData, synthesized core::int #offset, synthesized core::int #sizeInBytes) → self::MyStruct
: super ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes) : super ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
; ;
@#C12 @#C12
@#C10 @#C11
get a() → ffi::Array<ffi::Int8> 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 @#C12
@#C10 @#C11
set a(synthesized ffi::Array<ffi::Int8> #externalFieldValue) → void 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}); 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 static get a#offsetOf() → core::int
return #C16.{core::List::[]}(ffi::_abi()){(core::int) → core::int}; return #C16.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C10 @#C11
static get #sizeOf() → core::int static get #sizeOf() → core::int
return #C14.{core::List::[]}(ffi::_abi()){(core::int) → 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 constructor #fromTypedDataBase(synthesized core::Object #typedDataBase, synthesized core::int #offsetInBytes) → self::MyUnion
: super ffi::Union::_fromTypedDataBase(#typedDataBase, #offsetInBytes) : super ffi::Union::_fromTypedDataBase(#typedDataBase, #offsetInBytes)
; ;
@#C10 @#C11
constructor #fromTypedData(synthesized typ::TypedData #typedData, synthesized core::int #offset, synthesized core::int #sizeInBytes) → self::MyUnion constructor #fromTypedData(synthesized typ::TypedData #typedData, synthesized core::int #offset, synthesized core::int #sizeInBytes) → self::MyUnion
: super ffi::Union::_fromTypedData(#typedData, #offset, #sizeInBytes) : super ffi::Union::_fromTypedData(#typedData, #offset, #sizeInBytes)
; ;
@#C20 @#C20
@#C10 @#C11
get a() → core::int 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}); 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 @#C20
@#C10 @#C11
set a(synthesized core::int #externalFieldValue) → void 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); 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 static get a#offsetOf() → core::int
return #C16.{core::List::[]}(ffi::_abi()){(core::int) → core::int}; return #C16.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C10 @#C11
static get #sizeOf() → core::int static get #sizeOf() → core::int
return #C22.{core::List::[]}(ffi::_abi()){(core::int) → core::int}; return #C22.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
} }
@@ -89,21 +89,21 @@ constants {
#C1 = "vm:ffi:struct-fields" #C1 = "vm:ffi:struct-fields"
#C2 = TypeLiteralConstant(ffi::Int8) #C2 = TypeLiteralConstant(ffi::Int8)
#C3 = 10 #C3 = 10
#C4 = ffi::_FfiInlineArray {elementType:#C2, length:#C3} #C4 = false
#C5 = <core::Type>[#C4] #C5 = ffi::_FfiInlineArray {elementType:#C2, length:#C3, variableLength:#C4}
#C6 = null #C6 = <core::Type>[#C5]
#C7 = ffi::_FfiStructLayout {fieldTypes:#C5, packing:#C6} #C7 = null
#C8 = core::pragma {name:#C1, options:#C7} #C8 = ffi::_FfiStructLayout {fieldTypes:#C6, packing:#C7}
#C9 = "vm:prefer-inline" #C9 = core::pragma {name:#C1, options:#C8}
#C10 = core::pragma {name:#C9, options:#C6} #C10 = "vm:prefer-inline"
#C11 = false #C11 = core::pragma {name:#C10, options:#C7}
#C12 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C3, dimension2:#C6, dimension3:#C6, dimension4:#C6, dimension5:#C6, dimensions:#C6, variableLength:#C11} #C12 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C3, dimension2:#C7, dimension3:#C7, dimension4:#C7, dimension5:#C7, dimensions:#C7, variableDimension:#C7}
#C13 = <core::int>[] #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] #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 #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] #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] #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} #C19 = core::pragma {name:#C1, options:#C18}
#C20 = ffi::Int8 {} #C20 = ffi::Int8 {}
#C21 = 1 #C21 = 1
@@ -6,7 +6,7 @@ import "dart:typed_data" as typ;
import "dart:ffi"; import "dart:ffi";
@#C10 @#C11
final class MyStruct extends ffi::Struct { final class MyStruct extends ffi::Struct {
constructor #fromTypedDataBase([@vm.inferred-arg-type.metadata=dart.typed_data::_Uint8List] synthesized core::Object #typedDataBase) → self::MyStruct constructor #fromTypedDataBase([@vm.inferred-arg-type.metadata=dart.typed_data::_Uint8List] synthesized core::Object #typedDataBase) → self::MyStruct
: super ffi::Struct::_fromTypedDataBase(#typedDataBase) : 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.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] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]
@#C12 @#C13
get array() → ffi::Array<ffi::Int8> 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.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] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:2]
@#C12 @#C13
get array2() → ffi::Array<ffi::UnsignedLong> 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.inferred-return-type.metadata=dart.core::_Smi (value: 0)]
[@vm.unboxing-info.metadata=()->i] [@vm.unboxing-info.metadata=()->i]
@#C12 @#C13
static get a#offsetOf() → core::int 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.inferred-return-type.metadata=dart.core::_Smi (value: 1)]
[@vm.unboxing-info.metadata=()->i] [@vm.unboxing-info.metadata=()->i]
@#C12 @#C13
static get b#offsetOf() → core::int 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.inferred-return-type.metadata=dart.core::_Smi (value: 2)]
[@vm.unboxing-info.metadata=()->i] [@vm.unboxing-info.metadata=()->i]
@#C12 @#C13
static get array#offsetOf() → core::int 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.inferred-return-type.metadata=dart.core::_Smi]
[@vm.unboxing-info.metadata=()->i] [@vm.unboxing-info.metadata=()->i]
@#C12 @#C13
static get array2#offsetOf() → core::int 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.inferred-return-type.metadata=dart.core::_Smi]
[@vm.unboxing-info.metadata=()->i] [@vm.unboxing-info.metadata=()->i]
@#C12 @#C13
static get #sizeOf() → core::int 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 { final class MyUnion extends ffi::Union {
constructor #fromTypedDataBase([@vm.inferred-arg-type.metadata=dart.typed_data::_Uint8List] synthesized core::Object #typedDataBase) → self::MyUnion constructor #fromTypedDataBase([@vm.inferred-arg-type.metadata=dart.typed_data::_Uint8List] synthesized core::Object #typedDataBase) → self::MyUnion
: super ffi::Union::_fromTypedDataBase(#typedDataBase) : 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.inferred-return-type.metadata=dart.core::_Smi (value: 1)]
[@vm.unboxing-info.metadata=()->i] [@vm.unboxing-info.metadata=()->i]
@#C12 @#C13
static get #sizeOf() → core::int 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)] [@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(myUnion, myUnion);
self::myNative#CC( block { 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>}; 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>}; 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 { 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>}; 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 { } =>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>}; 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})); } =>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 @#C35
@#C36 @#C37
external static method myNative#CC([@vm.inferred-arg-type.metadata=!] ffi::_Compound pointer, [@vm.inferred-arg-type.metadata=!] ffi::_Compound pointer2) → void; external static method myNative#CC([@vm.inferred-arg-type.metadata=!] ffi::_Compound pointer, [@vm.inferred-arg-type.metadata=!] ffi::_Compound pointer2) → void;
constants { constants {
#C1 = "vm:ffi:struct-fields" #C1 = "vm:ffi:struct-fields"
#C2 = TypeLiteralConstant(ffi::Int8) #C2 = TypeLiteralConstant(ffi::Int8)
#C3 = 10 #C3 = 10
#C4 = ffi::_FfiInlineArray {elementType:#C2, length:#C3} #C4 = false
#C5 = TypeLiteralConstant(ffi::UnsignedLong) #C5 = ffi::_FfiInlineArray {elementType:#C2, length:#C3, variableLength:#C4}
#C6 = ffi::_FfiInlineArray {elementType:#C5, length:#C3} #C6 = TypeLiteralConstant(ffi::UnsignedLong)
#C7 = <core::Type>[#C2, #C2, #C4, #C6] #C7 = ffi::_FfiInlineArray {elementType:#C6, length:#C3, variableLength:#C4}
#C8 = null #C8 = <core::Type>[#C2, #C2, #C5, #C7]
#C9 = ffi::_FfiStructLayout {fieldTypes:#C7, packing:#C8} #C9 = null
#C10 = core::pragma {name:#C1, options:#C9} #C10 = ffi::_FfiStructLayout {fieldTypes:#C8, packing:#C9}
#C11 = "vm:prefer-inline" #C11 = core::pragma {name:#C1, options:#C10}
#C12 = core::pragma {name:#C11, options:#C8} #C12 = "vm:prefer-inline"
#C13 = <core::int>[] #C13 = core::pragma {name:#C12, options:#C9}
#C14 = 0 #C14 = <core::int>[]
#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] #C15 = 0
#C16 = 1 #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::int>[#C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16, #C16] #C17 = 1
#C18 = 2 #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 = <core::int>[#C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18, #C18] #C19 = 2
#C20 = 12 #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 = 16 #C21 = 12
#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] #C22 = 16
#C23 = 52 #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 = 96 #C24 = 52
#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] #C25 = 96
#C26 = <core::Type>[#C2, #C2] #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 = ffi::_FfiStructLayout {fieldTypes:#C26, packing:#C8} #C27 = <core::Type>[#C2, #C2]
#C28 = core::pragma {name:#C1, options:#C27} #C28 = ffi::_FfiStructLayout {fieldTypes:#C27, packing:#C9}
#C29 = "cfe:ffi:native-marker" #C29 = core::pragma {name:#C1, options:#C28}
#C30 = "myNative" #C30 = "cfe:ffi:native-marker"
#C31 = "#lib" #C31 = "myNative"
#C32 = true #C32 = "#lib"
#C33 = ffi::Native<(ffi::Pointer<ffi::Int8>, ffi::Pointer<ffi::Int8>) → ffi::Void> {symbol:#C30, assetId:#C31, isLeaf:#C32} #C33 = true
#C34 = core::pragma {name:#C29, options:#C33} #C34 = ffi::Native<(ffi::Pointer<ffi::Int8>, ffi::Pointer<ffi::Int8>) → ffi::Void> {symbol:#C31, assetId:#C32, isLeaf:#C33}
#C35 = "vm:ffi:native" #C35 = core::pragma {name:#C30, options:#C34}
#C36 = core::pragma {name:#C35, options:#C33} #C36 = "vm:ffi:native"
#C37 = core::pragma {name:#C36, options:#C34}
} }
@@ -6,7 +6,7 @@ import "dart:typed_data" as typ;
import "dart:ffi"; import "dart:ffi";
@#C10 @#C11
final class MyStruct extends ffi::Struct { final class MyStruct extends ffi::Struct {
synthetic constructor •() → self::MyStruct synthetic constructor •() → self::MyStruct
: super ffi::Struct::•() : 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 constructor #fromTypedDataBase(synthesized core::Object #typedDataBase, synthesized core::int #offsetInBytes) → self::MyStruct
: super ffi::Struct::_fromTypedDataBase(#typedDataBase, #offsetInBytes) : super ffi::Struct::_fromTypedDataBase(#typedDataBase, #offsetInBytes)
; ;
@#C12 @#C13
constructor #fromTypedData(synthesized typ::TypedData #typedData, synthesized core::int #offset, synthesized core::int #sizeInBytes) → self::MyStruct constructor #fromTypedData(synthesized typ::TypedData #typedData, synthesized core::int #offset, synthesized core::int #sizeInBytes) → self::MyStruct
: super ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes) : super ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
; ;
@#C14
@#C13 @#C13
@#C12
get a() → core::int 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}); 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 @#C13
@#C12
set a(synthesized core::int #externalFieldValue) → void 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); 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 @#C13
@#C12
get b() → core::int 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}); 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 @#C13
@#C12
set b(synthesized core::int #externalFieldValue) → void 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); 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 @#C15
@#C12 @#C13
get array() → ffi::Array<ffi::Int8> 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 @#C15
@#C12 @#C13
set array(synthesized ffi::Array<ffi::Int8> #externalFieldValue) → void 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}); 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 @#C15
@#C12 @#C13
get array2() → ffi::Array<ffi::UnsignedLong> 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 @#C15
@#C12 @#C13
set array2(synthesized ffi::Array<ffi::UnsignedLong> #externalFieldValue) → void 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}); 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 static get a#offsetOf() → core::int
return #C22.{core::List::[]}(ffi::_abi()){(core::int) → core::int}; return #C22.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C12 @#C13
static get b#offsetOf() → core::int static get b#offsetOf() → core::int
return #C24.{core::List::[]}(ffi::_abi()){(core::int) → core::int}; return #C24.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C12 @#C13
static get array#offsetOf() → core::int static get array#offsetOf() → core::int
return #C26.{core::List::[]}(ffi::_abi()){(core::int) → core::int}; return #C26.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C12 @#C13
static get array2#offsetOf() → core::int static get array2#offsetOf() → core::int
return #C29.{core::List::[]}(ffi::_abi()){(core::int) → core::int}; return #C29.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C12 @#C13
static get #sizeOf() → core::int static get #sizeOf() → core::int
return #C32.{core::List::[]}(ffi::_abi()){(core::int) → 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 constructor #fromTypedDataBase(synthesized core::Object #typedDataBase, synthesized core::int #offsetInBytes) → self::MyUnion
: super ffi::Union::_fromTypedDataBase(#typedDataBase, #offsetInBytes) : super ffi::Union::_fromTypedDataBase(#typedDataBase, #offsetInBytes)
; ;
@#C12 @#C13
constructor #fromTypedData(synthesized typ::TypedData #typedData, synthesized core::int #offset, synthesized core::int #sizeInBytes) → self::MyUnion constructor #fromTypedData(synthesized typ::TypedData #typedData, synthesized core::int #offset, synthesized core::int #sizeInBytes) → self::MyUnion
: super ffi::Union::_fromTypedData(#typedData, #offset, #sizeInBytes) : super ffi::Union::_fromTypedData(#typedData, #offset, #sizeInBytes)
; ;
@#C14
@#C13 @#C13
@#C12
get a() → core::int 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}); 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 @#C13
@#C12
set a(synthesized core::int #externalFieldValue) → void 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); 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 @#C13
@#C12
get b() → core::int 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}); 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 @#C13
@#C12
set b(synthesized core::int #externalFieldValue) → void 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); 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 static get a#offsetOf() → core::int
return #C22.{core::List::[]}(ffi::_abi()){(core::int) → core::int}; return #C22.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C12 @#C13
static get b#offsetOf() → core::int static get b#offsetOf() → core::int
return #C22.{core::List::[]}(ffi::_abi()){(core::int) → core::int}; return #C22.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
@#C12 @#C13
static get #sizeOf() → core::int static get #sizeOf() → core::int
return #C24.{core::List::[]}(ffi::_abi()){(core::int) → core::int}; return #C24.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
} }
@@ -134,18 +134,18 @@ constants {
#C1 = "vm:ffi:struct-fields" #C1 = "vm:ffi:struct-fields"
#C2 = TypeLiteralConstant(ffi::Int8) #C2 = TypeLiteralConstant(ffi::Int8)
#C3 = 10 #C3 = 10
#C4 = ffi::_FfiInlineArray {elementType:#C2, length:#C3} #C4 = false
#C5 = TypeLiteralConstant(ffi::UnsignedLong) #C5 = ffi::_FfiInlineArray {elementType:#C2, length:#C3, variableLength:#C4}
#C6 = ffi::_FfiInlineArray {elementType:#C5, length:#C3} #C6 = TypeLiteralConstant(ffi::UnsignedLong)
#C7 = <core::Type>[#C2, #C2, #C4, #C6] #C7 = ffi::_FfiInlineArray {elementType:#C6, length:#C3, variableLength:#C4}
#C8 = null #C8 = <core::Type>[#C2, #C2, #C5, #C7]
#C9 = ffi::_FfiStructLayout {fieldTypes:#C7, packing:#C8} #C9 = null
#C10 = core::pragma {name:#C1, options:#C9} #C10 = ffi::_FfiStructLayout {fieldTypes:#C8, packing:#C9}
#C11 = "vm:prefer-inline" #C11 = core::pragma {name:#C1, options:#C10}
#C12 = core::pragma {name:#C11, options:#C8} #C12 = "vm:prefer-inline"
#C13 = ffi::Int8 {} #C13 = core::pragma {name:#C12, options:#C9}
#C14 = false #C14 = ffi::Int8 {}
#C15 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C3, dimension2:#C8, dimension3:#C8, dimension4:#C8, dimension5:#C8, dimensions:#C8, variableLength:#C14} #C15 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C3, dimension2:#C9, dimension3:#C9, dimension4:#C9, dimension5:#C9, dimensions:#C9, variableDimension:#C9}
#C16 = <core::int>[] #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] #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 #C18 = 40
@@ -164,7 +164,7 @@ constants {
#C31 = 96 #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] #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] #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} #C35 = core::pragma {name:#C1, options:#C34}
#C36 = "cfe:ffi:native-marker" #C36 = "cfe:ffi:native-marker"
#C37 = "myNative" #C37 = "myNative"
@@ -16,6 +16,26 @@ final class Vec2d extends Struct {
external double y; 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 { final class MyUnion extends Union {
external Vec2d vector; external Vec2d vector;
external Pointer<Vec2d> indirectVector; 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>>>] [@vm.inferred-return-type.metadata=dart.ffi::Array<dart.ffi::Array<dart.ffi::Array<dart.ffi::Double>>>]
@#C35 @#C35
static get manyNumbers() → ffi::Array<ffi::Array<ffi::Array<ffi::Double>>> 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 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}); 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 #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 #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}; 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); 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}; [@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 #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 #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}; 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; self::manyNumbers = wholeArray;
ffi::DoubleArray|[]=( block { ffi::DoubleArray|[]=( block {
synthesized ffi::Array<dynamic> #array = _in::unsafeCast<ffi::Array<ffi::Array<ffi::Double>>>( 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 #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 #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}; 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); 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}; [@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 #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 #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}; 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 { constants {
#C1 = "vm:ffi:struct-fields" #C1 = "vm:ffi:struct-fields"
@@ -44,7 +44,115 @@ final class Vec2d extends ffi::Struct {
static get #sizeOf() → core::int static get #sizeOf() → core::int
return #C15.{core::List::[]}(ffi::_abi()){(core::int) → 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 { final class MyUnion extends ffi::Union {
synthetic constructor •() → self::MyUnion synthetic constructor •() → self::MyUnion
: super ffi::Union::•() : super ffi::Union::•()
@@ -78,36 +186,36 @@ final class MyUnion extends ffi::Union {
static get #sizeOf() → core::int static get #sizeOf() → core::int
return #C15.{core::List::[]}(ffi::_abi()){(core::int) → core::int}; return #C15.{core::List::[]}(ffi::_abi()){(core::int) → core::int};
} }
@#C26 @#C50
static get aString() → ffi::Pointer<ffi::Char> 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 static set aString(synthesized ffi::Pointer<ffi::Char> #externalFieldValue) → void
ffi::_storePointer<ffi::Char>(ffi::Native::_addressOf<ffi::Pointer<ffi::Char>>(#C25), #C10, #externalFieldValue); ffi::_storePointer<ffi::Char>(ffi::Native::_addressOf<ffi::Pointer<ffi::Char>>(#C49), #C10, #externalFieldValue);
@#C29 @#C53
static get anInt() → core::int 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 static set anInt(synthesized core::int #externalFieldValue) → void
ffi::_storeInt32(ffi::Native::_addressOf<ffi::Int32>(#C28), #C10, #externalFieldValue); ffi::_storeInt32(ffi::Native::_addressOf<ffi::Int32>(#C52), #C10, #externalFieldValue);
@#C32 @#C56
static get anotherInt() → core::int 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 static set anotherInt(synthesized core::int #externalFieldValue) → void
ffi::_storeAbiSpecificInt<ffi::Int>(ffi::Native::_addressOf<ffi::Int>(#C31), #C10, #externalFieldValue); ffi::_storeAbiSpecificInt<ffi::Int>(ffi::Native::_addressOf<ffi::Int>(#C55), #C10, #externalFieldValue);
@#C35 @#C59
static get vector() → self::Vec2d static get vector() → self::Vec2d
return new self::Vec2d::#fromTypedDataBase(ffi::Native::_addressOf<self::Vec2d>(#C34), #C10); return new self::Vec2d::#fromTypedDataBase(ffi::Native::_addressOf<self::Vec2d>(#C58), #C10);
@#C38 @#C62
static get union() → self::MyUnion 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 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); ffi::_memCopy(ffi::Native::_addressOf<self::MyUnion>(#C61), #C10, #externalFieldValue.{ffi::_Compound::_typedDataBase}{core::Object}, #externalFieldValue.{ffi::_Compound::_offsetInBytes}{core::int}, self::MyUnion::#sizeOf);
@#C42 @#C64
@#C45 @#C67
static get manyNumbers() → ffi::Array<ffi::Array<ffi::Array<ffi::Double>>> 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); 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);
@#C42 @#C64
static set manyNumbers(synthesized ffi::Array<ffi::Array<ffi::Array<ffi::Double>>> #externalFieldValue) → void 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 { static method main() → void {
core::print("first char of string: ${ffi::_loadAbiSpecificInt<ffi::Char>(self::aString, #C10)}"); core::print("first char of string: ${ffi::_loadAbiSpecificInt<ffi::Char>(self::aString, #C10)}");
core::print("global int: {${self::anInt}}"); 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}; self::anInt = self::anInt.{core::num::+}(1){(core::num) → core::int};
final self::Vec2d vec = self::vector; final self::Vec2d vec = self::vector;
core::print("(${vec.{self::Vec2d::x}{core::double}}, ${vec.{self::Vec2d::y}{core::double}})"); 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); self::union.{self::MyUnion::indirectVector} = ffi::Native::_addressOf<self::Vec2d>(#C58);
core::print(ffi::Native::_addressOf<ffi::Int>(#C31)); core::print(ffi::Native::_addressOf<ffi::Int>(#C55));
core::print(ffi::Native::_addressOf<self::Vec2d>(#C34)); core::print(ffi::Native::_addressOf<self::Vec2d>(#C58));
core::print(ffi::Native::_addressOf<self::MyUnion>(#C37)); core::print(ffi::Native::_addressOf<self::MyUnion>(#C61));
final ffi::Array<ffi::Array<ffi::Array<ffi::Double>>> wholeArray = self::manyNumbers; final ffi::Array<ffi::Array<ffi::Array<ffi::Double>>> wholeArray = self::manyNumbers;
ffi::DoubleArray|[]=( block { ffi::DoubleArray|[]=( block {
synthesized ffi::Array<dynamic> #array = ( block { synthesized ffi::Array<dynamic> #array = ( block {
@@ -128,13 +236,13 @@ static method main() → void {
synthesized core::int #singleElementSize = #C12; 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 #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}; 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!; synthesized core::int #index = 1!;
#array.{ffi::Array::_checkIndex}(#index){(core::int) → void}; #array.{ffi::Array::_checkIndex}(#index){(core::int) → void};
synthesized core::int #singleElementSize = #C12; 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 #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}; 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; self::manyNumbers = wholeArray;
ffi::DoubleArray|[]=( block { ffi::DoubleArray|[]=( block {
synthesized ffi::Array<dynamic> #array = ( block { synthesized ffi::Array<dynamic> #array = ( block {
@@ -144,13 +252,13 @@ static method main() → void {
synthesized core::int #singleElementSize = #C12; 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 #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}; 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!; synthesized core::int #index = 0!;
#array.{ffi::Array::_checkIndex}(#index){(core::int) → void}; #array.{ffi::Array::_checkIndex}(#index){(core::int) → void};
synthesized core::int #singleElementSize = #C12; 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 #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}; 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 { constants {
#C1 = "vm:ffi:struct-fields" #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] #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 #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] #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) #C16 = TypeLiteralConstant(ffi::Uint8)
#C17 = TypeLiteralConstant(ffi::Pointer<core::Object>) #C17 = true
#C18 = <core::Type>[#C16, #C17] #C18 = ffi::_FfiInlineArray {elementType:#C16, length:#C10, variableLength:#C17}
#C19 = ffi::_FfiStructLayout {fieldTypes:#C18, packing:#C4} #C19 = <core::Type>[#C18]
#C20 = core::pragma {name:#C1, options:#C19} #C20 = ffi::_FfiStructLayout {fieldTypes:#C19, packing:#C4}
#C21 = "cfe:ffi:native-marker" #C21 = core::pragma {name:#C1, options:#C20}
#C22 = "aString" #C22 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C10, dimension2:#C4, dimension3:#C4, dimension4:#C4, dimension5:#C4, dimensions:#C4, variableDimension:#C10}
#C23 = "#lib" #C23 = <core::int>[]
#C24 = false #C24 = 1
#C25 = ffi::Native<ffi::Pointer<ffi::Char>> {symbol:#C22, assetId:#C23, isLeaf:#C24} #C25 = ffi::_FfiInlineArray {elementType:#C16, length:#C24, variableLength:#C17}
#C26 = core::pragma {name:#C21, options:#C25} #C26 = <core::Type>[#C25]
#C27 = "anInt" #C27 = ffi::_FfiStructLayout {fieldTypes:#C26, packing:#C4}
#C28 = ffi::Native<ffi::Int32> {symbol:#C27, assetId:#C23, isLeaf:#C24} #C28 = core::pragma {name:#C1, options:#C27}
#C29 = core::pragma {name:#C21, options:#C28} #C29 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C24, dimension2:#C4, dimension3:#C4, dimension4:#C4, dimension5:#C4, dimensions:#C4, variableDimension:#C24}
#C30 = "anotherInt" #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 = ffi::Native<ffi::Int> {symbol:#C30, assetId:#C23, isLeaf:#C24} #C31 = 2
#C32 = core::pragma {name:#C21, options:#C31} #C32 = <core::int>[#C24, #C31]
#C33 = "vector" #C33 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C4, dimension2:#C4, dimension3:#C4, dimension4:#C4, dimension5:#C4, dimensions:#C32, variableDimension:#C10}
#C34 = ffi::Native<self::Vec2d> {symbol:#C33, assetId:#C23, isLeaf:#C24} #C34 = ffi::_FfiInlineArray {elementType:#C16, length:#C31, variableLength:#C17}
#C35 = core::pragma {name:#C21, options:#C34} #C35 = <core::Type>[#C34]
#C36 = "union" #C36 = ffi::_FfiStructLayout {fieldTypes:#C35, packing:#C4}
#C37 = ffi::Native<self::MyUnion> {symbol:#C36, assetId:#C23, isLeaf:#C24} #C37 = core::pragma {name:#C1, options:#C36}
#C38 = core::pragma {name:#C21, options:#C37} #C38 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C4, dimension2:#C4, dimension3:#C4, dimension4:#C4, dimension5:#C4, dimensions:#C32, variableDimension:#C24}
#C39 = 1 #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 = 2 #C40 = TypeLiteralConstant(self::Vec2d)
#C41 = 3 #C41 = TypeLiteralConstant(ffi::Pointer<core::Object>)
#C42 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C39, dimension2:#C40, dimension3:#C41, dimension4:#C4, dimension5:#C4, dimensions:#C4, variableLength:#C24} #C42 = <core::Type>[#C40, #C41]
#C43 = "manyNumbers" #C43 = ffi::_FfiStructLayout {fieldTypes:#C42, packing:#C4}
#C44 = ffi::Native<ffi::Array<ffi::Array<ffi::Array<ffi::Double>>>> {symbol:#C43, assetId:#C23, isLeaf:#C24} #C44 = core::pragma {name:#C1, options:#C43}
#C45 = core::pragma {name:#C21, options:#C44} #C45 = "cfe:ffi:native-marker"
#C46 = <core::int>[#C40, #C41] #C46 = "aString"
#C47 = 48 #C47 = "#lib"
#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] #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) #pragma pack(pop)
DART_EXPORT uint64_t SizeOfStruct3BytesPackedInt() {
return sizeof(Struct3BytesPackedIntCopy);
}
// Define ssize_t for Windows as intptr_t. // Define ssize_t for Windows as intptr_t.
#if defined(_WIN32) #if defined(_WIN32)
typedef intptr_t ssize_t; 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())); .Equals(Symbols::FfiStructLayoutArray()));
const auto& struct_layout_array_fields = const auto& struct_layout_array_fields =
Array::Handle(zone, struct_layout_array_class.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 = const auto& element_type_field =
Field::Handle(zone, Field::RawCast(struct_layout_array_fields.At(0))); Field::Handle(zone, Field::RawCast(struct_layout_array_fields.At(0)));
ASSERT(String::Handle(zone, element_type_field.UserVisibleName()) ASSERT(String::Handle(zone, element_type_field.UserVisibleName())
@@ -505,6 +505,18 @@ static const NativeType* CompoundFromPragma(Zone* zone,
if (*error != nullptr) { if (*error != nullptr) {
return 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 = const auto field_native_type =
new (zone) NativeArrayType(*element_type, length.Value()); new (zone) NativeArrayType(*element_type, length.Value());
field_native_types.Add(field_native_type); field_native_types.Add(field_native_type);
+1
View File
@@ -281,6 +281,7 @@ class ObjectPointerVisitor;
V(Value, "value") \ V(Value, "value") \
V(Values, "values") \ V(Values, "values") \
V(VarArgs, "VarArgs") \ V(VarArgs, "VarArgs") \
V(VariableLength, "variableLength") \
V(WeakArray, "WeakArray") \ V(WeakArray, "WeakArray") \
V(WeakSerializationReference, "WeakSerializationReference") \ V(WeakSerializationReference, "WeakSerializationReference") \
V(_AsyncStarStreamController, "_AsyncStarStreamController") \ V(_AsyncStarStreamController, "_AsyncStarStreamController") \
+12 -5
View File
@@ -332,9 +332,16 @@ final class _NativeCallableListener<T extends Function>
@patch @patch
@pragma("vm:entry-point") @pragma("vm:entry-point")
final class Array<T extends NativeType> extends _Compound { 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") @pragma("vm:entry-point")
final int _size; final int _size;
/// Whether the current dimension is variable.
@pragma("vm:entry-point")
final bool _variableLength;
@pragma("vm:entry-point") @pragma("vm:entry-point")
final List<int> _nestedDimensions; final List<int> _nestedDimensions;
@@ -347,6 +354,7 @@ final class Array<T extends NativeType> extends _Compound {
super._typedDataBase, super._typedDataBase,
super._offsetInBytes, super._offsetInBytes,
this._size, this._size,
this._variableLength,
this._nestedDimensions, this._nestedDimensions,
) : super._fromTypedDataBase(); ) : super._fromTypedDataBase();
@@ -362,13 +370,9 @@ final class Array<T extends NativeType> extends _Compound {
List<int> get _nestedDimensionsRest => List<int> get _nestedDimensionsRest =>
_nestedDimensionsRestCache ??= _nestedDimensions.sublist(1); _nestedDimensionsRestCache ??= _nestedDimensions.sublist(1);
static const _variableLengthLength = 0;
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
void _checkIndex(int index) { void _checkIndex(int index) {
if (_size == _variableLengthLength) { if (_variableLength) return;
return;
}
if (index < 0 || index >= _size) { if (index < 0 || index >= _size) {
throw RangeError.range(index, 0, _size - 1); 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'); int get _size => throw UnsupportedError('_ArraySize._size');
bool get _variableLength =>
throw UnsupportedError('_ArraySize._variableLength');
Object get _typedDataBase => Object get _typedDataBase =>
throw UnsupportedError('_ArraySize._typedDataBase'); throw UnsupportedError('_ArraySize._typedDataBase');
@@ -45,6 +45,9 @@ final class _FfiInlineArray {
@pragma("vm:entry-point") @pragma("vm:entry-point")
@pragma("wasm:entry-point") @pragma("wasm:entry-point")
final int length; 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 /// ```dart
/// import 'dart:ffi'; /// import 'dart:ffi';
@@ -195,6 +195,51 @@ final class Array<T extends NativeType> extends _Compound {
int dimension5, int dimension5,
]) = _ArraySize<T>.variable; ]) = _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. /// Annotation to a variable length [Array] in [Struct]s.
/// ///
/// ```dart /// ```dart
@@ -204,17 +249,29 @@ final class Array<T extends NativeType> extends _Compound {
/// } /// }
/// ///
/// final class MyStruct2 extends Struct { /// 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]) /// @Array.variableMulti([2, 2, 2, 2, 2, 2, 2])
/// external Array<Array<Array<Array<Array<Array<Array<Array<Uint8>>>>>>>> eightDimensionalInlineArray; /// 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. /// Do not invoke in normal code.
@Since('3.6') @Since('3.6')
const factory Array.variableMulti(List<int> dimensions) = const factory Array.variableMulti(
_ArraySize<T>.variableMulti; List<int> dimensions, {
@Since('3.7') int variableDimension,
}) = _ArraySize<T>.variableMulti;
} }
final class _ArraySize<T extends NativeType> implements Array<T> { 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; final List<int>? dimensions;
// When `true`, [dimension1] is [variableLengthLength], or [dimensions] // When non-null, [dimension1] is equal to this value, or [dimensions] should
// should be prepended with [variableLengthLength]. // be prepended with this value.
final bool variableLength; final int? variableDimension;
const _ArraySize( const _ArraySize(
this.dimension1, [ this.dimension1, [
@@ -237,7 +294,7 @@ final class _ArraySize<T extends NativeType> implements Array<T> {
this.dimension4, this.dimension4,
this.dimension5, this.dimension5,
]) : dimensions = null, ]) : dimensions = null,
variableLength = false; variableDimension = null;
const _ArraySize.multi(this.dimensions) const _ArraySize.multi(this.dimensions)
: dimension1 = null, : dimension1 = null,
@@ -245,40 +302,37 @@ final class _ArraySize<T extends NativeType> implements Array<T> {
dimension3 = null, dimension3 = null,
dimension4 = null, dimension4 = null,
dimension5 = null, dimension5 = null,
variableLength = false; variableDimension = null;
// 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;
const _ArraySize.variable([ const _ArraySize.variable([
this.dimension2, this.dimension2,
this.dimension3, this.dimension3,
this.dimension4, this.dimension4,
this.dimension5, this.dimension5,
]) : dimension1 = variableLengthLength, ]) : dimension1 = 0,
dimensions = null, dimensions = null,
variableLength = true; variableDimension = 0;
const _ArraySize.variableMulti(List<int> nestedDimensions) const _ArraySize.variableWithVariableDimension([
: dimensions = nestedDimensions, // Should be `[0, ...nestedDimensions]`. this.dimension1,
dimension1 = null, this.dimension2,
dimension2 = null, this.dimension3,
dimension3 = null, this.dimension4,
dimension4 = null, this.dimension5,
dimension5 = null, ]) : dimensions = null,
variableLength = true; 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]. /// Extension on [Pointer] specialized for the type argument [NativeFunction].
@@ -580,6 +580,14 @@ final testCases = [
), ),
noChecks, noChecks,
), ),
CallbackTest.withCheck(
"PassPointerStructInlineArrayVariable2",
Pointer.fromFunction<PassPointerStructInlineArrayVariable2Type>(
passPointerStructInlineArrayVariable2,
0,
),
noChecks,
),
CallbackTest.withCheck( CallbackTest.withCheck(
"ReturnStruct1ByteInt", "ReturnStruct1ByteInt",
Pointer.fromFunction<ReturnStruct1ByteIntType>(returnStruct1ByteInt), Pointer.fromFunction<ReturnStruct1ByteIntType>(returnStruct1ByteInt),
@@ -8629,6 +8637,59 @@ int passPointerStructInlineArrayVariableAlign(
return result; 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); typedef ReturnStruct1ByteIntType = Struct1ByteInt Function(Int8);
// Global variables to be able to test inputs after callback returned. // Global variables to be able to test inputs after callback returned.
@@ -620,6 +620,14 @@ final testCases = [
), ),
noChecks, noChecks,
), ),
CallbackTest.withCheck(
"PassPointerStructInlineArrayVariable2",
NativeCallable<PassPointerStructInlineArrayVariable2Type>.isolateLocal(
passPointerStructInlineArrayVariable2,
exceptionalReturn: 0,
),
noChecks,
),
CallbackTest.withCheck( CallbackTest.withCheck(
"ReturnStruct1ByteInt", "ReturnStruct1ByteInt",
NativeCallable<ReturnStruct1ByteIntType>.isolateLocal(returnStruct1ByteInt), NativeCallable<ReturnStruct1ByteIntType>.isolateLocal(returnStruct1ByteInt),
@@ -8677,6 +8685,59 @@ int passPointerStructInlineArrayVariableAlign(
return result; 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); typedef ReturnStruct1ByteIntType = Struct1ByteInt Function(Int8);
// Global variables to be able to test inputs after callback returned. // Global variables to be able to test inputs after callback returned.
@@ -95,6 +95,7 @@ void main() {
testPassPointerStruct12BytesHomogeneousInt32Leaf(); testPassPointerStruct12BytesHomogeneousInt32Leaf();
testPassPointerStructInlineArrayVariableLeaf(); testPassPointerStructInlineArrayVariableLeaf();
testPassPointerStructInlineArrayVariableAlignLeaf(); testPassPointerStructInlineArrayVariableAlignLeaf();
testPassPointerStructInlineArrayVariable2Leaf();
} }
} }
@@ -6149,3 +6150,36 @@ void testPassPointerStructInlineArrayVariableAlignLeaf() {
calloc.free(a0); 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(); testPassPointerStruct12BytesHomogeneousInt32NativeLeaf();
testPassPointerStructInlineArrayVariableNativeLeaf(); testPassPointerStructInlineArrayVariableNativeLeaf();
testPassPointerStructInlineArrayVariableAlignNativeLeaf(); testPassPointerStructInlineArrayVariableAlignNativeLeaf();
testPassPointerStructInlineArrayVariable2NativeLeaf();
} }
} }
@@ -6204,3 +6205,38 @@ void testPassPointerStructInlineArrayVariableAlignNativeLeaf() {
calloc.free(a0); 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(); testPassPointerStruct12BytesHomogeneousInt32Native();
testPassPointerStructInlineArrayVariableNative(); testPassPointerStructInlineArrayVariableNative();
testPassPointerStructInlineArrayVariableAlignNative(); testPassPointerStructInlineArrayVariableAlignNative();
testPassPointerStructInlineArrayVariable2Native();
} }
} }
@@ -6163,3 +6164,37 @@ void testPassPointerStructInlineArrayVariableAlignNative() {
calloc.free(a0); 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(); testPassPointerStruct12BytesHomogeneousInt32();
testPassPointerStructInlineArrayVariable(); testPassPointerStructInlineArrayVariable();
testPassPointerStructInlineArrayVariableAlign(); testPassPointerStructInlineArrayVariableAlign();
testPassPointerStructInlineArrayVariable2();
} }
} }
@@ -6094,3 +6095,35 @@ void testPassPointerStructInlineArrayVariableAlign() {
calloc.free(a0); 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})"; 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 get cStructField {
String postFix = ""; String postFix = "";
if (type is FixedLengthArrayType) { if (type case FixedLengthArrayType(:final dimensions)) {
final dimensions = (type as FixedLengthArrayType).dimensions;
postFix = postFix =
"[${dimensions.map((d) => d == 0 ? '' : d.toString()).join("][")}]"; "[${dimensions.map((d) => d == 0 ? '' : d.toString()).join("][")}]";
} }
@@ -488,24 +487,35 @@ class FixedLengthArrayType extends CType {
} }
class VariableLengthArrayType extends FixedLengthArrayType { class VariableLengthArrayType extends FixedLengthArrayType {
VariableLengthArrayType(CType elementType) : super(elementType, 0); VariableLengthArrayType(CType elementType, {this.variableDimension = 0})
: super(elementType, variableDimension);
factory VariableLengthArrayType.multi( factory VariableLengthArrayType.multi(
CType elementType, CType elementType,
List<int> fixedDimensions, List<int> fixedDimensions, {
) { int variableDimension = 0,
}) {
final nestedArray = FixedLengthArrayType.multi( final nestedArray = FixedLengthArrayType.multi(
elementType, elementType,
fixedDimensions, fixedDimensions,
); );
return VariableLengthArrayType(nestedArray); return VariableLengthArrayType(
nestedArray,
variableDimension: variableDimension,
);
} }
final int variableDimension;
String get dartStructFieldAnnotation { String get dartStructFieldAnnotation {
if (dimensions.length > 5) { 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) { } else if (returnValue is UnionType && arguments.length == 1) {
return "Return${returnValue.dartCType}"; return "Return${returnValue.dartCType}";
} else if (returnValue == uint64 && arguments.isEmpty) {
result = "SizeOf${reason}";
} else { } else {
result = "Uncategorized"; result = "Uncategorized";
} }
@@ -11,6 +11,12 @@ final functions = [
...functionsReturnArgument, ...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. /// Functions that pass structs as arguments.
final functionsStructArguments = [ final functionsStructArguments = [
FunctionType(List.filled(10, struct1byteInt), int64, """ FunctionType(List.filled(10, struct1byteInt), int64, """
@@ -475,6 +481,12 @@ Variable length array""",
Variable length array with variable length element having more alignment than Variable length array with variable length element having more alignment than
the rest of the struct.""", the rest of the struct.""",
), ),
FunctionType(
[PointerType(structVariableLengthArray5)],
int64,
"""
Variable length array with variable dimension of 1.""",
),
]; ];
/// Functions that return a struct by value. /// Functions that return a struct by value.
@@ -748,6 +760,9 @@ final compounds = [
structVariableLengthArray2, structVariableLengthArray2,
structVariableLengthArray3, structVariableLengthArray3,
structVariableLengthArray4, structVariableLengthArray4,
structVariableLengthArray5,
structVariableLengthArray6,
structVariableLengthArray7,
]; ];
/// Function signatures for variadic argument tests. /// Function signatures for variadic argument tests.
@@ -1160,3 +1175,25 @@ final structVariableLengthArray4 = StructType.override([
uint8, uint8,
VariableLengthArrayType(uint32), VariableLengthArrayType(uint32),
], "InlineArrayVariableAlign"); ], "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 'structs_by_value_tests_configuration.dart';
import 'utils.dart'; import 'utils.dart';
/// The test type determines how to convert the arguments into return values /// Defines the type of test, detailing how arguments are handled and return
/// such that the caller knows what to check. /// values are generated for validation.
enum TestType { 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 /// Tested by getting all the individual fields out of the structs and
/// summing their values. /// summing their values.
structArguments, structArguments,
@@ -41,6 +45,9 @@ extension on FunctionType {
return TestType.structReturn; return TestType.structReturn;
} }
} }
if (returnValue == uint64 && arguments.isEmpty) {
return TestType.compoundSizeOf;
}
// No structs, sum the arguments as well. // No structs, sum the arguments as well.
return TestType.structArguments; return TestType.structArguments;
@@ -344,8 +351,11 @@ extension on CType {
case StructType _: case StructType _:
final lastMember = pointerTo.memberTypes.last; final lastMember = pointerTo.memberTypes.last;
final String extraBytes = switch (lastMember) { final String extraBytes = switch (lastMember) {
VariableLengthArrayType _ => VariableLengthArrayType(:final variableDimension) =>
'+ $_variableLengthLength * sizeOf<${lastMember.elementType.dartCType}>()', variableDimension > 0
? '+ ${_variableLengthLength - variableDimension} * sizeOf<${lastMember.elementType.dartCType}>()'
: '+ $_variableLengthLength * sizeOf<${lastMember.elementType.dartCType}>()',
_ => '', _ => '',
}; };
return ''' return '''
@@ -753,6 +763,13 @@ extension on FunctionType {
String expects; String expects;
switch (testType) { switch (testType) {
case TestType.compoundSizeOf:
// Check against sizeOf.
expects = returnValue.dartExpectsStatements(
"sizeOf<$reason>()",
"result",
);
break;
case TestType.structArguments: case TestType.structArguments:
// Check against sum value. // Check against sum value.
final expectedResult = a.sumValue(returnValue as FundamentalType); final expectedResult = a.sumValue(returnValue as FundamentalType);
@@ -772,6 +789,12 @@ extension on FunctionType {
var namePostfix = isNative ? "Native" : ""; var namePostfix = isNative ? "Native" : "";
namePostfix += isLeaf ? "Leaf" : ""; 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 """ return """
${isNative ? ''' ${isNative ? '''
@@ -782,7 +805,7 @@ final $dartName$namePostfix =
ffiTestFunctions.lookupFunction<$dartCType, $dartType>( ffiTestFunctions.lookupFunction<$dartCType, $dartType>(
"$cName"${isLeaf ? ", isLeaf:true" : ""}); "$cName"${isLeaf ? ", isLeaf:true" : ""});
'''} '''}
${reason.makeDartDocComment()} $docs
void $dartTestName$namePostfix() { void $dartTestName$namePostfix() {
${arguments.dartAllocateStatements()} ${arguments.dartAllocateStatements()}
${assignValues} ${assignValues}
@@ -817,6 +840,8 @@ ${assignValues}
} }
switch (testType) { switch (testType) {
case TestType.compoundSizeOf:
throw UnsupportedError("Unsupported test type: $testType");
case TestType.structArguments: case TestType.structArguments:
// Sum all input values. // Sum all input values.
@@ -868,6 +893,8 @@ ${arguments.addToResultStatements(true, '${dartName}_')}
String afterCallbackExpects = ""; String afterCallbackExpects = "";
String afterCallbackFrees = ""; String afterCallbackFrees = "";
switch (testType) { switch (testType) {
case TestType.compoundSizeOf:
throw UnsupportedError("Unsupported test type: $testType");
case TestType.structArguments: case TestType.structArguments:
// Check that the input structs are still available. // Check that the input structs are still available.
// Check against sum value. // Check against sum value.
@@ -1043,6 +1070,11 @@ Future<void> ${dartName}AfterCallback() async {
returnStatement = 'return result % 2 != 0;'; returnStatement = 'return result % 2 != 0;';
} }
switch (testType) { switch (testType) {
case TestType.compoundSizeOf:
body = """
$returnValueType result = sizeof($reason);
""";
break;
case TestType.structArguments: case TestType.structArguments:
body = """ body = """
$returnValueType result = 0; $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 """ return """
// Used for testing structs and unions by value. $docs
${reason.makeCComment()}
DART_EXPORT ${returnValue.cType} $cName($argumentString) { DART_EXPORT ${returnValue.cType} $cName($argumentString) {
$varArgsUnpack $varArgsUnpack
@@ -1120,6 +1155,8 @@ $varArgsUnpack
String expects = ""; String expects = "";
String expectsZero = ""; String expectsZero = "";
switch (testType) { switch (testType) {
case TestType.compoundSizeOf:
throw UnsupportedError("Unsupported test type: $testType");
case TestType.structArguments: case TestType.structArguments:
// Check against sum value. // Check against sum value.
final returnValue_ = returnValue as FundamentalType; final returnValue_ = returnValue as FundamentalType;
@@ -1254,6 +1291,38 @@ Future<void> writeDartCompounds() async {
await runProcess(Platform.resolvedExecutable, ["format", path]); 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 = ''}) { headerDartCallTest({required int copyrightYear, String vmFlags = ''}) {
if (vmFlags.length != 0 && !vmFlags.endsWith(' ')) { if (vmFlags.length != 0 && !vmFlags.endsWith(' ')) {
vmFlags += ' '; vmFlags += ' ';
@@ -1403,7 +1472,7 @@ Future<void> writeDartCallbackTest(
buffer.write(""" buffer.write("""
final testCases = [ 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) { if (isAsync) {
functions = functions.where((f) => !f.arguments.containsPointers).toList(); functions = functions.where((f) => !f.arguments.containsPointers).toList();
} }
final constructors = functions final constructors =
.map((e) => e.dartNativeCallableListenerTestConstructor(isAsync: isAsync)) functions
.join("\n"); .map(
(e) =>
e.dartNativeCallableListenerTestConstructor(isAsync: isAsync),
)
.join();
buffer.write(""" buffer.write("""
final testCases = [ final testCases = [
@@ -1515,6 +1588,7 @@ Future<void> writeC() async {
buffer.write(headerC(copyrightYear: 2020, generatorPath: generatorPath)); buffer.write(headerC(copyrightYear: 2020, generatorPath: generatorPath));
buffer.writeAll(compounds.map((e) => e.cDefinition)); 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.cCallCode));
buffer.writeAll(functions.map((e) => e.cCallbackCode)); buffer.writeAll(functions.map((e) => e.cCallbackCode));
buffer.writeAll(functions.map((e) => e.cAsyncCallbackCode)); buffer.writeAll(functions.map((e) => e.cAsyncCallbackCode));
@@ -1563,6 +1637,7 @@ void main(List<String> arguments) async {
await Future.wait([ await Future.wait([
writeDartCompounds(), writeDartCompounds(),
writeDartCompoundsSizeOfTest(functionsCompoundSizeOf),
for (bool isLeaf in [false, true]) ...[ for (bool isLeaf in [false, true]) ...[
for (bool isNative in [false, true]) ...[ for (bool isNative in [false, true]) ...[
writeDartCallTest( writeDartCallTest(
@@ -16,6 +16,9 @@ void main() {
testInlineArray(); testInlineArray();
testInlineArrayNested(); testInlineArrayNested();
testInlineArrayNestedDeep(); testInlineArrayNestedDeep();
testInlineArray2();
testInlineArrayNested2();
testInlineArrayNestedDeep2();
testSizeOf(); testSizeOf();
} }
@@ -79,6 +82,67 @@ void testInlineArrayNestedDeep() {
Expect.equals(45, sum); 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 { final class Foo extends Struct {
@Int8() @Int8()
external int field0; external int field0;
@@ -88,11 +152,56 @@ final class Foo2 extends Struct {
@Int8() @Int8()
external int field0; external int field0;
@Array<Uint32>.variable() @Array.variable()
external Array<Uint32> field1; 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() { void testSizeOf() {
Expect.equals(1, sizeOf<Foo>()); Expect.equals(1, sizeOf<Foo>());
Expect.equals(4, sizeOf<Foo2>()); 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, noChecksAsync,
), ),
AsyncCallbackTest(
"PassPointerStructInlineArrayVariable2",
Pointer.fromFunction<PassPointerStructInlineArrayVariable2Type>(
passPointerStructInlineArrayVariable2,
),
noChecksAsync,
),
AsyncCallbackTest( AsyncCallbackTest(
"ReturnStruct1ByteInt", "ReturnStruct1ByteInt",
Pointer.fromFunction<ReturnStruct1ByteIntType>(returnStruct1ByteInt), Pointer.fromFunction<ReturnStruct1ByteIntType>(returnStruct1ByteInt),
@@ -5696,6 +5703,42 @@ Future<void> passPointerStructInlineArrayVariableAlignAfterCallback() async {
Expect.approxEquals(66, result); 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); typedef ReturnStruct1ByteIntType = Void Function(Int8);
// Global variable that stores the result. // Global variable that stores the result.
@@ -121,3 +121,41 @@ final class TestStruct12 extends Struct {
bool get a1 => true; bool get a1 => true;
set a1(bool value) {} 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;
}