| // Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| // |
| // This file has been automatically generated. Please do not edit it manually. |
| // Generated by tests/ffi/generator/structs_by_value_tests_generator.dart. |
| // |
| // SharedObjects=ffi_test_functions |
| // VMOptions= |
| // VMOptions=--deterministic --optimization-counter-threshold=90 |
| // VMOptions=--use-slow-path |
| // VMOptions=--use-slow-path --stacktrace-every=100 |
| |
| import 'dart:ffi'; |
| |
| import 'package:expect/expect.dart'; |
| // ignore: unused_import |
| import 'package:ffi/ffi.dart'; |
| |
| import 'dylib_utils.dart'; |
| |
| // Reuse the compound classes. |
| import 'function_structs_by_value_generated_compounds.dart'; |
| |
| final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions"); |
| void main() { |
| // Force dlopen so @Native lookups in DynamicLibrary.process() succeed. |
| dlopenGlobalPlatformSpecific('ffi_test_functions'); |
| |
| for (int i = 0; i < 100; ++i) { |
| testReturnStructArgumentStruct1ByteIntNativeLeaf(); |
| testReturnStructArgumentInt32x8Struct1ByteIntNativeLeaf(); |
| testReturnStructArgumentStruct8BytesHomogeneousFloatNativeLeaf(); |
| testReturnStructArgumentStruct20BytesHomogeneousInt32NativeLeaf(); |
| testReturnStructArgumentInt32x8Struct20BytesHomogeneouNativeLeaf(); |
| testReturnStructArgumentStruct8BytesInlineArrayIntNativeLeaf(); |
| testReturnStructArgumentStructStruct16BytesHomogeneousNativeLeaf(); |
| testReturnStructArgumentStructStruct32BytesHomogeneousNativeLeaf(); |
| testReturnStructArgumentStructStruct16BytesMixed3NativeLeaf(); |
| testReturnStructAlignmentInt16NativeLeaf(); |
| testReturnStructAlignmentInt32NativeLeaf(); |
| testReturnStructAlignmentInt64NativeLeaf(); |
| testReturnStruct8BytesNestedIntNativeLeaf(); |
| testReturnStruct8BytesNestedFloatNativeLeaf(); |
| testReturnStruct8BytesNestedFloat2NativeLeaf(); |
| testReturnStruct8BytesNestedMixedNativeLeaf(); |
| testReturnStruct16BytesNestedIntNativeLeaf(); |
| testReturnStruct32BytesNestedIntNativeLeaf(); |
| testReturnStructNestedIntStructAlignmentInt16NativeLeaf(); |
| testReturnStructNestedIntStructAlignmentInt32NativeLeaf(); |
| testReturnStructNestedIntStructAlignmentInt64NativeLeaf(); |
| testReturnStructNestedIrregularEvenBiggerNativeLeaf(); |
| } |
| } |
| |
| @Native<Struct1ByteInt Function(Struct1ByteInt)>( |
| symbol: 'ReturnStructArgumentStruct1ByteInt', |
| isLeaf: true, |
| ) |
| external Struct1ByteInt returnStructArgumentStruct1ByteIntNativeLeaf( |
| Struct1ByteInt a0, |
| ); |
| |
| /// Test that a struct passed in as argument can be returned. |
| /// Especially for ffi callbacks. |
| /// Struct is passed in int registers in most ABIs. |
| void testReturnStructArgumentStruct1ByteIntNativeLeaf() { |
| final a0Pointer = calloc<Struct1ByteInt>(); |
| final Struct1ByteInt a0 = a0Pointer.ref; |
| |
| a0.a0 = -1; |
| |
| final result = returnStructArgumentStruct1ByteIntNativeLeaf(a0); |
| |
| print("result = $result"); |
| |
| Expect.equals(a0.a0, result.a0); |
| |
| calloc.free(a0Pointer); |
| } |
| |
| @Native< |
| Struct1ByteInt Function( |
| Int32, |
| Int32, |
| Int32, |
| Int32, |
| Int32, |
| Int32, |
| Int32, |
| Int32, |
| Struct1ByteInt, |
| ) |
| >(symbol: 'ReturnStructArgumentInt32x8Struct1ByteInt', isLeaf: true) |
| external Struct1ByteInt returnStructArgumentInt32x8Struct1ByteIntNativeLeaf( |
| int a0, |
| int a1, |
| int a2, |
| int a3, |
| int a4, |
| int a5, |
| int a6, |
| int a7, |
| Struct1ByteInt a8, |
| ); |
| |
| /// Test that a struct passed in as argument can be returned. |
| /// Especially for ffi callbacks. |
| /// Struct is passed on stack on all ABIs. |
| void testReturnStructArgumentInt32x8Struct1ByteIntNativeLeaf() { |
| int a0; |
| int a1; |
| int a2; |
| int a3; |
| int a4; |
| int a5; |
| int a6; |
| int a7; |
| final a8Pointer = calloc<Struct1ByteInt>(); |
| final Struct1ByteInt a8 = a8Pointer.ref; |
| |
| a0 = -1; |
| a1 = 2; |
| a2 = -3; |
| a3 = 4; |
| a4 = -5; |
| a5 = 6; |
| a6 = -7; |
| a7 = 8; |
| a8.a0 = -9; |
| |
| final result = returnStructArgumentInt32x8Struct1ByteIntNativeLeaf( |
| a0, |
| a1, |
| a2, |
| a3, |
| a4, |
| a5, |
| a6, |
| a7, |
| a8, |
| ); |
| |
| print("result = $result"); |
| |
| Expect.equals(a8.a0, result.a0); |
| |
| calloc.free(a8Pointer); |
| } |
| |
| @Native<Struct8BytesHomogeneousFloat Function(Struct8BytesHomogeneousFloat)>( |
| symbol: 'ReturnStructArgumentStruct8BytesHomogeneousFloat', |
| isLeaf: true, |
| ) |
| external Struct8BytesHomogeneousFloat |
| returnStructArgumentStruct8BytesHomogeneousFloatNativeLeaf( |
| Struct8BytesHomogeneousFloat a0, |
| ); |
| |
| /// Test that a struct passed in as argument can be returned. |
| /// Especially for ffi callbacks. |
| /// Struct is passed in float registers in most ABIs. |
| void testReturnStructArgumentStruct8BytesHomogeneousFloatNativeLeaf() { |
| final a0Pointer = calloc<Struct8BytesHomogeneousFloat>(); |
| final Struct8BytesHomogeneousFloat a0 = a0Pointer.ref; |
| |
| a0.a0 = -1.0; |
| a0.a1 = 2.0; |
| |
| final result = returnStructArgumentStruct8BytesHomogeneousFloatNativeLeaf(a0); |
| |
| print("result = $result"); |
| |
| Expect.approxEquals(a0.a0, result.a0); |
| Expect.approxEquals(a0.a1, result.a1); |
| |
| calloc.free(a0Pointer); |
| } |
| |
| @Native<Struct20BytesHomogeneousInt32 Function(Struct20BytesHomogeneousInt32)>( |
| symbol: 'ReturnStructArgumentStruct20BytesHomogeneousInt32', |
| isLeaf: true, |
| ) |
| external Struct20BytesHomogeneousInt32 |
| returnStructArgumentStruct20BytesHomogeneousInt32NativeLeaf( |
| Struct20BytesHomogeneousInt32 a0, |
| ); |
| |
| /// On arm64, both argument and return value are passed in by pointer. |
| void testReturnStructArgumentStruct20BytesHomogeneousInt32NativeLeaf() { |
| final a0Pointer = calloc<Struct20BytesHomogeneousInt32>(); |
| final Struct20BytesHomogeneousInt32 a0 = a0Pointer.ref; |
| |
| a0.a0 = -1; |
| a0.a1 = 2; |
| a0.a2 = -3; |
| a0.a3 = 4; |
| a0.a4 = -5; |
| |
| final result = returnStructArgumentStruct20BytesHomogeneousInt32NativeLeaf( |
| a0, |
| ); |
| |
| print("result = $result"); |
| |
| Expect.equals(a0.a0, result.a0); |
| Expect.equals(a0.a1, result.a1); |
| Expect.equals(a0.a2, result.a2); |
| Expect.equals(a0.a3, result.a3); |
| Expect.equals(a0.a4, result.a4); |
| |
| calloc.free(a0Pointer); |
| } |
| |
| @Native< |
| Struct20BytesHomogeneousInt32 Function( |
| Int32, |
| Int32, |
| Int32, |
| Int32, |
| Int32, |
| Int32, |
| Int32, |
| Int32, |
| Struct20BytesHomogeneousInt32, |
| ) |
| >(symbol: 'ReturnStructArgumentInt32x8Struct20BytesHomogeneou', isLeaf: true) |
| external Struct20BytesHomogeneousInt32 |
| returnStructArgumentInt32x8Struct20BytesHomogeneouNativeLeaf( |
| int a0, |
| int a1, |
| int a2, |
| int a3, |
| int a4, |
| int a5, |
| int a6, |
| int a7, |
| Struct20BytesHomogeneousInt32 a8, |
| ); |
| |
| /// On arm64, both argument and return value are passed in by pointer. |
| /// Ints exhaust registers, so that pointer is passed on stack. |
| void testReturnStructArgumentInt32x8Struct20BytesHomogeneouNativeLeaf() { |
| int a0; |
| int a1; |
| int a2; |
| int a3; |
| int a4; |
| int a5; |
| int a6; |
| int a7; |
| final a8Pointer = calloc<Struct20BytesHomogeneousInt32>(); |
| final Struct20BytesHomogeneousInt32 a8 = a8Pointer.ref; |
| |
| a0 = -1; |
| a1 = 2; |
| a2 = -3; |
| a3 = 4; |
| a4 = -5; |
| a5 = 6; |
| a6 = -7; |
| a7 = 8; |
| a8.a0 = -9; |
| a8.a1 = 10; |
| a8.a2 = -11; |
| a8.a3 = 12; |
| a8.a4 = -13; |
| |
| final result = returnStructArgumentInt32x8Struct20BytesHomogeneouNativeLeaf( |
| a0, |
| a1, |
| a2, |
| a3, |
| a4, |
| a5, |
| a6, |
| a7, |
| a8, |
| ); |
| |
| print("result = $result"); |
| |
| Expect.equals(a8.a0, result.a0); |
| Expect.equals(a8.a1, result.a1); |
| Expect.equals(a8.a2, result.a2); |
| Expect.equals(a8.a3, result.a3); |
| Expect.equals(a8.a4, result.a4); |
| |
| calloc.free(a8Pointer); |
| } |
| |
| @Native<Struct8BytesInlineArrayInt Function(Struct8BytesInlineArrayInt)>( |
| symbol: 'ReturnStructArgumentStruct8BytesInlineArrayInt', |
| isLeaf: true, |
| ) |
| external Struct8BytesInlineArrayInt |
| returnStructArgumentStruct8BytesInlineArrayIntNativeLeaf( |
| Struct8BytesInlineArrayInt a0, |
| ); |
| |
| /// Test returning struct with inline array. |
| void testReturnStructArgumentStruct8BytesInlineArrayIntNativeLeaf() { |
| final a0Pointer = calloc<Struct8BytesInlineArrayInt>(); |
| final Struct8BytesInlineArrayInt a0 = a0Pointer.ref; |
| |
| a0.a0[0] = 1; |
| a0.a0[1] = 2; |
| a0.a0[2] = 3; |
| a0.a0[3] = 4; |
| a0.a0[4] = 5; |
| a0.a0[5] = 6; |
| a0.a0[6] = 7; |
| a0.a0[7] = 8; |
| |
| final result = returnStructArgumentStruct8BytesInlineArrayIntNativeLeaf(a0); |
| |
| print("result = $result"); |
| |
| for (int i = 0; i < 8; i++) { |
| Expect.equals(a0.a0[i], result.a0[i]); |
| } |
| |
| calloc.free(a0Pointer); |
| } |
| |
| @Native< |
| StructStruct16BytesHomogeneousFloat2 Function( |
| StructStruct16BytesHomogeneousFloat2, |
| ) |
| >(symbol: 'ReturnStructArgumentStructStruct16BytesHomogeneous', isLeaf: true) |
| external StructStruct16BytesHomogeneousFloat2 |
| returnStructArgumentStructStruct16BytesHomogeneousNativeLeaf( |
| StructStruct16BytesHomogeneousFloat2 a0, |
| ); |
| |
| /// Return value in FPU registers on arm hardfp and arm64. |
| void testReturnStructArgumentStructStruct16BytesHomogeneousNativeLeaf() { |
| final a0Pointer = calloc<StructStruct16BytesHomogeneousFloat2>(); |
| final StructStruct16BytesHomogeneousFloat2 a0 = a0Pointer.ref; |
| |
| a0.a0.a0 = -1.0; |
| a0.a1[0].a0 = 2.0; |
| a0.a1[1].a0 = -3.0; |
| a0.a2 = 4.0; |
| |
| final result = returnStructArgumentStructStruct16BytesHomogeneousNativeLeaf( |
| a0, |
| ); |
| |
| print("result = $result"); |
| |
| Expect.approxEquals(a0.a0.a0, result.a0.a0); |
| for (int i = 0; i < 2; i++) { |
| Expect.approxEquals(a0.a1[i].a0, result.a1[i].a0); |
| } |
| Expect.approxEquals(a0.a2, result.a2); |
| |
| calloc.free(a0Pointer); |
| } |
| |
| @Native< |
| StructStruct32BytesHomogeneousDouble2 Function( |
| StructStruct32BytesHomogeneousDouble2, |
| ) |
| >(symbol: 'ReturnStructArgumentStructStruct32BytesHomogeneous', isLeaf: true) |
| external StructStruct32BytesHomogeneousDouble2 |
| returnStructArgumentStructStruct32BytesHomogeneousNativeLeaf( |
| StructStruct32BytesHomogeneousDouble2 a0, |
| ); |
| |
| /// Return value in FPU registers on arm64. |
| void testReturnStructArgumentStructStruct32BytesHomogeneousNativeLeaf() { |
| final a0Pointer = calloc<StructStruct32BytesHomogeneousDouble2>(); |
| final StructStruct32BytesHomogeneousDouble2 a0 = a0Pointer.ref; |
| |
| a0.a0.a0 = -1.0; |
| a0.a1[0].a0 = 2.0; |
| a0.a1[1].a0 = -3.0; |
| a0.a2 = 4.0; |
| |
| final result = returnStructArgumentStructStruct32BytesHomogeneousNativeLeaf( |
| a0, |
| ); |
| |
| print("result = $result"); |
| |
| Expect.approxEquals(a0.a0.a0, result.a0.a0); |
| for (int i = 0; i < 2; i++) { |
| Expect.approxEquals(a0.a1[i].a0, result.a1[i].a0); |
| } |
| Expect.approxEquals(a0.a2, result.a2); |
| |
| calloc.free(a0Pointer); |
| } |
| |
| @Native<StructStruct16BytesMixed3 Function(StructStruct16BytesMixed3)>( |
| symbol: 'ReturnStructArgumentStructStruct16BytesMixed3', |
| isLeaf: true, |
| ) |
| external StructStruct16BytesMixed3 |
| returnStructArgumentStructStruct16BytesMixed3NativeLeaf( |
| StructStruct16BytesMixed3 a0, |
| ); |
| |
| /// On x64 Linux, return value is split over FP and int registers. |
| void testReturnStructArgumentStructStruct16BytesMixed3NativeLeaf() { |
| final a0Pointer = calloc<StructStruct16BytesMixed3>(); |
| final StructStruct16BytesMixed3 a0 = a0Pointer.ref; |
| |
| a0.a0.a0 = -1.0; |
| a0.a1[0].a0 = 2.0; |
| a0.a1[0].a1 = -3; |
| a0.a1[0].a2 = 4; |
| a0.a2[0] = -5; |
| a0.a2[1] = 6; |
| |
| final result = returnStructArgumentStructStruct16BytesMixed3NativeLeaf(a0); |
| |
| print("result = $result"); |
| |
| Expect.approxEquals(a0.a0.a0, result.a0.a0); |
| for (int i = 0; i < 1; i++) { |
| Expect.approxEquals(a0.a1[i].a0, result.a1[i].a0); |
| Expect.equals(a0.a1[i].a1, result.a1[i].a1); |
| Expect.equals(a0.a1[i].a2, result.a1[i].a2); |
| } |
| for (int i = 0; i < 2; i++) { |
| Expect.equals(a0.a2[i], result.a2[i]); |
| } |
| |
| calloc.free(a0Pointer); |
| } |
| |
| @Native<StructAlignmentInt16 Function(Int8, Int16, Int8)>( |
| symbol: 'ReturnStructAlignmentInt16', |
| isLeaf: true, |
| ) |
| external StructAlignmentInt16 returnStructAlignmentInt16NativeLeaf( |
| int a0, |
| int a1, |
| int a2, |
| ); |
| |
| /// Test alignment and padding of 16 byte int within struct. |
| void testReturnStructAlignmentInt16NativeLeaf() { |
| int a0; |
| int a1; |
| int a2; |
| |
| a0 = -1; |
| a1 = 2; |
| a2 = -3; |
| |
| final result = returnStructAlignmentInt16NativeLeaf(a0, a1, a2); |
| |
| print("result = $result"); |
| |
| Expect.equals(a0, result.a0); |
| Expect.equals(a1, result.a1); |
| Expect.equals(a2, result.a2); |
| } |
| |
| @Native<StructAlignmentInt32 Function(Int8, Int32, Int8)>( |
| symbol: 'ReturnStructAlignmentInt32', |
| isLeaf: true, |
| ) |
| external StructAlignmentInt32 returnStructAlignmentInt32NativeLeaf( |
| int a0, |
| int a1, |
| int a2, |
| ); |
| |
| /// Test alignment and padding of 32 byte int within struct. |
| void testReturnStructAlignmentInt32NativeLeaf() { |
| int a0; |
| int a1; |
| int a2; |
| |
| a0 = -1; |
| a1 = 2; |
| a2 = -3; |
| |
| final result = returnStructAlignmentInt32NativeLeaf(a0, a1, a2); |
| |
| print("result = $result"); |
| |
| Expect.equals(a0, result.a0); |
| Expect.equals(a1, result.a1); |
| Expect.equals(a2, result.a2); |
| } |
| |
| @Native<StructAlignmentInt64 Function(Int8, Int64, Int8)>( |
| symbol: 'ReturnStructAlignmentInt64', |
| isLeaf: true, |
| ) |
| external StructAlignmentInt64 returnStructAlignmentInt64NativeLeaf( |
| int a0, |
| int a1, |
| int a2, |
| ); |
| |
| /// Test alignment and padding of 64 byte int within struct. |
| void testReturnStructAlignmentInt64NativeLeaf() { |
| int a0; |
| int a1; |
| int a2; |
| |
| a0 = -1; |
| a1 = 2; |
| a2 = -3; |
| |
| final result = returnStructAlignmentInt64NativeLeaf(a0, a1, a2); |
| |
| print("result = $result"); |
| |
| Expect.equals(a0, result.a0); |
| Expect.equals(a1, result.a1); |
| Expect.equals(a2, result.a2); |
| } |
| |
| @Native< |
| Struct8BytesNestedInt Function( |
| Struct4BytesHomogeneousInt16, |
| Struct4BytesHomogeneousInt16, |
| ) |
| >(symbol: 'ReturnStruct8BytesNestedInt', isLeaf: true) |
| external Struct8BytesNestedInt returnStruct8BytesNestedIntNativeLeaf( |
| Struct4BytesHomogeneousInt16 a0, |
| Struct4BytesHomogeneousInt16 a1, |
| ); |
| |
| /// Simple nested struct. |
| void testReturnStruct8BytesNestedIntNativeLeaf() { |
| final a0Pointer = calloc<Struct4BytesHomogeneousInt16>(); |
| final Struct4BytesHomogeneousInt16 a0 = a0Pointer.ref; |
| final a1Pointer = calloc<Struct4BytesHomogeneousInt16>(); |
| final Struct4BytesHomogeneousInt16 a1 = a1Pointer.ref; |
| |
| a0.a0 = -1; |
| a0.a1 = 2; |
| a1.a0 = -3; |
| a1.a1 = 4; |
| |
| final result = returnStruct8BytesNestedIntNativeLeaf(a0, a1); |
| |
| print("result = $result"); |
| |
| Expect.equals(a0.a0, result.a0.a0); |
| Expect.equals(a0.a1, result.a0.a1); |
| Expect.equals(a1.a0, result.a1.a0); |
| Expect.equals(a1.a1, result.a1.a1); |
| |
| calloc.free(a0Pointer); |
| calloc.free(a1Pointer); |
| } |
| |
| @Native<Struct8BytesNestedFloat Function(Struct4BytesFloat, Struct4BytesFloat)>( |
| symbol: 'ReturnStruct8BytesNestedFloat', |
| isLeaf: true, |
| ) |
| external Struct8BytesNestedFloat returnStruct8BytesNestedFloatNativeLeaf( |
| Struct4BytesFloat a0, |
| Struct4BytesFloat a1, |
| ); |
| |
| /// Simple nested struct with floats. |
| void testReturnStruct8BytesNestedFloatNativeLeaf() { |
| final a0Pointer = calloc<Struct4BytesFloat>(); |
| final Struct4BytesFloat a0 = a0Pointer.ref; |
| final a1Pointer = calloc<Struct4BytesFloat>(); |
| final Struct4BytesFloat a1 = a1Pointer.ref; |
| |
| a0.a0 = -1.0; |
| a1.a0 = 2.0; |
| |
| final result = returnStruct8BytesNestedFloatNativeLeaf(a0, a1); |
| |
| print("result = $result"); |
| |
| Expect.approxEquals(a0.a0, result.a0.a0); |
| Expect.approxEquals(a1.a0, result.a1.a0); |
| |
| calloc.free(a0Pointer); |
| calloc.free(a1Pointer); |
| } |
| |
| @Native<Struct8BytesNestedFloat2 Function(Struct4BytesFloat, Float)>( |
| symbol: 'ReturnStruct8BytesNestedFloat2', |
| isLeaf: true, |
| ) |
| external Struct8BytesNestedFloat2 returnStruct8BytesNestedFloat2NativeLeaf( |
| Struct4BytesFloat a0, |
| double a1, |
| ); |
| |
| /// The nesting is irregular, testing homogenous float rules on arm and arm64, |
| /// and the fpu register usage on x64. |
| void testReturnStruct8BytesNestedFloat2NativeLeaf() { |
| final a0Pointer = calloc<Struct4BytesFloat>(); |
| final Struct4BytesFloat a0 = a0Pointer.ref; |
| double a1; |
| |
| a0.a0 = -1.0; |
| a1 = 2.0; |
| |
| final result = returnStruct8BytesNestedFloat2NativeLeaf(a0, a1); |
| |
| print("result = $result"); |
| |
| Expect.approxEquals(a0.a0, result.a0.a0); |
| Expect.approxEquals(a1, result.a1); |
| |
| calloc.free(a0Pointer); |
| } |
| |
| @Native< |
| Struct8BytesNestedMixed Function( |
| Struct4BytesHomogeneousInt16, |
| Struct4BytesFloat, |
| ) |
| >(symbol: 'ReturnStruct8BytesNestedMixed', isLeaf: true) |
| external Struct8BytesNestedMixed returnStruct8BytesNestedMixedNativeLeaf( |
| Struct4BytesHomogeneousInt16 a0, |
| Struct4BytesFloat a1, |
| ); |
| |
| /// Simple nested struct with mixed members. |
| void testReturnStruct8BytesNestedMixedNativeLeaf() { |
| final a0Pointer = calloc<Struct4BytesHomogeneousInt16>(); |
| final Struct4BytesHomogeneousInt16 a0 = a0Pointer.ref; |
| final a1Pointer = calloc<Struct4BytesFloat>(); |
| final Struct4BytesFloat a1 = a1Pointer.ref; |
| |
| a0.a0 = -1; |
| a0.a1 = 2; |
| a1.a0 = -3.0; |
| |
| final result = returnStruct8BytesNestedMixedNativeLeaf(a0, a1); |
| |
| print("result = $result"); |
| |
| Expect.equals(a0.a0, result.a0.a0); |
| Expect.equals(a0.a1, result.a0.a1); |
| Expect.approxEquals(a1.a0, result.a1.a0); |
| |
| calloc.free(a0Pointer); |
| calloc.free(a1Pointer); |
| } |
| |
| @Native< |
| Struct16BytesNestedInt Function(Struct8BytesNestedInt, Struct8BytesNestedInt) |
| >(symbol: 'ReturnStruct16BytesNestedInt', isLeaf: true) |
| external Struct16BytesNestedInt returnStruct16BytesNestedIntNativeLeaf( |
| Struct8BytesNestedInt a0, |
| Struct8BytesNestedInt a1, |
| ); |
| |
| /// Deeper nested struct to test recursive member access. |
| void testReturnStruct16BytesNestedIntNativeLeaf() { |
| final a0Pointer = calloc<Struct8BytesNestedInt>(); |
| final Struct8BytesNestedInt a0 = a0Pointer.ref; |
| final a1Pointer = calloc<Struct8BytesNestedInt>(); |
| final Struct8BytesNestedInt a1 = a1Pointer.ref; |
| |
| a0.a0.a0 = -1; |
| a0.a0.a1 = 2; |
| a0.a1.a0 = -3; |
| a0.a1.a1 = 4; |
| a1.a0.a0 = -5; |
| a1.a0.a1 = 6; |
| a1.a1.a0 = -7; |
| a1.a1.a1 = 8; |
| |
| final result = returnStruct16BytesNestedIntNativeLeaf(a0, a1); |
| |
| print("result = $result"); |
| |
| Expect.equals(a0.a0.a0, result.a0.a0.a0); |
| Expect.equals(a0.a0.a1, result.a0.a0.a1); |
| Expect.equals(a0.a1.a0, result.a0.a1.a0); |
| Expect.equals(a0.a1.a1, result.a0.a1.a1); |
| Expect.equals(a1.a0.a0, result.a1.a0.a0); |
| Expect.equals(a1.a0.a1, result.a1.a0.a1); |
| Expect.equals(a1.a1.a0, result.a1.a1.a0); |
| Expect.equals(a1.a1.a1, result.a1.a1.a1); |
| |
| calloc.free(a0Pointer); |
| calloc.free(a1Pointer); |
| } |
| |
| @Native< |
| Struct32BytesNestedInt Function( |
| Struct16BytesNestedInt, |
| Struct16BytesNestedInt, |
| ) |
| >(symbol: 'ReturnStruct32BytesNestedInt', isLeaf: true) |
| external Struct32BytesNestedInt returnStruct32BytesNestedIntNativeLeaf( |
| Struct16BytesNestedInt a0, |
| Struct16BytesNestedInt a1, |
| ); |
| |
| /// Even deeper nested struct to test recursive member access. |
| void testReturnStruct32BytesNestedIntNativeLeaf() { |
| final a0Pointer = calloc<Struct16BytesNestedInt>(); |
| final Struct16BytesNestedInt a0 = a0Pointer.ref; |
| final a1Pointer = calloc<Struct16BytesNestedInt>(); |
| final Struct16BytesNestedInt a1 = a1Pointer.ref; |
| |
| a0.a0.a0.a0 = -1; |
| a0.a0.a0.a1 = 2; |
| a0.a0.a1.a0 = -3; |
| a0.a0.a1.a1 = 4; |
| a0.a1.a0.a0 = -5; |
| a0.a1.a0.a1 = 6; |
| a0.a1.a1.a0 = -7; |
| a0.a1.a1.a1 = 8; |
| a1.a0.a0.a0 = -9; |
| a1.a0.a0.a1 = 10; |
| a1.a0.a1.a0 = -11; |
| a1.a0.a1.a1 = 12; |
| a1.a1.a0.a0 = -13; |
| a1.a1.a0.a1 = 14; |
| a1.a1.a1.a0 = -15; |
| a1.a1.a1.a1 = 16; |
| |
| final result = returnStruct32BytesNestedIntNativeLeaf(a0, a1); |
| |
| print("result = $result"); |
| |
| Expect.equals(a0.a0.a0.a0, result.a0.a0.a0.a0); |
| Expect.equals(a0.a0.a0.a1, result.a0.a0.a0.a1); |
| Expect.equals(a0.a0.a1.a0, result.a0.a0.a1.a0); |
| Expect.equals(a0.a0.a1.a1, result.a0.a0.a1.a1); |
| Expect.equals(a0.a1.a0.a0, result.a0.a1.a0.a0); |
| Expect.equals(a0.a1.a0.a1, result.a0.a1.a0.a1); |
| Expect.equals(a0.a1.a1.a0, result.a0.a1.a1.a0); |
| Expect.equals(a0.a1.a1.a1, result.a0.a1.a1.a1); |
| Expect.equals(a1.a0.a0.a0, result.a1.a0.a0.a0); |
| Expect.equals(a1.a0.a0.a1, result.a1.a0.a0.a1); |
| Expect.equals(a1.a0.a1.a0, result.a1.a0.a1.a0); |
| Expect.equals(a1.a0.a1.a1, result.a1.a0.a1.a1); |
| Expect.equals(a1.a1.a0.a0, result.a1.a1.a0.a0); |
| Expect.equals(a1.a1.a0.a1, result.a1.a1.a0.a1); |
| Expect.equals(a1.a1.a1.a0, result.a1.a1.a1.a0); |
| Expect.equals(a1.a1.a1.a1, result.a1.a1.a1.a1); |
| |
| calloc.free(a0Pointer); |
| calloc.free(a1Pointer); |
| } |
| |
| @Native< |
| StructNestedIntStructAlignmentInt16 Function( |
| StructAlignmentInt16, |
| StructAlignmentInt16, |
| ) |
| >(symbol: 'ReturnStructNestedIntStructAlignmentInt16', isLeaf: true) |
| external StructNestedIntStructAlignmentInt16 |
| returnStructNestedIntStructAlignmentInt16NativeLeaf( |
| StructAlignmentInt16 a0, |
| StructAlignmentInt16 a1, |
| ); |
| |
| /// Test alignment and padding of nested struct with 16 byte int. |
| void testReturnStructNestedIntStructAlignmentInt16NativeLeaf() { |
| final a0Pointer = calloc<StructAlignmentInt16>(); |
| final StructAlignmentInt16 a0 = a0Pointer.ref; |
| final a1Pointer = calloc<StructAlignmentInt16>(); |
| final StructAlignmentInt16 a1 = a1Pointer.ref; |
| |
| a0.a0 = -1; |
| a0.a1 = 2; |
| a0.a2 = -3; |
| a1.a0 = 4; |
| a1.a1 = -5; |
| a1.a2 = 6; |
| |
| final result = returnStructNestedIntStructAlignmentInt16NativeLeaf(a0, a1); |
| |
| print("result = $result"); |
| |
| Expect.equals(a0.a0, result.a0.a0); |
| Expect.equals(a0.a1, result.a0.a1); |
| Expect.equals(a0.a2, result.a0.a2); |
| Expect.equals(a1.a0, result.a1.a0); |
| Expect.equals(a1.a1, result.a1.a1); |
| Expect.equals(a1.a2, result.a1.a2); |
| |
| calloc.free(a0Pointer); |
| calloc.free(a1Pointer); |
| } |
| |
| @Native< |
| StructNestedIntStructAlignmentInt32 Function( |
| StructAlignmentInt32, |
| StructAlignmentInt32, |
| ) |
| >(symbol: 'ReturnStructNestedIntStructAlignmentInt32', isLeaf: true) |
| external StructNestedIntStructAlignmentInt32 |
| returnStructNestedIntStructAlignmentInt32NativeLeaf( |
| StructAlignmentInt32 a0, |
| StructAlignmentInt32 a1, |
| ); |
| |
| /// Test alignment and padding of nested struct with 32 byte int. |
| void testReturnStructNestedIntStructAlignmentInt32NativeLeaf() { |
| final a0Pointer = calloc<StructAlignmentInt32>(); |
| final StructAlignmentInt32 a0 = a0Pointer.ref; |
| final a1Pointer = calloc<StructAlignmentInt32>(); |
| final StructAlignmentInt32 a1 = a1Pointer.ref; |
| |
| a0.a0 = -1; |
| a0.a1 = 2; |
| a0.a2 = -3; |
| a1.a0 = 4; |
| a1.a1 = -5; |
| a1.a2 = 6; |
| |
| final result = returnStructNestedIntStructAlignmentInt32NativeLeaf(a0, a1); |
| |
| print("result = $result"); |
| |
| Expect.equals(a0.a0, result.a0.a0); |
| Expect.equals(a0.a1, result.a0.a1); |
| Expect.equals(a0.a2, result.a0.a2); |
| Expect.equals(a1.a0, result.a1.a0); |
| Expect.equals(a1.a1, result.a1.a1); |
| Expect.equals(a1.a2, result.a1.a2); |
| |
| calloc.free(a0Pointer); |
| calloc.free(a1Pointer); |
| } |
| |
| @Native< |
| StructNestedIntStructAlignmentInt64 Function( |
| StructAlignmentInt64, |
| StructAlignmentInt64, |
| ) |
| >(symbol: 'ReturnStructNestedIntStructAlignmentInt64', isLeaf: true) |
| external StructNestedIntStructAlignmentInt64 |
| returnStructNestedIntStructAlignmentInt64NativeLeaf( |
| StructAlignmentInt64 a0, |
| StructAlignmentInt64 a1, |
| ); |
| |
| /// Test alignment and padding of nested struct with 64 byte int. |
| void testReturnStructNestedIntStructAlignmentInt64NativeLeaf() { |
| final a0Pointer = calloc<StructAlignmentInt64>(); |
| final StructAlignmentInt64 a0 = a0Pointer.ref; |
| final a1Pointer = calloc<StructAlignmentInt64>(); |
| final StructAlignmentInt64 a1 = a1Pointer.ref; |
| |
| a0.a0 = -1; |
| a0.a1 = 2; |
| a0.a2 = -3; |
| a1.a0 = 4; |
| a1.a1 = -5; |
| a1.a2 = 6; |
| |
| final result = returnStructNestedIntStructAlignmentInt64NativeLeaf(a0, a1); |
| |
| print("result = $result"); |
| |
| Expect.equals(a0.a0, result.a0.a0); |
| Expect.equals(a0.a1, result.a0.a1); |
| Expect.equals(a0.a2, result.a0.a2); |
| Expect.equals(a1.a0, result.a1.a0); |
| Expect.equals(a1.a1, result.a1.a1); |
| Expect.equals(a1.a2, result.a1.a2); |
| |
| calloc.free(a0Pointer); |
| calloc.free(a1Pointer); |
| } |
| |
| @Native< |
| StructNestedIrregularEvenBigger Function( |
| Uint64, |
| StructNestedIrregularBigger, |
| StructNestedIrregularBigger, |
| Double, |
| ) |
| >(symbol: 'ReturnStructNestedIrregularEvenBigger', isLeaf: true) |
| external StructNestedIrregularEvenBigger |
| returnStructNestedIrregularEvenBiggerNativeLeaf( |
| int a0, |
| StructNestedIrregularBigger a1, |
| StructNestedIrregularBigger a2, |
| double a3, |
| ); |
| |
| /// Return big irregular struct as smoke test. |
| void testReturnStructNestedIrregularEvenBiggerNativeLeaf() { |
| int a0; |
| final a1Pointer = calloc<StructNestedIrregularBigger>(); |
| final StructNestedIrregularBigger a1 = a1Pointer.ref; |
| final a2Pointer = calloc<StructNestedIrregularBigger>(); |
| final StructNestedIrregularBigger a2 = a2Pointer.ref; |
| double a3; |
| |
| a0 = 1; |
| a1.a0.a0 = 2; |
| a1.a0.a1.a0.a0 = -3; |
| a1.a0.a1.a0.a1 = 4; |
| a1.a0.a1.a1.a0 = -5.0; |
| a1.a0.a2 = 6; |
| a1.a0.a3.a0.a0 = -7.0; |
| a1.a0.a3.a1 = 8.0; |
| a1.a0.a4 = 9; |
| a1.a0.a5.a0.a0 = 10.0; |
| a1.a0.a5.a1.a0 = -11.0; |
| a1.a0.a6 = 12; |
| a1.a1.a0.a0 = -13; |
| a1.a1.a0.a1 = 14; |
| a1.a1.a1.a0 = -15.0; |
| a1.a2 = 16.0; |
| a1.a3 = -17.0; |
| a2.a0.a0 = 18; |
| a2.a0.a1.a0.a0 = -19; |
| a2.a0.a1.a0.a1 = 20; |
| a2.a0.a1.a1.a0 = -21.0; |
| a2.a0.a2 = 22; |
| a2.a0.a3.a0.a0 = -23.0; |
| a2.a0.a3.a1 = 24.0; |
| a2.a0.a4 = 25; |
| a2.a0.a5.a0.a0 = 26.0; |
| a2.a0.a5.a1.a0 = -27.0; |
| a2.a0.a6 = 28; |
| a2.a1.a0.a0 = -29; |
| a2.a1.a0.a1 = 30; |
| a2.a1.a1.a0 = -31.0; |
| a2.a2 = 32.0; |
| a2.a3 = -33.0; |
| a3 = 34.0; |
| |
| final result = returnStructNestedIrregularEvenBiggerNativeLeaf( |
| a0, |
| a1, |
| a2, |
| a3, |
| ); |
| |
| print("result = $result"); |
| |
| Expect.equals(a0, result.a0); |
| Expect.equals(a1.a0.a0, result.a1.a0.a0); |
| Expect.equals(a1.a0.a1.a0.a0, result.a1.a0.a1.a0.a0); |
| Expect.equals(a1.a0.a1.a0.a1, result.a1.a0.a1.a0.a1); |
| Expect.approxEquals(a1.a0.a1.a1.a0, result.a1.a0.a1.a1.a0); |
| Expect.equals(a1.a0.a2, result.a1.a0.a2); |
| Expect.approxEquals(a1.a0.a3.a0.a0, result.a1.a0.a3.a0.a0); |
| Expect.approxEquals(a1.a0.a3.a1, result.a1.a0.a3.a1); |
| Expect.equals(a1.a0.a4, result.a1.a0.a4); |
| Expect.approxEquals(a1.a0.a5.a0.a0, result.a1.a0.a5.a0.a0); |
| Expect.approxEquals(a1.a0.a5.a1.a0, result.a1.a0.a5.a1.a0); |
| Expect.equals(a1.a0.a6, result.a1.a0.a6); |
| Expect.equals(a1.a1.a0.a0, result.a1.a1.a0.a0); |
| Expect.equals(a1.a1.a0.a1, result.a1.a1.a0.a1); |
| Expect.approxEquals(a1.a1.a1.a0, result.a1.a1.a1.a0); |
| Expect.approxEquals(a1.a2, result.a1.a2); |
| Expect.approxEquals(a1.a3, result.a1.a3); |
| Expect.equals(a2.a0.a0, result.a2.a0.a0); |
| Expect.equals(a2.a0.a1.a0.a0, result.a2.a0.a1.a0.a0); |
| Expect.equals(a2.a0.a1.a0.a1, result.a2.a0.a1.a0.a1); |
| Expect.approxEquals(a2.a0.a1.a1.a0, result.a2.a0.a1.a1.a0); |
| Expect.equals(a2.a0.a2, result.a2.a0.a2); |
| Expect.approxEquals(a2.a0.a3.a0.a0, result.a2.a0.a3.a0.a0); |
| Expect.approxEquals(a2.a0.a3.a1, result.a2.a0.a3.a1); |
| Expect.equals(a2.a0.a4, result.a2.a0.a4); |
| Expect.approxEquals(a2.a0.a5.a0.a0, result.a2.a0.a5.a0.a0); |
| Expect.approxEquals(a2.a0.a5.a1.a0, result.a2.a0.a5.a1.a0); |
| Expect.equals(a2.a0.a6, result.a2.a0.a6); |
| Expect.equals(a2.a1.a0.a0, result.a2.a1.a0.a0); |
| Expect.equals(a2.a1.a0.a1, result.a2.a1.a0.a1); |
| Expect.approxEquals(a2.a1.a1.a0, result.a2.a1.a1.a0); |
| Expect.approxEquals(a2.a2, result.a2.a2); |
| Expect.approxEquals(a2.a3, result.a2.a3); |
| Expect.approxEquals(a3, result.a3); |
| |
| calloc.free(a1Pointer); |
| calloc.free(a2Pointer); |
| } |