mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 12:24:24 +00:00
045b9c1715
We're adding these types to `dart:ffi` rather than `package:ffi` so that they can be used with `FfiNative`s. Adds `NativeType`s for the following C types: * unsigned char * signed char * short * unsigned short * int * unsigned int * long * unsigned long * long long * unsigned long long * uintptr_t * size_t * wchar_t Because the C standard only defines minimum sizes for many of these types, future platforms might diverge from the typical size even if all platforms currently agree on a size. To avoid having to reification later, we define all types as AbiSpecificIntegers rather than typedefs, even if all current target platforms agree on the size. Closes: https://github.com/dart-lang/sdk/issues/36140 TEST=tests/ffi/c_types_test.dart Original patch in patchset 1. * Removes `Char` for now until package:win32 has rolled to 2.3.8 in Flutter. https://pub.dev/packages/win32/versions/2.3.8/changelog https://logs.chromium.org/logs/flutter/buildbucket/cr-buildbucket/8824468064587445729/+/u/Android_Views_Integration_Tests/stdout * Adds `c_type.dart` in `ffi_source.gni` which should fix `IntPtr` missing when analyzing `path_provider_linux`. (However, I was unable to reproduce the issue locally.) https://logs.chromium.org/logs/flutter/buildbucket/cr-buildbucket/8824468064571399025/+/u/run_test.dart_for_flutter_plugins_shard_and_subshard_analyze/test_stdout `/tmp/flutter_plugins.KZMNMC/packages/path_provider/path_provider_linux$ ~/flt/engine/src/out/host_debug/dart-sdk/bin/dart analyze --fatal-infos` Change-Id: I89130cccba285fc9c483bb53f5710a302f2b104f Cq-Include-Trybots: luci.dart.try:dart-sdk-linux-try,dart-sdk-mac-try,dart-sdk-win-try,vm-ffi-android-debug-arm64c-try,vm-ffi-android-debug-arm-try,vm-canary-linux-debug-try,vm-fuchsia-release-x64-try,vm-kernel-gcc-linux-try,vm-kernel-asan-linux-release-x64-try,vm-kernel-linux-debug-x64-try,vm-kernel-linux-debug-ia32-try,vm-kernel-mac-debug-x64-try,vm-kernel-mac-release-arm64-try,vm-kernel-nnbd-win-release-ia32-try,vm-kernel-nnbd-win-release-x64-try,vm-precomp-ffi-qemu-linux-release-arm-try,vm-kernel-win-release-x64-try,flutter-analyze-try,flutter-engine-linux-try,flutter-frontend-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/229156 Reviewed-by: Martin Kustermann <kustermann@google.com> Commit-Queue: Daco Harkes <dacoharkes@google.com>
7785 lines
205 KiB
Dart
7785 lines
205 KiB
Dart
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
//
|
|
// 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=5
|
|
// VMOptions=--use-slow-path
|
|
// VMOptions=--use-slow-path --stacktrace-every=100
|
|
|
|
// @dart = 2.9
|
|
|
|
import 'dart:ffi';
|
|
|
|
import "package:expect/expect.dart";
|
|
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() {
|
|
for (int i = 0; i < 10; ++i) {
|
|
testPassStruct1ByteIntx10();
|
|
testPassStruct3BytesHomogeneousUint8x10();
|
|
testPassStruct3BytesInt2ByteAlignedx10();
|
|
testPassStruct4BytesHomogeneousInt16x10();
|
|
testPassStruct7BytesHomogeneousUint8x10();
|
|
testPassStruct7BytesInt4ByteAlignedx10();
|
|
testPassStruct8BytesIntx10();
|
|
testPassStruct8BytesHomogeneousFloatx10();
|
|
testPassStruct8BytesMixedx10();
|
|
testPassStruct9BytesHomogeneousUint8x10();
|
|
testPassStruct9BytesInt4Or8ByteAlignedx10();
|
|
testPassStruct12BytesHomogeneousFloatx6();
|
|
testPassStruct16BytesHomogeneousFloatx5();
|
|
testPassStruct16BytesMixedx10();
|
|
testPassStruct16BytesMixed2x10();
|
|
testPassStruct17BytesIntx10();
|
|
testPassStruct19BytesHomogeneousUint8x10();
|
|
testPassStruct20BytesHomogeneousInt32x10();
|
|
testPassStruct20BytesHomogeneousFloat();
|
|
testPassStruct32BytesHomogeneousDoublex5();
|
|
testPassStruct40BytesHomogeneousDouble();
|
|
testPassStruct1024BytesHomogeneousUint64();
|
|
testPassFloatStruct16BytesHomogeneousFloatFloatStruct1();
|
|
testPassFloatStruct32BytesHomogeneousDoubleFloatStruct();
|
|
testPassInt8Struct16BytesMixedInt8Struct16BytesMixedIn();
|
|
testPassDoublex6Struct16BytesMixedx4Int32();
|
|
testPassInt32x4Struct16BytesMixedx4Double();
|
|
testPassStruct40BytesHomogeneousDoubleStruct4BytesHomo();
|
|
testPassInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int();
|
|
testPassStructAlignmentInt16();
|
|
testPassStructAlignmentInt32();
|
|
testPassStructAlignmentInt64();
|
|
testPassStruct8BytesNestedIntx10();
|
|
testPassStruct8BytesNestedFloatx10();
|
|
testPassStruct8BytesNestedFloat2x10();
|
|
testPassStruct8BytesNestedMixedx10();
|
|
testPassStruct16BytesNestedIntx2();
|
|
testPassStruct32BytesNestedIntx2();
|
|
testPassStructNestedIntStructAlignmentInt16();
|
|
testPassStructNestedIntStructAlignmentInt32();
|
|
testPassStructNestedIntStructAlignmentInt64();
|
|
testPassStructNestedIrregularEvenBiggerx4();
|
|
testPassStruct8BytesInlineArrayIntx4();
|
|
testPassStructInlineArrayIrregularx4();
|
|
testPassStructInlineArray100Bytes();
|
|
testPassStructStruct16BytesHomogeneousFloat2x5();
|
|
testPassStructStruct32BytesHomogeneousDouble2x5();
|
|
testPassStructStruct16BytesMixed3x10();
|
|
testPassUint8Struct32BytesInlineArrayMultiDimensionalI();
|
|
testPassUint8Struct4BytesInlineArrayMultiDimensionalIn();
|
|
testPassStruct3BytesPackedIntx10();
|
|
testPassStruct8BytesPackedIntx10();
|
|
testPassStruct9BytesPackedMixedx10DoubleInt32x2();
|
|
testPassStruct5BytesPackedMixed();
|
|
testPassStructNestedAlignmentStruct5BytesPackedMixed();
|
|
testPassStruct6BytesInlineArrayInt();
|
|
testPassStruct15BytesInlineArrayMixed();
|
|
testPassUnion4BytesMixedx10();
|
|
testPassUnion8BytesNestedFloatx10();
|
|
testPassUnion9BytesNestedIntx10();
|
|
testPassUnion16BytesNestedInlineArrayFloatx10();
|
|
testPassUnion16BytesNestedFloatx10();
|
|
testPassUint8Boolx9Struct10BytesHomogeneousBoolBool();
|
|
testPassUint8Boolx9Struct10BytesInlineArrayBoolBool();
|
|
testPassUint8Struct1ByteBool();
|
|
testPassWCharStructInlineArrayIntUintPtrx2LongUnsigned();
|
|
testReturnStruct1ByteInt();
|
|
testReturnStruct3BytesHomogeneousUint8();
|
|
testReturnStruct3BytesInt2ByteAligned();
|
|
testReturnStruct4BytesHomogeneousInt16();
|
|
testReturnStruct7BytesHomogeneousUint8();
|
|
testReturnStruct7BytesInt4ByteAligned();
|
|
testReturnStruct8BytesInt();
|
|
testReturnStruct8BytesHomogeneousFloat();
|
|
testReturnStruct8BytesMixed();
|
|
testReturnStruct9BytesHomogeneousUint8();
|
|
testReturnStruct9BytesInt4Or8ByteAligned();
|
|
testReturnStruct12BytesHomogeneousFloat();
|
|
testReturnStruct16BytesHomogeneousFloat();
|
|
testReturnStruct16BytesMixed();
|
|
testReturnStruct16BytesMixed2();
|
|
testReturnStruct17BytesInt();
|
|
testReturnStruct19BytesHomogeneousUint8();
|
|
testReturnStruct20BytesHomogeneousInt32();
|
|
testReturnStruct20BytesHomogeneousFloat();
|
|
testReturnStruct32BytesHomogeneousDouble();
|
|
testReturnStruct40BytesHomogeneousDouble();
|
|
testReturnStruct1024BytesHomogeneousUint64();
|
|
testReturnStruct3BytesPackedInt();
|
|
testReturnStruct8BytesPackedInt();
|
|
testReturnStruct9BytesPackedMixed();
|
|
testReturnUnion4BytesMixed();
|
|
testReturnUnion8BytesNestedFloat();
|
|
testReturnUnion9BytesNestedInt();
|
|
testReturnUnion16BytesNestedFloat();
|
|
testReturnStructArgumentStruct1ByteInt();
|
|
testReturnStructArgumentInt32x8Struct1ByteInt();
|
|
testReturnStructArgumentStruct8BytesHomogeneousFloat();
|
|
testReturnStructArgumentStruct20BytesHomogeneousInt32();
|
|
testReturnStructArgumentInt32x8Struct20BytesHomogeneou();
|
|
testReturnStructArgumentStruct8BytesInlineArrayInt();
|
|
testReturnStructArgumentStructStruct16BytesHomogeneous();
|
|
testReturnStructArgumentStructStruct32BytesHomogeneous();
|
|
testReturnStructArgumentStructStruct16BytesMixed3();
|
|
testReturnStructAlignmentInt16();
|
|
testReturnStructAlignmentInt32();
|
|
testReturnStructAlignmentInt64();
|
|
testReturnStruct8BytesNestedInt();
|
|
testReturnStruct8BytesNestedFloat();
|
|
testReturnStruct8BytesNestedFloat2();
|
|
testReturnStruct8BytesNestedMixed();
|
|
testReturnStruct16BytesNestedInt();
|
|
testReturnStruct32BytesNestedInt();
|
|
testReturnStructNestedIntStructAlignmentInt16();
|
|
testReturnStructNestedIntStructAlignmentInt32();
|
|
testReturnStructNestedIntStructAlignmentInt64();
|
|
testReturnStructNestedIrregularEvenBigger();
|
|
}
|
|
}
|
|
|
|
final passStruct1ByteIntx10 = ffiTestFunctions.lookupFunction<
|
|
Int64 Function(
|
|
Struct1ByteInt,
|
|
Struct1ByteInt,
|
|
Struct1ByteInt,
|
|
Struct1ByteInt,
|
|
Struct1ByteInt,
|
|
Struct1ByteInt,
|
|
Struct1ByteInt,
|
|
Struct1ByteInt,
|
|
Struct1ByteInt,
|
|
Struct1ByteInt),
|
|
int Function(
|
|
Struct1ByteInt,
|
|
Struct1ByteInt,
|
|
Struct1ByteInt,
|
|
Struct1ByteInt,
|
|
Struct1ByteInt,
|
|
Struct1ByteInt,
|
|
Struct1ByteInt,
|
|
Struct1ByteInt,
|
|
Struct1ByteInt,
|
|
Struct1ByteInt)>("PassStruct1ByteIntx10");
|
|
|
|
/// Smallest struct with data.
|
|
/// 10 struct arguments will exhaust available registers.
|
|
void testPassStruct1ByteIntx10() {
|
|
final a0Pointer = calloc<Struct1ByteInt>();
|
|
final Struct1ByteInt a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<Struct1ByteInt>();
|
|
final Struct1ByteInt a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<Struct1ByteInt>();
|
|
final Struct1ByteInt a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<Struct1ByteInt>();
|
|
final Struct1ByteInt a3 = a3Pointer.ref;
|
|
final a4Pointer = calloc<Struct1ByteInt>();
|
|
final Struct1ByteInt a4 = a4Pointer.ref;
|
|
final a5Pointer = calloc<Struct1ByteInt>();
|
|
final Struct1ByteInt a5 = a5Pointer.ref;
|
|
final a6Pointer = calloc<Struct1ByteInt>();
|
|
final Struct1ByteInt a6 = a6Pointer.ref;
|
|
final a7Pointer = calloc<Struct1ByteInt>();
|
|
final Struct1ByteInt a7 = a7Pointer.ref;
|
|
final a8Pointer = calloc<Struct1ByteInt>();
|
|
final Struct1ByteInt a8 = a8Pointer.ref;
|
|
final a9Pointer = calloc<Struct1ByteInt>();
|
|
final Struct1ByteInt a9 = a9Pointer.ref;
|
|
|
|
a0.a0 = -1;
|
|
a1.a0 = 2;
|
|
a2.a0 = -3;
|
|
a3.a0 = 4;
|
|
a4.a0 = -5;
|
|
a5.a0 = 6;
|
|
a6.a0 = -7;
|
|
a7.a0 = 8;
|
|
a8.a0 = -9;
|
|
a9.a0 = 10;
|
|
|
|
final result = passStruct1ByteIntx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(5, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a4Pointer);
|
|
calloc.free(a5Pointer);
|
|
calloc.free(a6Pointer);
|
|
calloc.free(a7Pointer);
|
|
calloc.free(a8Pointer);
|
|
calloc.free(a9Pointer);
|
|
}
|
|
|
|
final passStruct3BytesHomogeneousUint8x10 = ffiTestFunctions.lookupFunction<
|
|
Int64 Function(
|
|
Struct3BytesHomogeneousUint8,
|
|
Struct3BytesHomogeneousUint8,
|
|
Struct3BytesHomogeneousUint8,
|
|
Struct3BytesHomogeneousUint8,
|
|
Struct3BytesHomogeneousUint8,
|
|
Struct3BytesHomogeneousUint8,
|
|
Struct3BytesHomogeneousUint8,
|
|
Struct3BytesHomogeneousUint8,
|
|
Struct3BytesHomogeneousUint8,
|
|
Struct3BytesHomogeneousUint8),
|
|
int Function(
|
|
Struct3BytesHomogeneousUint8,
|
|
Struct3BytesHomogeneousUint8,
|
|
Struct3BytesHomogeneousUint8,
|
|
Struct3BytesHomogeneousUint8,
|
|
Struct3BytesHomogeneousUint8,
|
|
Struct3BytesHomogeneousUint8,
|
|
Struct3BytesHomogeneousUint8,
|
|
Struct3BytesHomogeneousUint8,
|
|
Struct3BytesHomogeneousUint8,
|
|
Struct3BytesHomogeneousUint8)>("PassStruct3BytesHomogeneousUint8x10");
|
|
|
|
/// Not a multiple of word size, not a power of two.
|
|
/// 10 struct arguments will exhaust available registers.
|
|
void testPassStruct3BytesHomogeneousUint8x10() {
|
|
final a0Pointer = calloc<Struct3BytesHomogeneousUint8>();
|
|
final Struct3BytesHomogeneousUint8 a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<Struct3BytesHomogeneousUint8>();
|
|
final Struct3BytesHomogeneousUint8 a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<Struct3BytesHomogeneousUint8>();
|
|
final Struct3BytesHomogeneousUint8 a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<Struct3BytesHomogeneousUint8>();
|
|
final Struct3BytesHomogeneousUint8 a3 = a3Pointer.ref;
|
|
final a4Pointer = calloc<Struct3BytesHomogeneousUint8>();
|
|
final Struct3BytesHomogeneousUint8 a4 = a4Pointer.ref;
|
|
final a5Pointer = calloc<Struct3BytesHomogeneousUint8>();
|
|
final Struct3BytesHomogeneousUint8 a5 = a5Pointer.ref;
|
|
final a6Pointer = calloc<Struct3BytesHomogeneousUint8>();
|
|
final Struct3BytesHomogeneousUint8 a6 = a6Pointer.ref;
|
|
final a7Pointer = calloc<Struct3BytesHomogeneousUint8>();
|
|
final Struct3BytesHomogeneousUint8 a7 = a7Pointer.ref;
|
|
final a8Pointer = calloc<Struct3BytesHomogeneousUint8>();
|
|
final Struct3BytesHomogeneousUint8 a8 = a8Pointer.ref;
|
|
final a9Pointer = calloc<Struct3BytesHomogeneousUint8>();
|
|
final Struct3BytesHomogeneousUint8 a9 = a9Pointer.ref;
|
|
|
|
a0.a0 = 1;
|
|
a0.a1 = 2;
|
|
a0.a2 = 3;
|
|
a1.a0 = 4;
|
|
a1.a1 = 5;
|
|
a1.a2 = 6;
|
|
a2.a0 = 7;
|
|
a2.a1 = 8;
|
|
a2.a2 = 9;
|
|
a3.a0 = 10;
|
|
a3.a1 = 11;
|
|
a3.a2 = 12;
|
|
a4.a0 = 13;
|
|
a4.a1 = 14;
|
|
a4.a2 = 15;
|
|
a5.a0 = 16;
|
|
a5.a1 = 17;
|
|
a5.a2 = 18;
|
|
a6.a0 = 19;
|
|
a6.a1 = 20;
|
|
a6.a2 = 21;
|
|
a7.a0 = 22;
|
|
a7.a1 = 23;
|
|
a7.a2 = 24;
|
|
a8.a0 = 25;
|
|
a8.a1 = 26;
|
|
a8.a2 = 27;
|
|
a9.a0 = 28;
|
|
a9.a1 = 29;
|
|
a9.a2 = 30;
|
|
|
|
final result = passStruct3BytesHomogeneousUint8x10(
|
|
a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(465, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a4Pointer);
|
|
calloc.free(a5Pointer);
|
|
calloc.free(a6Pointer);
|
|
calloc.free(a7Pointer);
|
|
calloc.free(a8Pointer);
|
|
calloc.free(a9Pointer);
|
|
}
|
|
|
|
final passStruct3BytesInt2ByteAlignedx10 = ffiTestFunctions.lookupFunction<
|
|
Int64 Function(
|
|
Struct3BytesInt2ByteAligned,
|
|
Struct3BytesInt2ByteAligned,
|
|
Struct3BytesInt2ByteAligned,
|
|
Struct3BytesInt2ByteAligned,
|
|
Struct3BytesInt2ByteAligned,
|
|
Struct3BytesInt2ByteAligned,
|
|
Struct3BytesInt2ByteAligned,
|
|
Struct3BytesInt2ByteAligned,
|
|
Struct3BytesInt2ByteAligned,
|
|
Struct3BytesInt2ByteAligned),
|
|
int Function(
|
|
Struct3BytesInt2ByteAligned,
|
|
Struct3BytesInt2ByteAligned,
|
|
Struct3BytesInt2ByteAligned,
|
|
Struct3BytesInt2ByteAligned,
|
|
Struct3BytesInt2ByteAligned,
|
|
Struct3BytesInt2ByteAligned,
|
|
Struct3BytesInt2ByteAligned,
|
|
Struct3BytesInt2ByteAligned,
|
|
Struct3BytesInt2ByteAligned,
|
|
Struct3BytesInt2ByteAligned)>("PassStruct3BytesInt2ByteAlignedx10");
|
|
|
|
/// Not a multiple of word size, not a power of two.
|
|
/// With alignment rules taken into account size is 4 bytes.
|
|
/// 10 struct arguments will exhaust available registers.
|
|
void testPassStruct3BytesInt2ByteAlignedx10() {
|
|
final a0Pointer = calloc<Struct3BytesInt2ByteAligned>();
|
|
final Struct3BytesInt2ByteAligned a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<Struct3BytesInt2ByteAligned>();
|
|
final Struct3BytesInt2ByteAligned a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<Struct3BytesInt2ByteAligned>();
|
|
final Struct3BytesInt2ByteAligned a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<Struct3BytesInt2ByteAligned>();
|
|
final Struct3BytesInt2ByteAligned a3 = a3Pointer.ref;
|
|
final a4Pointer = calloc<Struct3BytesInt2ByteAligned>();
|
|
final Struct3BytesInt2ByteAligned a4 = a4Pointer.ref;
|
|
final a5Pointer = calloc<Struct3BytesInt2ByteAligned>();
|
|
final Struct3BytesInt2ByteAligned a5 = a5Pointer.ref;
|
|
final a6Pointer = calloc<Struct3BytesInt2ByteAligned>();
|
|
final Struct3BytesInt2ByteAligned a6 = a6Pointer.ref;
|
|
final a7Pointer = calloc<Struct3BytesInt2ByteAligned>();
|
|
final Struct3BytesInt2ByteAligned a7 = a7Pointer.ref;
|
|
final a8Pointer = calloc<Struct3BytesInt2ByteAligned>();
|
|
final Struct3BytesInt2ByteAligned a8 = a8Pointer.ref;
|
|
final a9Pointer = calloc<Struct3BytesInt2ByteAligned>();
|
|
final Struct3BytesInt2ByteAligned a9 = a9Pointer.ref;
|
|
|
|
a0.a0 = -1;
|
|
a0.a1 = 2;
|
|
a1.a0 = -3;
|
|
a1.a1 = 4;
|
|
a2.a0 = -5;
|
|
a2.a1 = 6;
|
|
a3.a0 = -7;
|
|
a3.a1 = 8;
|
|
a4.a0 = -9;
|
|
a4.a1 = 10;
|
|
a5.a0 = -11;
|
|
a5.a1 = 12;
|
|
a6.a0 = -13;
|
|
a6.a1 = 14;
|
|
a7.a0 = -15;
|
|
a7.a1 = 16;
|
|
a8.a0 = -17;
|
|
a8.a1 = 18;
|
|
a9.a0 = -19;
|
|
a9.a1 = 20;
|
|
|
|
final result = passStruct3BytesInt2ByteAlignedx10(
|
|
a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(10, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a4Pointer);
|
|
calloc.free(a5Pointer);
|
|
calloc.free(a6Pointer);
|
|
calloc.free(a7Pointer);
|
|
calloc.free(a8Pointer);
|
|
calloc.free(a9Pointer);
|
|
}
|
|
|
|
final passStruct4BytesHomogeneousInt16x10 = ffiTestFunctions.lookupFunction<
|
|
Int64 Function(
|
|
Struct4BytesHomogeneousInt16,
|
|
Struct4BytesHomogeneousInt16,
|
|
Struct4BytesHomogeneousInt16,
|
|
Struct4BytesHomogeneousInt16,
|
|
Struct4BytesHomogeneousInt16,
|
|
Struct4BytesHomogeneousInt16,
|
|
Struct4BytesHomogeneousInt16,
|
|
Struct4BytesHomogeneousInt16,
|
|
Struct4BytesHomogeneousInt16,
|
|
Struct4BytesHomogeneousInt16),
|
|
int Function(
|
|
Struct4BytesHomogeneousInt16,
|
|
Struct4BytesHomogeneousInt16,
|
|
Struct4BytesHomogeneousInt16,
|
|
Struct4BytesHomogeneousInt16,
|
|
Struct4BytesHomogeneousInt16,
|
|
Struct4BytesHomogeneousInt16,
|
|
Struct4BytesHomogeneousInt16,
|
|
Struct4BytesHomogeneousInt16,
|
|
Struct4BytesHomogeneousInt16,
|
|
Struct4BytesHomogeneousInt16)>("PassStruct4BytesHomogeneousInt16x10");
|
|
|
|
/// Exactly word size on 32-bit architectures.
|
|
/// 10 struct arguments will exhaust available registers.
|
|
void testPassStruct4BytesHomogeneousInt16x10() {
|
|
final a0Pointer = calloc<Struct4BytesHomogeneousInt16>();
|
|
final Struct4BytesHomogeneousInt16 a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<Struct4BytesHomogeneousInt16>();
|
|
final Struct4BytesHomogeneousInt16 a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<Struct4BytesHomogeneousInt16>();
|
|
final Struct4BytesHomogeneousInt16 a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<Struct4BytesHomogeneousInt16>();
|
|
final Struct4BytesHomogeneousInt16 a3 = a3Pointer.ref;
|
|
final a4Pointer = calloc<Struct4BytesHomogeneousInt16>();
|
|
final Struct4BytesHomogeneousInt16 a4 = a4Pointer.ref;
|
|
final a5Pointer = calloc<Struct4BytesHomogeneousInt16>();
|
|
final Struct4BytesHomogeneousInt16 a5 = a5Pointer.ref;
|
|
final a6Pointer = calloc<Struct4BytesHomogeneousInt16>();
|
|
final Struct4BytesHomogeneousInt16 a6 = a6Pointer.ref;
|
|
final a7Pointer = calloc<Struct4BytesHomogeneousInt16>();
|
|
final Struct4BytesHomogeneousInt16 a7 = a7Pointer.ref;
|
|
final a8Pointer = calloc<Struct4BytesHomogeneousInt16>();
|
|
final Struct4BytesHomogeneousInt16 a8 = a8Pointer.ref;
|
|
final a9Pointer = calloc<Struct4BytesHomogeneousInt16>();
|
|
final Struct4BytesHomogeneousInt16 a9 = a9Pointer.ref;
|
|
|
|
a0.a0 = -1;
|
|
a0.a1 = 2;
|
|
a1.a0 = -3;
|
|
a1.a1 = 4;
|
|
a2.a0 = -5;
|
|
a2.a1 = 6;
|
|
a3.a0 = -7;
|
|
a3.a1 = 8;
|
|
a4.a0 = -9;
|
|
a4.a1 = 10;
|
|
a5.a0 = -11;
|
|
a5.a1 = 12;
|
|
a6.a0 = -13;
|
|
a6.a1 = 14;
|
|
a7.a0 = -15;
|
|
a7.a1 = 16;
|
|
a8.a0 = -17;
|
|
a8.a1 = 18;
|
|
a9.a0 = -19;
|
|
a9.a1 = 20;
|
|
|
|
final result = passStruct4BytesHomogeneousInt16x10(
|
|
a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(10, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a4Pointer);
|
|
calloc.free(a5Pointer);
|
|
calloc.free(a6Pointer);
|
|
calloc.free(a7Pointer);
|
|
calloc.free(a8Pointer);
|
|
calloc.free(a9Pointer);
|
|
}
|
|
|
|
final passStruct7BytesHomogeneousUint8x10 = ffiTestFunctions.lookupFunction<
|
|
Int64 Function(
|
|
Struct7BytesHomogeneousUint8,
|
|
Struct7BytesHomogeneousUint8,
|
|
Struct7BytesHomogeneousUint8,
|
|
Struct7BytesHomogeneousUint8,
|
|
Struct7BytesHomogeneousUint8,
|
|
Struct7BytesHomogeneousUint8,
|
|
Struct7BytesHomogeneousUint8,
|
|
Struct7BytesHomogeneousUint8,
|
|
Struct7BytesHomogeneousUint8,
|
|
Struct7BytesHomogeneousUint8),
|
|
int Function(
|
|
Struct7BytesHomogeneousUint8,
|
|
Struct7BytesHomogeneousUint8,
|
|
Struct7BytesHomogeneousUint8,
|
|
Struct7BytesHomogeneousUint8,
|
|
Struct7BytesHomogeneousUint8,
|
|
Struct7BytesHomogeneousUint8,
|
|
Struct7BytesHomogeneousUint8,
|
|
Struct7BytesHomogeneousUint8,
|
|
Struct7BytesHomogeneousUint8,
|
|
Struct7BytesHomogeneousUint8)>("PassStruct7BytesHomogeneousUint8x10");
|
|
|
|
/// Sub word size on 64 bit architectures.
|
|
/// 10 struct arguments will exhaust available registers.
|
|
void testPassStruct7BytesHomogeneousUint8x10() {
|
|
final a0Pointer = calloc<Struct7BytesHomogeneousUint8>();
|
|
final Struct7BytesHomogeneousUint8 a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<Struct7BytesHomogeneousUint8>();
|
|
final Struct7BytesHomogeneousUint8 a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<Struct7BytesHomogeneousUint8>();
|
|
final Struct7BytesHomogeneousUint8 a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<Struct7BytesHomogeneousUint8>();
|
|
final Struct7BytesHomogeneousUint8 a3 = a3Pointer.ref;
|
|
final a4Pointer = calloc<Struct7BytesHomogeneousUint8>();
|
|
final Struct7BytesHomogeneousUint8 a4 = a4Pointer.ref;
|
|
final a5Pointer = calloc<Struct7BytesHomogeneousUint8>();
|
|
final Struct7BytesHomogeneousUint8 a5 = a5Pointer.ref;
|
|
final a6Pointer = calloc<Struct7BytesHomogeneousUint8>();
|
|
final Struct7BytesHomogeneousUint8 a6 = a6Pointer.ref;
|
|
final a7Pointer = calloc<Struct7BytesHomogeneousUint8>();
|
|
final Struct7BytesHomogeneousUint8 a7 = a7Pointer.ref;
|
|
final a8Pointer = calloc<Struct7BytesHomogeneousUint8>();
|
|
final Struct7BytesHomogeneousUint8 a8 = a8Pointer.ref;
|
|
final a9Pointer = calloc<Struct7BytesHomogeneousUint8>();
|
|
final Struct7BytesHomogeneousUint8 a9 = a9Pointer.ref;
|
|
|
|
a0.a0 = 1;
|
|
a0.a1 = 2;
|
|
a0.a2 = 3;
|
|
a0.a3 = 4;
|
|
a0.a4 = 5;
|
|
a0.a5 = 6;
|
|
a0.a6 = 7;
|
|
a1.a0 = 8;
|
|
a1.a1 = 9;
|
|
a1.a2 = 10;
|
|
a1.a3 = 11;
|
|
a1.a4 = 12;
|
|
a1.a5 = 13;
|
|
a1.a6 = 14;
|
|
a2.a0 = 15;
|
|
a2.a1 = 16;
|
|
a2.a2 = 17;
|
|
a2.a3 = 18;
|
|
a2.a4 = 19;
|
|
a2.a5 = 20;
|
|
a2.a6 = 21;
|
|
a3.a0 = 22;
|
|
a3.a1 = 23;
|
|
a3.a2 = 24;
|
|
a3.a3 = 25;
|
|
a3.a4 = 26;
|
|
a3.a5 = 27;
|
|
a3.a6 = 28;
|
|
a4.a0 = 29;
|
|
a4.a1 = 30;
|
|
a4.a2 = 31;
|
|
a4.a3 = 32;
|
|
a4.a4 = 33;
|
|
a4.a5 = 34;
|
|
a4.a6 = 35;
|
|
a5.a0 = 36;
|
|
a5.a1 = 37;
|
|
a5.a2 = 38;
|
|
a5.a3 = 39;
|
|
a5.a4 = 40;
|
|
a5.a5 = 41;
|
|
a5.a6 = 42;
|
|
a6.a0 = 43;
|
|
a6.a1 = 44;
|
|
a6.a2 = 45;
|
|
a6.a3 = 46;
|
|
a6.a4 = 47;
|
|
a6.a5 = 48;
|
|
a6.a6 = 49;
|
|
a7.a0 = 50;
|
|
a7.a1 = 51;
|
|
a7.a2 = 52;
|
|
a7.a3 = 53;
|
|
a7.a4 = 54;
|
|
a7.a5 = 55;
|
|
a7.a6 = 56;
|
|
a8.a0 = 57;
|
|
a8.a1 = 58;
|
|
a8.a2 = 59;
|
|
a8.a3 = 60;
|
|
a8.a4 = 61;
|
|
a8.a5 = 62;
|
|
a8.a6 = 63;
|
|
a9.a0 = 64;
|
|
a9.a1 = 65;
|
|
a9.a2 = 66;
|
|
a9.a3 = 67;
|
|
a9.a4 = 68;
|
|
a9.a5 = 69;
|
|
a9.a6 = 70;
|
|
|
|
final result = passStruct7BytesHomogeneousUint8x10(
|
|
a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(2485, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a4Pointer);
|
|
calloc.free(a5Pointer);
|
|
calloc.free(a6Pointer);
|
|
calloc.free(a7Pointer);
|
|
calloc.free(a8Pointer);
|
|
calloc.free(a9Pointer);
|
|
}
|
|
|
|
final passStruct7BytesInt4ByteAlignedx10 = ffiTestFunctions.lookupFunction<
|
|
Int64 Function(
|
|
Struct7BytesInt4ByteAligned,
|
|
Struct7BytesInt4ByteAligned,
|
|
Struct7BytesInt4ByteAligned,
|
|
Struct7BytesInt4ByteAligned,
|
|
Struct7BytesInt4ByteAligned,
|
|
Struct7BytesInt4ByteAligned,
|
|
Struct7BytesInt4ByteAligned,
|
|
Struct7BytesInt4ByteAligned,
|
|
Struct7BytesInt4ByteAligned,
|
|
Struct7BytesInt4ByteAligned),
|
|
int Function(
|
|
Struct7BytesInt4ByteAligned,
|
|
Struct7BytesInt4ByteAligned,
|
|
Struct7BytesInt4ByteAligned,
|
|
Struct7BytesInt4ByteAligned,
|
|
Struct7BytesInt4ByteAligned,
|
|
Struct7BytesInt4ByteAligned,
|
|
Struct7BytesInt4ByteAligned,
|
|
Struct7BytesInt4ByteAligned,
|
|
Struct7BytesInt4ByteAligned,
|
|
Struct7BytesInt4ByteAligned)>("PassStruct7BytesInt4ByteAlignedx10");
|
|
|
|
/// Sub word size on 64 bit architectures.
|
|
/// With alignment rules taken into account size is 8 bytes.
|
|
/// 10 struct arguments will exhaust available registers.
|
|
void testPassStruct7BytesInt4ByteAlignedx10() {
|
|
final a0Pointer = calloc<Struct7BytesInt4ByteAligned>();
|
|
final Struct7BytesInt4ByteAligned a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<Struct7BytesInt4ByteAligned>();
|
|
final Struct7BytesInt4ByteAligned a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<Struct7BytesInt4ByteAligned>();
|
|
final Struct7BytesInt4ByteAligned a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<Struct7BytesInt4ByteAligned>();
|
|
final Struct7BytesInt4ByteAligned a3 = a3Pointer.ref;
|
|
final a4Pointer = calloc<Struct7BytesInt4ByteAligned>();
|
|
final Struct7BytesInt4ByteAligned a4 = a4Pointer.ref;
|
|
final a5Pointer = calloc<Struct7BytesInt4ByteAligned>();
|
|
final Struct7BytesInt4ByteAligned a5 = a5Pointer.ref;
|
|
final a6Pointer = calloc<Struct7BytesInt4ByteAligned>();
|
|
final Struct7BytesInt4ByteAligned a6 = a6Pointer.ref;
|
|
final a7Pointer = calloc<Struct7BytesInt4ByteAligned>();
|
|
final Struct7BytesInt4ByteAligned a7 = a7Pointer.ref;
|
|
final a8Pointer = calloc<Struct7BytesInt4ByteAligned>();
|
|
final Struct7BytesInt4ByteAligned a8 = a8Pointer.ref;
|
|
final a9Pointer = calloc<Struct7BytesInt4ByteAligned>();
|
|
final Struct7BytesInt4ByteAligned a9 = a9Pointer.ref;
|
|
|
|
a0.a0 = -1;
|
|
a0.a1 = 2;
|
|
a0.a2 = -3;
|
|
a1.a0 = 4;
|
|
a1.a1 = -5;
|
|
a1.a2 = 6;
|
|
a2.a0 = -7;
|
|
a2.a1 = 8;
|
|
a2.a2 = -9;
|
|
a3.a0 = 10;
|
|
a3.a1 = -11;
|
|
a3.a2 = 12;
|
|
a4.a0 = -13;
|
|
a4.a1 = 14;
|
|
a4.a2 = -15;
|
|
a5.a0 = 16;
|
|
a5.a1 = -17;
|
|
a5.a2 = 18;
|
|
a6.a0 = -19;
|
|
a6.a1 = 20;
|
|
a6.a2 = -21;
|
|
a7.a0 = 22;
|
|
a7.a1 = -23;
|
|
a7.a2 = 24;
|
|
a8.a0 = -25;
|
|
a8.a1 = 26;
|
|
a8.a2 = -27;
|
|
a9.a0 = 28;
|
|
a9.a1 = -29;
|
|
a9.a2 = 30;
|
|
|
|
final result = passStruct7BytesInt4ByteAlignedx10(
|
|
a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(15, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a4Pointer);
|
|
calloc.free(a5Pointer);
|
|
calloc.free(a6Pointer);
|
|
calloc.free(a7Pointer);
|
|
calloc.free(a8Pointer);
|
|
calloc.free(a9Pointer);
|
|
}
|
|
|
|
final passStruct8BytesIntx10 = ffiTestFunctions.lookupFunction<
|
|
Int64 Function(
|
|
Struct8BytesInt,
|
|
Struct8BytesInt,
|
|
Struct8BytesInt,
|
|
Struct8BytesInt,
|
|
Struct8BytesInt,
|
|
Struct8BytesInt,
|
|
Struct8BytesInt,
|
|
Struct8BytesInt,
|
|
Struct8BytesInt,
|
|
Struct8BytesInt),
|
|
int Function(
|
|
Struct8BytesInt,
|
|
Struct8BytesInt,
|
|
Struct8BytesInt,
|
|
Struct8BytesInt,
|
|
Struct8BytesInt,
|
|
Struct8BytesInt,
|
|
Struct8BytesInt,
|
|
Struct8BytesInt,
|
|
Struct8BytesInt,
|
|
Struct8BytesInt)>("PassStruct8BytesIntx10");
|
|
|
|
/// Exactly word size struct on 64bit architectures.
|
|
/// 10 struct arguments will exhaust available registers.
|
|
void testPassStruct8BytesIntx10() {
|
|
final a0Pointer = calloc<Struct8BytesInt>();
|
|
final Struct8BytesInt a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<Struct8BytesInt>();
|
|
final Struct8BytesInt a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<Struct8BytesInt>();
|
|
final Struct8BytesInt a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<Struct8BytesInt>();
|
|
final Struct8BytesInt a3 = a3Pointer.ref;
|
|
final a4Pointer = calloc<Struct8BytesInt>();
|
|
final Struct8BytesInt a4 = a4Pointer.ref;
|
|
final a5Pointer = calloc<Struct8BytesInt>();
|
|
final Struct8BytesInt a5 = a5Pointer.ref;
|
|
final a6Pointer = calloc<Struct8BytesInt>();
|
|
final Struct8BytesInt a6 = a6Pointer.ref;
|
|
final a7Pointer = calloc<Struct8BytesInt>();
|
|
final Struct8BytesInt a7 = a7Pointer.ref;
|
|
final a8Pointer = calloc<Struct8BytesInt>();
|
|
final Struct8BytesInt a8 = a8Pointer.ref;
|
|
final a9Pointer = calloc<Struct8BytesInt>();
|
|
final Struct8BytesInt a9 = a9Pointer.ref;
|
|
|
|
a0.a0 = -1;
|
|
a0.a1 = 2;
|
|
a0.a2 = -3;
|
|
a1.a0 = 4;
|
|
a1.a1 = -5;
|
|
a1.a2 = 6;
|
|
a2.a0 = -7;
|
|
a2.a1 = 8;
|
|
a2.a2 = -9;
|
|
a3.a0 = 10;
|
|
a3.a1 = -11;
|
|
a3.a2 = 12;
|
|
a4.a0 = -13;
|
|
a4.a1 = 14;
|
|
a4.a2 = -15;
|
|
a5.a0 = 16;
|
|
a5.a1 = -17;
|
|
a5.a2 = 18;
|
|
a6.a0 = -19;
|
|
a6.a1 = 20;
|
|
a6.a2 = -21;
|
|
a7.a0 = 22;
|
|
a7.a1 = -23;
|
|
a7.a2 = 24;
|
|
a8.a0 = -25;
|
|
a8.a1 = 26;
|
|
a8.a2 = -27;
|
|
a9.a0 = 28;
|
|
a9.a1 = -29;
|
|
a9.a2 = 30;
|
|
|
|
final result = passStruct8BytesIntx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(15, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a4Pointer);
|
|
calloc.free(a5Pointer);
|
|
calloc.free(a6Pointer);
|
|
calloc.free(a7Pointer);
|
|
calloc.free(a8Pointer);
|
|
calloc.free(a9Pointer);
|
|
}
|
|
|
|
final passStruct8BytesHomogeneousFloatx10 = ffiTestFunctions.lookupFunction<
|
|
Float Function(
|
|
Struct8BytesHomogeneousFloat,
|
|
Struct8BytesHomogeneousFloat,
|
|
Struct8BytesHomogeneousFloat,
|
|
Struct8BytesHomogeneousFloat,
|
|
Struct8BytesHomogeneousFloat,
|
|
Struct8BytesHomogeneousFloat,
|
|
Struct8BytesHomogeneousFloat,
|
|
Struct8BytesHomogeneousFloat,
|
|
Struct8BytesHomogeneousFloat,
|
|
Struct8BytesHomogeneousFloat),
|
|
double Function(
|
|
Struct8BytesHomogeneousFloat,
|
|
Struct8BytesHomogeneousFloat,
|
|
Struct8BytesHomogeneousFloat,
|
|
Struct8BytesHomogeneousFloat,
|
|
Struct8BytesHomogeneousFloat,
|
|
Struct8BytesHomogeneousFloat,
|
|
Struct8BytesHomogeneousFloat,
|
|
Struct8BytesHomogeneousFloat,
|
|
Struct8BytesHomogeneousFloat,
|
|
Struct8BytesHomogeneousFloat)>("PassStruct8BytesHomogeneousFloatx10");
|
|
|
|
/// Arguments passed in FP registers as long as they fit.
|
|
/// 10 struct arguments will exhaust available registers.
|
|
void testPassStruct8BytesHomogeneousFloatx10() {
|
|
final a0Pointer = calloc<Struct8BytesHomogeneousFloat>();
|
|
final Struct8BytesHomogeneousFloat a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<Struct8BytesHomogeneousFloat>();
|
|
final Struct8BytesHomogeneousFloat a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<Struct8BytesHomogeneousFloat>();
|
|
final Struct8BytesHomogeneousFloat a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<Struct8BytesHomogeneousFloat>();
|
|
final Struct8BytesHomogeneousFloat a3 = a3Pointer.ref;
|
|
final a4Pointer = calloc<Struct8BytesHomogeneousFloat>();
|
|
final Struct8BytesHomogeneousFloat a4 = a4Pointer.ref;
|
|
final a5Pointer = calloc<Struct8BytesHomogeneousFloat>();
|
|
final Struct8BytesHomogeneousFloat a5 = a5Pointer.ref;
|
|
final a6Pointer = calloc<Struct8BytesHomogeneousFloat>();
|
|
final Struct8BytesHomogeneousFloat a6 = a6Pointer.ref;
|
|
final a7Pointer = calloc<Struct8BytesHomogeneousFloat>();
|
|
final Struct8BytesHomogeneousFloat a7 = a7Pointer.ref;
|
|
final a8Pointer = calloc<Struct8BytesHomogeneousFloat>();
|
|
final Struct8BytesHomogeneousFloat a8 = a8Pointer.ref;
|
|
final a9Pointer = calloc<Struct8BytesHomogeneousFloat>();
|
|
final Struct8BytesHomogeneousFloat a9 = a9Pointer.ref;
|
|
|
|
a0.a0 = -1.0;
|
|
a0.a1 = 2.0;
|
|
a1.a0 = -3.0;
|
|
a1.a1 = 4.0;
|
|
a2.a0 = -5.0;
|
|
a2.a1 = 6.0;
|
|
a3.a0 = -7.0;
|
|
a3.a1 = 8.0;
|
|
a4.a0 = -9.0;
|
|
a4.a1 = 10.0;
|
|
a5.a0 = -11.0;
|
|
a5.a1 = 12.0;
|
|
a6.a0 = -13.0;
|
|
a6.a1 = 14.0;
|
|
a7.a0 = -15.0;
|
|
a7.a1 = 16.0;
|
|
a8.a0 = -17.0;
|
|
a8.a1 = 18.0;
|
|
a9.a0 = -19.0;
|
|
a9.a1 = 20.0;
|
|
|
|
final result = passStruct8BytesHomogeneousFloatx10(
|
|
a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(10.0, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a4Pointer);
|
|
calloc.free(a5Pointer);
|
|
calloc.free(a6Pointer);
|
|
calloc.free(a7Pointer);
|
|
calloc.free(a8Pointer);
|
|
calloc.free(a9Pointer);
|
|
}
|
|
|
|
final passStruct8BytesMixedx10 = ffiTestFunctions.lookupFunction<
|
|
Float Function(
|
|
Struct8BytesMixed,
|
|
Struct8BytesMixed,
|
|
Struct8BytesMixed,
|
|
Struct8BytesMixed,
|
|
Struct8BytesMixed,
|
|
Struct8BytesMixed,
|
|
Struct8BytesMixed,
|
|
Struct8BytesMixed,
|
|
Struct8BytesMixed,
|
|
Struct8BytesMixed),
|
|
double Function(
|
|
Struct8BytesMixed,
|
|
Struct8BytesMixed,
|
|
Struct8BytesMixed,
|
|
Struct8BytesMixed,
|
|
Struct8BytesMixed,
|
|
Struct8BytesMixed,
|
|
Struct8BytesMixed,
|
|
Struct8BytesMixed,
|
|
Struct8BytesMixed,
|
|
Struct8BytesMixed)>("PassStruct8BytesMixedx10");
|
|
|
|
/// On x64, arguments go in int registers because it is not only float.
|
|
/// 10 struct arguments will exhaust available registers.
|
|
void testPassStruct8BytesMixedx10() {
|
|
final a0Pointer = calloc<Struct8BytesMixed>();
|
|
final Struct8BytesMixed a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<Struct8BytesMixed>();
|
|
final Struct8BytesMixed a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<Struct8BytesMixed>();
|
|
final Struct8BytesMixed a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<Struct8BytesMixed>();
|
|
final Struct8BytesMixed a3 = a3Pointer.ref;
|
|
final a4Pointer = calloc<Struct8BytesMixed>();
|
|
final Struct8BytesMixed a4 = a4Pointer.ref;
|
|
final a5Pointer = calloc<Struct8BytesMixed>();
|
|
final Struct8BytesMixed a5 = a5Pointer.ref;
|
|
final a6Pointer = calloc<Struct8BytesMixed>();
|
|
final Struct8BytesMixed a6 = a6Pointer.ref;
|
|
final a7Pointer = calloc<Struct8BytesMixed>();
|
|
final Struct8BytesMixed a7 = a7Pointer.ref;
|
|
final a8Pointer = calloc<Struct8BytesMixed>();
|
|
final Struct8BytesMixed a8 = a8Pointer.ref;
|
|
final a9Pointer = calloc<Struct8BytesMixed>();
|
|
final Struct8BytesMixed a9 = a9Pointer.ref;
|
|
|
|
a0.a0 = -1.0;
|
|
a0.a1 = 2;
|
|
a0.a2 = -3;
|
|
a1.a0 = 4.0;
|
|
a1.a1 = -5;
|
|
a1.a2 = 6;
|
|
a2.a0 = -7.0;
|
|
a2.a1 = 8;
|
|
a2.a2 = -9;
|
|
a3.a0 = 10.0;
|
|
a3.a1 = -11;
|
|
a3.a2 = 12;
|
|
a4.a0 = -13.0;
|
|
a4.a1 = 14;
|
|
a4.a2 = -15;
|
|
a5.a0 = 16.0;
|
|
a5.a1 = -17;
|
|
a5.a2 = 18;
|
|
a6.a0 = -19.0;
|
|
a6.a1 = 20;
|
|
a6.a2 = -21;
|
|
a7.a0 = 22.0;
|
|
a7.a1 = -23;
|
|
a7.a2 = 24;
|
|
a8.a0 = -25.0;
|
|
a8.a1 = 26;
|
|
a8.a2 = -27;
|
|
a9.a0 = 28.0;
|
|
a9.a1 = -29;
|
|
a9.a2 = 30;
|
|
|
|
final result =
|
|
passStruct8BytesMixedx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(15.0, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a4Pointer);
|
|
calloc.free(a5Pointer);
|
|
calloc.free(a6Pointer);
|
|
calloc.free(a7Pointer);
|
|
calloc.free(a8Pointer);
|
|
calloc.free(a9Pointer);
|
|
}
|
|
|
|
final passStruct9BytesHomogeneousUint8x10 = ffiTestFunctions.lookupFunction<
|
|
Int64 Function(
|
|
Struct9BytesHomogeneousUint8,
|
|
Struct9BytesHomogeneousUint8,
|
|
Struct9BytesHomogeneousUint8,
|
|
Struct9BytesHomogeneousUint8,
|
|
Struct9BytesHomogeneousUint8,
|
|
Struct9BytesHomogeneousUint8,
|
|
Struct9BytesHomogeneousUint8,
|
|
Struct9BytesHomogeneousUint8,
|
|
Struct9BytesHomogeneousUint8,
|
|
Struct9BytesHomogeneousUint8),
|
|
int Function(
|
|
Struct9BytesHomogeneousUint8,
|
|
Struct9BytesHomogeneousUint8,
|
|
Struct9BytesHomogeneousUint8,
|
|
Struct9BytesHomogeneousUint8,
|
|
Struct9BytesHomogeneousUint8,
|
|
Struct9BytesHomogeneousUint8,
|
|
Struct9BytesHomogeneousUint8,
|
|
Struct9BytesHomogeneousUint8,
|
|
Struct9BytesHomogeneousUint8,
|
|
Struct9BytesHomogeneousUint8)>("PassStruct9BytesHomogeneousUint8x10");
|
|
|
|
/// Argument is a single byte over a multiple of word size.
|
|
/// 10 struct arguments will exhaust available registers.
|
|
/// Struct only has 1-byte aligned fields to test struct alignment itself.
|
|
/// Tests upper bytes in the integer registers that are partly filled.
|
|
/// Tests stack alignment of non word size stack arguments.
|
|
void testPassStruct9BytesHomogeneousUint8x10() {
|
|
final a0Pointer = calloc<Struct9BytesHomogeneousUint8>();
|
|
final Struct9BytesHomogeneousUint8 a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<Struct9BytesHomogeneousUint8>();
|
|
final Struct9BytesHomogeneousUint8 a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<Struct9BytesHomogeneousUint8>();
|
|
final Struct9BytesHomogeneousUint8 a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<Struct9BytesHomogeneousUint8>();
|
|
final Struct9BytesHomogeneousUint8 a3 = a3Pointer.ref;
|
|
final a4Pointer = calloc<Struct9BytesHomogeneousUint8>();
|
|
final Struct9BytesHomogeneousUint8 a4 = a4Pointer.ref;
|
|
final a5Pointer = calloc<Struct9BytesHomogeneousUint8>();
|
|
final Struct9BytesHomogeneousUint8 a5 = a5Pointer.ref;
|
|
final a6Pointer = calloc<Struct9BytesHomogeneousUint8>();
|
|
final Struct9BytesHomogeneousUint8 a6 = a6Pointer.ref;
|
|
final a7Pointer = calloc<Struct9BytesHomogeneousUint8>();
|
|
final Struct9BytesHomogeneousUint8 a7 = a7Pointer.ref;
|
|
final a8Pointer = calloc<Struct9BytesHomogeneousUint8>();
|
|
final Struct9BytesHomogeneousUint8 a8 = a8Pointer.ref;
|
|
final a9Pointer = calloc<Struct9BytesHomogeneousUint8>();
|
|
final Struct9BytesHomogeneousUint8 a9 = a9Pointer.ref;
|
|
|
|
a0.a0 = 1;
|
|
a0.a1 = 2;
|
|
a0.a2 = 3;
|
|
a0.a3 = 4;
|
|
a0.a4 = 5;
|
|
a0.a5 = 6;
|
|
a0.a6 = 7;
|
|
a0.a7 = 8;
|
|
a0.a8 = 9;
|
|
a1.a0 = 10;
|
|
a1.a1 = 11;
|
|
a1.a2 = 12;
|
|
a1.a3 = 13;
|
|
a1.a4 = 14;
|
|
a1.a5 = 15;
|
|
a1.a6 = 16;
|
|
a1.a7 = 17;
|
|
a1.a8 = 18;
|
|
a2.a0 = 19;
|
|
a2.a1 = 20;
|
|
a2.a2 = 21;
|
|
a2.a3 = 22;
|
|
a2.a4 = 23;
|
|
a2.a5 = 24;
|
|
a2.a6 = 25;
|
|
a2.a7 = 26;
|
|
a2.a8 = 27;
|
|
a3.a0 = 28;
|
|
a3.a1 = 29;
|
|
a3.a2 = 30;
|
|
a3.a3 = 31;
|
|
a3.a4 = 32;
|
|
a3.a5 = 33;
|
|
a3.a6 = 34;
|
|
a3.a7 = 35;
|
|
a3.a8 = 36;
|
|
a4.a0 = 37;
|
|
a4.a1 = 38;
|
|
a4.a2 = 39;
|
|
a4.a3 = 40;
|
|
a4.a4 = 41;
|
|
a4.a5 = 42;
|
|
a4.a6 = 43;
|
|
a4.a7 = 44;
|
|
a4.a8 = 45;
|
|
a5.a0 = 46;
|
|
a5.a1 = 47;
|
|
a5.a2 = 48;
|
|
a5.a3 = 49;
|
|
a5.a4 = 50;
|
|
a5.a5 = 51;
|
|
a5.a6 = 52;
|
|
a5.a7 = 53;
|
|
a5.a8 = 54;
|
|
a6.a0 = 55;
|
|
a6.a1 = 56;
|
|
a6.a2 = 57;
|
|
a6.a3 = 58;
|
|
a6.a4 = 59;
|
|
a6.a5 = 60;
|
|
a6.a6 = 61;
|
|
a6.a7 = 62;
|
|
a6.a8 = 63;
|
|
a7.a0 = 64;
|
|
a7.a1 = 65;
|
|
a7.a2 = 66;
|
|
a7.a3 = 67;
|
|
a7.a4 = 68;
|
|
a7.a5 = 69;
|
|
a7.a6 = 70;
|
|
a7.a7 = 71;
|
|
a7.a8 = 72;
|
|
a8.a0 = 73;
|
|
a8.a1 = 74;
|
|
a8.a2 = 75;
|
|
a8.a3 = 76;
|
|
a8.a4 = 77;
|
|
a8.a5 = 78;
|
|
a8.a6 = 79;
|
|
a8.a7 = 80;
|
|
a8.a8 = 81;
|
|
a9.a0 = 82;
|
|
a9.a1 = 83;
|
|
a9.a2 = 84;
|
|
a9.a3 = 85;
|
|
a9.a4 = 86;
|
|
a9.a5 = 87;
|
|
a9.a6 = 88;
|
|
a9.a7 = 89;
|
|
a9.a8 = 90;
|
|
|
|
final result = passStruct9BytesHomogeneousUint8x10(
|
|
a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(4095, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a4Pointer);
|
|
calloc.free(a5Pointer);
|
|
calloc.free(a6Pointer);
|
|
calloc.free(a7Pointer);
|
|
calloc.free(a8Pointer);
|
|
calloc.free(a9Pointer);
|
|
}
|
|
|
|
final passStruct9BytesInt4Or8ByteAlignedx10 = ffiTestFunctions.lookupFunction<
|
|
Int64 Function(
|
|
Struct9BytesInt4Or8ByteAligned,
|
|
Struct9BytesInt4Or8ByteAligned,
|
|
Struct9BytesInt4Or8ByteAligned,
|
|
Struct9BytesInt4Or8ByteAligned,
|
|
Struct9BytesInt4Or8ByteAligned,
|
|
Struct9BytesInt4Or8ByteAligned,
|
|
Struct9BytesInt4Or8ByteAligned,
|
|
Struct9BytesInt4Or8ByteAligned,
|
|
Struct9BytesInt4Or8ByteAligned,
|
|
Struct9BytesInt4Or8ByteAligned),
|
|
int Function(
|
|
Struct9BytesInt4Or8ByteAligned,
|
|
Struct9BytesInt4Or8ByteAligned,
|
|
Struct9BytesInt4Or8ByteAligned,
|
|
Struct9BytesInt4Or8ByteAligned,
|
|
Struct9BytesInt4Or8ByteAligned,
|
|
Struct9BytesInt4Or8ByteAligned,
|
|
Struct9BytesInt4Or8ByteAligned,
|
|
Struct9BytesInt4Or8ByteAligned,
|
|
Struct9BytesInt4Or8ByteAligned,
|
|
Struct9BytesInt4Or8ByteAligned)>(
|
|
"PassStruct9BytesInt4Or8ByteAlignedx10");
|
|
|
|
/// Argument is a single byte over a multiple of word size.
|
|
/// With alignment rules taken into account size is 12 or 16 bytes.
|
|
/// 10 struct arguments will exhaust available registers.
|
|
///
|
|
void testPassStruct9BytesInt4Or8ByteAlignedx10() {
|
|
final a0Pointer = calloc<Struct9BytesInt4Or8ByteAligned>();
|
|
final Struct9BytesInt4Or8ByteAligned a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<Struct9BytesInt4Or8ByteAligned>();
|
|
final Struct9BytesInt4Or8ByteAligned a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<Struct9BytesInt4Or8ByteAligned>();
|
|
final Struct9BytesInt4Or8ByteAligned a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<Struct9BytesInt4Or8ByteAligned>();
|
|
final Struct9BytesInt4Or8ByteAligned a3 = a3Pointer.ref;
|
|
final a4Pointer = calloc<Struct9BytesInt4Or8ByteAligned>();
|
|
final Struct9BytesInt4Or8ByteAligned a4 = a4Pointer.ref;
|
|
final a5Pointer = calloc<Struct9BytesInt4Or8ByteAligned>();
|
|
final Struct9BytesInt4Or8ByteAligned a5 = a5Pointer.ref;
|
|
final a6Pointer = calloc<Struct9BytesInt4Or8ByteAligned>();
|
|
final Struct9BytesInt4Or8ByteAligned a6 = a6Pointer.ref;
|
|
final a7Pointer = calloc<Struct9BytesInt4Or8ByteAligned>();
|
|
final Struct9BytesInt4Or8ByteAligned a7 = a7Pointer.ref;
|
|
final a8Pointer = calloc<Struct9BytesInt4Or8ByteAligned>();
|
|
final Struct9BytesInt4Or8ByteAligned a8 = a8Pointer.ref;
|
|
final a9Pointer = calloc<Struct9BytesInt4Or8ByteAligned>();
|
|
final Struct9BytesInt4Or8ByteAligned a9 = a9Pointer.ref;
|
|
|
|
a0.a0 = -1;
|
|
a0.a1 = 2;
|
|
a1.a0 = -3;
|
|
a1.a1 = 4;
|
|
a2.a0 = -5;
|
|
a2.a1 = 6;
|
|
a3.a0 = -7;
|
|
a3.a1 = 8;
|
|
a4.a0 = -9;
|
|
a4.a1 = 10;
|
|
a5.a0 = -11;
|
|
a5.a1 = 12;
|
|
a6.a0 = -13;
|
|
a6.a1 = 14;
|
|
a7.a0 = -15;
|
|
a7.a1 = 16;
|
|
a8.a0 = -17;
|
|
a8.a1 = 18;
|
|
a9.a0 = -19;
|
|
a9.a1 = 20;
|
|
|
|
final result = passStruct9BytesInt4Or8ByteAlignedx10(
|
|
a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(10, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a4Pointer);
|
|
calloc.free(a5Pointer);
|
|
calloc.free(a6Pointer);
|
|
calloc.free(a7Pointer);
|
|
calloc.free(a8Pointer);
|
|
calloc.free(a9Pointer);
|
|
}
|
|
|
|
final passStruct12BytesHomogeneousFloatx6 = ffiTestFunctions.lookupFunction<
|
|
Float Function(
|
|
Struct12BytesHomogeneousFloat,
|
|
Struct12BytesHomogeneousFloat,
|
|
Struct12BytesHomogeneousFloat,
|
|
Struct12BytesHomogeneousFloat,
|
|
Struct12BytesHomogeneousFloat,
|
|
Struct12BytesHomogeneousFloat),
|
|
double Function(
|
|
Struct12BytesHomogeneousFloat,
|
|
Struct12BytesHomogeneousFloat,
|
|
Struct12BytesHomogeneousFloat,
|
|
Struct12BytesHomogeneousFloat,
|
|
Struct12BytesHomogeneousFloat,
|
|
Struct12BytesHomogeneousFloat)>("PassStruct12BytesHomogeneousFloatx6");
|
|
|
|
/// Arguments in FPU registers on arm hardfp and arm64.
|
|
/// Struct arguments will exhaust available registers, and leave some empty.
|
|
/// The last argument is to test whether arguments are backfilled.
|
|
void testPassStruct12BytesHomogeneousFloatx6() {
|
|
final a0Pointer = calloc<Struct12BytesHomogeneousFloat>();
|
|
final Struct12BytesHomogeneousFloat a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<Struct12BytesHomogeneousFloat>();
|
|
final Struct12BytesHomogeneousFloat a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<Struct12BytesHomogeneousFloat>();
|
|
final Struct12BytesHomogeneousFloat a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<Struct12BytesHomogeneousFloat>();
|
|
final Struct12BytesHomogeneousFloat a3 = a3Pointer.ref;
|
|
final a4Pointer = calloc<Struct12BytesHomogeneousFloat>();
|
|
final Struct12BytesHomogeneousFloat a4 = a4Pointer.ref;
|
|
final a5Pointer = calloc<Struct12BytesHomogeneousFloat>();
|
|
final Struct12BytesHomogeneousFloat a5 = a5Pointer.ref;
|
|
|
|
a0.a0 = -1.0;
|
|
a0.a1 = 2.0;
|
|
a0.a2 = -3.0;
|
|
a1.a0 = 4.0;
|
|
a1.a1 = -5.0;
|
|
a1.a2 = 6.0;
|
|
a2.a0 = -7.0;
|
|
a2.a1 = 8.0;
|
|
a2.a2 = -9.0;
|
|
a3.a0 = 10.0;
|
|
a3.a1 = -11.0;
|
|
a3.a2 = 12.0;
|
|
a4.a0 = -13.0;
|
|
a4.a1 = 14.0;
|
|
a4.a2 = -15.0;
|
|
a5.a0 = 16.0;
|
|
a5.a1 = -17.0;
|
|
a5.a2 = 18.0;
|
|
|
|
final result = passStruct12BytesHomogeneousFloatx6(a0, a1, a2, a3, a4, a5);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(9.0, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a4Pointer);
|
|
calloc.free(a5Pointer);
|
|
}
|
|
|
|
final passStruct16BytesHomogeneousFloatx5 = ffiTestFunctions.lookupFunction<
|
|
Float Function(
|
|
Struct16BytesHomogeneousFloat,
|
|
Struct16BytesHomogeneousFloat,
|
|
Struct16BytesHomogeneousFloat,
|
|
Struct16BytesHomogeneousFloat,
|
|
Struct16BytesHomogeneousFloat),
|
|
double Function(
|
|
Struct16BytesHomogeneousFloat,
|
|
Struct16BytesHomogeneousFloat,
|
|
Struct16BytesHomogeneousFloat,
|
|
Struct16BytesHomogeneousFloat,
|
|
Struct16BytesHomogeneousFloat)>("PassStruct16BytesHomogeneousFloatx5");
|
|
|
|
/// On Linux x64 argument is transferred on stack because it is over 16 bytes.
|
|
/// Arguments in FPU registers on arm hardfp and arm64.
|
|
/// 5 struct arguments will exhaust available registers.
|
|
void testPassStruct16BytesHomogeneousFloatx5() {
|
|
final a0Pointer = calloc<Struct16BytesHomogeneousFloat>();
|
|
final Struct16BytesHomogeneousFloat a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<Struct16BytesHomogeneousFloat>();
|
|
final Struct16BytesHomogeneousFloat a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<Struct16BytesHomogeneousFloat>();
|
|
final Struct16BytesHomogeneousFloat a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<Struct16BytesHomogeneousFloat>();
|
|
final Struct16BytesHomogeneousFloat a3 = a3Pointer.ref;
|
|
final a4Pointer = calloc<Struct16BytesHomogeneousFloat>();
|
|
final Struct16BytesHomogeneousFloat a4 = a4Pointer.ref;
|
|
|
|
a0.a0 = -1.0;
|
|
a0.a1 = 2.0;
|
|
a0.a2 = -3.0;
|
|
a0.a3 = 4.0;
|
|
a1.a0 = -5.0;
|
|
a1.a1 = 6.0;
|
|
a1.a2 = -7.0;
|
|
a1.a3 = 8.0;
|
|
a2.a0 = -9.0;
|
|
a2.a1 = 10.0;
|
|
a2.a2 = -11.0;
|
|
a2.a3 = 12.0;
|
|
a3.a0 = -13.0;
|
|
a3.a1 = 14.0;
|
|
a3.a2 = -15.0;
|
|
a3.a3 = 16.0;
|
|
a4.a0 = -17.0;
|
|
a4.a1 = 18.0;
|
|
a4.a2 = -19.0;
|
|
a4.a3 = 20.0;
|
|
|
|
final result = passStruct16BytesHomogeneousFloatx5(a0, a1, a2, a3, a4);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(10.0, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a4Pointer);
|
|
}
|
|
|
|
final passStruct16BytesMixedx10 = ffiTestFunctions.lookupFunction<
|
|
Double Function(
|
|
Struct16BytesMixed,
|
|
Struct16BytesMixed,
|
|
Struct16BytesMixed,
|
|
Struct16BytesMixed,
|
|
Struct16BytesMixed,
|
|
Struct16BytesMixed,
|
|
Struct16BytesMixed,
|
|
Struct16BytesMixed,
|
|
Struct16BytesMixed,
|
|
Struct16BytesMixed),
|
|
double Function(
|
|
Struct16BytesMixed,
|
|
Struct16BytesMixed,
|
|
Struct16BytesMixed,
|
|
Struct16BytesMixed,
|
|
Struct16BytesMixed,
|
|
Struct16BytesMixed,
|
|
Struct16BytesMixed,
|
|
Struct16BytesMixed,
|
|
Struct16BytesMixed,
|
|
Struct16BytesMixed)>("PassStruct16BytesMixedx10");
|
|
|
|
/// On x64, arguments are split over FP and int registers.
|
|
/// On x64, it will exhaust the integer registers with the 6th argument.
|
|
/// The rest goes on the stack.
|
|
/// On arm, arguments are 8 byte aligned.
|
|
void testPassStruct16BytesMixedx10() {
|
|
final a0Pointer = calloc<Struct16BytesMixed>();
|
|
final Struct16BytesMixed a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<Struct16BytesMixed>();
|
|
final Struct16BytesMixed a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<Struct16BytesMixed>();
|
|
final Struct16BytesMixed a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<Struct16BytesMixed>();
|
|
final Struct16BytesMixed a3 = a3Pointer.ref;
|
|
final a4Pointer = calloc<Struct16BytesMixed>();
|
|
final Struct16BytesMixed a4 = a4Pointer.ref;
|
|
final a5Pointer = calloc<Struct16BytesMixed>();
|
|
final Struct16BytesMixed a5 = a5Pointer.ref;
|
|
final a6Pointer = calloc<Struct16BytesMixed>();
|
|
final Struct16BytesMixed a6 = a6Pointer.ref;
|
|
final a7Pointer = calloc<Struct16BytesMixed>();
|
|
final Struct16BytesMixed a7 = a7Pointer.ref;
|
|
final a8Pointer = calloc<Struct16BytesMixed>();
|
|
final Struct16BytesMixed a8 = a8Pointer.ref;
|
|
final a9Pointer = calloc<Struct16BytesMixed>();
|
|
final Struct16BytesMixed a9 = a9Pointer.ref;
|
|
|
|
a0.a0 = -1.0;
|
|
a0.a1 = 2;
|
|
a1.a0 = -3.0;
|
|
a1.a1 = 4;
|
|
a2.a0 = -5.0;
|
|
a2.a1 = 6;
|
|
a3.a0 = -7.0;
|
|
a3.a1 = 8;
|
|
a4.a0 = -9.0;
|
|
a4.a1 = 10;
|
|
a5.a0 = -11.0;
|
|
a5.a1 = 12;
|
|
a6.a0 = -13.0;
|
|
a6.a1 = 14;
|
|
a7.a0 = -15.0;
|
|
a7.a1 = 16;
|
|
a8.a0 = -17.0;
|
|
a8.a1 = 18;
|
|
a9.a0 = -19.0;
|
|
a9.a1 = 20;
|
|
|
|
final result =
|
|
passStruct16BytesMixedx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(10.0, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a4Pointer);
|
|
calloc.free(a5Pointer);
|
|
calloc.free(a6Pointer);
|
|
calloc.free(a7Pointer);
|
|
calloc.free(a8Pointer);
|
|
calloc.free(a9Pointer);
|
|
}
|
|
|
|
final passStruct16BytesMixed2x10 = ffiTestFunctions.lookupFunction<
|
|
Float Function(
|
|
Struct16BytesMixed2,
|
|
Struct16BytesMixed2,
|
|
Struct16BytesMixed2,
|
|
Struct16BytesMixed2,
|
|
Struct16BytesMixed2,
|
|
Struct16BytesMixed2,
|
|
Struct16BytesMixed2,
|
|
Struct16BytesMixed2,
|
|
Struct16BytesMixed2,
|
|
Struct16BytesMixed2),
|
|
double Function(
|
|
Struct16BytesMixed2,
|
|
Struct16BytesMixed2,
|
|
Struct16BytesMixed2,
|
|
Struct16BytesMixed2,
|
|
Struct16BytesMixed2,
|
|
Struct16BytesMixed2,
|
|
Struct16BytesMixed2,
|
|
Struct16BytesMixed2,
|
|
Struct16BytesMixed2,
|
|
Struct16BytesMixed2)>("PassStruct16BytesMixed2x10");
|
|
|
|
/// On x64, arguments are split over FP and int registers.
|
|
/// On x64, it will exhaust the integer registers with the 6th argument.
|
|
/// The rest goes on the stack.
|
|
/// On arm, arguments are 4 byte aligned.
|
|
void testPassStruct16BytesMixed2x10() {
|
|
final a0Pointer = calloc<Struct16BytesMixed2>();
|
|
final Struct16BytesMixed2 a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<Struct16BytesMixed2>();
|
|
final Struct16BytesMixed2 a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<Struct16BytesMixed2>();
|
|
final Struct16BytesMixed2 a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<Struct16BytesMixed2>();
|
|
final Struct16BytesMixed2 a3 = a3Pointer.ref;
|
|
final a4Pointer = calloc<Struct16BytesMixed2>();
|
|
final Struct16BytesMixed2 a4 = a4Pointer.ref;
|
|
final a5Pointer = calloc<Struct16BytesMixed2>();
|
|
final Struct16BytesMixed2 a5 = a5Pointer.ref;
|
|
final a6Pointer = calloc<Struct16BytesMixed2>();
|
|
final Struct16BytesMixed2 a6 = a6Pointer.ref;
|
|
final a7Pointer = calloc<Struct16BytesMixed2>();
|
|
final Struct16BytesMixed2 a7 = a7Pointer.ref;
|
|
final a8Pointer = calloc<Struct16BytesMixed2>();
|
|
final Struct16BytesMixed2 a8 = a8Pointer.ref;
|
|
final a9Pointer = calloc<Struct16BytesMixed2>();
|
|
final Struct16BytesMixed2 a9 = a9Pointer.ref;
|
|
|
|
a0.a0 = -1.0;
|
|
a0.a1 = 2.0;
|
|
a0.a2 = -3.0;
|
|
a0.a3 = 4;
|
|
a1.a0 = -5.0;
|
|
a1.a1 = 6.0;
|
|
a1.a2 = -7.0;
|
|
a1.a3 = 8;
|
|
a2.a0 = -9.0;
|
|
a2.a1 = 10.0;
|
|
a2.a2 = -11.0;
|
|
a2.a3 = 12;
|
|
a3.a0 = -13.0;
|
|
a3.a1 = 14.0;
|
|
a3.a2 = -15.0;
|
|
a3.a3 = 16;
|
|
a4.a0 = -17.0;
|
|
a4.a1 = 18.0;
|
|
a4.a2 = -19.0;
|
|
a4.a3 = 20;
|
|
a5.a0 = -21.0;
|
|
a5.a1 = 22.0;
|
|
a5.a2 = -23.0;
|
|
a5.a3 = 24;
|
|
a6.a0 = -25.0;
|
|
a6.a1 = 26.0;
|
|
a6.a2 = -27.0;
|
|
a6.a3 = 28;
|
|
a7.a0 = -29.0;
|
|
a7.a1 = 30.0;
|
|
a7.a2 = -31.0;
|
|
a7.a3 = 32;
|
|
a8.a0 = -33.0;
|
|
a8.a1 = 34.0;
|
|
a8.a2 = -35.0;
|
|
a8.a3 = 36;
|
|
a9.a0 = -37.0;
|
|
a9.a1 = 38.0;
|
|
a9.a2 = -39.0;
|
|
a9.a3 = 40;
|
|
|
|
final result =
|
|
passStruct16BytesMixed2x10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(20.0, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a4Pointer);
|
|
calloc.free(a5Pointer);
|
|
calloc.free(a6Pointer);
|
|
calloc.free(a7Pointer);
|
|
calloc.free(a8Pointer);
|
|
calloc.free(a9Pointer);
|
|
}
|
|
|
|
final passStruct17BytesIntx10 = ffiTestFunctions.lookupFunction<
|
|
Int64 Function(
|
|
Struct17BytesInt,
|
|
Struct17BytesInt,
|
|
Struct17BytesInt,
|
|
Struct17BytesInt,
|
|
Struct17BytesInt,
|
|
Struct17BytesInt,
|
|
Struct17BytesInt,
|
|
Struct17BytesInt,
|
|
Struct17BytesInt,
|
|
Struct17BytesInt),
|
|
int Function(
|
|
Struct17BytesInt,
|
|
Struct17BytesInt,
|
|
Struct17BytesInt,
|
|
Struct17BytesInt,
|
|
Struct17BytesInt,
|
|
Struct17BytesInt,
|
|
Struct17BytesInt,
|
|
Struct17BytesInt,
|
|
Struct17BytesInt,
|
|
Struct17BytesInt)>("PassStruct17BytesIntx10");
|
|
|
|
/// Arguments are passed as pointer to copy on arm64.
|
|
/// Tests that the memory allocated for copies are rounded up to word size.
|
|
void testPassStruct17BytesIntx10() {
|
|
final a0Pointer = calloc<Struct17BytesInt>();
|
|
final Struct17BytesInt a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<Struct17BytesInt>();
|
|
final Struct17BytesInt a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<Struct17BytesInt>();
|
|
final Struct17BytesInt a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<Struct17BytesInt>();
|
|
final Struct17BytesInt a3 = a3Pointer.ref;
|
|
final a4Pointer = calloc<Struct17BytesInt>();
|
|
final Struct17BytesInt a4 = a4Pointer.ref;
|
|
final a5Pointer = calloc<Struct17BytesInt>();
|
|
final Struct17BytesInt a5 = a5Pointer.ref;
|
|
final a6Pointer = calloc<Struct17BytesInt>();
|
|
final Struct17BytesInt a6 = a6Pointer.ref;
|
|
final a7Pointer = calloc<Struct17BytesInt>();
|
|
final Struct17BytesInt a7 = a7Pointer.ref;
|
|
final a8Pointer = calloc<Struct17BytesInt>();
|
|
final Struct17BytesInt a8 = a8Pointer.ref;
|
|
final a9Pointer = calloc<Struct17BytesInt>();
|
|
final Struct17BytesInt a9 = a9Pointer.ref;
|
|
|
|
a0.a0 = -1;
|
|
a0.a1 = 2;
|
|
a0.a2 = -3;
|
|
a1.a0 = 4;
|
|
a1.a1 = -5;
|
|
a1.a2 = 6;
|
|
a2.a0 = -7;
|
|
a2.a1 = 8;
|
|
a2.a2 = -9;
|
|
a3.a0 = 10;
|
|
a3.a1 = -11;
|
|
a3.a2 = 12;
|
|
a4.a0 = -13;
|
|
a4.a1 = 14;
|
|
a4.a2 = -15;
|
|
a5.a0 = 16;
|
|
a5.a1 = -17;
|
|
a5.a2 = 18;
|
|
a6.a0 = -19;
|
|
a6.a1 = 20;
|
|
a6.a2 = -21;
|
|
a7.a0 = 22;
|
|
a7.a1 = -23;
|
|
a7.a2 = 24;
|
|
a8.a0 = -25;
|
|
a8.a1 = 26;
|
|
a8.a2 = -27;
|
|
a9.a0 = 28;
|
|
a9.a1 = -29;
|
|
a9.a2 = 30;
|
|
|
|
final result =
|
|
passStruct17BytesIntx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(15, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a4Pointer);
|
|
calloc.free(a5Pointer);
|
|
calloc.free(a6Pointer);
|
|
calloc.free(a7Pointer);
|
|
calloc.free(a8Pointer);
|
|
calloc.free(a9Pointer);
|
|
}
|
|
|
|
final passStruct19BytesHomogeneousUint8x10 = ffiTestFunctions.lookupFunction<
|
|
Int64 Function(
|
|
Struct19BytesHomogeneousUint8,
|
|
Struct19BytesHomogeneousUint8,
|
|
Struct19BytesHomogeneousUint8,
|
|
Struct19BytesHomogeneousUint8,
|
|
Struct19BytesHomogeneousUint8,
|
|
Struct19BytesHomogeneousUint8,
|
|
Struct19BytesHomogeneousUint8,
|
|
Struct19BytesHomogeneousUint8,
|
|
Struct19BytesHomogeneousUint8,
|
|
Struct19BytesHomogeneousUint8),
|
|
int Function(
|
|
Struct19BytesHomogeneousUint8,
|
|
Struct19BytesHomogeneousUint8,
|
|
Struct19BytesHomogeneousUint8,
|
|
Struct19BytesHomogeneousUint8,
|
|
Struct19BytesHomogeneousUint8,
|
|
Struct19BytesHomogeneousUint8,
|
|
Struct19BytesHomogeneousUint8,
|
|
Struct19BytesHomogeneousUint8,
|
|
Struct19BytesHomogeneousUint8,
|
|
Struct19BytesHomogeneousUint8)>("PassStruct19BytesHomogeneousUint8x10");
|
|
|
|
/// The minimum alignment of this struct is only 1 byte based on its fields.
|
|
/// Test that the memory backing these structs is extended to the right size.
|
|
///
|
|
void testPassStruct19BytesHomogeneousUint8x10() {
|
|
final a0Pointer = calloc<Struct19BytesHomogeneousUint8>();
|
|
final Struct19BytesHomogeneousUint8 a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<Struct19BytesHomogeneousUint8>();
|
|
final Struct19BytesHomogeneousUint8 a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<Struct19BytesHomogeneousUint8>();
|
|
final Struct19BytesHomogeneousUint8 a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<Struct19BytesHomogeneousUint8>();
|
|
final Struct19BytesHomogeneousUint8 a3 = a3Pointer.ref;
|
|
final a4Pointer = calloc<Struct19BytesHomogeneousUint8>();
|
|
final Struct19BytesHomogeneousUint8 a4 = a4Pointer.ref;
|
|
final a5Pointer = calloc<Struct19BytesHomogeneousUint8>();
|
|
final Struct19BytesHomogeneousUint8 a5 = a5Pointer.ref;
|
|
final a6Pointer = calloc<Struct19BytesHomogeneousUint8>();
|
|
final Struct19BytesHomogeneousUint8 a6 = a6Pointer.ref;
|
|
final a7Pointer = calloc<Struct19BytesHomogeneousUint8>();
|
|
final Struct19BytesHomogeneousUint8 a7 = a7Pointer.ref;
|
|
final a8Pointer = calloc<Struct19BytesHomogeneousUint8>();
|
|
final Struct19BytesHomogeneousUint8 a8 = a8Pointer.ref;
|
|
final a9Pointer = calloc<Struct19BytesHomogeneousUint8>();
|
|
final Struct19BytesHomogeneousUint8 a9 = a9Pointer.ref;
|
|
|
|
a0.a0 = 1;
|
|
a0.a1 = 2;
|
|
a0.a2 = 3;
|
|
a0.a3 = 4;
|
|
a0.a4 = 5;
|
|
a0.a5 = 6;
|
|
a0.a6 = 7;
|
|
a0.a7 = 8;
|
|
a0.a8 = 9;
|
|
a0.a9 = 10;
|
|
a0.a10 = 11;
|
|
a0.a11 = 12;
|
|
a0.a12 = 13;
|
|
a0.a13 = 14;
|
|
a0.a14 = 15;
|
|
a0.a15 = 16;
|
|
a0.a16 = 17;
|
|
a0.a17 = 18;
|
|
a0.a18 = 19;
|
|
a1.a0 = 20;
|
|
a1.a1 = 21;
|
|
a1.a2 = 22;
|
|
a1.a3 = 23;
|
|
a1.a4 = 24;
|
|
a1.a5 = 25;
|
|
a1.a6 = 26;
|
|
a1.a7 = 27;
|
|
a1.a8 = 28;
|
|
a1.a9 = 29;
|
|
a1.a10 = 30;
|
|
a1.a11 = 31;
|
|
a1.a12 = 32;
|
|
a1.a13 = 33;
|
|
a1.a14 = 34;
|
|
a1.a15 = 35;
|
|
a1.a16 = 36;
|
|
a1.a17 = 37;
|
|
a1.a18 = 38;
|
|
a2.a0 = 39;
|
|
a2.a1 = 40;
|
|
a2.a2 = 41;
|
|
a2.a3 = 42;
|
|
a2.a4 = 43;
|
|
a2.a5 = 44;
|
|
a2.a6 = 45;
|
|
a2.a7 = 46;
|
|
a2.a8 = 47;
|
|
a2.a9 = 48;
|
|
a2.a10 = 49;
|
|
a2.a11 = 50;
|
|
a2.a12 = 51;
|
|
a2.a13 = 52;
|
|
a2.a14 = 53;
|
|
a2.a15 = 54;
|
|
a2.a16 = 55;
|
|
a2.a17 = 56;
|
|
a2.a18 = 57;
|
|
a3.a0 = 58;
|
|
a3.a1 = 59;
|
|
a3.a2 = 60;
|
|
a3.a3 = 61;
|
|
a3.a4 = 62;
|
|
a3.a5 = 63;
|
|
a3.a6 = 64;
|
|
a3.a7 = 65;
|
|
a3.a8 = 66;
|
|
a3.a9 = 67;
|
|
a3.a10 = 68;
|
|
a3.a11 = 69;
|
|
a3.a12 = 70;
|
|
a3.a13 = 71;
|
|
a3.a14 = 72;
|
|
a3.a15 = 73;
|
|
a3.a16 = 74;
|
|
a3.a17 = 75;
|
|
a3.a18 = 76;
|
|
a4.a0 = 77;
|
|
a4.a1 = 78;
|
|
a4.a2 = 79;
|
|
a4.a3 = 80;
|
|
a4.a4 = 81;
|
|
a4.a5 = 82;
|
|
a4.a6 = 83;
|
|
a4.a7 = 84;
|
|
a4.a8 = 85;
|
|
a4.a9 = 86;
|
|
a4.a10 = 87;
|
|
a4.a11 = 88;
|
|
a4.a12 = 89;
|
|
a4.a13 = 90;
|
|
a4.a14 = 91;
|
|
a4.a15 = 92;
|
|
a4.a16 = 93;
|
|
a4.a17 = 94;
|
|
a4.a18 = 95;
|
|
a5.a0 = 96;
|
|
a5.a1 = 97;
|
|
a5.a2 = 98;
|
|
a5.a3 = 99;
|
|
a5.a4 = 100;
|
|
a5.a5 = 101;
|
|
a5.a6 = 102;
|
|
a5.a7 = 103;
|
|
a5.a8 = 104;
|
|
a5.a9 = 105;
|
|
a5.a10 = 106;
|
|
a5.a11 = 107;
|
|
a5.a12 = 108;
|
|
a5.a13 = 109;
|
|
a5.a14 = 110;
|
|
a5.a15 = 111;
|
|
a5.a16 = 112;
|
|
a5.a17 = 113;
|
|
a5.a18 = 114;
|
|
a6.a0 = 115;
|
|
a6.a1 = 116;
|
|
a6.a2 = 117;
|
|
a6.a3 = 118;
|
|
a6.a4 = 119;
|
|
a6.a5 = 120;
|
|
a6.a6 = 121;
|
|
a6.a7 = 122;
|
|
a6.a8 = 123;
|
|
a6.a9 = 124;
|
|
a6.a10 = 125;
|
|
a6.a11 = 126;
|
|
a6.a12 = 127;
|
|
a6.a13 = 128;
|
|
a6.a14 = 129;
|
|
a6.a15 = 130;
|
|
a6.a16 = 131;
|
|
a6.a17 = 132;
|
|
a6.a18 = 133;
|
|
a7.a0 = 134;
|
|
a7.a1 = 135;
|
|
a7.a2 = 136;
|
|
a7.a3 = 137;
|
|
a7.a4 = 138;
|
|
a7.a5 = 139;
|
|
a7.a6 = 140;
|
|
a7.a7 = 141;
|
|
a7.a8 = 142;
|
|
a7.a9 = 143;
|
|
a7.a10 = 144;
|
|
a7.a11 = 145;
|
|
a7.a12 = 146;
|
|
a7.a13 = 147;
|
|
a7.a14 = 148;
|
|
a7.a15 = 149;
|
|
a7.a16 = 150;
|
|
a7.a17 = 151;
|
|
a7.a18 = 152;
|
|
a8.a0 = 153;
|
|
a8.a1 = 154;
|
|
a8.a2 = 155;
|
|
a8.a3 = 156;
|
|
a8.a4 = 157;
|
|
a8.a5 = 158;
|
|
a8.a6 = 159;
|
|
a8.a7 = 160;
|
|
a8.a8 = 161;
|
|
a8.a9 = 162;
|
|
a8.a10 = 163;
|
|
a8.a11 = 164;
|
|
a8.a12 = 165;
|
|
a8.a13 = 166;
|
|
a8.a14 = 167;
|
|
a8.a15 = 168;
|
|
a8.a16 = 169;
|
|
a8.a17 = 170;
|
|
a8.a18 = 171;
|
|
a9.a0 = 172;
|
|
a9.a1 = 173;
|
|
a9.a2 = 174;
|
|
a9.a3 = 175;
|
|
a9.a4 = 176;
|
|
a9.a5 = 177;
|
|
a9.a6 = 178;
|
|
a9.a7 = 179;
|
|
a9.a8 = 180;
|
|
a9.a9 = 181;
|
|
a9.a10 = 182;
|
|
a9.a11 = 183;
|
|
a9.a12 = 184;
|
|
a9.a13 = 185;
|
|
a9.a14 = 186;
|
|
a9.a15 = 187;
|
|
a9.a16 = 188;
|
|
a9.a17 = 189;
|
|
a9.a18 = 190;
|
|
|
|
final result = passStruct19BytesHomogeneousUint8x10(
|
|
a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(18145, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a4Pointer);
|
|
calloc.free(a5Pointer);
|
|
calloc.free(a6Pointer);
|
|
calloc.free(a7Pointer);
|
|
calloc.free(a8Pointer);
|
|
calloc.free(a9Pointer);
|
|
}
|
|
|
|
final passStruct20BytesHomogeneousInt32x10 = ffiTestFunctions.lookupFunction<
|
|
Int32 Function(
|
|
Struct20BytesHomogeneousInt32,
|
|
Struct20BytesHomogeneousInt32,
|
|
Struct20BytesHomogeneousInt32,
|
|
Struct20BytesHomogeneousInt32,
|
|
Struct20BytesHomogeneousInt32,
|
|
Struct20BytesHomogeneousInt32,
|
|
Struct20BytesHomogeneousInt32,
|
|
Struct20BytesHomogeneousInt32,
|
|
Struct20BytesHomogeneousInt32,
|
|
Struct20BytesHomogeneousInt32),
|
|
int Function(
|
|
Struct20BytesHomogeneousInt32,
|
|
Struct20BytesHomogeneousInt32,
|
|
Struct20BytesHomogeneousInt32,
|
|
Struct20BytesHomogeneousInt32,
|
|
Struct20BytesHomogeneousInt32,
|
|
Struct20BytesHomogeneousInt32,
|
|
Struct20BytesHomogeneousInt32,
|
|
Struct20BytesHomogeneousInt32,
|
|
Struct20BytesHomogeneousInt32,
|
|
Struct20BytesHomogeneousInt32)>("PassStruct20BytesHomogeneousInt32x10");
|
|
|
|
/// Argument too big to go into integer registers on arm64.
|
|
/// The arguments are passed as pointers to copies.
|
|
/// The amount of arguments exhausts the number of integer registers, such that
|
|
/// pointers to copies are also passed on the stack.
|
|
void testPassStruct20BytesHomogeneousInt32x10() {
|
|
final a0Pointer = calloc<Struct20BytesHomogeneousInt32>();
|
|
final Struct20BytesHomogeneousInt32 a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<Struct20BytesHomogeneousInt32>();
|
|
final Struct20BytesHomogeneousInt32 a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<Struct20BytesHomogeneousInt32>();
|
|
final Struct20BytesHomogeneousInt32 a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<Struct20BytesHomogeneousInt32>();
|
|
final Struct20BytesHomogeneousInt32 a3 = a3Pointer.ref;
|
|
final a4Pointer = calloc<Struct20BytesHomogeneousInt32>();
|
|
final Struct20BytesHomogeneousInt32 a4 = a4Pointer.ref;
|
|
final a5Pointer = calloc<Struct20BytesHomogeneousInt32>();
|
|
final Struct20BytesHomogeneousInt32 a5 = a5Pointer.ref;
|
|
final a6Pointer = calloc<Struct20BytesHomogeneousInt32>();
|
|
final Struct20BytesHomogeneousInt32 a6 = a6Pointer.ref;
|
|
final a7Pointer = calloc<Struct20BytesHomogeneousInt32>();
|
|
final Struct20BytesHomogeneousInt32 a7 = a7Pointer.ref;
|
|
final a8Pointer = calloc<Struct20BytesHomogeneousInt32>();
|
|
final Struct20BytesHomogeneousInt32 a8 = a8Pointer.ref;
|
|
final a9Pointer = calloc<Struct20BytesHomogeneousInt32>();
|
|
final Struct20BytesHomogeneousInt32 a9 = a9Pointer.ref;
|
|
|
|
a0.a0 = -1;
|
|
a0.a1 = 2;
|
|
a0.a2 = -3;
|
|
a0.a3 = 4;
|
|
a0.a4 = -5;
|
|
a1.a0 = 6;
|
|
a1.a1 = -7;
|
|
a1.a2 = 8;
|
|
a1.a3 = -9;
|
|
a1.a4 = 10;
|
|
a2.a0 = -11;
|
|
a2.a1 = 12;
|
|
a2.a2 = -13;
|
|
a2.a3 = 14;
|
|
a2.a4 = -15;
|
|
a3.a0 = 16;
|
|
a3.a1 = -17;
|
|
a3.a2 = 18;
|
|
a3.a3 = -19;
|
|
a3.a4 = 20;
|
|
a4.a0 = -21;
|
|
a4.a1 = 22;
|
|
a4.a2 = -23;
|
|
a4.a3 = 24;
|
|
a4.a4 = -25;
|
|
a5.a0 = 26;
|
|
a5.a1 = -27;
|
|
a5.a2 = 28;
|
|
a5.a3 = -29;
|
|
a5.a4 = 30;
|
|
a6.a0 = -31;
|
|
a6.a1 = 32;
|
|
a6.a2 = -33;
|
|
a6.a3 = 34;
|
|
a6.a4 = -35;
|
|
a7.a0 = 36;
|
|
a7.a1 = -37;
|
|
a7.a2 = 38;
|
|
a7.a3 = -39;
|
|
a7.a4 = 40;
|
|
a8.a0 = -41;
|
|
a8.a1 = 42;
|
|
a8.a2 = -43;
|
|
a8.a3 = 44;
|
|
a8.a4 = -45;
|
|
a9.a0 = 46;
|
|
a9.a1 = -47;
|
|
a9.a2 = 48;
|
|
a9.a3 = -49;
|
|
a9.a4 = 50;
|
|
|
|
final result = passStruct20BytesHomogeneousInt32x10(
|
|
a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(25, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a4Pointer);
|
|
calloc.free(a5Pointer);
|
|
calloc.free(a6Pointer);
|
|
calloc.free(a7Pointer);
|
|
calloc.free(a8Pointer);
|
|
calloc.free(a9Pointer);
|
|
}
|
|
|
|
final passStruct20BytesHomogeneousFloat = ffiTestFunctions.lookupFunction<
|
|
Float Function(Struct20BytesHomogeneousFloat),
|
|
double Function(
|
|
Struct20BytesHomogeneousFloat)>("PassStruct20BytesHomogeneousFloat");
|
|
|
|
/// Argument too big to go into FPU registers in hardfp and arm64.
|
|
void testPassStruct20BytesHomogeneousFloat() {
|
|
final a0Pointer = calloc<Struct20BytesHomogeneousFloat>();
|
|
final Struct20BytesHomogeneousFloat a0 = a0Pointer.ref;
|
|
|
|
a0.a0 = -1.0;
|
|
a0.a1 = 2.0;
|
|
a0.a2 = -3.0;
|
|
a0.a3 = 4.0;
|
|
a0.a4 = -5.0;
|
|
|
|
final result = passStruct20BytesHomogeneousFloat(a0);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(-3.0, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
}
|
|
|
|
final passStruct32BytesHomogeneousDoublex5 = ffiTestFunctions.lookupFunction<
|
|
Double Function(
|
|
Struct32BytesHomogeneousDouble,
|
|
Struct32BytesHomogeneousDouble,
|
|
Struct32BytesHomogeneousDouble,
|
|
Struct32BytesHomogeneousDouble,
|
|
Struct32BytesHomogeneousDouble),
|
|
double Function(
|
|
Struct32BytesHomogeneousDouble,
|
|
Struct32BytesHomogeneousDouble,
|
|
Struct32BytesHomogeneousDouble,
|
|
Struct32BytesHomogeneousDouble,
|
|
Struct32BytesHomogeneousDouble)>(
|
|
"PassStruct32BytesHomogeneousDoublex5");
|
|
|
|
/// Arguments in FPU registers on arm64.
|
|
/// 5 struct arguments will exhaust available registers.
|
|
void testPassStruct32BytesHomogeneousDoublex5() {
|
|
final a0Pointer = calloc<Struct32BytesHomogeneousDouble>();
|
|
final Struct32BytesHomogeneousDouble a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<Struct32BytesHomogeneousDouble>();
|
|
final Struct32BytesHomogeneousDouble a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<Struct32BytesHomogeneousDouble>();
|
|
final Struct32BytesHomogeneousDouble a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<Struct32BytesHomogeneousDouble>();
|
|
final Struct32BytesHomogeneousDouble a3 = a3Pointer.ref;
|
|
final a4Pointer = calloc<Struct32BytesHomogeneousDouble>();
|
|
final Struct32BytesHomogeneousDouble a4 = a4Pointer.ref;
|
|
|
|
a0.a0 = -1.0;
|
|
a0.a1 = 2.0;
|
|
a0.a2 = -3.0;
|
|
a0.a3 = 4.0;
|
|
a1.a0 = -5.0;
|
|
a1.a1 = 6.0;
|
|
a1.a2 = -7.0;
|
|
a1.a3 = 8.0;
|
|
a2.a0 = -9.0;
|
|
a2.a1 = 10.0;
|
|
a2.a2 = -11.0;
|
|
a2.a3 = 12.0;
|
|
a3.a0 = -13.0;
|
|
a3.a1 = 14.0;
|
|
a3.a2 = -15.0;
|
|
a3.a3 = 16.0;
|
|
a4.a0 = -17.0;
|
|
a4.a1 = 18.0;
|
|
a4.a2 = -19.0;
|
|
a4.a3 = 20.0;
|
|
|
|
final result = passStruct32BytesHomogeneousDoublex5(a0, a1, a2, a3, a4);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(10.0, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a4Pointer);
|
|
}
|
|
|
|
final passStruct40BytesHomogeneousDouble = ffiTestFunctions.lookupFunction<
|
|
Double Function(Struct40BytesHomogeneousDouble),
|
|
double Function(
|
|
Struct40BytesHomogeneousDouble)>("PassStruct40BytesHomogeneousDouble");
|
|
|
|
/// Argument too big to go into FPU registers in arm64.
|
|
void testPassStruct40BytesHomogeneousDouble() {
|
|
final a0Pointer = calloc<Struct40BytesHomogeneousDouble>();
|
|
final Struct40BytesHomogeneousDouble a0 = a0Pointer.ref;
|
|
|
|
a0.a0 = -1.0;
|
|
a0.a1 = 2.0;
|
|
a0.a2 = -3.0;
|
|
a0.a3 = 4.0;
|
|
a0.a4 = -5.0;
|
|
|
|
final result = passStruct40BytesHomogeneousDouble(a0);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(-3.0, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
}
|
|
|
|
final passStruct1024BytesHomogeneousUint64 = ffiTestFunctions.lookupFunction<
|
|
Uint64 Function(Struct1024BytesHomogeneousUint64),
|
|
int Function(Struct1024BytesHomogeneousUint64)>(
|
|
"PassStruct1024BytesHomogeneousUint64");
|
|
|
|
/// Test 1kb struct.
|
|
void testPassStruct1024BytesHomogeneousUint64() {
|
|
final a0Pointer = calloc<Struct1024BytesHomogeneousUint64>();
|
|
final Struct1024BytesHomogeneousUint64 a0 = a0Pointer.ref;
|
|
|
|
a0.a0 = 1;
|
|
a0.a1 = 2;
|
|
a0.a2 = 3;
|
|
a0.a3 = 4;
|
|
a0.a4 = 5;
|
|
a0.a5 = 6;
|
|
a0.a6 = 7;
|
|
a0.a7 = 8;
|
|
a0.a8 = 9;
|
|
a0.a9 = 10;
|
|
a0.a10 = 11;
|
|
a0.a11 = 12;
|
|
a0.a12 = 13;
|
|
a0.a13 = 14;
|
|
a0.a14 = 15;
|
|
a0.a15 = 16;
|
|
a0.a16 = 17;
|
|
a0.a17 = 18;
|
|
a0.a18 = 19;
|
|
a0.a19 = 20;
|
|
a0.a20 = 21;
|
|
a0.a21 = 22;
|
|
a0.a22 = 23;
|
|
a0.a23 = 24;
|
|
a0.a24 = 25;
|
|
a0.a25 = 26;
|
|
a0.a26 = 27;
|
|
a0.a27 = 28;
|
|
a0.a28 = 29;
|
|
a0.a29 = 30;
|
|
a0.a30 = 31;
|
|
a0.a31 = 32;
|
|
a0.a32 = 33;
|
|
a0.a33 = 34;
|
|
a0.a34 = 35;
|
|
a0.a35 = 36;
|
|
a0.a36 = 37;
|
|
a0.a37 = 38;
|
|
a0.a38 = 39;
|
|
a0.a39 = 40;
|
|
a0.a40 = 41;
|
|
a0.a41 = 42;
|
|
a0.a42 = 43;
|
|
a0.a43 = 44;
|
|
a0.a44 = 45;
|
|
a0.a45 = 46;
|
|
a0.a46 = 47;
|
|
a0.a47 = 48;
|
|
a0.a48 = 49;
|
|
a0.a49 = 50;
|
|
a0.a50 = 51;
|
|
a0.a51 = 52;
|
|
a0.a52 = 53;
|
|
a0.a53 = 54;
|
|
a0.a54 = 55;
|
|
a0.a55 = 56;
|
|
a0.a56 = 57;
|
|
a0.a57 = 58;
|
|
a0.a58 = 59;
|
|
a0.a59 = 60;
|
|
a0.a60 = 61;
|
|
a0.a61 = 62;
|
|
a0.a62 = 63;
|
|
a0.a63 = 64;
|
|
a0.a64 = 65;
|
|
a0.a65 = 66;
|
|
a0.a66 = 67;
|
|
a0.a67 = 68;
|
|
a0.a68 = 69;
|
|
a0.a69 = 70;
|
|
a0.a70 = 71;
|
|
a0.a71 = 72;
|
|
a0.a72 = 73;
|
|
a0.a73 = 74;
|
|
a0.a74 = 75;
|
|
a0.a75 = 76;
|
|
a0.a76 = 77;
|
|
a0.a77 = 78;
|
|
a0.a78 = 79;
|
|
a0.a79 = 80;
|
|
a0.a80 = 81;
|
|
a0.a81 = 82;
|
|
a0.a82 = 83;
|
|
a0.a83 = 84;
|
|
a0.a84 = 85;
|
|
a0.a85 = 86;
|
|
a0.a86 = 87;
|
|
a0.a87 = 88;
|
|
a0.a88 = 89;
|
|
a0.a89 = 90;
|
|
a0.a90 = 91;
|
|
a0.a91 = 92;
|
|
a0.a92 = 93;
|
|
a0.a93 = 94;
|
|
a0.a94 = 95;
|
|
a0.a95 = 96;
|
|
a0.a96 = 97;
|
|
a0.a97 = 98;
|
|
a0.a98 = 99;
|
|
a0.a99 = 100;
|
|
a0.a100 = 101;
|
|
a0.a101 = 102;
|
|
a0.a102 = 103;
|
|
a0.a103 = 104;
|
|
a0.a104 = 105;
|
|
a0.a105 = 106;
|
|
a0.a106 = 107;
|
|
a0.a107 = 108;
|
|
a0.a108 = 109;
|
|
a0.a109 = 110;
|
|
a0.a110 = 111;
|
|
a0.a111 = 112;
|
|
a0.a112 = 113;
|
|
a0.a113 = 114;
|
|
a0.a114 = 115;
|
|
a0.a115 = 116;
|
|
a0.a116 = 117;
|
|
a0.a117 = 118;
|
|
a0.a118 = 119;
|
|
a0.a119 = 120;
|
|
a0.a120 = 121;
|
|
a0.a121 = 122;
|
|
a0.a122 = 123;
|
|
a0.a123 = 124;
|
|
a0.a124 = 125;
|
|
a0.a125 = 126;
|
|
a0.a126 = 127;
|
|
a0.a127 = 128;
|
|
|
|
final result = passStruct1024BytesHomogeneousUint64(a0);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(8256, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
}
|
|
|
|
final passFloatStruct16BytesHomogeneousFloatFloatStruct1 =
|
|
ffiTestFunctions.lookupFunction<
|
|
Float Function(
|
|
Float,
|
|
Struct16BytesHomogeneousFloat,
|
|
Float,
|
|
Struct16BytesHomogeneousFloat,
|
|
Float,
|
|
Struct16BytesHomogeneousFloat,
|
|
Float,
|
|
Struct16BytesHomogeneousFloat,
|
|
Float),
|
|
double Function(
|
|
double,
|
|
Struct16BytesHomogeneousFloat,
|
|
double,
|
|
Struct16BytesHomogeneousFloat,
|
|
double,
|
|
Struct16BytesHomogeneousFloat,
|
|
double,
|
|
Struct16BytesHomogeneousFloat,
|
|
double)>("PassFloatStruct16BytesHomogeneousFloatFloatStruct1");
|
|
|
|
/// Tests the alignment of structs in FPU registers and backfilling.
|
|
void testPassFloatStruct16BytesHomogeneousFloatFloatStruct1() {
|
|
double a0;
|
|
final a1Pointer = calloc<Struct16BytesHomogeneousFloat>();
|
|
final Struct16BytesHomogeneousFloat a1 = a1Pointer.ref;
|
|
double a2;
|
|
final a3Pointer = calloc<Struct16BytesHomogeneousFloat>();
|
|
final Struct16BytesHomogeneousFloat a3 = a3Pointer.ref;
|
|
double a4;
|
|
final a5Pointer = calloc<Struct16BytesHomogeneousFloat>();
|
|
final Struct16BytesHomogeneousFloat a5 = a5Pointer.ref;
|
|
double a6;
|
|
final a7Pointer = calloc<Struct16BytesHomogeneousFloat>();
|
|
final Struct16BytesHomogeneousFloat a7 = a7Pointer.ref;
|
|
double a8;
|
|
|
|
a0 = -1.0;
|
|
a1.a0 = 2.0;
|
|
a1.a1 = -3.0;
|
|
a1.a2 = 4.0;
|
|
a1.a3 = -5.0;
|
|
a2 = 6.0;
|
|
a3.a0 = -7.0;
|
|
a3.a1 = 8.0;
|
|
a3.a2 = -9.0;
|
|
a3.a3 = 10.0;
|
|
a4 = -11.0;
|
|
a5.a0 = 12.0;
|
|
a5.a1 = -13.0;
|
|
a5.a2 = 14.0;
|
|
a5.a3 = -15.0;
|
|
a6 = 16.0;
|
|
a7.a0 = -17.0;
|
|
a7.a1 = 18.0;
|
|
a7.a2 = -19.0;
|
|
a7.a3 = 20.0;
|
|
a8 = -21.0;
|
|
|
|
final result = passFloatStruct16BytesHomogeneousFloatFloatStruct1(
|
|
a0, a1, a2, a3, a4, a5, a6, a7, a8);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(-11.0, result);
|
|
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a5Pointer);
|
|
calloc.free(a7Pointer);
|
|
}
|
|
|
|
final passFloatStruct32BytesHomogeneousDoubleFloatStruct =
|
|
ffiTestFunctions.lookupFunction<
|
|
Double Function(
|
|
Float,
|
|
Struct32BytesHomogeneousDouble,
|
|
Float,
|
|
Struct32BytesHomogeneousDouble,
|
|
Float,
|
|
Struct32BytesHomogeneousDouble,
|
|
Float,
|
|
Struct32BytesHomogeneousDouble,
|
|
Float),
|
|
double Function(
|
|
double,
|
|
Struct32BytesHomogeneousDouble,
|
|
double,
|
|
Struct32BytesHomogeneousDouble,
|
|
double,
|
|
Struct32BytesHomogeneousDouble,
|
|
double,
|
|
Struct32BytesHomogeneousDouble,
|
|
double)>("PassFloatStruct32BytesHomogeneousDoubleFloatStruct");
|
|
|
|
/// Tests the alignment of structs in FPU registers and backfilling.
|
|
void testPassFloatStruct32BytesHomogeneousDoubleFloatStruct() {
|
|
double a0;
|
|
final a1Pointer = calloc<Struct32BytesHomogeneousDouble>();
|
|
final Struct32BytesHomogeneousDouble a1 = a1Pointer.ref;
|
|
double a2;
|
|
final a3Pointer = calloc<Struct32BytesHomogeneousDouble>();
|
|
final Struct32BytesHomogeneousDouble a3 = a3Pointer.ref;
|
|
double a4;
|
|
final a5Pointer = calloc<Struct32BytesHomogeneousDouble>();
|
|
final Struct32BytesHomogeneousDouble a5 = a5Pointer.ref;
|
|
double a6;
|
|
final a7Pointer = calloc<Struct32BytesHomogeneousDouble>();
|
|
final Struct32BytesHomogeneousDouble a7 = a7Pointer.ref;
|
|
double a8;
|
|
|
|
a0 = -1.0;
|
|
a1.a0 = 2.0;
|
|
a1.a1 = -3.0;
|
|
a1.a2 = 4.0;
|
|
a1.a3 = -5.0;
|
|
a2 = 6.0;
|
|
a3.a0 = -7.0;
|
|
a3.a1 = 8.0;
|
|
a3.a2 = -9.0;
|
|
a3.a3 = 10.0;
|
|
a4 = -11.0;
|
|
a5.a0 = 12.0;
|
|
a5.a1 = -13.0;
|
|
a5.a2 = 14.0;
|
|
a5.a3 = -15.0;
|
|
a6 = 16.0;
|
|
a7.a0 = -17.0;
|
|
a7.a1 = 18.0;
|
|
a7.a2 = -19.0;
|
|
a7.a3 = 20.0;
|
|
a8 = -21.0;
|
|
|
|
final result = passFloatStruct32BytesHomogeneousDoubleFloatStruct(
|
|
a0, a1, a2, a3, a4, a5, a6, a7, a8);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(-11.0, result);
|
|
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a5Pointer);
|
|
calloc.free(a7Pointer);
|
|
}
|
|
|
|
final passInt8Struct16BytesMixedInt8Struct16BytesMixedIn =
|
|
ffiTestFunctions.lookupFunction<
|
|
Double Function(Int8, Struct16BytesMixed, Int8, Struct16BytesMixed,
|
|
Int8, Struct16BytesMixed, Int8, Struct16BytesMixed, Int8),
|
|
double Function(
|
|
int,
|
|
Struct16BytesMixed,
|
|
int,
|
|
Struct16BytesMixed,
|
|
int,
|
|
Struct16BytesMixed,
|
|
int,
|
|
Struct16BytesMixed,
|
|
int)>("PassInt8Struct16BytesMixedInt8Struct16BytesMixedIn");
|
|
|
|
/// Tests the alignment of structs in integers registers and on the stack.
|
|
/// Arm32 aligns this struct at 8.
|
|
/// Also, arm32 allocates the second struct partially in registers, partially
|
|
/// on stack.
|
|
/// Test backfilling of integer registers.
|
|
void testPassInt8Struct16BytesMixedInt8Struct16BytesMixedIn() {
|
|
int a0;
|
|
final a1Pointer = calloc<Struct16BytesMixed>();
|
|
final Struct16BytesMixed a1 = a1Pointer.ref;
|
|
int a2;
|
|
final a3Pointer = calloc<Struct16BytesMixed>();
|
|
final Struct16BytesMixed a3 = a3Pointer.ref;
|
|
int a4;
|
|
final a5Pointer = calloc<Struct16BytesMixed>();
|
|
final Struct16BytesMixed a5 = a5Pointer.ref;
|
|
int a6;
|
|
final a7Pointer = calloc<Struct16BytesMixed>();
|
|
final Struct16BytesMixed a7 = a7Pointer.ref;
|
|
int a8;
|
|
|
|
a0 = -1;
|
|
a1.a0 = 2.0;
|
|
a1.a1 = -3;
|
|
a2 = 4;
|
|
a3.a0 = -5.0;
|
|
a3.a1 = 6;
|
|
a4 = -7;
|
|
a5.a0 = 8.0;
|
|
a5.a1 = -9;
|
|
a6 = 10;
|
|
a7.a0 = -11.0;
|
|
a7.a1 = 12;
|
|
a8 = -13;
|
|
|
|
final result = passInt8Struct16BytesMixedInt8Struct16BytesMixedIn(
|
|
a0, a1, a2, a3, a4, a5, a6, a7, a8);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(-7.0, result);
|
|
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a5Pointer);
|
|
calloc.free(a7Pointer);
|
|
}
|
|
|
|
final passDoublex6Struct16BytesMixedx4Int32 = ffiTestFunctions.lookupFunction<
|
|
Double Function(
|
|
Double,
|
|
Double,
|
|
Double,
|
|
Double,
|
|
Double,
|
|
Double,
|
|
Struct16BytesMixed,
|
|
Struct16BytesMixed,
|
|
Struct16BytesMixed,
|
|
Struct16BytesMixed,
|
|
Int32),
|
|
double Function(
|
|
double,
|
|
double,
|
|
double,
|
|
double,
|
|
double,
|
|
double,
|
|
Struct16BytesMixed,
|
|
Struct16BytesMixed,
|
|
Struct16BytesMixed,
|
|
Struct16BytesMixed,
|
|
int)>("PassDoublex6Struct16BytesMixedx4Int32");
|
|
|
|
/// On Linux x64, it will exhaust xmm registers first, after 6 doubles and 2
|
|
/// structs. The rest of the structs will go on the stack.
|
|
/// The int will be backfilled into the int register.
|
|
void testPassDoublex6Struct16BytesMixedx4Int32() {
|
|
double a0;
|
|
double a1;
|
|
double a2;
|
|
double a3;
|
|
double a4;
|
|
double a5;
|
|
final a6Pointer = calloc<Struct16BytesMixed>();
|
|
final Struct16BytesMixed a6 = a6Pointer.ref;
|
|
final a7Pointer = calloc<Struct16BytesMixed>();
|
|
final Struct16BytesMixed a7 = a7Pointer.ref;
|
|
final a8Pointer = calloc<Struct16BytesMixed>();
|
|
final Struct16BytesMixed a8 = a8Pointer.ref;
|
|
final a9Pointer = calloc<Struct16BytesMixed>();
|
|
final Struct16BytesMixed a9 = a9Pointer.ref;
|
|
int a10;
|
|
|
|
a0 = -1.0;
|
|
a1 = 2.0;
|
|
a2 = -3.0;
|
|
a3 = 4.0;
|
|
a4 = -5.0;
|
|
a5 = 6.0;
|
|
a6.a0 = -7.0;
|
|
a6.a1 = 8;
|
|
a7.a0 = -9.0;
|
|
a7.a1 = 10;
|
|
a8.a0 = -11.0;
|
|
a8.a1 = 12;
|
|
a9.a0 = -13.0;
|
|
a9.a1 = 14;
|
|
a10 = -15;
|
|
|
|
final result = passDoublex6Struct16BytesMixedx4Int32(
|
|
a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(-8.0, result);
|
|
|
|
calloc.free(a6Pointer);
|
|
calloc.free(a7Pointer);
|
|
calloc.free(a8Pointer);
|
|
calloc.free(a9Pointer);
|
|
}
|
|
|
|
final passInt32x4Struct16BytesMixedx4Double = ffiTestFunctions.lookupFunction<
|
|
Double Function(Int32, Int32, Int32, Int32, Struct16BytesMixed,
|
|
Struct16BytesMixed, Struct16BytesMixed, Struct16BytesMixed, Double),
|
|
double Function(
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
Struct16BytesMixed,
|
|
Struct16BytesMixed,
|
|
Struct16BytesMixed,
|
|
Struct16BytesMixed,
|
|
double)>("PassInt32x4Struct16BytesMixedx4Double");
|
|
|
|
/// On Linux x64, it will exhaust int registers first.
|
|
/// The rest of the structs will go on the stack.
|
|
/// The double will be backfilled into the xmm register.
|
|
void testPassInt32x4Struct16BytesMixedx4Double() {
|
|
int a0;
|
|
int a1;
|
|
int a2;
|
|
int a3;
|
|
final a4Pointer = calloc<Struct16BytesMixed>();
|
|
final Struct16BytesMixed a4 = a4Pointer.ref;
|
|
final a5Pointer = calloc<Struct16BytesMixed>();
|
|
final Struct16BytesMixed a5 = a5Pointer.ref;
|
|
final a6Pointer = calloc<Struct16BytesMixed>();
|
|
final Struct16BytesMixed a6 = a6Pointer.ref;
|
|
final a7Pointer = calloc<Struct16BytesMixed>();
|
|
final Struct16BytesMixed a7 = a7Pointer.ref;
|
|
double a8;
|
|
|
|
a0 = -1;
|
|
a1 = 2;
|
|
a2 = -3;
|
|
a3 = 4;
|
|
a4.a0 = -5.0;
|
|
a4.a1 = 6;
|
|
a5.a0 = -7.0;
|
|
a5.a1 = 8;
|
|
a6.a0 = -9.0;
|
|
a6.a1 = 10;
|
|
a7.a0 = -11.0;
|
|
a7.a1 = 12;
|
|
a8 = -13.0;
|
|
|
|
final result =
|
|
passInt32x4Struct16BytesMixedx4Double(a0, a1, a2, a3, a4, a5, a6, a7, a8);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(-7.0, result);
|
|
|
|
calloc.free(a4Pointer);
|
|
calloc.free(a5Pointer);
|
|
calloc.free(a6Pointer);
|
|
calloc.free(a7Pointer);
|
|
}
|
|
|
|
final passStruct40BytesHomogeneousDoubleStruct4BytesHomo =
|
|
ffiTestFunctions.lookupFunction<
|
|
Double Function(Struct40BytesHomogeneousDouble,
|
|
Struct4BytesHomogeneousInt16, Struct8BytesHomogeneousFloat),
|
|
double Function(Struct40BytesHomogeneousDouble,
|
|
Struct4BytesHomogeneousInt16, Struct8BytesHomogeneousFloat)>(
|
|
"PassStruct40BytesHomogeneousDoubleStruct4BytesHomo");
|
|
|
|
/// On various architectures, first struct is allocated on stack.
|
|
/// Check that the other two arguments are allocated on registers.
|
|
void testPassStruct40BytesHomogeneousDoubleStruct4BytesHomo() {
|
|
final a0Pointer = calloc<Struct40BytesHomogeneousDouble>();
|
|
final Struct40BytesHomogeneousDouble a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<Struct4BytesHomogeneousInt16>();
|
|
final Struct4BytesHomogeneousInt16 a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<Struct8BytesHomogeneousFloat>();
|
|
final Struct8BytesHomogeneousFloat a2 = a2Pointer.ref;
|
|
|
|
a0.a0 = -1.0;
|
|
a0.a1 = 2.0;
|
|
a0.a2 = -3.0;
|
|
a0.a3 = 4.0;
|
|
a0.a4 = -5.0;
|
|
a1.a0 = 6;
|
|
a1.a1 = -7;
|
|
a2.a0 = 8.0;
|
|
a2.a1 = -9.0;
|
|
|
|
final result = passStruct40BytesHomogeneousDoubleStruct4BytesHomo(a0, a1, a2);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(-5.0, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
}
|
|
|
|
final passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int =
|
|
ffiTestFunctions.lookupFunction<
|
|
Double Function(
|
|
Int32,
|
|
Int32,
|
|
Int32,
|
|
Int32,
|
|
Int32,
|
|
Int32,
|
|
Int32,
|
|
Int32,
|
|
Double,
|
|
Double,
|
|
Double,
|
|
Double,
|
|
Double,
|
|
Double,
|
|
Double,
|
|
Double,
|
|
Int64,
|
|
Int8,
|
|
Struct1ByteInt,
|
|
Int64,
|
|
Int8,
|
|
Struct4BytesHomogeneousInt16,
|
|
Int64,
|
|
Int8,
|
|
Struct8BytesInt,
|
|
Int64,
|
|
Int8,
|
|
Struct8BytesHomogeneousFloat,
|
|
Int64,
|
|
Int8,
|
|
Struct8BytesMixed,
|
|
Int64,
|
|
Int8,
|
|
StructAlignmentInt16,
|
|
Int64,
|
|
Int8,
|
|
StructAlignmentInt32,
|
|
Int64,
|
|
Int8,
|
|
StructAlignmentInt64),
|
|
double Function(
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
double,
|
|
double,
|
|
double,
|
|
double,
|
|
double,
|
|
double,
|
|
double,
|
|
double,
|
|
int,
|
|
int,
|
|
Struct1ByteInt,
|
|
int,
|
|
int,
|
|
Struct4BytesHomogeneousInt16,
|
|
int,
|
|
int,
|
|
Struct8BytesInt,
|
|
int,
|
|
int,
|
|
Struct8BytesHomogeneousFloat,
|
|
int,
|
|
int,
|
|
Struct8BytesMixed,
|
|
int,
|
|
int,
|
|
StructAlignmentInt16,
|
|
int,
|
|
int,
|
|
StructAlignmentInt32,
|
|
int,
|
|
int,
|
|
StructAlignmentInt64)>("PassInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int");
|
|
|
|
/// Test alignment and padding of 16 byte int within struct.
|
|
void testPassInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int() {
|
|
int a0;
|
|
int a1;
|
|
int a2;
|
|
int a3;
|
|
int a4;
|
|
int a5;
|
|
int a6;
|
|
int a7;
|
|
double a8;
|
|
double a9;
|
|
double a10;
|
|
double a11;
|
|
double a12;
|
|
double a13;
|
|
double a14;
|
|
double a15;
|
|
int a16;
|
|
int a17;
|
|
final a18Pointer = calloc<Struct1ByteInt>();
|
|
final Struct1ByteInt a18 = a18Pointer.ref;
|
|
int a19;
|
|
int a20;
|
|
final a21Pointer = calloc<Struct4BytesHomogeneousInt16>();
|
|
final Struct4BytesHomogeneousInt16 a21 = a21Pointer.ref;
|
|
int a22;
|
|
int a23;
|
|
final a24Pointer = calloc<Struct8BytesInt>();
|
|
final Struct8BytesInt a24 = a24Pointer.ref;
|
|
int a25;
|
|
int a26;
|
|
final a27Pointer = calloc<Struct8BytesHomogeneousFloat>();
|
|
final Struct8BytesHomogeneousFloat a27 = a27Pointer.ref;
|
|
int a28;
|
|
int a29;
|
|
final a30Pointer = calloc<Struct8BytesMixed>();
|
|
final Struct8BytesMixed a30 = a30Pointer.ref;
|
|
int a31;
|
|
int a32;
|
|
final a33Pointer = calloc<StructAlignmentInt16>();
|
|
final StructAlignmentInt16 a33 = a33Pointer.ref;
|
|
int a34;
|
|
int a35;
|
|
final a36Pointer = calloc<StructAlignmentInt32>();
|
|
final StructAlignmentInt32 a36 = a36Pointer.ref;
|
|
int a37;
|
|
int a38;
|
|
final a39Pointer = calloc<StructAlignmentInt64>();
|
|
final StructAlignmentInt64 a39 = a39Pointer.ref;
|
|
|
|
a0 = -1;
|
|
a1 = 2;
|
|
a2 = -3;
|
|
a3 = 4;
|
|
a4 = -5;
|
|
a5 = 6;
|
|
a6 = -7;
|
|
a7 = 8;
|
|
a8 = -9.0;
|
|
a9 = 10.0;
|
|
a10 = -11.0;
|
|
a11 = 12.0;
|
|
a12 = -13.0;
|
|
a13 = 14.0;
|
|
a14 = -15.0;
|
|
a15 = 16.0;
|
|
a16 = -17;
|
|
a17 = 18;
|
|
a18.a0 = -19;
|
|
a19 = 20;
|
|
a20 = -21;
|
|
a21.a0 = 22;
|
|
a21.a1 = -23;
|
|
a22 = 24;
|
|
a23 = -25;
|
|
a24.a0 = 26;
|
|
a24.a1 = -27;
|
|
a24.a2 = 28;
|
|
a25 = -29;
|
|
a26 = 30;
|
|
a27.a0 = -31.0;
|
|
a27.a1 = 32.0;
|
|
a28 = -33;
|
|
a29 = 34;
|
|
a30.a0 = -35.0;
|
|
a30.a1 = 36;
|
|
a30.a2 = -37;
|
|
a31 = 38;
|
|
a32 = -39;
|
|
a33.a0 = 40;
|
|
a33.a1 = -41;
|
|
a33.a2 = 42;
|
|
a34 = -43;
|
|
a35 = 44;
|
|
a36.a0 = -45;
|
|
a36.a1 = 46;
|
|
a36.a2 = -47;
|
|
a37 = 48;
|
|
a38 = -49;
|
|
a39.a0 = 50;
|
|
a39.a1 = -51;
|
|
a39.a2 = 52;
|
|
|
|
final result = passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int(
|
|
a0,
|
|
a1,
|
|
a2,
|
|
a3,
|
|
a4,
|
|
a5,
|
|
a6,
|
|
a7,
|
|
a8,
|
|
a9,
|
|
a10,
|
|
a11,
|
|
a12,
|
|
a13,
|
|
a14,
|
|
a15,
|
|
a16,
|
|
a17,
|
|
a18,
|
|
a19,
|
|
a20,
|
|
a21,
|
|
a22,
|
|
a23,
|
|
a24,
|
|
a25,
|
|
a26,
|
|
a27,
|
|
a28,
|
|
a29,
|
|
a30,
|
|
a31,
|
|
a32,
|
|
a33,
|
|
a34,
|
|
a35,
|
|
a36,
|
|
a37,
|
|
a38,
|
|
a39);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(26.0, result);
|
|
|
|
calloc.free(a18Pointer);
|
|
calloc.free(a21Pointer);
|
|
calloc.free(a24Pointer);
|
|
calloc.free(a27Pointer);
|
|
calloc.free(a30Pointer);
|
|
calloc.free(a33Pointer);
|
|
calloc.free(a36Pointer);
|
|
calloc.free(a39Pointer);
|
|
}
|
|
|
|
final passStructAlignmentInt16 = ffiTestFunctions.lookupFunction<
|
|
Int64 Function(StructAlignmentInt16),
|
|
int Function(StructAlignmentInt16)>("PassStructAlignmentInt16");
|
|
|
|
/// Test alignment and padding of 16 byte int within struct.
|
|
void testPassStructAlignmentInt16() {
|
|
final a0Pointer = calloc<StructAlignmentInt16>();
|
|
final StructAlignmentInt16 a0 = a0Pointer.ref;
|
|
|
|
a0.a0 = -1;
|
|
a0.a1 = 2;
|
|
a0.a2 = -3;
|
|
|
|
final result = passStructAlignmentInt16(a0);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(-2, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
}
|
|
|
|
final passStructAlignmentInt32 = ffiTestFunctions.lookupFunction<
|
|
Int64 Function(StructAlignmentInt32),
|
|
int Function(StructAlignmentInt32)>("PassStructAlignmentInt32");
|
|
|
|
/// Test alignment and padding of 32 byte int within struct.
|
|
void testPassStructAlignmentInt32() {
|
|
final a0Pointer = calloc<StructAlignmentInt32>();
|
|
final StructAlignmentInt32 a0 = a0Pointer.ref;
|
|
|
|
a0.a0 = -1;
|
|
a0.a1 = 2;
|
|
a0.a2 = -3;
|
|
|
|
final result = passStructAlignmentInt32(a0);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(-2, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
}
|
|
|
|
final passStructAlignmentInt64 = ffiTestFunctions.lookupFunction<
|
|
Int64 Function(StructAlignmentInt64),
|
|
int Function(StructAlignmentInt64)>("PassStructAlignmentInt64");
|
|
|
|
/// Test alignment and padding of 64 byte int within struct.
|
|
void testPassStructAlignmentInt64() {
|
|
final a0Pointer = calloc<StructAlignmentInt64>();
|
|
final StructAlignmentInt64 a0 = a0Pointer.ref;
|
|
|
|
a0.a0 = -1;
|
|
a0.a1 = 2;
|
|
a0.a2 = -3;
|
|
|
|
final result = passStructAlignmentInt64(a0);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(-2, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
}
|
|
|
|
final passStruct8BytesNestedIntx10 = ffiTestFunctions.lookupFunction<
|
|
Int64 Function(
|
|
Struct8BytesNestedInt,
|
|
Struct8BytesNestedInt,
|
|
Struct8BytesNestedInt,
|
|
Struct8BytesNestedInt,
|
|
Struct8BytesNestedInt,
|
|
Struct8BytesNestedInt,
|
|
Struct8BytesNestedInt,
|
|
Struct8BytesNestedInt,
|
|
Struct8BytesNestedInt,
|
|
Struct8BytesNestedInt),
|
|
int Function(
|
|
Struct8BytesNestedInt,
|
|
Struct8BytesNestedInt,
|
|
Struct8BytesNestedInt,
|
|
Struct8BytesNestedInt,
|
|
Struct8BytesNestedInt,
|
|
Struct8BytesNestedInt,
|
|
Struct8BytesNestedInt,
|
|
Struct8BytesNestedInt,
|
|
Struct8BytesNestedInt,
|
|
Struct8BytesNestedInt)>("PassStruct8BytesNestedIntx10");
|
|
|
|
/// Simple nested struct. No alignment gaps on any architectures.
|
|
/// 10 arguments exhaust registers on all platforms.
|
|
void testPassStruct8BytesNestedIntx10() {
|
|
final a0Pointer = calloc<Struct8BytesNestedInt>();
|
|
final Struct8BytesNestedInt a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<Struct8BytesNestedInt>();
|
|
final Struct8BytesNestedInt a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<Struct8BytesNestedInt>();
|
|
final Struct8BytesNestedInt a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<Struct8BytesNestedInt>();
|
|
final Struct8BytesNestedInt a3 = a3Pointer.ref;
|
|
final a4Pointer = calloc<Struct8BytesNestedInt>();
|
|
final Struct8BytesNestedInt a4 = a4Pointer.ref;
|
|
final a5Pointer = calloc<Struct8BytesNestedInt>();
|
|
final Struct8BytesNestedInt a5 = a5Pointer.ref;
|
|
final a6Pointer = calloc<Struct8BytesNestedInt>();
|
|
final Struct8BytesNestedInt a6 = a6Pointer.ref;
|
|
final a7Pointer = calloc<Struct8BytesNestedInt>();
|
|
final Struct8BytesNestedInt a7 = a7Pointer.ref;
|
|
final a8Pointer = calloc<Struct8BytesNestedInt>();
|
|
final Struct8BytesNestedInt a8 = a8Pointer.ref;
|
|
final a9Pointer = calloc<Struct8BytesNestedInt>();
|
|
final Struct8BytesNestedInt a9 = a9Pointer.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;
|
|
a2.a0.a0 = -9;
|
|
a2.a0.a1 = 10;
|
|
a2.a1.a0 = -11;
|
|
a2.a1.a1 = 12;
|
|
a3.a0.a0 = -13;
|
|
a3.a0.a1 = 14;
|
|
a3.a1.a0 = -15;
|
|
a3.a1.a1 = 16;
|
|
a4.a0.a0 = -17;
|
|
a4.a0.a1 = 18;
|
|
a4.a1.a0 = -19;
|
|
a4.a1.a1 = 20;
|
|
a5.a0.a0 = -21;
|
|
a5.a0.a1 = 22;
|
|
a5.a1.a0 = -23;
|
|
a5.a1.a1 = 24;
|
|
a6.a0.a0 = -25;
|
|
a6.a0.a1 = 26;
|
|
a6.a1.a0 = -27;
|
|
a6.a1.a1 = 28;
|
|
a7.a0.a0 = -29;
|
|
a7.a0.a1 = 30;
|
|
a7.a1.a0 = -31;
|
|
a7.a1.a1 = 32;
|
|
a8.a0.a0 = -33;
|
|
a8.a0.a1 = 34;
|
|
a8.a1.a0 = -35;
|
|
a8.a1.a1 = 36;
|
|
a9.a0.a0 = -37;
|
|
a9.a0.a1 = 38;
|
|
a9.a1.a0 = -39;
|
|
a9.a1.a1 = 40;
|
|
|
|
final result =
|
|
passStruct8BytesNestedIntx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(20, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a4Pointer);
|
|
calloc.free(a5Pointer);
|
|
calloc.free(a6Pointer);
|
|
calloc.free(a7Pointer);
|
|
calloc.free(a8Pointer);
|
|
calloc.free(a9Pointer);
|
|
}
|
|
|
|
final passStruct8BytesNestedFloatx10 = ffiTestFunctions.lookupFunction<
|
|
Float Function(
|
|
Struct8BytesNestedFloat,
|
|
Struct8BytesNestedFloat,
|
|
Struct8BytesNestedFloat,
|
|
Struct8BytesNestedFloat,
|
|
Struct8BytesNestedFloat,
|
|
Struct8BytesNestedFloat,
|
|
Struct8BytesNestedFloat,
|
|
Struct8BytesNestedFloat,
|
|
Struct8BytesNestedFloat,
|
|
Struct8BytesNestedFloat),
|
|
double Function(
|
|
Struct8BytesNestedFloat,
|
|
Struct8BytesNestedFloat,
|
|
Struct8BytesNestedFloat,
|
|
Struct8BytesNestedFloat,
|
|
Struct8BytesNestedFloat,
|
|
Struct8BytesNestedFloat,
|
|
Struct8BytesNestedFloat,
|
|
Struct8BytesNestedFloat,
|
|
Struct8BytesNestedFloat,
|
|
Struct8BytesNestedFloat)>("PassStruct8BytesNestedFloatx10");
|
|
|
|
/// Simple nested struct. No alignment gaps on any architectures.
|
|
/// 10 arguments exhaust fpu registers on all platforms.
|
|
void testPassStruct8BytesNestedFloatx10() {
|
|
final a0Pointer = calloc<Struct8BytesNestedFloat>();
|
|
final Struct8BytesNestedFloat a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<Struct8BytesNestedFloat>();
|
|
final Struct8BytesNestedFloat a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<Struct8BytesNestedFloat>();
|
|
final Struct8BytesNestedFloat a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<Struct8BytesNestedFloat>();
|
|
final Struct8BytesNestedFloat a3 = a3Pointer.ref;
|
|
final a4Pointer = calloc<Struct8BytesNestedFloat>();
|
|
final Struct8BytesNestedFloat a4 = a4Pointer.ref;
|
|
final a5Pointer = calloc<Struct8BytesNestedFloat>();
|
|
final Struct8BytesNestedFloat a5 = a5Pointer.ref;
|
|
final a6Pointer = calloc<Struct8BytesNestedFloat>();
|
|
final Struct8BytesNestedFloat a6 = a6Pointer.ref;
|
|
final a7Pointer = calloc<Struct8BytesNestedFloat>();
|
|
final Struct8BytesNestedFloat a7 = a7Pointer.ref;
|
|
final a8Pointer = calloc<Struct8BytesNestedFloat>();
|
|
final Struct8BytesNestedFloat a8 = a8Pointer.ref;
|
|
final a9Pointer = calloc<Struct8BytesNestedFloat>();
|
|
final Struct8BytesNestedFloat a9 = a9Pointer.ref;
|
|
|
|
a0.a0.a0 = -1.0;
|
|
a0.a1.a0 = 2.0;
|
|
a1.a0.a0 = -3.0;
|
|
a1.a1.a0 = 4.0;
|
|
a2.a0.a0 = -5.0;
|
|
a2.a1.a0 = 6.0;
|
|
a3.a0.a0 = -7.0;
|
|
a3.a1.a0 = 8.0;
|
|
a4.a0.a0 = -9.0;
|
|
a4.a1.a0 = 10.0;
|
|
a5.a0.a0 = -11.0;
|
|
a5.a1.a0 = 12.0;
|
|
a6.a0.a0 = -13.0;
|
|
a6.a1.a0 = 14.0;
|
|
a7.a0.a0 = -15.0;
|
|
a7.a1.a0 = 16.0;
|
|
a8.a0.a0 = -17.0;
|
|
a8.a1.a0 = 18.0;
|
|
a9.a0.a0 = -19.0;
|
|
a9.a1.a0 = 20.0;
|
|
|
|
final result =
|
|
passStruct8BytesNestedFloatx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(10.0, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a4Pointer);
|
|
calloc.free(a5Pointer);
|
|
calloc.free(a6Pointer);
|
|
calloc.free(a7Pointer);
|
|
calloc.free(a8Pointer);
|
|
calloc.free(a9Pointer);
|
|
}
|
|
|
|
final passStruct8BytesNestedFloat2x10 = ffiTestFunctions.lookupFunction<
|
|
Float Function(
|
|
Struct8BytesNestedFloat2,
|
|
Struct8BytesNestedFloat2,
|
|
Struct8BytesNestedFloat2,
|
|
Struct8BytesNestedFloat2,
|
|
Struct8BytesNestedFloat2,
|
|
Struct8BytesNestedFloat2,
|
|
Struct8BytesNestedFloat2,
|
|
Struct8BytesNestedFloat2,
|
|
Struct8BytesNestedFloat2,
|
|
Struct8BytesNestedFloat2),
|
|
double Function(
|
|
Struct8BytesNestedFloat2,
|
|
Struct8BytesNestedFloat2,
|
|
Struct8BytesNestedFloat2,
|
|
Struct8BytesNestedFloat2,
|
|
Struct8BytesNestedFloat2,
|
|
Struct8BytesNestedFloat2,
|
|
Struct8BytesNestedFloat2,
|
|
Struct8BytesNestedFloat2,
|
|
Struct8BytesNestedFloat2,
|
|
Struct8BytesNestedFloat2)>("PassStruct8BytesNestedFloat2x10");
|
|
|
|
/// Simple nested struct. No alignment gaps on any architectures.
|
|
/// 10 arguments exhaust fpu registers on all platforms.
|
|
/// The nesting is irregular, testing homogenous float rules on arm and arm64,
|
|
/// and the fpu register usage on x64.
|
|
void testPassStruct8BytesNestedFloat2x10() {
|
|
final a0Pointer = calloc<Struct8BytesNestedFloat2>();
|
|
final Struct8BytesNestedFloat2 a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<Struct8BytesNestedFloat2>();
|
|
final Struct8BytesNestedFloat2 a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<Struct8BytesNestedFloat2>();
|
|
final Struct8BytesNestedFloat2 a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<Struct8BytesNestedFloat2>();
|
|
final Struct8BytesNestedFloat2 a3 = a3Pointer.ref;
|
|
final a4Pointer = calloc<Struct8BytesNestedFloat2>();
|
|
final Struct8BytesNestedFloat2 a4 = a4Pointer.ref;
|
|
final a5Pointer = calloc<Struct8BytesNestedFloat2>();
|
|
final Struct8BytesNestedFloat2 a5 = a5Pointer.ref;
|
|
final a6Pointer = calloc<Struct8BytesNestedFloat2>();
|
|
final Struct8BytesNestedFloat2 a6 = a6Pointer.ref;
|
|
final a7Pointer = calloc<Struct8BytesNestedFloat2>();
|
|
final Struct8BytesNestedFloat2 a7 = a7Pointer.ref;
|
|
final a8Pointer = calloc<Struct8BytesNestedFloat2>();
|
|
final Struct8BytesNestedFloat2 a8 = a8Pointer.ref;
|
|
final a9Pointer = calloc<Struct8BytesNestedFloat2>();
|
|
final Struct8BytesNestedFloat2 a9 = a9Pointer.ref;
|
|
|
|
a0.a0.a0 = -1.0;
|
|
a0.a1 = 2.0;
|
|
a1.a0.a0 = -3.0;
|
|
a1.a1 = 4.0;
|
|
a2.a0.a0 = -5.0;
|
|
a2.a1 = 6.0;
|
|
a3.a0.a0 = -7.0;
|
|
a3.a1 = 8.0;
|
|
a4.a0.a0 = -9.0;
|
|
a4.a1 = 10.0;
|
|
a5.a0.a0 = -11.0;
|
|
a5.a1 = 12.0;
|
|
a6.a0.a0 = -13.0;
|
|
a6.a1 = 14.0;
|
|
a7.a0.a0 = -15.0;
|
|
a7.a1 = 16.0;
|
|
a8.a0.a0 = -17.0;
|
|
a8.a1 = 18.0;
|
|
a9.a0.a0 = -19.0;
|
|
a9.a1 = 20.0;
|
|
|
|
final result =
|
|
passStruct8BytesNestedFloat2x10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(10.0, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a4Pointer);
|
|
calloc.free(a5Pointer);
|
|
calloc.free(a6Pointer);
|
|
calloc.free(a7Pointer);
|
|
calloc.free(a8Pointer);
|
|
calloc.free(a9Pointer);
|
|
}
|
|
|
|
final passStruct8BytesNestedMixedx10 = ffiTestFunctions.lookupFunction<
|
|
Double Function(
|
|
Struct8BytesNestedMixed,
|
|
Struct8BytesNestedMixed,
|
|
Struct8BytesNestedMixed,
|
|
Struct8BytesNestedMixed,
|
|
Struct8BytesNestedMixed,
|
|
Struct8BytesNestedMixed,
|
|
Struct8BytesNestedMixed,
|
|
Struct8BytesNestedMixed,
|
|
Struct8BytesNestedMixed,
|
|
Struct8BytesNestedMixed),
|
|
double Function(
|
|
Struct8BytesNestedMixed,
|
|
Struct8BytesNestedMixed,
|
|
Struct8BytesNestedMixed,
|
|
Struct8BytesNestedMixed,
|
|
Struct8BytesNestedMixed,
|
|
Struct8BytesNestedMixed,
|
|
Struct8BytesNestedMixed,
|
|
Struct8BytesNestedMixed,
|
|
Struct8BytesNestedMixed,
|
|
Struct8BytesNestedMixed)>("PassStruct8BytesNestedMixedx10");
|
|
|
|
/// Simple nested struct. No alignment gaps on any architectures.
|
|
/// 10 arguments exhaust all registers on all platforms.
|
|
void testPassStruct8BytesNestedMixedx10() {
|
|
final a0Pointer = calloc<Struct8BytesNestedMixed>();
|
|
final Struct8BytesNestedMixed a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<Struct8BytesNestedMixed>();
|
|
final Struct8BytesNestedMixed a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<Struct8BytesNestedMixed>();
|
|
final Struct8BytesNestedMixed a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<Struct8BytesNestedMixed>();
|
|
final Struct8BytesNestedMixed a3 = a3Pointer.ref;
|
|
final a4Pointer = calloc<Struct8BytesNestedMixed>();
|
|
final Struct8BytesNestedMixed a4 = a4Pointer.ref;
|
|
final a5Pointer = calloc<Struct8BytesNestedMixed>();
|
|
final Struct8BytesNestedMixed a5 = a5Pointer.ref;
|
|
final a6Pointer = calloc<Struct8BytesNestedMixed>();
|
|
final Struct8BytesNestedMixed a6 = a6Pointer.ref;
|
|
final a7Pointer = calloc<Struct8BytesNestedMixed>();
|
|
final Struct8BytesNestedMixed a7 = a7Pointer.ref;
|
|
final a8Pointer = calloc<Struct8BytesNestedMixed>();
|
|
final Struct8BytesNestedMixed a8 = a8Pointer.ref;
|
|
final a9Pointer = calloc<Struct8BytesNestedMixed>();
|
|
final Struct8BytesNestedMixed a9 = a9Pointer.ref;
|
|
|
|
a0.a0.a0 = -1;
|
|
a0.a0.a1 = 2;
|
|
a0.a1.a0 = -3.0;
|
|
a1.a0.a0 = 4;
|
|
a1.a0.a1 = -5;
|
|
a1.a1.a0 = 6.0;
|
|
a2.a0.a0 = -7;
|
|
a2.a0.a1 = 8;
|
|
a2.a1.a0 = -9.0;
|
|
a3.a0.a0 = 10;
|
|
a3.a0.a1 = -11;
|
|
a3.a1.a0 = 12.0;
|
|
a4.a0.a0 = -13;
|
|
a4.a0.a1 = 14;
|
|
a4.a1.a0 = -15.0;
|
|
a5.a0.a0 = 16;
|
|
a5.a0.a1 = -17;
|
|
a5.a1.a0 = 18.0;
|
|
a6.a0.a0 = -19;
|
|
a6.a0.a1 = 20;
|
|
a6.a1.a0 = -21.0;
|
|
a7.a0.a0 = 22;
|
|
a7.a0.a1 = -23;
|
|
a7.a1.a0 = 24.0;
|
|
a8.a0.a0 = -25;
|
|
a8.a0.a1 = 26;
|
|
a8.a1.a0 = -27.0;
|
|
a9.a0.a0 = 28;
|
|
a9.a0.a1 = -29;
|
|
a9.a1.a0 = 30.0;
|
|
|
|
final result =
|
|
passStruct8BytesNestedMixedx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(15.0, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a4Pointer);
|
|
calloc.free(a5Pointer);
|
|
calloc.free(a6Pointer);
|
|
calloc.free(a7Pointer);
|
|
calloc.free(a8Pointer);
|
|
calloc.free(a9Pointer);
|
|
}
|
|
|
|
final passStruct16BytesNestedIntx2 = ffiTestFunctions.lookupFunction<
|
|
Int64 Function(Struct16BytesNestedInt, Struct16BytesNestedInt),
|
|
int Function(Struct16BytesNestedInt,
|
|
Struct16BytesNestedInt)>("PassStruct16BytesNestedIntx2");
|
|
|
|
/// Deeper nested struct to test recursive member access.
|
|
void testPassStruct16BytesNestedIntx2() {
|
|
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 = passStruct16BytesNestedIntx2(a0, a1);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(8, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
}
|
|
|
|
final passStruct32BytesNestedIntx2 = ffiTestFunctions.lookupFunction<
|
|
Int64 Function(Struct32BytesNestedInt, Struct32BytesNestedInt),
|
|
int Function(Struct32BytesNestedInt,
|
|
Struct32BytesNestedInt)>("PassStruct32BytesNestedIntx2");
|
|
|
|
/// Even deeper nested struct to test recursive member access.
|
|
void testPassStruct32BytesNestedIntx2() {
|
|
final a0Pointer = calloc<Struct32BytesNestedInt>();
|
|
final Struct32BytesNestedInt a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<Struct32BytesNestedInt>();
|
|
final Struct32BytesNestedInt a1 = a1Pointer.ref;
|
|
|
|
a0.a0.a0.a0.a0 = -1;
|
|
a0.a0.a0.a0.a1 = 2;
|
|
a0.a0.a0.a1.a0 = -3;
|
|
a0.a0.a0.a1.a1 = 4;
|
|
a0.a0.a1.a0.a0 = -5;
|
|
a0.a0.a1.a0.a1 = 6;
|
|
a0.a0.a1.a1.a0 = -7;
|
|
a0.a0.a1.a1.a1 = 8;
|
|
a0.a1.a0.a0.a0 = -9;
|
|
a0.a1.a0.a0.a1 = 10;
|
|
a0.a1.a0.a1.a0 = -11;
|
|
a0.a1.a0.a1.a1 = 12;
|
|
a0.a1.a1.a0.a0 = -13;
|
|
a0.a1.a1.a0.a1 = 14;
|
|
a0.a1.a1.a1.a0 = -15;
|
|
a0.a1.a1.a1.a1 = 16;
|
|
a1.a0.a0.a0.a0 = -17;
|
|
a1.a0.a0.a0.a1 = 18;
|
|
a1.a0.a0.a1.a0 = -19;
|
|
a1.a0.a0.a1.a1 = 20;
|
|
a1.a0.a1.a0.a0 = -21;
|
|
a1.a0.a1.a0.a1 = 22;
|
|
a1.a0.a1.a1.a0 = -23;
|
|
a1.a0.a1.a1.a1 = 24;
|
|
a1.a1.a0.a0.a0 = -25;
|
|
a1.a1.a0.a0.a1 = 26;
|
|
a1.a1.a0.a1.a0 = -27;
|
|
a1.a1.a0.a1.a1 = 28;
|
|
a1.a1.a1.a0.a0 = -29;
|
|
a1.a1.a1.a0.a1 = 30;
|
|
a1.a1.a1.a1.a0 = -31;
|
|
a1.a1.a1.a1.a1 = 32;
|
|
|
|
final result = passStruct32BytesNestedIntx2(a0, a1);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(16, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
}
|
|
|
|
final passStructNestedIntStructAlignmentInt16 = ffiTestFunctions.lookupFunction<
|
|
Int64 Function(StructNestedIntStructAlignmentInt16),
|
|
int Function(StructNestedIntStructAlignmentInt16)>(
|
|
"PassStructNestedIntStructAlignmentInt16");
|
|
|
|
/// Test alignment and padding of nested struct with 16 byte int.
|
|
void testPassStructNestedIntStructAlignmentInt16() {
|
|
final a0Pointer = calloc<StructNestedIntStructAlignmentInt16>();
|
|
final StructNestedIntStructAlignmentInt16 a0 = a0Pointer.ref;
|
|
|
|
a0.a0.a0 = -1;
|
|
a0.a0.a1 = 2;
|
|
a0.a0.a2 = -3;
|
|
a0.a1.a0 = 4;
|
|
a0.a1.a1 = -5;
|
|
a0.a1.a2 = 6;
|
|
|
|
final result = passStructNestedIntStructAlignmentInt16(a0);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(3, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
}
|
|
|
|
final passStructNestedIntStructAlignmentInt32 = ffiTestFunctions.lookupFunction<
|
|
Int64 Function(StructNestedIntStructAlignmentInt32),
|
|
int Function(StructNestedIntStructAlignmentInt32)>(
|
|
"PassStructNestedIntStructAlignmentInt32");
|
|
|
|
/// Test alignment and padding of nested struct with 32 byte int.
|
|
void testPassStructNestedIntStructAlignmentInt32() {
|
|
final a0Pointer = calloc<StructNestedIntStructAlignmentInt32>();
|
|
final StructNestedIntStructAlignmentInt32 a0 = a0Pointer.ref;
|
|
|
|
a0.a0.a0 = -1;
|
|
a0.a0.a1 = 2;
|
|
a0.a0.a2 = -3;
|
|
a0.a1.a0 = 4;
|
|
a0.a1.a1 = -5;
|
|
a0.a1.a2 = 6;
|
|
|
|
final result = passStructNestedIntStructAlignmentInt32(a0);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(3, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
}
|
|
|
|
final passStructNestedIntStructAlignmentInt64 = ffiTestFunctions.lookupFunction<
|
|
Int64 Function(StructNestedIntStructAlignmentInt64),
|
|
int Function(StructNestedIntStructAlignmentInt64)>(
|
|
"PassStructNestedIntStructAlignmentInt64");
|
|
|
|
/// Test alignment and padding of nested struct with 64 byte int.
|
|
void testPassStructNestedIntStructAlignmentInt64() {
|
|
final a0Pointer = calloc<StructNestedIntStructAlignmentInt64>();
|
|
final StructNestedIntStructAlignmentInt64 a0 = a0Pointer.ref;
|
|
|
|
a0.a0.a0 = -1;
|
|
a0.a0.a1 = 2;
|
|
a0.a0.a2 = -3;
|
|
a0.a1.a0 = 4;
|
|
a0.a1.a1 = -5;
|
|
a0.a1.a2 = 6;
|
|
|
|
final result = passStructNestedIntStructAlignmentInt64(a0);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(3, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
}
|
|
|
|
final passStructNestedIrregularEvenBiggerx4 = ffiTestFunctions.lookupFunction<
|
|
Double Function(
|
|
StructNestedIrregularEvenBigger,
|
|
StructNestedIrregularEvenBigger,
|
|
StructNestedIrregularEvenBigger,
|
|
StructNestedIrregularEvenBigger),
|
|
double Function(
|
|
StructNestedIrregularEvenBigger,
|
|
StructNestedIrregularEvenBigger,
|
|
StructNestedIrregularEvenBigger,
|
|
StructNestedIrregularEvenBigger)>(
|
|
"PassStructNestedIrregularEvenBiggerx4");
|
|
|
|
/// Return big irregular struct as smoke test.
|
|
void testPassStructNestedIrregularEvenBiggerx4() {
|
|
final a0Pointer = calloc<StructNestedIrregularEvenBigger>();
|
|
final StructNestedIrregularEvenBigger a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<StructNestedIrregularEvenBigger>();
|
|
final StructNestedIrregularEvenBigger a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<StructNestedIrregularEvenBigger>();
|
|
final StructNestedIrregularEvenBigger a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<StructNestedIrregularEvenBigger>();
|
|
final StructNestedIrregularEvenBigger a3 = a3Pointer.ref;
|
|
|
|
a0.a0 = 1;
|
|
a0.a1.a0.a0 = 2;
|
|
a0.a1.a0.a1.a0.a0 = -3;
|
|
a0.a1.a0.a1.a0.a1 = 4;
|
|
a0.a1.a0.a1.a1.a0 = -5.0;
|
|
a0.a1.a0.a2 = 6;
|
|
a0.a1.a0.a3.a0.a0 = -7.0;
|
|
a0.a1.a0.a3.a1 = 8.0;
|
|
a0.a1.a0.a4 = 9;
|
|
a0.a1.a0.a5.a0.a0 = 10.0;
|
|
a0.a1.a0.a5.a1.a0 = -11.0;
|
|
a0.a1.a0.a6 = 12;
|
|
a0.a1.a1.a0.a0 = -13;
|
|
a0.a1.a1.a0.a1 = 14;
|
|
a0.a1.a1.a1.a0 = -15.0;
|
|
a0.a1.a2 = 16.0;
|
|
a0.a1.a3 = -17.0;
|
|
a0.a2.a0.a0 = 18;
|
|
a0.a2.a0.a1.a0.a0 = -19;
|
|
a0.a2.a0.a1.a0.a1 = 20;
|
|
a0.a2.a0.a1.a1.a0 = -21.0;
|
|
a0.a2.a0.a2 = 22;
|
|
a0.a2.a0.a3.a0.a0 = -23.0;
|
|
a0.a2.a0.a3.a1 = 24.0;
|
|
a0.a2.a0.a4 = 25;
|
|
a0.a2.a0.a5.a0.a0 = 26.0;
|
|
a0.a2.a0.a5.a1.a0 = -27.0;
|
|
a0.a2.a0.a6 = 28;
|
|
a0.a2.a1.a0.a0 = -29;
|
|
a0.a2.a1.a0.a1 = 30;
|
|
a0.a2.a1.a1.a0 = -31.0;
|
|
a0.a2.a2 = 32.0;
|
|
a0.a2.a3 = -33.0;
|
|
a0.a3 = 34.0;
|
|
a1.a0 = 35;
|
|
a1.a1.a0.a0 = 36;
|
|
a1.a1.a0.a1.a0.a0 = -37;
|
|
a1.a1.a0.a1.a0.a1 = 38;
|
|
a1.a1.a0.a1.a1.a0 = -39.0;
|
|
a1.a1.a0.a2 = 40;
|
|
a1.a1.a0.a3.a0.a0 = -41.0;
|
|
a1.a1.a0.a3.a1 = 42.0;
|
|
a1.a1.a0.a4 = 43;
|
|
a1.a1.a0.a5.a0.a0 = 44.0;
|
|
a1.a1.a0.a5.a1.a0 = -45.0;
|
|
a1.a1.a0.a6 = 46;
|
|
a1.a1.a1.a0.a0 = -47;
|
|
a1.a1.a1.a0.a1 = 48;
|
|
a1.a1.a1.a1.a0 = -49.0;
|
|
a1.a1.a2 = 50.0;
|
|
a1.a1.a3 = -51.0;
|
|
a1.a2.a0.a0 = 52;
|
|
a1.a2.a0.a1.a0.a0 = -53;
|
|
a1.a2.a0.a1.a0.a1 = 54;
|
|
a1.a2.a0.a1.a1.a0 = -55.0;
|
|
a1.a2.a0.a2 = 56;
|
|
a1.a2.a0.a3.a0.a0 = -57.0;
|
|
a1.a2.a0.a3.a1 = 58.0;
|
|
a1.a2.a0.a4 = 59;
|
|
a1.a2.a0.a5.a0.a0 = 60.0;
|
|
a1.a2.a0.a5.a1.a0 = -61.0;
|
|
a1.a2.a0.a6 = 62;
|
|
a1.a2.a1.a0.a0 = -63;
|
|
a1.a2.a1.a0.a1 = 64;
|
|
a1.a2.a1.a1.a0 = -65.0;
|
|
a1.a2.a2 = 66.0;
|
|
a1.a2.a3 = -67.0;
|
|
a1.a3 = 68.0;
|
|
a2.a0 = 69;
|
|
a2.a1.a0.a0 = 70;
|
|
a2.a1.a0.a1.a0.a0 = -71;
|
|
a2.a1.a0.a1.a0.a1 = 72;
|
|
a2.a1.a0.a1.a1.a0 = -73.0;
|
|
a2.a1.a0.a2 = 74;
|
|
a2.a1.a0.a3.a0.a0 = -75.0;
|
|
a2.a1.a0.a3.a1 = 76.0;
|
|
a2.a1.a0.a4 = 77;
|
|
a2.a1.a0.a5.a0.a0 = 78.0;
|
|
a2.a1.a0.a5.a1.a0 = -79.0;
|
|
a2.a1.a0.a6 = 80;
|
|
a2.a1.a1.a0.a0 = -81;
|
|
a2.a1.a1.a0.a1 = 82;
|
|
a2.a1.a1.a1.a0 = -83.0;
|
|
a2.a1.a2 = 84.0;
|
|
a2.a1.a3 = -85.0;
|
|
a2.a2.a0.a0 = 86;
|
|
a2.a2.a0.a1.a0.a0 = -87;
|
|
a2.a2.a0.a1.a0.a1 = 88;
|
|
a2.a2.a0.a1.a1.a0 = -89.0;
|
|
a2.a2.a0.a2 = 90;
|
|
a2.a2.a0.a3.a0.a0 = -91.0;
|
|
a2.a2.a0.a3.a1 = 92.0;
|
|
a2.a2.a0.a4 = 93;
|
|
a2.a2.a0.a5.a0.a0 = 94.0;
|
|
a2.a2.a0.a5.a1.a0 = -95.0;
|
|
a2.a2.a0.a6 = 96;
|
|
a2.a2.a1.a0.a0 = -97;
|
|
a2.a2.a1.a0.a1 = 98;
|
|
a2.a2.a1.a1.a0 = -99.0;
|
|
a2.a2.a2 = 100.0;
|
|
a2.a2.a3 = -101.0;
|
|
a2.a3 = 102.0;
|
|
a3.a0 = 103;
|
|
a3.a1.a0.a0 = 104;
|
|
a3.a1.a0.a1.a0.a0 = -105;
|
|
a3.a1.a0.a1.a0.a1 = 106;
|
|
a3.a1.a0.a1.a1.a0 = -107.0;
|
|
a3.a1.a0.a2 = 108;
|
|
a3.a1.a0.a3.a0.a0 = -109.0;
|
|
a3.a1.a0.a3.a1 = 110.0;
|
|
a3.a1.a0.a4 = 111;
|
|
a3.a1.a0.a5.a0.a0 = 112.0;
|
|
a3.a1.a0.a5.a1.a0 = -113.0;
|
|
a3.a1.a0.a6 = 114;
|
|
a3.a1.a1.a0.a0 = -115;
|
|
a3.a1.a1.a0.a1 = 116;
|
|
a3.a1.a1.a1.a0 = -117.0;
|
|
a3.a1.a2 = 118.0;
|
|
a3.a1.a3 = -119.0;
|
|
a3.a2.a0.a0 = 120;
|
|
a3.a2.a0.a1.a0.a0 = -121;
|
|
a3.a2.a0.a1.a0.a1 = 122;
|
|
a3.a2.a0.a1.a1.a0 = -123.0;
|
|
a3.a2.a0.a2 = 124;
|
|
a3.a2.a0.a3.a0.a0 = -125.0;
|
|
a3.a2.a0.a3.a1 = 126.0;
|
|
a3.a2.a0.a4 = 127;
|
|
a3.a2.a0.a5.a0.a0 = 128.0;
|
|
a3.a2.a0.a5.a1.a0 = -129.0;
|
|
a3.a2.a0.a6 = 130;
|
|
a3.a2.a1.a0.a0 = -131;
|
|
a3.a2.a1.a0.a1 = 132;
|
|
a3.a2.a1.a1.a0 = -133.0;
|
|
a3.a2.a2 = 134.0;
|
|
a3.a2.a3 = -135.0;
|
|
a3.a3 = 136.0;
|
|
|
|
final result = passStructNestedIrregularEvenBiggerx4(a0, a1, a2, a3);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(1572.0, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
}
|
|
|
|
final passStruct8BytesInlineArrayIntx4 = ffiTestFunctions.lookupFunction<
|
|
Int32 Function(Struct8BytesInlineArrayInt, Struct8BytesInlineArrayInt,
|
|
Struct8BytesInlineArrayInt, Struct8BytesInlineArrayInt),
|
|
int Function(
|
|
Struct8BytesInlineArrayInt,
|
|
Struct8BytesInlineArrayInt,
|
|
Struct8BytesInlineArrayInt,
|
|
Struct8BytesInlineArrayInt)>("PassStruct8BytesInlineArrayIntx4");
|
|
|
|
/// Simple struct with inline array.
|
|
void testPassStruct8BytesInlineArrayIntx4() {
|
|
final a0Pointer = calloc<Struct8BytesInlineArrayInt>();
|
|
final Struct8BytesInlineArrayInt a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<Struct8BytesInlineArrayInt>();
|
|
final Struct8BytesInlineArrayInt a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<Struct8BytesInlineArrayInt>();
|
|
final Struct8BytesInlineArrayInt a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<Struct8BytesInlineArrayInt>();
|
|
final Struct8BytesInlineArrayInt a3 = a3Pointer.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;
|
|
a1.a0[0] = 9;
|
|
a1.a0[1] = 10;
|
|
a1.a0[2] = 11;
|
|
a1.a0[3] = 12;
|
|
a1.a0[4] = 13;
|
|
a1.a0[5] = 14;
|
|
a1.a0[6] = 15;
|
|
a1.a0[7] = 16;
|
|
a2.a0[0] = 17;
|
|
a2.a0[1] = 18;
|
|
a2.a0[2] = 19;
|
|
a2.a0[3] = 20;
|
|
a2.a0[4] = 21;
|
|
a2.a0[5] = 22;
|
|
a2.a0[6] = 23;
|
|
a2.a0[7] = 24;
|
|
a3.a0[0] = 25;
|
|
a3.a0[1] = 26;
|
|
a3.a0[2] = 27;
|
|
a3.a0[3] = 28;
|
|
a3.a0[4] = 29;
|
|
a3.a0[5] = 30;
|
|
a3.a0[6] = 31;
|
|
a3.a0[7] = 32;
|
|
|
|
final result = passStruct8BytesInlineArrayIntx4(a0, a1, a2, a3);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(528, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
}
|
|
|
|
final passStructInlineArrayIrregularx4 = ffiTestFunctions.lookupFunction<
|
|
Int32 Function(StructInlineArrayIrregular, StructInlineArrayIrregular,
|
|
StructInlineArrayIrregular, StructInlineArrayIrregular),
|
|
int Function(
|
|
StructInlineArrayIrregular,
|
|
StructInlineArrayIrregular,
|
|
StructInlineArrayIrregular,
|
|
StructInlineArrayIrregular)>("PassStructInlineArrayIrregularx4");
|
|
|
|
/// Irregular struct with inline array.
|
|
void testPassStructInlineArrayIrregularx4() {
|
|
final a0Pointer = calloc<StructInlineArrayIrregular>();
|
|
final StructInlineArrayIrregular a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<StructInlineArrayIrregular>();
|
|
final StructInlineArrayIrregular a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<StructInlineArrayIrregular>();
|
|
final StructInlineArrayIrregular a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<StructInlineArrayIrregular>();
|
|
final StructInlineArrayIrregular a3 = a3Pointer.ref;
|
|
|
|
a0.a0[0].a0 = -1;
|
|
a0.a0[0].a1 = 2;
|
|
a0.a0[1].a0 = -3;
|
|
a0.a0[1].a1 = 4;
|
|
a0.a1 = 5;
|
|
a1.a0[0].a0 = 6;
|
|
a1.a0[0].a1 = -7;
|
|
a1.a0[1].a0 = 8;
|
|
a1.a0[1].a1 = -9;
|
|
a1.a1 = 10;
|
|
a2.a0[0].a0 = -11;
|
|
a2.a0[0].a1 = 12;
|
|
a2.a0[1].a0 = -13;
|
|
a2.a0[1].a1 = 14;
|
|
a2.a1 = 15;
|
|
a3.a0[0].a0 = 16;
|
|
a3.a0[0].a1 = -17;
|
|
a3.a0[1].a0 = 18;
|
|
a3.a0[1].a1 = -19;
|
|
a3.a1 = 20;
|
|
|
|
final result = passStructInlineArrayIrregularx4(a0, a1, a2, a3);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(50, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
}
|
|
|
|
final passStructInlineArray100Bytes = ffiTestFunctions.lookupFunction<
|
|
Int32 Function(StructInlineArray100Bytes),
|
|
int Function(StructInlineArray100Bytes)>("PassStructInlineArray100Bytes");
|
|
|
|
/// Regular larger struct with inline array.
|
|
void testPassStructInlineArray100Bytes() {
|
|
final a0Pointer = calloc<StructInlineArray100Bytes>();
|
|
final StructInlineArray100Bytes 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;
|
|
a0.a0[8] = 9;
|
|
a0.a0[9] = 10;
|
|
a0.a0[10] = 11;
|
|
a0.a0[11] = 12;
|
|
a0.a0[12] = 13;
|
|
a0.a0[13] = 14;
|
|
a0.a0[14] = 15;
|
|
a0.a0[15] = 16;
|
|
a0.a0[16] = 17;
|
|
a0.a0[17] = 18;
|
|
a0.a0[18] = 19;
|
|
a0.a0[19] = 20;
|
|
a0.a0[20] = 21;
|
|
a0.a0[21] = 22;
|
|
a0.a0[22] = 23;
|
|
a0.a0[23] = 24;
|
|
a0.a0[24] = 25;
|
|
a0.a0[25] = 26;
|
|
a0.a0[26] = 27;
|
|
a0.a0[27] = 28;
|
|
a0.a0[28] = 29;
|
|
a0.a0[29] = 30;
|
|
a0.a0[30] = 31;
|
|
a0.a0[31] = 32;
|
|
a0.a0[32] = 33;
|
|
a0.a0[33] = 34;
|
|
a0.a0[34] = 35;
|
|
a0.a0[35] = 36;
|
|
a0.a0[36] = 37;
|
|
a0.a0[37] = 38;
|
|
a0.a0[38] = 39;
|
|
a0.a0[39] = 40;
|
|
a0.a0[40] = 41;
|
|
a0.a0[41] = 42;
|
|
a0.a0[42] = 43;
|
|
a0.a0[43] = 44;
|
|
a0.a0[44] = 45;
|
|
a0.a0[45] = 46;
|
|
a0.a0[46] = 47;
|
|
a0.a0[47] = 48;
|
|
a0.a0[48] = 49;
|
|
a0.a0[49] = 50;
|
|
a0.a0[50] = 51;
|
|
a0.a0[51] = 52;
|
|
a0.a0[52] = 53;
|
|
a0.a0[53] = 54;
|
|
a0.a0[54] = 55;
|
|
a0.a0[55] = 56;
|
|
a0.a0[56] = 57;
|
|
a0.a0[57] = 58;
|
|
a0.a0[58] = 59;
|
|
a0.a0[59] = 60;
|
|
a0.a0[60] = 61;
|
|
a0.a0[61] = 62;
|
|
a0.a0[62] = 63;
|
|
a0.a0[63] = 64;
|
|
a0.a0[64] = 65;
|
|
a0.a0[65] = 66;
|
|
a0.a0[66] = 67;
|
|
a0.a0[67] = 68;
|
|
a0.a0[68] = 69;
|
|
a0.a0[69] = 70;
|
|
a0.a0[70] = 71;
|
|
a0.a0[71] = 72;
|
|
a0.a0[72] = 73;
|
|
a0.a0[73] = 74;
|
|
a0.a0[74] = 75;
|
|
a0.a0[75] = 76;
|
|
a0.a0[76] = 77;
|
|
a0.a0[77] = 78;
|
|
a0.a0[78] = 79;
|
|
a0.a0[79] = 80;
|
|
a0.a0[80] = 81;
|
|
a0.a0[81] = 82;
|
|
a0.a0[82] = 83;
|
|
a0.a0[83] = 84;
|
|
a0.a0[84] = 85;
|
|
a0.a0[85] = 86;
|
|
a0.a0[86] = 87;
|
|
a0.a0[87] = 88;
|
|
a0.a0[88] = 89;
|
|
a0.a0[89] = 90;
|
|
a0.a0[90] = 91;
|
|
a0.a0[91] = 92;
|
|
a0.a0[92] = 93;
|
|
a0.a0[93] = 94;
|
|
a0.a0[94] = 95;
|
|
a0.a0[95] = 96;
|
|
a0.a0[96] = 97;
|
|
a0.a0[97] = 98;
|
|
a0.a0[98] = 99;
|
|
a0.a0[99] = 100;
|
|
|
|
final result = passStructInlineArray100Bytes(a0);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(5050, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
}
|
|
|
|
final passStructStruct16BytesHomogeneousFloat2x5 =
|
|
ffiTestFunctions.lookupFunction<
|
|
Float Function(
|
|
StructStruct16BytesHomogeneousFloat2,
|
|
StructStruct16BytesHomogeneousFloat2,
|
|
StructStruct16BytesHomogeneousFloat2,
|
|
StructStruct16BytesHomogeneousFloat2,
|
|
StructStruct16BytesHomogeneousFloat2),
|
|
double Function(
|
|
StructStruct16BytesHomogeneousFloat2,
|
|
StructStruct16BytesHomogeneousFloat2,
|
|
StructStruct16BytesHomogeneousFloat2,
|
|
StructStruct16BytesHomogeneousFloat2,
|
|
StructStruct16BytesHomogeneousFloat2)>(
|
|
"PassStructStruct16BytesHomogeneousFloat2x5");
|
|
|
|
/// Arguments in FPU registers on arm hardfp and arm64.
|
|
/// 5 struct arguments will exhaust available registers.
|
|
void testPassStructStruct16BytesHomogeneousFloat2x5() {
|
|
final a0Pointer = calloc<StructStruct16BytesHomogeneousFloat2>();
|
|
final StructStruct16BytesHomogeneousFloat2 a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<StructStruct16BytesHomogeneousFloat2>();
|
|
final StructStruct16BytesHomogeneousFloat2 a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<StructStruct16BytesHomogeneousFloat2>();
|
|
final StructStruct16BytesHomogeneousFloat2 a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<StructStruct16BytesHomogeneousFloat2>();
|
|
final StructStruct16BytesHomogeneousFloat2 a3 = a3Pointer.ref;
|
|
final a4Pointer = calloc<StructStruct16BytesHomogeneousFloat2>();
|
|
final StructStruct16BytesHomogeneousFloat2 a4 = a4Pointer.ref;
|
|
|
|
a0.a0.a0 = -1.0;
|
|
a0.a1[0].a0 = 2.0;
|
|
a0.a1[1].a0 = -3.0;
|
|
a0.a2 = 4.0;
|
|
a1.a0.a0 = -5.0;
|
|
a1.a1[0].a0 = 6.0;
|
|
a1.a1[1].a0 = -7.0;
|
|
a1.a2 = 8.0;
|
|
a2.a0.a0 = -9.0;
|
|
a2.a1[0].a0 = 10.0;
|
|
a2.a1[1].a0 = -11.0;
|
|
a2.a2 = 12.0;
|
|
a3.a0.a0 = -13.0;
|
|
a3.a1[0].a0 = 14.0;
|
|
a3.a1[1].a0 = -15.0;
|
|
a3.a2 = 16.0;
|
|
a4.a0.a0 = -17.0;
|
|
a4.a1[0].a0 = 18.0;
|
|
a4.a1[1].a0 = -19.0;
|
|
a4.a2 = 20.0;
|
|
|
|
final result = passStructStruct16BytesHomogeneousFloat2x5(a0, a1, a2, a3, a4);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(10.0, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a4Pointer);
|
|
}
|
|
|
|
final passStructStruct32BytesHomogeneousDouble2x5 =
|
|
ffiTestFunctions.lookupFunction<
|
|
Double Function(
|
|
StructStruct32BytesHomogeneousDouble2,
|
|
StructStruct32BytesHomogeneousDouble2,
|
|
StructStruct32BytesHomogeneousDouble2,
|
|
StructStruct32BytesHomogeneousDouble2,
|
|
StructStruct32BytesHomogeneousDouble2),
|
|
double Function(
|
|
StructStruct32BytesHomogeneousDouble2,
|
|
StructStruct32BytesHomogeneousDouble2,
|
|
StructStruct32BytesHomogeneousDouble2,
|
|
StructStruct32BytesHomogeneousDouble2,
|
|
StructStruct32BytesHomogeneousDouble2)>(
|
|
"PassStructStruct32BytesHomogeneousDouble2x5");
|
|
|
|
/// Arguments in FPU registers on arm64.
|
|
/// 5 struct arguments will exhaust available registers.
|
|
void testPassStructStruct32BytesHomogeneousDouble2x5() {
|
|
final a0Pointer = calloc<StructStruct32BytesHomogeneousDouble2>();
|
|
final StructStruct32BytesHomogeneousDouble2 a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<StructStruct32BytesHomogeneousDouble2>();
|
|
final StructStruct32BytesHomogeneousDouble2 a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<StructStruct32BytesHomogeneousDouble2>();
|
|
final StructStruct32BytesHomogeneousDouble2 a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<StructStruct32BytesHomogeneousDouble2>();
|
|
final StructStruct32BytesHomogeneousDouble2 a3 = a3Pointer.ref;
|
|
final a4Pointer = calloc<StructStruct32BytesHomogeneousDouble2>();
|
|
final StructStruct32BytesHomogeneousDouble2 a4 = a4Pointer.ref;
|
|
|
|
a0.a0.a0 = -1.0;
|
|
a0.a1[0].a0 = 2.0;
|
|
a0.a1[1].a0 = -3.0;
|
|
a0.a2 = 4.0;
|
|
a1.a0.a0 = -5.0;
|
|
a1.a1[0].a0 = 6.0;
|
|
a1.a1[1].a0 = -7.0;
|
|
a1.a2 = 8.0;
|
|
a2.a0.a0 = -9.0;
|
|
a2.a1[0].a0 = 10.0;
|
|
a2.a1[1].a0 = -11.0;
|
|
a2.a2 = 12.0;
|
|
a3.a0.a0 = -13.0;
|
|
a3.a1[0].a0 = 14.0;
|
|
a3.a1[1].a0 = -15.0;
|
|
a3.a2 = 16.0;
|
|
a4.a0.a0 = -17.0;
|
|
a4.a1[0].a0 = 18.0;
|
|
a4.a1[1].a0 = -19.0;
|
|
a4.a2 = 20.0;
|
|
|
|
final result =
|
|
passStructStruct32BytesHomogeneousDouble2x5(a0, a1, a2, a3, a4);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(10.0, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a4Pointer);
|
|
}
|
|
|
|
final passStructStruct16BytesMixed3x10 = ffiTestFunctions.lookupFunction<
|
|
Float Function(
|
|
StructStruct16BytesMixed3,
|
|
StructStruct16BytesMixed3,
|
|
StructStruct16BytesMixed3,
|
|
StructStruct16BytesMixed3,
|
|
StructStruct16BytesMixed3,
|
|
StructStruct16BytesMixed3,
|
|
StructStruct16BytesMixed3,
|
|
StructStruct16BytesMixed3,
|
|
StructStruct16BytesMixed3,
|
|
StructStruct16BytesMixed3),
|
|
double Function(
|
|
StructStruct16BytesMixed3,
|
|
StructStruct16BytesMixed3,
|
|
StructStruct16BytesMixed3,
|
|
StructStruct16BytesMixed3,
|
|
StructStruct16BytesMixed3,
|
|
StructStruct16BytesMixed3,
|
|
StructStruct16BytesMixed3,
|
|
StructStruct16BytesMixed3,
|
|
StructStruct16BytesMixed3,
|
|
StructStruct16BytesMixed3)>("PassStructStruct16BytesMixed3x10");
|
|
|
|
/// On x64, arguments are split over FP and int registers.
|
|
/// On x64, it will exhaust the integer registers with the 6th argument.
|
|
/// The rest goes on the stack.
|
|
/// On arm, arguments are 4 byte aligned.
|
|
void testPassStructStruct16BytesMixed3x10() {
|
|
final a0Pointer = calloc<StructStruct16BytesMixed3>();
|
|
final StructStruct16BytesMixed3 a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<StructStruct16BytesMixed3>();
|
|
final StructStruct16BytesMixed3 a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<StructStruct16BytesMixed3>();
|
|
final StructStruct16BytesMixed3 a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<StructStruct16BytesMixed3>();
|
|
final StructStruct16BytesMixed3 a3 = a3Pointer.ref;
|
|
final a4Pointer = calloc<StructStruct16BytesMixed3>();
|
|
final StructStruct16BytesMixed3 a4 = a4Pointer.ref;
|
|
final a5Pointer = calloc<StructStruct16BytesMixed3>();
|
|
final StructStruct16BytesMixed3 a5 = a5Pointer.ref;
|
|
final a6Pointer = calloc<StructStruct16BytesMixed3>();
|
|
final StructStruct16BytesMixed3 a6 = a6Pointer.ref;
|
|
final a7Pointer = calloc<StructStruct16BytesMixed3>();
|
|
final StructStruct16BytesMixed3 a7 = a7Pointer.ref;
|
|
final a8Pointer = calloc<StructStruct16BytesMixed3>();
|
|
final StructStruct16BytesMixed3 a8 = a8Pointer.ref;
|
|
final a9Pointer = calloc<StructStruct16BytesMixed3>();
|
|
final StructStruct16BytesMixed3 a9 = a9Pointer.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;
|
|
a1.a0.a0 = -7.0;
|
|
a1.a1[0].a0 = 8.0;
|
|
a1.a1[0].a1 = -9;
|
|
a1.a1[0].a2 = 10;
|
|
a1.a2[0] = -11;
|
|
a1.a2[1] = 12;
|
|
a2.a0.a0 = -13.0;
|
|
a2.a1[0].a0 = 14.0;
|
|
a2.a1[0].a1 = -15;
|
|
a2.a1[0].a2 = 16;
|
|
a2.a2[0] = -17;
|
|
a2.a2[1] = 18;
|
|
a3.a0.a0 = -19.0;
|
|
a3.a1[0].a0 = 20.0;
|
|
a3.a1[0].a1 = -21;
|
|
a3.a1[0].a2 = 22;
|
|
a3.a2[0] = -23;
|
|
a3.a2[1] = 24;
|
|
a4.a0.a0 = -25.0;
|
|
a4.a1[0].a0 = 26.0;
|
|
a4.a1[0].a1 = -27;
|
|
a4.a1[0].a2 = 28;
|
|
a4.a2[0] = -29;
|
|
a4.a2[1] = 30;
|
|
a5.a0.a0 = -31.0;
|
|
a5.a1[0].a0 = 32.0;
|
|
a5.a1[0].a1 = -33;
|
|
a5.a1[0].a2 = 34;
|
|
a5.a2[0] = -35;
|
|
a5.a2[1] = 36;
|
|
a6.a0.a0 = -37.0;
|
|
a6.a1[0].a0 = 38.0;
|
|
a6.a1[0].a1 = -39;
|
|
a6.a1[0].a2 = 40;
|
|
a6.a2[0] = -41;
|
|
a6.a2[1] = 42;
|
|
a7.a0.a0 = -43.0;
|
|
a7.a1[0].a0 = 44.0;
|
|
a7.a1[0].a1 = -45;
|
|
a7.a1[0].a2 = 46;
|
|
a7.a2[0] = -47;
|
|
a7.a2[1] = 48;
|
|
a8.a0.a0 = -49.0;
|
|
a8.a1[0].a0 = 50.0;
|
|
a8.a1[0].a1 = -51;
|
|
a8.a1[0].a2 = 52;
|
|
a8.a2[0] = -53;
|
|
a8.a2[1] = 54;
|
|
a9.a0.a0 = -55.0;
|
|
a9.a1[0].a0 = 56.0;
|
|
a9.a1[0].a1 = -57;
|
|
a9.a1[0].a2 = 58;
|
|
a9.a2[0] = -59;
|
|
a9.a2[1] = 60;
|
|
|
|
final result =
|
|
passStructStruct16BytesMixed3x10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(30.0, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a4Pointer);
|
|
calloc.free(a5Pointer);
|
|
calloc.free(a6Pointer);
|
|
calloc.free(a7Pointer);
|
|
calloc.free(a8Pointer);
|
|
calloc.free(a9Pointer);
|
|
}
|
|
|
|
final passUint8Struct32BytesInlineArrayMultiDimensionalI =
|
|
ffiTestFunctions.lookupFunction<
|
|
Uint32 Function(
|
|
Uint8,
|
|
Struct32BytesInlineArrayMultiDimensionalInt,
|
|
Uint8,
|
|
Struct8BytesInlineArrayMultiDimensionalInt,
|
|
Uint8,
|
|
Struct8BytesInlineArrayMultiDimensionalInt,
|
|
Uint8),
|
|
int Function(
|
|
int,
|
|
Struct32BytesInlineArrayMultiDimensionalInt,
|
|
int,
|
|
Struct8BytesInlineArrayMultiDimensionalInt,
|
|
int,
|
|
Struct8BytesInlineArrayMultiDimensionalInt,
|
|
int)>("PassUint8Struct32BytesInlineArrayMultiDimensionalI");
|
|
|
|
/// Test multi dimensional inline array struct as argument.
|
|
void testPassUint8Struct32BytesInlineArrayMultiDimensionalI() {
|
|
int a0;
|
|
final a1Pointer = calloc<Struct32BytesInlineArrayMultiDimensionalInt>();
|
|
final Struct32BytesInlineArrayMultiDimensionalInt a1 = a1Pointer.ref;
|
|
int a2;
|
|
final a3Pointer = calloc<Struct8BytesInlineArrayMultiDimensionalInt>();
|
|
final Struct8BytesInlineArrayMultiDimensionalInt a3 = a3Pointer.ref;
|
|
int a4;
|
|
final a5Pointer = calloc<Struct8BytesInlineArrayMultiDimensionalInt>();
|
|
final Struct8BytesInlineArrayMultiDimensionalInt a5 = a5Pointer.ref;
|
|
int a6;
|
|
|
|
a0 = 1;
|
|
a1.a0[0][0][0][0][0] = 2;
|
|
a1.a0[0][0][0][0][1] = 3;
|
|
a1.a0[0][0][0][1][0] = 4;
|
|
a1.a0[0][0][0][1][1] = 5;
|
|
a1.a0[0][0][1][0][0] = 6;
|
|
a1.a0[0][0][1][0][1] = 7;
|
|
a1.a0[0][0][1][1][0] = 8;
|
|
a1.a0[0][0][1][1][1] = 9;
|
|
a1.a0[0][1][0][0][0] = 10;
|
|
a1.a0[0][1][0][0][1] = 11;
|
|
a1.a0[0][1][0][1][0] = 12;
|
|
a1.a0[0][1][0][1][1] = 13;
|
|
a1.a0[0][1][1][0][0] = 14;
|
|
a1.a0[0][1][1][0][1] = 15;
|
|
a1.a0[0][1][1][1][0] = 16;
|
|
a1.a0[0][1][1][1][1] = 17;
|
|
a1.a0[1][0][0][0][0] = 18;
|
|
a1.a0[1][0][0][0][1] = 19;
|
|
a1.a0[1][0][0][1][0] = 20;
|
|
a1.a0[1][0][0][1][1] = 21;
|
|
a1.a0[1][0][1][0][0] = 22;
|
|
a1.a0[1][0][1][0][1] = 23;
|
|
a1.a0[1][0][1][1][0] = 24;
|
|
a1.a0[1][0][1][1][1] = 25;
|
|
a1.a0[1][1][0][0][0] = 26;
|
|
a1.a0[1][1][0][0][1] = 27;
|
|
a1.a0[1][1][0][1][0] = 28;
|
|
a1.a0[1][1][0][1][1] = 29;
|
|
a1.a0[1][1][1][0][0] = 30;
|
|
a1.a0[1][1][1][0][1] = 31;
|
|
a1.a0[1][1][1][1][0] = 32;
|
|
a1.a0[1][1][1][1][1] = 33;
|
|
a2 = 34;
|
|
a3.a0[0][0][0] = 35;
|
|
a3.a0[0][0][1] = 36;
|
|
a3.a0[0][1][0] = 37;
|
|
a3.a0[0][1][1] = 38;
|
|
a3.a0[1][0][0] = 39;
|
|
a3.a0[1][0][1] = 40;
|
|
a3.a0[1][1][0] = 41;
|
|
a3.a0[1][1][1] = 42;
|
|
a4 = 43;
|
|
a5.a0[0][0][0] = 44;
|
|
a5.a0[0][0][1] = 45;
|
|
a5.a0[0][1][0] = 46;
|
|
a5.a0[0][1][1] = 47;
|
|
a5.a0[1][0][0] = 48;
|
|
a5.a0[1][0][1] = 49;
|
|
a5.a0[1][1][0] = 50;
|
|
a5.a0[1][1][1] = 51;
|
|
a6 = 52;
|
|
|
|
final result = passUint8Struct32BytesInlineArrayMultiDimensionalI(
|
|
a0, a1, a2, a3, a4, a5, a6);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(1378, result);
|
|
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a5Pointer);
|
|
}
|
|
|
|
final passUint8Struct4BytesInlineArrayMultiDimensionalIn =
|
|
ffiTestFunctions.lookupFunction<
|
|
Uint32 Function(
|
|
Uint8, Struct4BytesInlineArrayMultiDimensionalInt, Uint8),
|
|
int Function(int, Struct4BytesInlineArrayMultiDimensionalInt,
|
|
int)>("PassUint8Struct4BytesInlineArrayMultiDimensionalIn");
|
|
|
|
/// Test struct in multi dimensional inline array.
|
|
void testPassUint8Struct4BytesInlineArrayMultiDimensionalIn() {
|
|
int a0;
|
|
final a1Pointer = calloc<Struct4BytesInlineArrayMultiDimensionalInt>();
|
|
final Struct4BytesInlineArrayMultiDimensionalInt a1 = a1Pointer.ref;
|
|
int a2;
|
|
|
|
a0 = 1;
|
|
a1.a0[0][0].a0 = 2;
|
|
a1.a0[0][1].a0 = -3;
|
|
a1.a0[1][0].a0 = 4;
|
|
a1.a0[1][1].a0 = -5;
|
|
a2 = 6;
|
|
|
|
final result = passUint8Struct4BytesInlineArrayMultiDimensionalIn(a0, a1, a2);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(5, result);
|
|
|
|
calloc.free(a1Pointer);
|
|
}
|
|
|
|
final passStruct3BytesPackedIntx10 = ffiTestFunctions.lookupFunction<
|
|
Int64 Function(
|
|
Struct3BytesPackedInt,
|
|
Struct3BytesPackedInt,
|
|
Struct3BytesPackedInt,
|
|
Struct3BytesPackedInt,
|
|
Struct3BytesPackedInt,
|
|
Struct3BytesPackedInt,
|
|
Struct3BytesPackedInt,
|
|
Struct3BytesPackedInt,
|
|
Struct3BytesPackedInt,
|
|
Struct3BytesPackedInt),
|
|
int Function(
|
|
Struct3BytesPackedInt,
|
|
Struct3BytesPackedInt,
|
|
Struct3BytesPackedInt,
|
|
Struct3BytesPackedInt,
|
|
Struct3BytesPackedInt,
|
|
Struct3BytesPackedInt,
|
|
Struct3BytesPackedInt,
|
|
Struct3BytesPackedInt,
|
|
Struct3BytesPackedInt,
|
|
Struct3BytesPackedInt)>("PassStruct3BytesPackedIntx10");
|
|
|
|
/// Small struct with mis-aligned member.
|
|
void testPassStruct3BytesPackedIntx10() {
|
|
final a0Pointer = calloc<Struct3BytesPackedInt>();
|
|
final Struct3BytesPackedInt a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<Struct3BytesPackedInt>();
|
|
final Struct3BytesPackedInt a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<Struct3BytesPackedInt>();
|
|
final Struct3BytesPackedInt a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<Struct3BytesPackedInt>();
|
|
final Struct3BytesPackedInt a3 = a3Pointer.ref;
|
|
final a4Pointer = calloc<Struct3BytesPackedInt>();
|
|
final Struct3BytesPackedInt a4 = a4Pointer.ref;
|
|
final a5Pointer = calloc<Struct3BytesPackedInt>();
|
|
final Struct3BytesPackedInt a5 = a5Pointer.ref;
|
|
final a6Pointer = calloc<Struct3BytesPackedInt>();
|
|
final Struct3BytesPackedInt a6 = a6Pointer.ref;
|
|
final a7Pointer = calloc<Struct3BytesPackedInt>();
|
|
final Struct3BytesPackedInt a7 = a7Pointer.ref;
|
|
final a8Pointer = calloc<Struct3BytesPackedInt>();
|
|
final Struct3BytesPackedInt a8 = a8Pointer.ref;
|
|
final a9Pointer = calloc<Struct3BytesPackedInt>();
|
|
final Struct3BytesPackedInt a9 = a9Pointer.ref;
|
|
|
|
a0.a0 = -1;
|
|
a0.a1 = 2;
|
|
a1.a0 = -3;
|
|
a1.a1 = 4;
|
|
a2.a0 = -5;
|
|
a2.a1 = 6;
|
|
a3.a0 = -7;
|
|
a3.a1 = 8;
|
|
a4.a0 = -9;
|
|
a4.a1 = 10;
|
|
a5.a0 = -11;
|
|
a5.a1 = 12;
|
|
a6.a0 = -13;
|
|
a6.a1 = 14;
|
|
a7.a0 = -15;
|
|
a7.a1 = 16;
|
|
a8.a0 = -17;
|
|
a8.a1 = 18;
|
|
a9.a0 = -19;
|
|
a9.a1 = 20;
|
|
|
|
final result =
|
|
passStruct3BytesPackedIntx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(10, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a4Pointer);
|
|
calloc.free(a5Pointer);
|
|
calloc.free(a6Pointer);
|
|
calloc.free(a7Pointer);
|
|
calloc.free(a8Pointer);
|
|
calloc.free(a9Pointer);
|
|
}
|
|
|
|
final passStruct8BytesPackedIntx10 = ffiTestFunctions.lookupFunction<
|
|
Int64 Function(
|
|
Struct8BytesPackedInt,
|
|
Struct8BytesPackedInt,
|
|
Struct8BytesPackedInt,
|
|
Struct8BytesPackedInt,
|
|
Struct8BytesPackedInt,
|
|
Struct8BytesPackedInt,
|
|
Struct8BytesPackedInt,
|
|
Struct8BytesPackedInt,
|
|
Struct8BytesPackedInt,
|
|
Struct8BytesPackedInt),
|
|
int Function(
|
|
Struct8BytesPackedInt,
|
|
Struct8BytesPackedInt,
|
|
Struct8BytesPackedInt,
|
|
Struct8BytesPackedInt,
|
|
Struct8BytesPackedInt,
|
|
Struct8BytesPackedInt,
|
|
Struct8BytesPackedInt,
|
|
Struct8BytesPackedInt,
|
|
Struct8BytesPackedInt,
|
|
Struct8BytesPackedInt)>("PassStruct8BytesPackedIntx10");
|
|
|
|
/// Struct with mis-aligned member.
|
|
void testPassStruct8BytesPackedIntx10() {
|
|
final a0Pointer = calloc<Struct8BytesPackedInt>();
|
|
final Struct8BytesPackedInt a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<Struct8BytesPackedInt>();
|
|
final Struct8BytesPackedInt a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<Struct8BytesPackedInt>();
|
|
final Struct8BytesPackedInt a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<Struct8BytesPackedInt>();
|
|
final Struct8BytesPackedInt a3 = a3Pointer.ref;
|
|
final a4Pointer = calloc<Struct8BytesPackedInt>();
|
|
final Struct8BytesPackedInt a4 = a4Pointer.ref;
|
|
final a5Pointer = calloc<Struct8BytesPackedInt>();
|
|
final Struct8BytesPackedInt a5 = a5Pointer.ref;
|
|
final a6Pointer = calloc<Struct8BytesPackedInt>();
|
|
final Struct8BytesPackedInt a6 = a6Pointer.ref;
|
|
final a7Pointer = calloc<Struct8BytesPackedInt>();
|
|
final Struct8BytesPackedInt a7 = a7Pointer.ref;
|
|
final a8Pointer = calloc<Struct8BytesPackedInt>();
|
|
final Struct8BytesPackedInt a8 = a8Pointer.ref;
|
|
final a9Pointer = calloc<Struct8BytesPackedInt>();
|
|
final Struct8BytesPackedInt a9 = a9Pointer.ref;
|
|
|
|
a0.a0 = 1;
|
|
a0.a1 = 2;
|
|
a0.a2 = 3;
|
|
a0.a3 = 4;
|
|
a0.a4 = 5;
|
|
a1.a0 = 6;
|
|
a1.a1 = 7;
|
|
a1.a2 = 8;
|
|
a1.a3 = 9;
|
|
a1.a4 = 10;
|
|
a2.a0 = 11;
|
|
a2.a1 = 12;
|
|
a2.a2 = 13;
|
|
a2.a3 = 14;
|
|
a2.a4 = 15;
|
|
a3.a0 = 16;
|
|
a3.a1 = 17;
|
|
a3.a2 = 18;
|
|
a3.a3 = 19;
|
|
a3.a4 = 20;
|
|
a4.a0 = 21;
|
|
a4.a1 = 22;
|
|
a4.a2 = 23;
|
|
a4.a3 = 24;
|
|
a4.a4 = 25;
|
|
a5.a0 = 26;
|
|
a5.a1 = 27;
|
|
a5.a2 = 28;
|
|
a5.a3 = 29;
|
|
a5.a4 = 30;
|
|
a6.a0 = 31;
|
|
a6.a1 = 32;
|
|
a6.a2 = 33;
|
|
a6.a3 = 34;
|
|
a6.a4 = 35;
|
|
a7.a0 = 36;
|
|
a7.a1 = 37;
|
|
a7.a2 = 38;
|
|
a7.a3 = 39;
|
|
a7.a4 = 40;
|
|
a8.a0 = 41;
|
|
a8.a1 = 42;
|
|
a8.a2 = 43;
|
|
a8.a3 = 44;
|
|
a8.a4 = 45;
|
|
a9.a0 = 46;
|
|
a9.a1 = 47;
|
|
a9.a2 = 48;
|
|
a9.a3 = 49;
|
|
a9.a4 = 50;
|
|
|
|
final result =
|
|
passStruct8BytesPackedIntx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(1275, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a4Pointer);
|
|
calloc.free(a5Pointer);
|
|
calloc.free(a6Pointer);
|
|
calloc.free(a7Pointer);
|
|
calloc.free(a8Pointer);
|
|
calloc.free(a9Pointer);
|
|
}
|
|
|
|
final passStruct9BytesPackedMixedx10DoubleInt32x2 =
|
|
ffiTestFunctions.lookupFunction<
|
|
Double Function(
|
|
Struct9BytesPackedMixed,
|
|
Struct9BytesPackedMixed,
|
|
Struct9BytesPackedMixed,
|
|
Struct9BytesPackedMixed,
|
|
Struct9BytesPackedMixed,
|
|
Struct9BytesPackedMixed,
|
|
Struct9BytesPackedMixed,
|
|
Struct9BytesPackedMixed,
|
|
Struct9BytesPackedMixed,
|
|
Struct9BytesPackedMixed,
|
|
Double,
|
|
Int32,
|
|
Int32),
|
|
double Function(
|
|
Struct9BytesPackedMixed,
|
|
Struct9BytesPackedMixed,
|
|
Struct9BytesPackedMixed,
|
|
Struct9BytesPackedMixed,
|
|
Struct9BytesPackedMixed,
|
|
Struct9BytesPackedMixed,
|
|
Struct9BytesPackedMixed,
|
|
Struct9BytesPackedMixed,
|
|
Struct9BytesPackedMixed,
|
|
Struct9BytesPackedMixed,
|
|
double,
|
|
int,
|
|
int)>("PassStruct9BytesPackedMixedx10DoubleInt32x2");
|
|
|
|
/// Struct with mis-aligned member.
|
|
/// Tests backfilling of CPU and FPU registers.
|
|
void testPassStruct9BytesPackedMixedx10DoubleInt32x2() {
|
|
final a0Pointer = calloc<Struct9BytesPackedMixed>();
|
|
final Struct9BytesPackedMixed a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<Struct9BytesPackedMixed>();
|
|
final Struct9BytesPackedMixed a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<Struct9BytesPackedMixed>();
|
|
final Struct9BytesPackedMixed a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<Struct9BytesPackedMixed>();
|
|
final Struct9BytesPackedMixed a3 = a3Pointer.ref;
|
|
final a4Pointer = calloc<Struct9BytesPackedMixed>();
|
|
final Struct9BytesPackedMixed a4 = a4Pointer.ref;
|
|
final a5Pointer = calloc<Struct9BytesPackedMixed>();
|
|
final Struct9BytesPackedMixed a5 = a5Pointer.ref;
|
|
final a6Pointer = calloc<Struct9BytesPackedMixed>();
|
|
final Struct9BytesPackedMixed a6 = a6Pointer.ref;
|
|
final a7Pointer = calloc<Struct9BytesPackedMixed>();
|
|
final Struct9BytesPackedMixed a7 = a7Pointer.ref;
|
|
final a8Pointer = calloc<Struct9BytesPackedMixed>();
|
|
final Struct9BytesPackedMixed a8 = a8Pointer.ref;
|
|
final a9Pointer = calloc<Struct9BytesPackedMixed>();
|
|
final Struct9BytesPackedMixed a9 = a9Pointer.ref;
|
|
double a10;
|
|
int a11;
|
|
int a12;
|
|
|
|
a0.a0 = 1;
|
|
a0.a1 = 2.0;
|
|
a1.a0 = 3;
|
|
a1.a1 = 4.0;
|
|
a2.a0 = 5;
|
|
a2.a1 = 6.0;
|
|
a3.a0 = 7;
|
|
a3.a1 = 8.0;
|
|
a4.a0 = 9;
|
|
a4.a1 = 10.0;
|
|
a5.a0 = 11;
|
|
a5.a1 = 12.0;
|
|
a6.a0 = 13;
|
|
a6.a1 = 14.0;
|
|
a7.a0 = 15;
|
|
a7.a1 = 16.0;
|
|
a8.a0 = 17;
|
|
a8.a1 = 18.0;
|
|
a9.a0 = 19;
|
|
a9.a1 = 20.0;
|
|
a10 = -21.0;
|
|
a11 = 22;
|
|
a12 = -23;
|
|
|
|
final result = passStruct9BytesPackedMixedx10DoubleInt32x2(
|
|
a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(188.0, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a4Pointer);
|
|
calloc.free(a5Pointer);
|
|
calloc.free(a6Pointer);
|
|
calloc.free(a7Pointer);
|
|
calloc.free(a8Pointer);
|
|
calloc.free(a9Pointer);
|
|
}
|
|
|
|
final passStruct5BytesPackedMixed = ffiTestFunctions.lookupFunction<
|
|
Double Function(Struct5BytesPackedMixed),
|
|
double Function(Struct5BytesPackedMixed)>("PassStruct5BytesPackedMixed");
|
|
|
|
/// This packed struct happens to have only aligned members.
|
|
void testPassStruct5BytesPackedMixed() {
|
|
final a0Pointer = calloc<Struct5BytesPackedMixed>();
|
|
final Struct5BytesPackedMixed a0 = a0Pointer.ref;
|
|
|
|
a0.a0 = -1.0;
|
|
a0.a1 = 2;
|
|
|
|
final result = passStruct5BytesPackedMixed(a0);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(1.0, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
}
|
|
|
|
final passStructNestedAlignmentStruct5BytesPackedMixed =
|
|
ffiTestFunctions.lookupFunction<
|
|
Double Function(StructNestedAlignmentStruct5BytesPackedMixed),
|
|
double Function(StructNestedAlignmentStruct5BytesPackedMixed)>(
|
|
"PassStructNestedAlignmentStruct5BytesPackedMixed");
|
|
|
|
/// Check alignment of packed struct in non-packed struct.
|
|
void testPassStructNestedAlignmentStruct5BytesPackedMixed() {
|
|
final a0Pointer = calloc<StructNestedAlignmentStruct5BytesPackedMixed>();
|
|
final StructNestedAlignmentStruct5BytesPackedMixed a0 = a0Pointer.ref;
|
|
|
|
a0.a0 = 1;
|
|
a0.a1.a0 = 2.0;
|
|
a0.a1.a1 = 3;
|
|
|
|
final result = passStructNestedAlignmentStruct5BytesPackedMixed(a0);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(6.0, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
}
|
|
|
|
final passStruct6BytesInlineArrayInt = ffiTestFunctions.lookupFunction<
|
|
Double Function(Struct6BytesInlineArrayInt),
|
|
double Function(
|
|
Struct6BytesInlineArrayInt)>("PassStruct6BytesInlineArrayInt");
|
|
|
|
/// Check alignment of packed struct array in non-packed struct.
|
|
void testPassStruct6BytesInlineArrayInt() {
|
|
final a0Pointer = calloc<Struct6BytesInlineArrayInt>();
|
|
final Struct6BytesInlineArrayInt a0 = a0Pointer.ref;
|
|
|
|
a0.a0[0].a0 = -1;
|
|
a0.a0[0].a1 = 2;
|
|
a0.a0[1].a0 = -3;
|
|
a0.a0[1].a1 = 4;
|
|
|
|
final result = passStruct6BytesInlineArrayInt(a0);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(2.0, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
}
|
|
|
|
final passStruct15BytesInlineArrayMixed = ffiTestFunctions.lookupFunction<
|
|
Double Function(Struct15BytesInlineArrayMixed),
|
|
double Function(
|
|
Struct15BytesInlineArrayMixed)>("PassStruct15BytesInlineArrayMixed");
|
|
|
|
/// Check alignment of packed struct array in non-packed struct.
|
|
void testPassStruct15BytesInlineArrayMixed() {
|
|
final a0Pointer = calloc<Struct15BytesInlineArrayMixed>();
|
|
final Struct15BytesInlineArrayMixed a0 = a0Pointer.ref;
|
|
|
|
a0.a0[0].a0 = -1.0;
|
|
a0.a0[0].a1 = 2;
|
|
a0.a0[1].a0 = -3.0;
|
|
a0.a0[1].a1 = 4;
|
|
a0.a0[2].a0 = -5.0;
|
|
a0.a0[2].a1 = 6;
|
|
|
|
final result = passStruct15BytesInlineArrayMixed(a0);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(3.0, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
}
|
|
|
|
final passUnion4BytesMixedx10 = ffiTestFunctions.lookupFunction<
|
|
Double Function(
|
|
Union4BytesMixed,
|
|
Union4BytesMixed,
|
|
Union4BytesMixed,
|
|
Union4BytesMixed,
|
|
Union4BytesMixed,
|
|
Union4BytesMixed,
|
|
Union4BytesMixed,
|
|
Union4BytesMixed,
|
|
Union4BytesMixed,
|
|
Union4BytesMixed),
|
|
double Function(
|
|
Union4BytesMixed,
|
|
Union4BytesMixed,
|
|
Union4BytesMixed,
|
|
Union4BytesMixed,
|
|
Union4BytesMixed,
|
|
Union4BytesMixed,
|
|
Union4BytesMixed,
|
|
Union4BytesMixed,
|
|
Union4BytesMixed,
|
|
Union4BytesMixed)>("PassUnion4BytesMixedx10");
|
|
|
|
/// Check placement of mixed integer/float union.
|
|
void testPassUnion4BytesMixedx10() {
|
|
final a0Pointer = calloc<Union4BytesMixed>();
|
|
final Union4BytesMixed a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<Union4BytesMixed>();
|
|
final Union4BytesMixed a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<Union4BytesMixed>();
|
|
final Union4BytesMixed a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<Union4BytesMixed>();
|
|
final Union4BytesMixed a3 = a3Pointer.ref;
|
|
final a4Pointer = calloc<Union4BytesMixed>();
|
|
final Union4BytesMixed a4 = a4Pointer.ref;
|
|
final a5Pointer = calloc<Union4BytesMixed>();
|
|
final Union4BytesMixed a5 = a5Pointer.ref;
|
|
final a6Pointer = calloc<Union4BytesMixed>();
|
|
final Union4BytesMixed a6 = a6Pointer.ref;
|
|
final a7Pointer = calloc<Union4BytesMixed>();
|
|
final Union4BytesMixed a7 = a7Pointer.ref;
|
|
final a8Pointer = calloc<Union4BytesMixed>();
|
|
final Union4BytesMixed a8 = a8Pointer.ref;
|
|
final a9Pointer = calloc<Union4BytesMixed>();
|
|
final Union4BytesMixed a9 = a9Pointer.ref;
|
|
|
|
a0.a0 = 1;
|
|
a1.a0 = 2;
|
|
a2.a0 = 3;
|
|
a3.a0 = 4;
|
|
a4.a0 = 5;
|
|
a5.a0 = 6;
|
|
a6.a0 = 7;
|
|
a7.a0 = 8;
|
|
a8.a0 = 9;
|
|
a9.a0 = 10;
|
|
|
|
final result =
|
|
passUnion4BytesMixedx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(55.0, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a4Pointer);
|
|
calloc.free(a5Pointer);
|
|
calloc.free(a6Pointer);
|
|
calloc.free(a7Pointer);
|
|
calloc.free(a8Pointer);
|
|
calloc.free(a9Pointer);
|
|
}
|
|
|
|
final passUnion8BytesNestedFloatx10 = ffiTestFunctions.lookupFunction<
|
|
Double Function(
|
|
Union8BytesNestedFloat,
|
|
Union8BytesNestedFloat,
|
|
Union8BytesNestedFloat,
|
|
Union8BytesNestedFloat,
|
|
Union8BytesNestedFloat,
|
|
Union8BytesNestedFloat,
|
|
Union8BytesNestedFloat,
|
|
Union8BytesNestedFloat,
|
|
Union8BytesNestedFloat,
|
|
Union8BytesNestedFloat),
|
|
double Function(
|
|
Union8BytesNestedFloat,
|
|
Union8BytesNestedFloat,
|
|
Union8BytesNestedFloat,
|
|
Union8BytesNestedFloat,
|
|
Union8BytesNestedFloat,
|
|
Union8BytesNestedFloat,
|
|
Union8BytesNestedFloat,
|
|
Union8BytesNestedFloat,
|
|
Union8BytesNestedFloat,
|
|
Union8BytesNestedFloat)>("PassUnion8BytesNestedFloatx10");
|
|
|
|
/// Check placement of mixed floats union.
|
|
void testPassUnion8BytesNestedFloatx10() {
|
|
final a0Pointer = calloc<Union8BytesNestedFloat>();
|
|
final Union8BytesNestedFloat a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<Union8BytesNestedFloat>();
|
|
final Union8BytesNestedFloat a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<Union8BytesNestedFloat>();
|
|
final Union8BytesNestedFloat a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<Union8BytesNestedFloat>();
|
|
final Union8BytesNestedFloat a3 = a3Pointer.ref;
|
|
final a4Pointer = calloc<Union8BytesNestedFloat>();
|
|
final Union8BytesNestedFloat a4 = a4Pointer.ref;
|
|
final a5Pointer = calloc<Union8BytesNestedFloat>();
|
|
final Union8BytesNestedFloat a5 = a5Pointer.ref;
|
|
final a6Pointer = calloc<Union8BytesNestedFloat>();
|
|
final Union8BytesNestedFloat a6 = a6Pointer.ref;
|
|
final a7Pointer = calloc<Union8BytesNestedFloat>();
|
|
final Union8BytesNestedFloat a7 = a7Pointer.ref;
|
|
final a8Pointer = calloc<Union8BytesNestedFloat>();
|
|
final Union8BytesNestedFloat a8 = a8Pointer.ref;
|
|
final a9Pointer = calloc<Union8BytesNestedFloat>();
|
|
final Union8BytesNestedFloat a9 = a9Pointer.ref;
|
|
|
|
a0.a0 = -1.0;
|
|
a1.a0 = 2.0;
|
|
a2.a0 = -3.0;
|
|
a3.a0 = 4.0;
|
|
a4.a0 = -5.0;
|
|
a5.a0 = 6.0;
|
|
a6.a0 = -7.0;
|
|
a7.a0 = 8.0;
|
|
a8.a0 = -9.0;
|
|
a9.a0 = 10.0;
|
|
|
|
final result =
|
|
passUnion8BytesNestedFloatx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(5.0, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a4Pointer);
|
|
calloc.free(a5Pointer);
|
|
calloc.free(a6Pointer);
|
|
calloc.free(a7Pointer);
|
|
calloc.free(a8Pointer);
|
|
calloc.free(a9Pointer);
|
|
}
|
|
|
|
final passUnion9BytesNestedIntx10 = ffiTestFunctions.lookupFunction<
|
|
Double Function(
|
|
Union9BytesNestedInt,
|
|
Union9BytesNestedInt,
|
|
Union9BytesNestedInt,
|
|
Union9BytesNestedInt,
|
|
Union9BytesNestedInt,
|
|
Union9BytesNestedInt,
|
|
Union9BytesNestedInt,
|
|
Union9BytesNestedInt,
|
|
Union9BytesNestedInt,
|
|
Union9BytesNestedInt),
|
|
double Function(
|
|
Union9BytesNestedInt,
|
|
Union9BytesNestedInt,
|
|
Union9BytesNestedInt,
|
|
Union9BytesNestedInt,
|
|
Union9BytesNestedInt,
|
|
Union9BytesNestedInt,
|
|
Union9BytesNestedInt,
|
|
Union9BytesNestedInt,
|
|
Union9BytesNestedInt,
|
|
Union9BytesNestedInt)>("PassUnion9BytesNestedIntx10");
|
|
|
|
/// Mixed-size union argument.
|
|
void testPassUnion9BytesNestedIntx10() {
|
|
final a0Pointer = calloc<Union9BytesNestedInt>();
|
|
final Union9BytesNestedInt a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<Union9BytesNestedInt>();
|
|
final Union9BytesNestedInt a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<Union9BytesNestedInt>();
|
|
final Union9BytesNestedInt a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<Union9BytesNestedInt>();
|
|
final Union9BytesNestedInt a3 = a3Pointer.ref;
|
|
final a4Pointer = calloc<Union9BytesNestedInt>();
|
|
final Union9BytesNestedInt a4 = a4Pointer.ref;
|
|
final a5Pointer = calloc<Union9BytesNestedInt>();
|
|
final Union9BytesNestedInt a5 = a5Pointer.ref;
|
|
final a6Pointer = calloc<Union9BytesNestedInt>();
|
|
final Union9BytesNestedInt a6 = a6Pointer.ref;
|
|
final a7Pointer = calloc<Union9BytesNestedInt>();
|
|
final Union9BytesNestedInt a7 = a7Pointer.ref;
|
|
final a8Pointer = calloc<Union9BytesNestedInt>();
|
|
final Union9BytesNestedInt a8 = a8Pointer.ref;
|
|
final a9Pointer = calloc<Union9BytesNestedInt>();
|
|
final Union9BytesNestedInt a9 = a9Pointer.ref;
|
|
|
|
a0.a0.a0 = -1;
|
|
a0.a0.a1 = 2;
|
|
a0.a0.a2 = -3;
|
|
a1.a0.a0 = 4;
|
|
a1.a0.a1 = -5;
|
|
a1.a0.a2 = 6;
|
|
a2.a0.a0 = -7;
|
|
a2.a0.a1 = 8;
|
|
a2.a0.a2 = -9;
|
|
a3.a0.a0 = 10;
|
|
a3.a0.a1 = -11;
|
|
a3.a0.a2 = 12;
|
|
a4.a0.a0 = -13;
|
|
a4.a0.a1 = 14;
|
|
a4.a0.a2 = -15;
|
|
a5.a0.a0 = 16;
|
|
a5.a0.a1 = -17;
|
|
a5.a0.a2 = 18;
|
|
a6.a0.a0 = -19;
|
|
a6.a0.a1 = 20;
|
|
a6.a0.a2 = -21;
|
|
a7.a0.a0 = 22;
|
|
a7.a0.a1 = -23;
|
|
a7.a0.a2 = 24;
|
|
a8.a0.a0 = -25;
|
|
a8.a0.a1 = 26;
|
|
a8.a0.a2 = -27;
|
|
a9.a0.a0 = 28;
|
|
a9.a0.a1 = -29;
|
|
a9.a0.a2 = 30;
|
|
|
|
final result =
|
|
passUnion9BytesNestedIntx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(15.0, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a4Pointer);
|
|
calloc.free(a5Pointer);
|
|
calloc.free(a6Pointer);
|
|
calloc.free(a7Pointer);
|
|
calloc.free(a8Pointer);
|
|
calloc.free(a9Pointer);
|
|
}
|
|
|
|
final passUnion16BytesNestedInlineArrayFloatx10 =
|
|
ffiTestFunctions.lookupFunction<
|
|
Double Function(
|
|
Union16BytesNestedInlineArrayFloat,
|
|
Union16BytesNestedInlineArrayFloat,
|
|
Union16BytesNestedInlineArrayFloat,
|
|
Union16BytesNestedInlineArrayFloat,
|
|
Union16BytesNestedInlineArrayFloat,
|
|
Union16BytesNestedInlineArrayFloat,
|
|
Union16BytesNestedInlineArrayFloat,
|
|
Union16BytesNestedInlineArrayFloat,
|
|
Union16BytesNestedInlineArrayFloat,
|
|
Union16BytesNestedInlineArrayFloat),
|
|
double Function(
|
|
Union16BytesNestedInlineArrayFloat,
|
|
Union16BytesNestedInlineArrayFloat,
|
|
Union16BytesNestedInlineArrayFloat,
|
|
Union16BytesNestedInlineArrayFloat,
|
|
Union16BytesNestedInlineArrayFloat,
|
|
Union16BytesNestedInlineArrayFloat,
|
|
Union16BytesNestedInlineArrayFloat,
|
|
Union16BytesNestedInlineArrayFloat,
|
|
Union16BytesNestedInlineArrayFloat,
|
|
Union16BytesNestedInlineArrayFloat)>(
|
|
"PassUnion16BytesNestedInlineArrayFloatx10");
|
|
|
|
/// Union with homogenous floats.
|
|
void testPassUnion16BytesNestedInlineArrayFloatx10() {
|
|
final a0Pointer = calloc<Union16BytesNestedInlineArrayFloat>();
|
|
final Union16BytesNestedInlineArrayFloat a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<Union16BytesNestedInlineArrayFloat>();
|
|
final Union16BytesNestedInlineArrayFloat a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<Union16BytesNestedInlineArrayFloat>();
|
|
final Union16BytesNestedInlineArrayFloat a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<Union16BytesNestedInlineArrayFloat>();
|
|
final Union16BytesNestedInlineArrayFloat a3 = a3Pointer.ref;
|
|
final a4Pointer = calloc<Union16BytesNestedInlineArrayFloat>();
|
|
final Union16BytesNestedInlineArrayFloat a4 = a4Pointer.ref;
|
|
final a5Pointer = calloc<Union16BytesNestedInlineArrayFloat>();
|
|
final Union16BytesNestedInlineArrayFloat a5 = a5Pointer.ref;
|
|
final a6Pointer = calloc<Union16BytesNestedInlineArrayFloat>();
|
|
final Union16BytesNestedInlineArrayFloat a6 = a6Pointer.ref;
|
|
final a7Pointer = calloc<Union16BytesNestedInlineArrayFloat>();
|
|
final Union16BytesNestedInlineArrayFloat a7 = a7Pointer.ref;
|
|
final a8Pointer = calloc<Union16BytesNestedInlineArrayFloat>();
|
|
final Union16BytesNestedInlineArrayFloat a8 = a8Pointer.ref;
|
|
final a9Pointer = calloc<Union16BytesNestedInlineArrayFloat>();
|
|
final Union16BytesNestedInlineArrayFloat a9 = a9Pointer.ref;
|
|
|
|
a0.a0[0] = -1.0;
|
|
a0.a0[1] = 2.0;
|
|
a0.a0[2] = -3.0;
|
|
a0.a0[3] = 4.0;
|
|
a1.a0[0] = -5.0;
|
|
a1.a0[1] = 6.0;
|
|
a1.a0[2] = -7.0;
|
|
a1.a0[3] = 8.0;
|
|
a2.a0[0] = -9.0;
|
|
a2.a0[1] = 10.0;
|
|
a2.a0[2] = -11.0;
|
|
a2.a0[3] = 12.0;
|
|
a3.a0[0] = -13.0;
|
|
a3.a0[1] = 14.0;
|
|
a3.a0[2] = -15.0;
|
|
a3.a0[3] = 16.0;
|
|
a4.a0[0] = -17.0;
|
|
a4.a0[1] = 18.0;
|
|
a4.a0[2] = -19.0;
|
|
a4.a0[3] = 20.0;
|
|
a5.a0[0] = -21.0;
|
|
a5.a0[1] = 22.0;
|
|
a5.a0[2] = -23.0;
|
|
a5.a0[3] = 24.0;
|
|
a6.a0[0] = -25.0;
|
|
a6.a0[1] = 26.0;
|
|
a6.a0[2] = -27.0;
|
|
a6.a0[3] = 28.0;
|
|
a7.a0[0] = -29.0;
|
|
a7.a0[1] = 30.0;
|
|
a7.a0[2] = -31.0;
|
|
a7.a0[3] = 32.0;
|
|
a8.a0[0] = -33.0;
|
|
a8.a0[1] = 34.0;
|
|
a8.a0[2] = -35.0;
|
|
a8.a0[3] = 36.0;
|
|
a9.a0[0] = -37.0;
|
|
a9.a0[1] = 38.0;
|
|
a9.a0[2] = -39.0;
|
|
a9.a0[3] = 40.0;
|
|
|
|
final result = passUnion16BytesNestedInlineArrayFloatx10(
|
|
a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(20.0, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a4Pointer);
|
|
calloc.free(a5Pointer);
|
|
calloc.free(a6Pointer);
|
|
calloc.free(a7Pointer);
|
|
calloc.free(a8Pointer);
|
|
calloc.free(a9Pointer);
|
|
}
|
|
|
|
final passUnion16BytesNestedFloatx10 = ffiTestFunctions.lookupFunction<
|
|
Double Function(
|
|
Union16BytesNestedFloat,
|
|
Union16BytesNestedFloat,
|
|
Union16BytesNestedFloat,
|
|
Union16BytesNestedFloat,
|
|
Union16BytesNestedFloat,
|
|
Union16BytesNestedFloat,
|
|
Union16BytesNestedFloat,
|
|
Union16BytesNestedFloat,
|
|
Union16BytesNestedFloat,
|
|
Union16BytesNestedFloat),
|
|
double Function(
|
|
Union16BytesNestedFloat,
|
|
Union16BytesNestedFloat,
|
|
Union16BytesNestedFloat,
|
|
Union16BytesNestedFloat,
|
|
Union16BytesNestedFloat,
|
|
Union16BytesNestedFloat,
|
|
Union16BytesNestedFloat,
|
|
Union16BytesNestedFloat,
|
|
Union16BytesNestedFloat,
|
|
Union16BytesNestedFloat)>("PassUnion16BytesNestedFloatx10");
|
|
|
|
/// Union with homogenous floats.
|
|
void testPassUnion16BytesNestedFloatx10() {
|
|
final a0Pointer = calloc<Union16BytesNestedFloat>();
|
|
final Union16BytesNestedFloat a0 = a0Pointer.ref;
|
|
final a1Pointer = calloc<Union16BytesNestedFloat>();
|
|
final Union16BytesNestedFloat a1 = a1Pointer.ref;
|
|
final a2Pointer = calloc<Union16BytesNestedFloat>();
|
|
final Union16BytesNestedFloat a2 = a2Pointer.ref;
|
|
final a3Pointer = calloc<Union16BytesNestedFloat>();
|
|
final Union16BytesNestedFloat a3 = a3Pointer.ref;
|
|
final a4Pointer = calloc<Union16BytesNestedFloat>();
|
|
final Union16BytesNestedFloat a4 = a4Pointer.ref;
|
|
final a5Pointer = calloc<Union16BytesNestedFloat>();
|
|
final Union16BytesNestedFloat a5 = a5Pointer.ref;
|
|
final a6Pointer = calloc<Union16BytesNestedFloat>();
|
|
final Union16BytesNestedFloat a6 = a6Pointer.ref;
|
|
final a7Pointer = calloc<Union16BytesNestedFloat>();
|
|
final Union16BytesNestedFloat a7 = a7Pointer.ref;
|
|
final a8Pointer = calloc<Union16BytesNestedFloat>();
|
|
final Union16BytesNestedFloat a8 = a8Pointer.ref;
|
|
final a9Pointer = calloc<Union16BytesNestedFloat>();
|
|
final Union16BytesNestedFloat a9 = a9Pointer.ref;
|
|
|
|
a0.a0.a0 = -1.0;
|
|
a0.a0.a1 = 2.0;
|
|
a1.a0.a0 = -3.0;
|
|
a1.a0.a1 = 4.0;
|
|
a2.a0.a0 = -5.0;
|
|
a2.a0.a1 = 6.0;
|
|
a3.a0.a0 = -7.0;
|
|
a3.a0.a1 = 8.0;
|
|
a4.a0.a0 = -9.0;
|
|
a4.a0.a1 = 10.0;
|
|
a5.a0.a0 = -11.0;
|
|
a5.a0.a1 = 12.0;
|
|
a6.a0.a0 = -13.0;
|
|
a6.a0.a1 = 14.0;
|
|
a7.a0.a0 = -15.0;
|
|
a7.a0.a1 = 16.0;
|
|
a8.a0.a0 = -17.0;
|
|
a8.a0.a1 = 18.0;
|
|
a9.a0.a0 = -19.0;
|
|
a9.a0.a1 = 20.0;
|
|
|
|
final result =
|
|
passUnion16BytesNestedFloatx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(10.0, result);
|
|
|
|
calloc.free(a0Pointer);
|
|
calloc.free(a1Pointer);
|
|
calloc.free(a2Pointer);
|
|
calloc.free(a3Pointer);
|
|
calloc.free(a4Pointer);
|
|
calloc.free(a5Pointer);
|
|
calloc.free(a6Pointer);
|
|
calloc.free(a7Pointer);
|
|
calloc.free(a8Pointer);
|
|
calloc.free(a9Pointer);
|
|
}
|
|
|
|
final passUint8Boolx9Struct10BytesHomogeneousBoolBool =
|
|
ffiTestFunctions.lookupFunction<
|
|
Int32 Function(Uint8, Bool, Bool, Bool, Bool, Bool, Bool, Bool, Bool,
|
|
Bool, Struct10BytesHomogeneousBool, Bool),
|
|
int Function(
|
|
int,
|
|
bool,
|
|
bool,
|
|
bool,
|
|
bool,
|
|
bool,
|
|
bool,
|
|
bool,
|
|
bool,
|
|
bool,
|
|
Struct10BytesHomogeneousBool,
|
|
bool)>("PassUint8Boolx9Struct10BytesHomogeneousBoolBool");
|
|
|
|
/// Passing bools and a struct with bools.
|
|
/// Exhausts the registers to test bools and the bool struct alignment on the
|
|
/// stack.
|
|
void testPassUint8Boolx9Struct10BytesHomogeneousBoolBool() {
|
|
int a0;
|
|
bool a1;
|
|
bool a2;
|
|
bool a3;
|
|
bool a4;
|
|
bool a5;
|
|
bool a6;
|
|
bool a7;
|
|
bool a8;
|
|
bool a9;
|
|
final a10Pointer = calloc<Struct10BytesHomogeneousBool>();
|
|
final Struct10BytesHomogeneousBool a10 = a10Pointer.ref;
|
|
bool a11;
|
|
|
|
a0 = 1;
|
|
a1 = false;
|
|
a2 = true;
|
|
a3 = false;
|
|
a4 = true;
|
|
a5 = false;
|
|
a6 = true;
|
|
a7 = false;
|
|
a8 = true;
|
|
a9 = false;
|
|
a10.a0 = true;
|
|
a10.a1 = false;
|
|
a10.a2 = true;
|
|
a10.a3 = false;
|
|
a10.a4 = true;
|
|
a10.a5 = false;
|
|
a10.a6 = true;
|
|
a10.a7 = false;
|
|
a10.a8 = true;
|
|
a10.a9 = false;
|
|
a11 = true;
|
|
|
|
final result = passUint8Boolx9Struct10BytesHomogeneousBoolBool(
|
|
a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(11, result);
|
|
|
|
calloc.free(a10Pointer);
|
|
}
|
|
|
|
final passUint8Boolx9Struct10BytesInlineArrayBoolBool =
|
|
ffiTestFunctions.lookupFunction<
|
|
Int32 Function(Uint8, Bool, Bool, Bool, Bool, Bool, Bool, Bool, Bool,
|
|
Bool, Struct10BytesInlineArrayBool, Bool),
|
|
int Function(
|
|
int,
|
|
bool,
|
|
bool,
|
|
bool,
|
|
bool,
|
|
bool,
|
|
bool,
|
|
bool,
|
|
bool,
|
|
bool,
|
|
Struct10BytesInlineArrayBool,
|
|
bool)>("PassUint8Boolx9Struct10BytesInlineArrayBoolBool");
|
|
|
|
/// Passing bools and a struct with bools.
|
|
/// Exhausts the registers to test bools and the bool struct alignment on the
|
|
/// stack.
|
|
void testPassUint8Boolx9Struct10BytesInlineArrayBoolBool() {
|
|
int a0;
|
|
bool a1;
|
|
bool a2;
|
|
bool a3;
|
|
bool a4;
|
|
bool a5;
|
|
bool a6;
|
|
bool a7;
|
|
bool a8;
|
|
bool a9;
|
|
final a10Pointer = calloc<Struct10BytesInlineArrayBool>();
|
|
final Struct10BytesInlineArrayBool a10 = a10Pointer.ref;
|
|
bool a11;
|
|
|
|
a0 = 1;
|
|
a1 = false;
|
|
a2 = true;
|
|
a3 = false;
|
|
a4 = true;
|
|
a5 = false;
|
|
a6 = true;
|
|
a7 = false;
|
|
a8 = true;
|
|
a9 = false;
|
|
a10.a0[0] = true;
|
|
a10.a0[1] = false;
|
|
a10.a0[2] = true;
|
|
a10.a0[3] = false;
|
|
a10.a0[4] = true;
|
|
a10.a0[5] = false;
|
|
a10.a0[6] = true;
|
|
a10.a0[7] = false;
|
|
a10.a0[8] = true;
|
|
a10.a0[9] = false;
|
|
a11 = true;
|
|
|
|
final result = passUint8Boolx9Struct10BytesInlineArrayBoolBool(
|
|
a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(11, result);
|
|
|
|
calloc.free(a10Pointer);
|
|
}
|
|
|
|
final passUint8Struct1ByteBool = ffiTestFunctions.lookupFunction<
|
|
Bool Function(Uint8, Struct1ByteBool),
|
|
bool Function(int, Struct1ByteBool)>("PassUint8Struct1ByteBool");
|
|
|
|
/// Returning a bool.
|
|
void testPassUint8Struct1ByteBool() {
|
|
int a0;
|
|
final a1Pointer = calloc<Struct1ByteBool>();
|
|
final Struct1ByteBool a1 = a1Pointer.ref;
|
|
|
|
a0 = 1;
|
|
a1.a0 = false;
|
|
|
|
final result = passUint8Struct1ByteBool(a0, a1);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(1 % 2 != 0, result);
|
|
|
|
calloc.free(a1Pointer);
|
|
}
|
|
|
|
final passWCharStructInlineArrayIntUintPtrx2LongUnsigned =
|
|
ffiTestFunctions.lookupFunction<
|
|
WChar Function(
|
|
WChar, StructInlineArrayInt, UintPtr, UintPtr, Long, UnsignedLong),
|
|
int Function(int, StructInlineArrayInt, int, int, int,
|
|
int)>("PassWCharStructInlineArrayIntUintPtrx2LongUnsigned");
|
|
|
|
/// Returning a wchar.
|
|
void testPassWCharStructInlineArrayIntUintPtrx2LongUnsigned() {
|
|
int a0;
|
|
final a1Pointer = calloc<StructInlineArrayInt>();
|
|
final StructInlineArrayInt a1 = a1Pointer.ref;
|
|
int a2;
|
|
int a3;
|
|
int a4;
|
|
int a5;
|
|
|
|
a0 = 1;
|
|
a1.a0[0] = 2;
|
|
a1.a0[1] = 3;
|
|
a1.a0[2] = 4;
|
|
a1.a0[3] = 5;
|
|
a1.a0[4] = 6;
|
|
a1.a0[5] = 7;
|
|
a1.a0[6] = 8;
|
|
a1.a0[7] = 9;
|
|
a1.a0[8] = 10;
|
|
a1.a0[9] = 11;
|
|
a2 = 12;
|
|
a3 = 13;
|
|
a4 = 14;
|
|
a5 = 15;
|
|
|
|
final result = passWCharStructInlineArrayIntUintPtrx2LongUnsigned(
|
|
a0, a1, a2, a3, a4, a5);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(120, result);
|
|
|
|
calloc.free(a1Pointer);
|
|
}
|
|
|
|
final returnStruct1ByteInt = ffiTestFunctions.lookupFunction<
|
|
Struct1ByteInt Function(Int8),
|
|
Struct1ByteInt Function(int)>("ReturnStruct1ByteInt");
|
|
|
|
/// Smallest struct with data.
|
|
void testReturnStruct1ByteInt() {
|
|
int a0;
|
|
|
|
a0 = -1;
|
|
|
|
final result = returnStruct1ByteInt(a0);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(a0, result.a0);
|
|
}
|
|
|
|
final returnStruct3BytesHomogeneousUint8 = ffiTestFunctions.lookupFunction<
|
|
Struct3BytesHomogeneousUint8 Function(Uint8, Uint8, Uint8),
|
|
Struct3BytesHomogeneousUint8 Function(
|
|
int, int, int)>("ReturnStruct3BytesHomogeneousUint8");
|
|
|
|
/// Smaller than word size return value on all architectures.
|
|
void testReturnStruct3BytesHomogeneousUint8() {
|
|
int a0;
|
|
int a1;
|
|
int a2;
|
|
|
|
a0 = 1;
|
|
a1 = 2;
|
|
a2 = 3;
|
|
|
|
final result = returnStruct3BytesHomogeneousUint8(a0, a1, a2);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(a0, result.a0);
|
|
Expect.equals(a1, result.a1);
|
|
Expect.equals(a2, result.a2);
|
|
}
|
|
|
|
final returnStruct3BytesInt2ByteAligned = ffiTestFunctions.lookupFunction<
|
|
Struct3BytesInt2ByteAligned Function(Int16, Int8),
|
|
Struct3BytesInt2ByteAligned Function(
|
|
int, int)>("ReturnStruct3BytesInt2ByteAligned");
|
|
|
|
/// Smaller than word size return value on all architectures.
|
|
/// With alignment rules taken into account size is 4 bytes.
|
|
void testReturnStruct3BytesInt2ByteAligned() {
|
|
int a0;
|
|
int a1;
|
|
|
|
a0 = -1;
|
|
a1 = 2;
|
|
|
|
final result = returnStruct3BytesInt2ByteAligned(a0, a1);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(a0, result.a0);
|
|
Expect.equals(a1, result.a1);
|
|
}
|
|
|
|
final returnStruct4BytesHomogeneousInt16 = ffiTestFunctions.lookupFunction<
|
|
Struct4BytesHomogeneousInt16 Function(Int16, Int16),
|
|
Struct4BytesHomogeneousInt16 Function(
|
|
int, int)>("ReturnStruct4BytesHomogeneousInt16");
|
|
|
|
/// Word size return value on 32 bit architectures..
|
|
void testReturnStruct4BytesHomogeneousInt16() {
|
|
int a0;
|
|
int a1;
|
|
|
|
a0 = -1;
|
|
a1 = 2;
|
|
|
|
final result = returnStruct4BytesHomogeneousInt16(a0, a1);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(a0, result.a0);
|
|
Expect.equals(a1, result.a1);
|
|
}
|
|
|
|
final returnStruct7BytesHomogeneousUint8 = ffiTestFunctions.lookupFunction<
|
|
Struct7BytesHomogeneousUint8 Function(
|
|
Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8),
|
|
Struct7BytesHomogeneousUint8 Function(int, int, int, int, int, int,
|
|
int)>("ReturnStruct7BytesHomogeneousUint8");
|
|
|
|
/// Non-wordsize return value.
|
|
void testReturnStruct7BytesHomogeneousUint8() {
|
|
int a0;
|
|
int a1;
|
|
int a2;
|
|
int a3;
|
|
int a4;
|
|
int a5;
|
|
int a6;
|
|
|
|
a0 = 1;
|
|
a1 = 2;
|
|
a2 = 3;
|
|
a3 = 4;
|
|
a4 = 5;
|
|
a5 = 6;
|
|
a6 = 7;
|
|
|
|
final result = returnStruct7BytesHomogeneousUint8(a0, a1, a2, a3, a4, a5, a6);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(a0, result.a0);
|
|
Expect.equals(a1, result.a1);
|
|
Expect.equals(a2, result.a2);
|
|
Expect.equals(a3, result.a3);
|
|
Expect.equals(a4, result.a4);
|
|
Expect.equals(a5, result.a5);
|
|
Expect.equals(a6, result.a6);
|
|
}
|
|
|
|
final returnStruct7BytesInt4ByteAligned = ffiTestFunctions.lookupFunction<
|
|
Struct7BytesInt4ByteAligned Function(Int32, Int16, Int8),
|
|
Struct7BytesInt4ByteAligned Function(
|
|
int, int, int)>("ReturnStruct7BytesInt4ByteAligned");
|
|
|
|
/// Non-wordsize return value.
|
|
/// With alignment rules taken into account size is 8 bytes.
|
|
void testReturnStruct7BytesInt4ByteAligned() {
|
|
int a0;
|
|
int a1;
|
|
int a2;
|
|
|
|
a0 = -1;
|
|
a1 = 2;
|
|
a2 = -3;
|
|
|
|
final result = returnStruct7BytesInt4ByteAligned(a0, a1, a2);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(a0, result.a0);
|
|
Expect.equals(a1, result.a1);
|
|
Expect.equals(a2, result.a2);
|
|
}
|
|
|
|
final returnStruct8BytesInt = ffiTestFunctions.lookupFunction<
|
|
Struct8BytesInt Function(Int16, Int16, Int32),
|
|
Struct8BytesInt Function(int, int, int)>("ReturnStruct8BytesInt");
|
|
|
|
/// Return value in integer registers on many architectures.
|
|
void testReturnStruct8BytesInt() {
|
|
int a0;
|
|
int a1;
|
|
int a2;
|
|
|
|
a0 = -1;
|
|
a1 = 2;
|
|
a2 = -3;
|
|
|
|
final result = returnStruct8BytesInt(a0, a1, a2);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(a0, result.a0);
|
|
Expect.equals(a1, result.a1);
|
|
Expect.equals(a2, result.a2);
|
|
}
|
|
|
|
final returnStruct8BytesHomogeneousFloat = ffiTestFunctions.lookupFunction<
|
|
Struct8BytesHomogeneousFloat Function(Float, Float),
|
|
Struct8BytesHomogeneousFloat Function(
|
|
double, double)>("ReturnStruct8BytesHomogeneousFloat");
|
|
|
|
/// Return value in FP registers on many architectures.
|
|
void testReturnStruct8BytesHomogeneousFloat() {
|
|
double a0;
|
|
double a1;
|
|
|
|
a0 = -1.0;
|
|
a1 = 2.0;
|
|
|
|
final result = returnStruct8BytesHomogeneousFloat(a0, a1);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(a0, result.a0);
|
|
Expect.approxEquals(a1, result.a1);
|
|
}
|
|
|
|
final returnStruct8BytesMixed = ffiTestFunctions.lookupFunction<
|
|
Struct8BytesMixed Function(Float, Int16, Int16),
|
|
Struct8BytesMixed Function(double, int, int)>("ReturnStruct8BytesMixed");
|
|
|
|
/// Return value split over FP and integer register in x64.
|
|
void testReturnStruct8BytesMixed() {
|
|
double a0;
|
|
int a1;
|
|
int a2;
|
|
|
|
a0 = -1.0;
|
|
a1 = 2;
|
|
a2 = -3;
|
|
|
|
final result = returnStruct8BytesMixed(a0, a1, a2);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(a0, result.a0);
|
|
Expect.equals(a1, result.a1);
|
|
Expect.equals(a2, result.a2);
|
|
}
|
|
|
|
final returnStruct9BytesHomogeneousUint8 = ffiTestFunctions.lookupFunction<
|
|
Struct9BytesHomogeneousUint8 Function(
|
|
Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8),
|
|
Struct9BytesHomogeneousUint8 Function(int, int, int, int, int, int, int,
|
|
int, int)>("ReturnStruct9BytesHomogeneousUint8");
|
|
|
|
/// The minimum alignment of this struct is only 1 byte based on its fields.
|
|
/// Test that the memory backing these structs is the right size and that
|
|
/// dart:ffi trampolines do not write outside this size.
|
|
void testReturnStruct9BytesHomogeneousUint8() {
|
|
int a0;
|
|
int a1;
|
|
int a2;
|
|
int a3;
|
|
int a4;
|
|
int a5;
|
|
int a6;
|
|
int a7;
|
|
int a8;
|
|
|
|
a0 = 1;
|
|
a1 = 2;
|
|
a2 = 3;
|
|
a3 = 4;
|
|
a4 = 5;
|
|
a5 = 6;
|
|
a6 = 7;
|
|
a7 = 8;
|
|
a8 = 9;
|
|
|
|
final result =
|
|
returnStruct9BytesHomogeneousUint8(a0, a1, a2, a3, a4, a5, a6, a7, a8);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(a0, result.a0);
|
|
Expect.equals(a1, result.a1);
|
|
Expect.equals(a2, result.a2);
|
|
Expect.equals(a3, result.a3);
|
|
Expect.equals(a4, result.a4);
|
|
Expect.equals(a5, result.a5);
|
|
Expect.equals(a6, result.a6);
|
|
Expect.equals(a7, result.a7);
|
|
Expect.equals(a8, result.a8);
|
|
}
|
|
|
|
final returnStruct9BytesInt4Or8ByteAligned = ffiTestFunctions.lookupFunction<
|
|
Struct9BytesInt4Or8ByteAligned Function(Int64, Int8),
|
|
Struct9BytesInt4Or8ByteAligned Function(
|
|
int, int)>("ReturnStruct9BytesInt4Or8ByteAligned");
|
|
|
|
/// Return value in two integer registers on x64.
|
|
/// With alignment rules taken into account size is 12 or 16 bytes.
|
|
void testReturnStruct9BytesInt4Or8ByteAligned() {
|
|
int a0;
|
|
int a1;
|
|
|
|
a0 = -1;
|
|
a1 = 2;
|
|
|
|
final result = returnStruct9BytesInt4Or8ByteAligned(a0, a1);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(a0, result.a0);
|
|
Expect.equals(a1, result.a1);
|
|
}
|
|
|
|
final returnStruct12BytesHomogeneousFloat = ffiTestFunctions.lookupFunction<
|
|
Struct12BytesHomogeneousFloat Function(Float, Float, Float),
|
|
Struct12BytesHomogeneousFloat Function(
|
|
double, double, double)>("ReturnStruct12BytesHomogeneousFloat");
|
|
|
|
/// Return value in FPU registers, but does not use all registers on arm hardfp
|
|
/// and arm64.
|
|
void testReturnStruct12BytesHomogeneousFloat() {
|
|
double a0;
|
|
double a1;
|
|
double a2;
|
|
|
|
a0 = -1.0;
|
|
a1 = 2.0;
|
|
a2 = -3.0;
|
|
|
|
final result = returnStruct12BytesHomogeneousFloat(a0, a1, a2);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(a0, result.a0);
|
|
Expect.approxEquals(a1, result.a1);
|
|
Expect.approxEquals(a2, result.a2);
|
|
}
|
|
|
|
final returnStruct16BytesHomogeneousFloat = ffiTestFunctions.lookupFunction<
|
|
Struct16BytesHomogeneousFloat Function(Float, Float, Float, Float),
|
|
Struct16BytesHomogeneousFloat Function(
|
|
double, double, double, double)>("ReturnStruct16BytesHomogeneousFloat");
|
|
|
|
/// Return value in FPU registers on arm hardfp and arm64.
|
|
void testReturnStruct16BytesHomogeneousFloat() {
|
|
double a0;
|
|
double a1;
|
|
double a2;
|
|
double a3;
|
|
|
|
a0 = -1.0;
|
|
a1 = 2.0;
|
|
a2 = -3.0;
|
|
a3 = 4.0;
|
|
|
|
final result = returnStruct16BytesHomogeneousFloat(a0, a1, a2, a3);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(a0, result.a0);
|
|
Expect.approxEquals(a1, result.a1);
|
|
Expect.approxEquals(a2, result.a2);
|
|
Expect.approxEquals(a3, result.a3);
|
|
}
|
|
|
|
final returnStruct16BytesMixed = ffiTestFunctions.lookupFunction<
|
|
Struct16BytesMixed Function(Double, Int64),
|
|
Struct16BytesMixed Function(double, int)>("ReturnStruct16BytesMixed");
|
|
|
|
/// Return value split over FP and integer register in x64.
|
|
void testReturnStruct16BytesMixed() {
|
|
double a0;
|
|
int a1;
|
|
|
|
a0 = -1.0;
|
|
a1 = 2;
|
|
|
|
final result = returnStruct16BytesMixed(a0, a1);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(a0, result.a0);
|
|
Expect.equals(a1, result.a1);
|
|
}
|
|
|
|
final returnStruct16BytesMixed2 = ffiTestFunctions.lookupFunction<
|
|
Struct16BytesMixed2 Function(Float, Float, Float, Int32),
|
|
Struct16BytesMixed2 Function(
|
|
double, double, double, int)>("ReturnStruct16BytesMixed2");
|
|
|
|
/// Return value split over FP and integer register in x64.
|
|
/// The integer register contains half float half int.
|
|
void testReturnStruct16BytesMixed2() {
|
|
double a0;
|
|
double a1;
|
|
double a2;
|
|
int a3;
|
|
|
|
a0 = -1.0;
|
|
a1 = 2.0;
|
|
a2 = -3.0;
|
|
a3 = 4;
|
|
|
|
final result = returnStruct16BytesMixed2(a0, a1, a2, a3);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(a0, result.a0);
|
|
Expect.approxEquals(a1, result.a1);
|
|
Expect.approxEquals(a2, result.a2);
|
|
Expect.equals(a3, result.a3);
|
|
}
|
|
|
|
final returnStruct17BytesInt = ffiTestFunctions.lookupFunction<
|
|
Struct17BytesInt Function(Int64, Int64, Int8),
|
|
Struct17BytesInt Function(int, int, int)>("ReturnStruct17BytesInt");
|
|
|
|
/// Rerturn value returned in preallocated space passed by pointer on most ABIs.
|
|
/// Is non word size on purpose, to test that structs are rounded up to word size
|
|
/// on all ABIs.
|
|
void testReturnStruct17BytesInt() {
|
|
int a0;
|
|
int a1;
|
|
int a2;
|
|
|
|
a0 = -1;
|
|
a1 = 2;
|
|
a2 = -3;
|
|
|
|
final result = returnStruct17BytesInt(a0, a1, a2);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(a0, result.a0);
|
|
Expect.equals(a1, result.a1);
|
|
Expect.equals(a2, result.a2);
|
|
}
|
|
|
|
final returnStruct19BytesHomogeneousUint8 = ffiTestFunctions.lookupFunction<
|
|
Struct19BytesHomogeneousUint8 Function(
|
|
Uint8,
|
|
Uint8,
|
|
Uint8,
|
|
Uint8,
|
|
Uint8,
|
|
Uint8,
|
|
Uint8,
|
|
Uint8,
|
|
Uint8,
|
|
Uint8,
|
|
Uint8,
|
|
Uint8,
|
|
Uint8,
|
|
Uint8,
|
|
Uint8,
|
|
Uint8,
|
|
Uint8,
|
|
Uint8,
|
|
Uint8),
|
|
Struct19BytesHomogeneousUint8 Function(
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int)>("ReturnStruct19BytesHomogeneousUint8");
|
|
|
|
/// The minimum alignment of this struct is only 1 byte based on its fields.
|
|
/// Test that the memory backing these structs is the right size and that
|
|
/// dart:ffi trampolines do not write outside this size.
|
|
void testReturnStruct19BytesHomogeneousUint8() {
|
|
int a0;
|
|
int a1;
|
|
int a2;
|
|
int a3;
|
|
int a4;
|
|
int a5;
|
|
int a6;
|
|
int a7;
|
|
int a8;
|
|
int a9;
|
|
int a10;
|
|
int a11;
|
|
int a12;
|
|
int a13;
|
|
int a14;
|
|
int a15;
|
|
int a16;
|
|
int a17;
|
|
int a18;
|
|
|
|
a0 = 1;
|
|
a1 = 2;
|
|
a2 = 3;
|
|
a3 = 4;
|
|
a4 = 5;
|
|
a5 = 6;
|
|
a6 = 7;
|
|
a7 = 8;
|
|
a8 = 9;
|
|
a9 = 10;
|
|
a10 = 11;
|
|
a11 = 12;
|
|
a12 = 13;
|
|
a13 = 14;
|
|
a14 = 15;
|
|
a15 = 16;
|
|
a16 = 17;
|
|
a17 = 18;
|
|
a18 = 19;
|
|
|
|
final result = returnStruct19BytesHomogeneousUint8(a0, a1, a2, a3, a4, a5, a6,
|
|
a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(a0, result.a0);
|
|
Expect.equals(a1, result.a1);
|
|
Expect.equals(a2, result.a2);
|
|
Expect.equals(a3, result.a3);
|
|
Expect.equals(a4, result.a4);
|
|
Expect.equals(a5, result.a5);
|
|
Expect.equals(a6, result.a6);
|
|
Expect.equals(a7, result.a7);
|
|
Expect.equals(a8, result.a8);
|
|
Expect.equals(a9, result.a9);
|
|
Expect.equals(a10, result.a10);
|
|
Expect.equals(a11, result.a11);
|
|
Expect.equals(a12, result.a12);
|
|
Expect.equals(a13, result.a13);
|
|
Expect.equals(a14, result.a14);
|
|
Expect.equals(a15, result.a15);
|
|
Expect.equals(a16, result.a16);
|
|
Expect.equals(a17, result.a17);
|
|
Expect.equals(a18, result.a18);
|
|
}
|
|
|
|
final returnStruct20BytesHomogeneousInt32 = ffiTestFunctions.lookupFunction<
|
|
Struct20BytesHomogeneousInt32 Function(Int32, Int32, Int32, Int32, Int32),
|
|
Struct20BytesHomogeneousInt32 Function(
|
|
int, int, int, int, int)>("ReturnStruct20BytesHomogeneousInt32");
|
|
|
|
/// Return value too big to go in cpu registers on arm64.
|
|
void testReturnStruct20BytesHomogeneousInt32() {
|
|
int a0;
|
|
int a1;
|
|
int a2;
|
|
int a3;
|
|
int a4;
|
|
|
|
a0 = -1;
|
|
a1 = 2;
|
|
a2 = -3;
|
|
a3 = 4;
|
|
a4 = -5;
|
|
|
|
final result = returnStruct20BytesHomogeneousInt32(a0, a1, a2, a3, a4);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(a0, result.a0);
|
|
Expect.equals(a1, result.a1);
|
|
Expect.equals(a2, result.a2);
|
|
Expect.equals(a3, result.a3);
|
|
Expect.equals(a4, result.a4);
|
|
}
|
|
|
|
final returnStruct20BytesHomogeneousFloat = ffiTestFunctions.lookupFunction<
|
|
Struct20BytesHomogeneousFloat Function(Float, Float, Float, Float, Float),
|
|
Struct20BytesHomogeneousFloat Function(double, double, double, double,
|
|
double)>("ReturnStruct20BytesHomogeneousFloat");
|
|
|
|
/// Return value too big to go in FPU registers on x64, arm hardfp and arm64.
|
|
void testReturnStruct20BytesHomogeneousFloat() {
|
|
double a0;
|
|
double a1;
|
|
double a2;
|
|
double a3;
|
|
double a4;
|
|
|
|
a0 = -1.0;
|
|
a1 = 2.0;
|
|
a2 = -3.0;
|
|
a3 = 4.0;
|
|
a4 = -5.0;
|
|
|
|
final result = returnStruct20BytesHomogeneousFloat(a0, a1, a2, a3, a4);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(a0, result.a0);
|
|
Expect.approxEquals(a1, result.a1);
|
|
Expect.approxEquals(a2, result.a2);
|
|
Expect.approxEquals(a3, result.a3);
|
|
Expect.approxEquals(a4, result.a4);
|
|
}
|
|
|
|
final returnStruct32BytesHomogeneousDouble = ffiTestFunctions.lookupFunction<
|
|
Struct32BytesHomogeneousDouble Function(Double, Double, Double, Double),
|
|
Struct32BytesHomogeneousDouble Function(double, double, double,
|
|
double)>("ReturnStruct32BytesHomogeneousDouble");
|
|
|
|
/// Return value in FPU registers on arm64.
|
|
void testReturnStruct32BytesHomogeneousDouble() {
|
|
double a0;
|
|
double a1;
|
|
double a2;
|
|
double a3;
|
|
|
|
a0 = -1.0;
|
|
a1 = 2.0;
|
|
a2 = -3.0;
|
|
a3 = 4.0;
|
|
|
|
final result = returnStruct32BytesHomogeneousDouble(a0, a1, a2, a3);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(a0, result.a0);
|
|
Expect.approxEquals(a1, result.a1);
|
|
Expect.approxEquals(a2, result.a2);
|
|
Expect.approxEquals(a3, result.a3);
|
|
}
|
|
|
|
final returnStruct40BytesHomogeneousDouble = ffiTestFunctions.lookupFunction<
|
|
Struct40BytesHomogeneousDouble Function(
|
|
Double, Double, Double, Double, Double),
|
|
Struct40BytesHomogeneousDouble Function(double, double, double, double,
|
|
double)>("ReturnStruct40BytesHomogeneousDouble");
|
|
|
|
/// Return value too big to go in FPU registers on arm64.
|
|
void testReturnStruct40BytesHomogeneousDouble() {
|
|
double a0;
|
|
double a1;
|
|
double a2;
|
|
double a3;
|
|
double a4;
|
|
|
|
a0 = -1.0;
|
|
a1 = 2.0;
|
|
a2 = -3.0;
|
|
a3 = 4.0;
|
|
a4 = -5.0;
|
|
|
|
final result = returnStruct40BytesHomogeneousDouble(a0, a1, a2, a3, a4);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(a0, result.a0);
|
|
Expect.approxEquals(a1, result.a1);
|
|
Expect.approxEquals(a2, result.a2);
|
|
Expect.approxEquals(a3, result.a3);
|
|
Expect.approxEquals(a4, result.a4);
|
|
}
|
|
|
|
final returnStruct1024BytesHomogeneousUint64 = ffiTestFunctions.lookupFunction<
|
|
Struct1024BytesHomogeneousUint64 Function(
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64,
|
|
Uint64),
|
|
Struct1024BytesHomogeneousUint64 Function(
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int,
|
|
int)>("ReturnStruct1024BytesHomogeneousUint64");
|
|
|
|
/// Test 1kb struct.
|
|
void testReturnStruct1024BytesHomogeneousUint64() {
|
|
int a0;
|
|
int a1;
|
|
int a2;
|
|
int a3;
|
|
int a4;
|
|
int a5;
|
|
int a6;
|
|
int a7;
|
|
int a8;
|
|
int a9;
|
|
int a10;
|
|
int a11;
|
|
int a12;
|
|
int a13;
|
|
int a14;
|
|
int a15;
|
|
int a16;
|
|
int a17;
|
|
int a18;
|
|
int a19;
|
|
int a20;
|
|
int a21;
|
|
int a22;
|
|
int a23;
|
|
int a24;
|
|
int a25;
|
|
int a26;
|
|
int a27;
|
|
int a28;
|
|
int a29;
|
|
int a30;
|
|
int a31;
|
|
int a32;
|
|
int a33;
|
|
int a34;
|
|
int a35;
|
|
int a36;
|
|
int a37;
|
|
int a38;
|
|
int a39;
|
|
int a40;
|
|
int a41;
|
|
int a42;
|
|
int a43;
|
|
int a44;
|
|
int a45;
|
|
int a46;
|
|
int a47;
|
|
int a48;
|
|
int a49;
|
|
int a50;
|
|
int a51;
|
|
int a52;
|
|
int a53;
|
|
int a54;
|
|
int a55;
|
|
int a56;
|
|
int a57;
|
|
int a58;
|
|
int a59;
|
|
int a60;
|
|
int a61;
|
|
int a62;
|
|
int a63;
|
|
int a64;
|
|
int a65;
|
|
int a66;
|
|
int a67;
|
|
int a68;
|
|
int a69;
|
|
int a70;
|
|
int a71;
|
|
int a72;
|
|
int a73;
|
|
int a74;
|
|
int a75;
|
|
int a76;
|
|
int a77;
|
|
int a78;
|
|
int a79;
|
|
int a80;
|
|
int a81;
|
|
int a82;
|
|
int a83;
|
|
int a84;
|
|
int a85;
|
|
int a86;
|
|
int a87;
|
|
int a88;
|
|
int a89;
|
|
int a90;
|
|
int a91;
|
|
int a92;
|
|
int a93;
|
|
int a94;
|
|
int a95;
|
|
int a96;
|
|
int a97;
|
|
int a98;
|
|
int a99;
|
|
int a100;
|
|
int a101;
|
|
int a102;
|
|
int a103;
|
|
int a104;
|
|
int a105;
|
|
int a106;
|
|
int a107;
|
|
int a108;
|
|
int a109;
|
|
int a110;
|
|
int a111;
|
|
int a112;
|
|
int a113;
|
|
int a114;
|
|
int a115;
|
|
int a116;
|
|
int a117;
|
|
int a118;
|
|
int a119;
|
|
int a120;
|
|
int a121;
|
|
int a122;
|
|
int a123;
|
|
int a124;
|
|
int a125;
|
|
int a126;
|
|
int a127;
|
|
|
|
a0 = 1;
|
|
a1 = 2;
|
|
a2 = 3;
|
|
a3 = 4;
|
|
a4 = 5;
|
|
a5 = 6;
|
|
a6 = 7;
|
|
a7 = 8;
|
|
a8 = 9;
|
|
a9 = 10;
|
|
a10 = 11;
|
|
a11 = 12;
|
|
a12 = 13;
|
|
a13 = 14;
|
|
a14 = 15;
|
|
a15 = 16;
|
|
a16 = 17;
|
|
a17 = 18;
|
|
a18 = 19;
|
|
a19 = 20;
|
|
a20 = 21;
|
|
a21 = 22;
|
|
a22 = 23;
|
|
a23 = 24;
|
|
a24 = 25;
|
|
a25 = 26;
|
|
a26 = 27;
|
|
a27 = 28;
|
|
a28 = 29;
|
|
a29 = 30;
|
|
a30 = 31;
|
|
a31 = 32;
|
|
a32 = 33;
|
|
a33 = 34;
|
|
a34 = 35;
|
|
a35 = 36;
|
|
a36 = 37;
|
|
a37 = 38;
|
|
a38 = 39;
|
|
a39 = 40;
|
|
a40 = 41;
|
|
a41 = 42;
|
|
a42 = 43;
|
|
a43 = 44;
|
|
a44 = 45;
|
|
a45 = 46;
|
|
a46 = 47;
|
|
a47 = 48;
|
|
a48 = 49;
|
|
a49 = 50;
|
|
a50 = 51;
|
|
a51 = 52;
|
|
a52 = 53;
|
|
a53 = 54;
|
|
a54 = 55;
|
|
a55 = 56;
|
|
a56 = 57;
|
|
a57 = 58;
|
|
a58 = 59;
|
|
a59 = 60;
|
|
a60 = 61;
|
|
a61 = 62;
|
|
a62 = 63;
|
|
a63 = 64;
|
|
a64 = 65;
|
|
a65 = 66;
|
|
a66 = 67;
|
|
a67 = 68;
|
|
a68 = 69;
|
|
a69 = 70;
|
|
a70 = 71;
|
|
a71 = 72;
|
|
a72 = 73;
|
|
a73 = 74;
|
|
a74 = 75;
|
|
a75 = 76;
|
|
a76 = 77;
|
|
a77 = 78;
|
|
a78 = 79;
|
|
a79 = 80;
|
|
a80 = 81;
|
|
a81 = 82;
|
|
a82 = 83;
|
|
a83 = 84;
|
|
a84 = 85;
|
|
a85 = 86;
|
|
a86 = 87;
|
|
a87 = 88;
|
|
a88 = 89;
|
|
a89 = 90;
|
|
a90 = 91;
|
|
a91 = 92;
|
|
a92 = 93;
|
|
a93 = 94;
|
|
a94 = 95;
|
|
a95 = 96;
|
|
a96 = 97;
|
|
a97 = 98;
|
|
a98 = 99;
|
|
a99 = 100;
|
|
a100 = 101;
|
|
a101 = 102;
|
|
a102 = 103;
|
|
a103 = 104;
|
|
a104 = 105;
|
|
a105 = 106;
|
|
a106 = 107;
|
|
a107 = 108;
|
|
a108 = 109;
|
|
a109 = 110;
|
|
a110 = 111;
|
|
a111 = 112;
|
|
a112 = 113;
|
|
a113 = 114;
|
|
a114 = 115;
|
|
a115 = 116;
|
|
a116 = 117;
|
|
a117 = 118;
|
|
a118 = 119;
|
|
a119 = 120;
|
|
a120 = 121;
|
|
a121 = 122;
|
|
a122 = 123;
|
|
a123 = 124;
|
|
a124 = 125;
|
|
a125 = 126;
|
|
a126 = 127;
|
|
a127 = 128;
|
|
|
|
final result = returnStruct1024BytesHomogeneousUint64(
|
|
a0,
|
|
a1,
|
|
a2,
|
|
a3,
|
|
a4,
|
|
a5,
|
|
a6,
|
|
a7,
|
|
a8,
|
|
a9,
|
|
a10,
|
|
a11,
|
|
a12,
|
|
a13,
|
|
a14,
|
|
a15,
|
|
a16,
|
|
a17,
|
|
a18,
|
|
a19,
|
|
a20,
|
|
a21,
|
|
a22,
|
|
a23,
|
|
a24,
|
|
a25,
|
|
a26,
|
|
a27,
|
|
a28,
|
|
a29,
|
|
a30,
|
|
a31,
|
|
a32,
|
|
a33,
|
|
a34,
|
|
a35,
|
|
a36,
|
|
a37,
|
|
a38,
|
|
a39,
|
|
a40,
|
|
a41,
|
|
a42,
|
|
a43,
|
|
a44,
|
|
a45,
|
|
a46,
|
|
a47,
|
|
a48,
|
|
a49,
|
|
a50,
|
|
a51,
|
|
a52,
|
|
a53,
|
|
a54,
|
|
a55,
|
|
a56,
|
|
a57,
|
|
a58,
|
|
a59,
|
|
a60,
|
|
a61,
|
|
a62,
|
|
a63,
|
|
a64,
|
|
a65,
|
|
a66,
|
|
a67,
|
|
a68,
|
|
a69,
|
|
a70,
|
|
a71,
|
|
a72,
|
|
a73,
|
|
a74,
|
|
a75,
|
|
a76,
|
|
a77,
|
|
a78,
|
|
a79,
|
|
a80,
|
|
a81,
|
|
a82,
|
|
a83,
|
|
a84,
|
|
a85,
|
|
a86,
|
|
a87,
|
|
a88,
|
|
a89,
|
|
a90,
|
|
a91,
|
|
a92,
|
|
a93,
|
|
a94,
|
|
a95,
|
|
a96,
|
|
a97,
|
|
a98,
|
|
a99,
|
|
a100,
|
|
a101,
|
|
a102,
|
|
a103,
|
|
a104,
|
|
a105,
|
|
a106,
|
|
a107,
|
|
a108,
|
|
a109,
|
|
a110,
|
|
a111,
|
|
a112,
|
|
a113,
|
|
a114,
|
|
a115,
|
|
a116,
|
|
a117,
|
|
a118,
|
|
a119,
|
|
a120,
|
|
a121,
|
|
a122,
|
|
a123,
|
|
a124,
|
|
a125,
|
|
a126,
|
|
a127);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(a0, result.a0);
|
|
Expect.equals(a1, result.a1);
|
|
Expect.equals(a2, result.a2);
|
|
Expect.equals(a3, result.a3);
|
|
Expect.equals(a4, result.a4);
|
|
Expect.equals(a5, result.a5);
|
|
Expect.equals(a6, result.a6);
|
|
Expect.equals(a7, result.a7);
|
|
Expect.equals(a8, result.a8);
|
|
Expect.equals(a9, result.a9);
|
|
Expect.equals(a10, result.a10);
|
|
Expect.equals(a11, result.a11);
|
|
Expect.equals(a12, result.a12);
|
|
Expect.equals(a13, result.a13);
|
|
Expect.equals(a14, result.a14);
|
|
Expect.equals(a15, result.a15);
|
|
Expect.equals(a16, result.a16);
|
|
Expect.equals(a17, result.a17);
|
|
Expect.equals(a18, result.a18);
|
|
Expect.equals(a19, result.a19);
|
|
Expect.equals(a20, result.a20);
|
|
Expect.equals(a21, result.a21);
|
|
Expect.equals(a22, result.a22);
|
|
Expect.equals(a23, result.a23);
|
|
Expect.equals(a24, result.a24);
|
|
Expect.equals(a25, result.a25);
|
|
Expect.equals(a26, result.a26);
|
|
Expect.equals(a27, result.a27);
|
|
Expect.equals(a28, result.a28);
|
|
Expect.equals(a29, result.a29);
|
|
Expect.equals(a30, result.a30);
|
|
Expect.equals(a31, result.a31);
|
|
Expect.equals(a32, result.a32);
|
|
Expect.equals(a33, result.a33);
|
|
Expect.equals(a34, result.a34);
|
|
Expect.equals(a35, result.a35);
|
|
Expect.equals(a36, result.a36);
|
|
Expect.equals(a37, result.a37);
|
|
Expect.equals(a38, result.a38);
|
|
Expect.equals(a39, result.a39);
|
|
Expect.equals(a40, result.a40);
|
|
Expect.equals(a41, result.a41);
|
|
Expect.equals(a42, result.a42);
|
|
Expect.equals(a43, result.a43);
|
|
Expect.equals(a44, result.a44);
|
|
Expect.equals(a45, result.a45);
|
|
Expect.equals(a46, result.a46);
|
|
Expect.equals(a47, result.a47);
|
|
Expect.equals(a48, result.a48);
|
|
Expect.equals(a49, result.a49);
|
|
Expect.equals(a50, result.a50);
|
|
Expect.equals(a51, result.a51);
|
|
Expect.equals(a52, result.a52);
|
|
Expect.equals(a53, result.a53);
|
|
Expect.equals(a54, result.a54);
|
|
Expect.equals(a55, result.a55);
|
|
Expect.equals(a56, result.a56);
|
|
Expect.equals(a57, result.a57);
|
|
Expect.equals(a58, result.a58);
|
|
Expect.equals(a59, result.a59);
|
|
Expect.equals(a60, result.a60);
|
|
Expect.equals(a61, result.a61);
|
|
Expect.equals(a62, result.a62);
|
|
Expect.equals(a63, result.a63);
|
|
Expect.equals(a64, result.a64);
|
|
Expect.equals(a65, result.a65);
|
|
Expect.equals(a66, result.a66);
|
|
Expect.equals(a67, result.a67);
|
|
Expect.equals(a68, result.a68);
|
|
Expect.equals(a69, result.a69);
|
|
Expect.equals(a70, result.a70);
|
|
Expect.equals(a71, result.a71);
|
|
Expect.equals(a72, result.a72);
|
|
Expect.equals(a73, result.a73);
|
|
Expect.equals(a74, result.a74);
|
|
Expect.equals(a75, result.a75);
|
|
Expect.equals(a76, result.a76);
|
|
Expect.equals(a77, result.a77);
|
|
Expect.equals(a78, result.a78);
|
|
Expect.equals(a79, result.a79);
|
|
Expect.equals(a80, result.a80);
|
|
Expect.equals(a81, result.a81);
|
|
Expect.equals(a82, result.a82);
|
|
Expect.equals(a83, result.a83);
|
|
Expect.equals(a84, result.a84);
|
|
Expect.equals(a85, result.a85);
|
|
Expect.equals(a86, result.a86);
|
|
Expect.equals(a87, result.a87);
|
|
Expect.equals(a88, result.a88);
|
|
Expect.equals(a89, result.a89);
|
|
Expect.equals(a90, result.a90);
|
|
Expect.equals(a91, result.a91);
|
|
Expect.equals(a92, result.a92);
|
|
Expect.equals(a93, result.a93);
|
|
Expect.equals(a94, result.a94);
|
|
Expect.equals(a95, result.a95);
|
|
Expect.equals(a96, result.a96);
|
|
Expect.equals(a97, result.a97);
|
|
Expect.equals(a98, result.a98);
|
|
Expect.equals(a99, result.a99);
|
|
Expect.equals(a100, result.a100);
|
|
Expect.equals(a101, result.a101);
|
|
Expect.equals(a102, result.a102);
|
|
Expect.equals(a103, result.a103);
|
|
Expect.equals(a104, result.a104);
|
|
Expect.equals(a105, result.a105);
|
|
Expect.equals(a106, result.a106);
|
|
Expect.equals(a107, result.a107);
|
|
Expect.equals(a108, result.a108);
|
|
Expect.equals(a109, result.a109);
|
|
Expect.equals(a110, result.a110);
|
|
Expect.equals(a111, result.a111);
|
|
Expect.equals(a112, result.a112);
|
|
Expect.equals(a113, result.a113);
|
|
Expect.equals(a114, result.a114);
|
|
Expect.equals(a115, result.a115);
|
|
Expect.equals(a116, result.a116);
|
|
Expect.equals(a117, result.a117);
|
|
Expect.equals(a118, result.a118);
|
|
Expect.equals(a119, result.a119);
|
|
Expect.equals(a120, result.a120);
|
|
Expect.equals(a121, result.a121);
|
|
Expect.equals(a122, result.a122);
|
|
Expect.equals(a123, result.a123);
|
|
Expect.equals(a124, result.a124);
|
|
Expect.equals(a125, result.a125);
|
|
Expect.equals(a126, result.a126);
|
|
Expect.equals(a127, result.a127);
|
|
}
|
|
|
|
final returnStruct3BytesPackedInt = ffiTestFunctions.lookupFunction<
|
|
Struct3BytesPackedInt Function(Int8, Int16),
|
|
Struct3BytesPackedInt Function(int, int)>("ReturnStruct3BytesPackedInt");
|
|
|
|
/// Small struct with mis-aligned member.
|
|
void testReturnStruct3BytesPackedInt() {
|
|
int a0;
|
|
int a1;
|
|
|
|
a0 = -1;
|
|
a1 = 2;
|
|
|
|
final result = returnStruct3BytesPackedInt(a0, a1);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(a0, result.a0);
|
|
Expect.equals(a1, result.a1);
|
|
}
|
|
|
|
final returnStruct8BytesPackedInt = ffiTestFunctions.lookupFunction<
|
|
Struct8BytesPackedInt Function(Uint8, Uint32, Uint8, Uint8, Uint8),
|
|
Struct8BytesPackedInt Function(
|
|
int, int, int, int, int)>("ReturnStruct8BytesPackedInt");
|
|
|
|
/// Struct with mis-aligned member.
|
|
void testReturnStruct8BytesPackedInt() {
|
|
int a0;
|
|
int a1;
|
|
int a2;
|
|
int a3;
|
|
int a4;
|
|
|
|
a0 = 1;
|
|
a1 = 2;
|
|
a2 = 3;
|
|
a3 = 4;
|
|
a4 = 5;
|
|
|
|
final result = returnStruct8BytesPackedInt(a0, a1, a2, a3, a4);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(a0, result.a0);
|
|
Expect.equals(a1, result.a1);
|
|
Expect.equals(a2, result.a2);
|
|
Expect.equals(a3, result.a3);
|
|
Expect.equals(a4, result.a4);
|
|
}
|
|
|
|
final returnStruct9BytesPackedMixed = ffiTestFunctions.lookupFunction<
|
|
Struct9BytesPackedMixed Function(Uint8, Double),
|
|
Struct9BytesPackedMixed Function(
|
|
int, double)>("ReturnStruct9BytesPackedMixed");
|
|
|
|
/// Struct with mis-aligned member.
|
|
/// Tests backfilling of CPU and FPU registers.
|
|
void testReturnStruct9BytesPackedMixed() {
|
|
int a0;
|
|
double a1;
|
|
|
|
a0 = 1;
|
|
a1 = 2.0;
|
|
|
|
final result = returnStruct9BytesPackedMixed(a0, a1);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(a0, result.a0);
|
|
Expect.approxEquals(a1, result.a1);
|
|
}
|
|
|
|
final returnUnion4BytesMixed = ffiTestFunctions.lookupFunction<
|
|
Union4BytesMixed Function(Uint32),
|
|
Union4BytesMixed Function(int)>("ReturnUnion4BytesMixed");
|
|
|
|
/// Returning a mixed integer/float union.
|
|
void testReturnUnion4BytesMixed() {
|
|
int a0;
|
|
|
|
a0 = 1;
|
|
|
|
final result = returnUnion4BytesMixed(a0);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(a0, result.a0);
|
|
}
|
|
|
|
final returnUnion8BytesNestedFloat = ffiTestFunctions.lookupFunction<
|
|
Union8BytesNestedFloat Function(Double),
|
|
Union8BytesNestedFloat Function(double)>("ReturnUnion8BytesNestedFloat");
|
|
|
|
/// Returning a floating point only union.
|
|
void testReturnUnion8BytesNestedFloat() {
|
|
double a0;
|
|
|
|
a0 = -1.0;
|
|
|
|
final result = returnUnion8BytesNestedFloat(a0);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(a0, result.a0);
|
|
}
|
|
|
|
final returnUnion9BytesNestedInt = ffiTestFunctions.lookupFunction<
|
|
Union9BytesNestedInt Function(Struct8BytesInt),
|
|
Union9BytesNestedInt Function(
|
|
Struct8BytesInt)>("ReturnUnion9BytesNestedInt");
|
|
|
|
/// Returning a mixed-size union.
|
|
void testReturnUnion9BytesNestedInt() {
|
|
final a0Pointer = calloc<Struct8BytesInt>();
|
|
final Struct8BytesInt a0 = a0Pointer.ref;
|
|
|
|
a0.a0 = -1;
|
|
a0.a1 = 2;
|
|
a0.a2 = -3;
|
|
|
|
final result = returnUnion9BytesNestedInt(a0);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(a0.a0, result.a0.a0);
|
|
Expect.equals(a0.a1, result.a0.a1);
|
|
Expect.equals(a0.a2, result.a0.a2);
|
|
|
|
calloc.free(a0Pointer);
|
|
}
|
|
|
|
final returnUnion16BytesNestedFloat = ffiTestFunctions.lookupFunction<
|
|
Union16BytesNestedFloat Function(Struct8BytesHomogeneousFloat),
|
|
Union16BytesNestedFloat Function(
|
|
Struct8BytesHomogeneousFloat)>("ReturnUnion16BytesNestedFloat");
|
|
|
|
/// Returning union with homogenous floats.
|
|
void testReturnUnion16BytesNestedFloat() {
|
|
final a0Pointer = calloc<Struct8BytesHomogeneousFloat>();
|
|
final Struct8BytesHomogeneousFloat a0 = a0Pointer.ref;
|
|
|
|
a0.a0 = -1.0;
|
|
a0.a1 = 2.0;
|
|
|
|
final result = returnUnion16BytesNestedFloat(a0);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(a0.a0, result.a0.a0);
|
|
Expect.approxEquals(a0.a1, result.a0.a1);
|
|
|
|
calloc.free(a0Pointer);
|
|
}
|
|
|
|
final returnStructArgumentStruct1ByteInt = ffiTestFunctions.lookupFunction<
|
|
Struct1ByteInt Function(Struct1ByteInt),
|
|
Struct1ByteInt Function(
|
|
Struct1ByteInt)>("ReturnStructArgumentStruct1ByteInt");
|
|
|
|
/// 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 testReturnStructArgumentStruct1ByteInt() {
|
|
final a0Pointer = calloc<Struct1ByteInt>();
|
|
final Struct1ByteInt a0 = a0Pointer.ref;
|
|
|
|
a0.a0 = -1;
|
|
|
|
final result = returnStructArgumentStruct1ByteInt(a0);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(a0.a0, result.a0);
|
|
|
|
calloc.free(a0Pointer);
|
|
}
|
|
|
|
final returnStructArgumentInt32x8Struct1ByteInt =
|
|
ffiTestFunctions.lookupFunction<
|
|
Struct1ByteInt Function(Int32, Int32, Int32, Int32, Int32, Int32, Int32,
|
|
Int32, Struct1ByteInt),
|
|
Struct1ByteInt Function(int, int, int, int, int, int, int, int,
|
|
Struct1ByteInt)>("ReturnStructArgumentInt32x8Struct1ByteInt");
|
|
|
|
/// Test that a struct passed in as argument can be returned.
|
|
/// Especially for ffi callbacks.
|
|
/// Struct is passed on stack on all ABIs.
|
|
void testReturnStructArgumentInt32x8Struct1ByteInt() {
|
|
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 = returnStructArgumentInt32x8Struct1ByteInt(
|
|
a0, a1, a2, a3, a4, a5, a6, a7, a8);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(a8.a0, result.a0);
|
|
|
|
calloc.free(a8Pointer);
|
|
}
|
|
|
|
final returnStructArgumentStruct8BytesHomogeneousFloat =
|
|
ffiTestFunctions.lookupFunction<
|
|
Struct8BytesHomogeneousFloat Function(Struct8BytesHomogeneousFloat),
|
|
Struct8BytesHomogeneousFloat Function(
|
|
Struct8BytesHomogeneousFloat)>(
|
|
"ReturnStructArgumentStruct8BytesHomogeneousFloat");
|
|
|
|
/// 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 testReturnStructArgumentStruct8BytesHomogeneousFloat() {
|
|
final a0Pointer = calloc<Struct8BytesHomogeneousFloat>();
|
|
final Struct8BytesHomogeneousFloat a0 = a0Pointer.ref;
|
|
|
|
a0.a0 = -1.0;
|
|
a0.a1 = 2.0;
|
|
|
|
final result = returnStructArgumentStruct8BytesHomogeneousFloat(a0);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(a0.a0, result.a0);
|
|
Expect.approxEquals(a0.a1, result.a1);
|
|
|
|
calloc.free(a0Pointer);
|
|
}
|
|
|
|
final returnStructArgumentStruct20BytesHomogeneousInt32 =
|
|
ffiTestFunctions
|
|
.lookupFunction<
|
|
Struct20BytesHomogeneousInt32 Function(
|
|
Struct20BytesHomogeneousInt32),
|
|
Struct20BytesHomogeneousInt32 Function(
|
|
Struct20BytesHomogeneousInt32)>(
|
|
"ReturnStructArgumentStruct20BytesHomogeneousInt32");
|
|
|
|
/// On arm64, both argument and return value are passed in by pointer.
|
|
void testReturnStructArgumentStruct20BytesHomogeneousInt32() {
|
|
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 = returnStructArgumentStruct20BytesHomogeneousInt32(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);
|
|
}
|
|
|
|
final returnStructArgumentInt32x8Struct20BytesHomogeneou =
|
|
ffiTestFunctions.lookupFunction<
|
|
Struct20BytesHomogeneousInt32 Function(Int32, Int32, Int32, Int32,
|
|
Int32, Int32, Int32, Int32, Struct20BytesHomogeneousInt32),
|
|
Struct20BytesHomogeneousInt32 Function(int, int, int, int, int, int,
|
|
int, int, Struct20BytesHomogeneousInt32)>(
|
|
"ReturnStructArgumentInt32x8Struct20BytesHomogeneou");
|
|
|
|
/// On arm64, both argument and return value are passed in by pointer.
|
|
/// Ints exhaust registers, so that pointer is passed on stack.
|
|
void testReturnStructArgumentInt32x8Struct20BytesHomogeneou() {
|
|
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 = returnStructArgumentInt32x8Struct20BytesHomogeneou(
|
|
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);
|
|
}
|
|
|
|
final returnStructArgumentStruct8BytesInlineArrayInt =
|
|
ffiTestFunctions.lookupFunction<
|
|
Struct8BytesInlineArrayInt Function(Struct8BytesInlineArrayInt),
|
|
Struct8BytesInlineArrayInt Function(Struct8BytesInlineArrayInt)>(
|
|
"ReturnStructArgumentStruct8BytesInlineArrayInt");
|
|
|
|
/// Test returning struct with inline array.
|
|
void testReturnStructArgumentStruct8BytesInlineArrayInt() {
|
|
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 = returnStructArgumentStruct8BytesInlineArrayInt(a0);
|
|
|
|
print("result = $result");
|
|
|
|
for (int i = 0; i < 8; i++) {
|
|
Expect.equals(a0.a0[i], result.a0[i]);
|
|
}
|
|
|
|
calloc.free(a0Pointer);
|
|
}
|
|
|
|
final returnStructArgumentStructStruct16BytesHomogeneous =
|
|
ffiTestFunctions.lookupFunction<
|
|
StructStruct16BytesHomogeneousFloat2 Function(
|
|
StructStruct16BytesHomogeneousFloat2),
|
|
StructStruct16BytesHomogeneousFloat2 Function(
|
|
StructStruct16BytesHomogeneousFloat2)>(
|
|
"ReturnStructArgumentStructStruct16BytesHomogeneous");
|
|
|
|
/// Return value in FPU registers on arm hardfp and arm64.
|
|
void testReturnStructArgumentStructStruct16BytesHomogeneous() {
|
|
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 = returnStructArgumentStructStruct16BytesHomogeneous(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);
|
|
}
|
|
|
|
final returnStructArgumentStructStruct32BytesHomogeneous =
|
|
ffiTestFunctions.lookupFunction<
|
|
StructStruct32BytesHomogeneousDouble2 Function(
|
|
StructStruct32BytesHomogeneousDouble2),
|
|
StructStruct32BytesHomogeneousDouble2 Function(
|
|
StructStruct32BytesHomogeneousDouble2)>(
|
|
"ReturnStructArgumentStructStruct32BytesHomogeneous");
|
|
|
|
/// Return value in FPU registers on arm64.
|
|
void testReturnStructArgumentStructStruct32BytesHomogeneous() {
|
|
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 = returnStructArgumentStructStruct32BytesHomogeneous(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);
|
|
}
|
|
|
|
final returnStructArgumentStructStruct16BytesMixed3 =
|
|
ffiTestFunctions.lookupFunction<
|
|
StructStruct16BytesMixed3 Function(StructStruct16BytesMixed3),
|
|
StructStruct16BytesMixed3 Function(StructStruct16BytesMixed3)>(
|
|
"ReturnStructArgumentStructStruct16BytesMixed3");
|
|
|
|
/// On x64 Linux, return value is split over FP and int registers.
|
|
void testReturnStructArgumentStructStruct16BytesMixed3() {
|
|
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 = returnStructArgumentStructStruct16BytesMixed3(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);
|
|
}
|
|
|
|
final returnStructAlignmentInt16 = ffiTestFunctions.lookupFunction<
|
|
StructAlignmentInt16 Function(Int8, Int16, Int8),
|
|
StructAlignmentInt16 Function(int, int, int)>("ReturnStructAlignmentInt16");
|
|
|
|
/// Test alignment and padding of 16 byte int within struct.
|
|
void testReturnStructAlignmentInt16() {
|
|
int a0;
|
|
int a1;
|
|
int a2;
|
|
|
|
a0 = -1;
|
|
a1 = 2;
|
|
a2 = -3;
|
|
|
|
final result = returnStructAlignmentInt16(a0, a1, a2);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(a0, result.a0);
|
|
Expect.equals(a1, result.a1);
|
|
Expect.equals(a2, result.a2);
|
|
}
|
|
|
|
final returnStructAlignmentInt32 = ffiTestFunctions.lookupFunction<
|
|
StructAlignmentInt32 Function(Int8, Int32, Int8),
|
|
StructAlignmentInt32 Function(int, int, int)>("ReturnStructAlignmentInt32");
|
|
|
|
/// Test alignment and padding of 32 byte int within struct.
|
|
void testReturnStructAlignmentInt32() {
|
|
int a0;
|
|
int a1;
|
|
int a2;
|
|
|
|
a0 = -1;
|
|
a1 = 2;
|
|
a2 = -3;
|
|
|
|
final result = returnStructAlignmentInt32(a0, a1, a2);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(a0, result.a0);
|
|
Expect.equals(a1, result.a1);
|
|
Expect.equals(a2, result.a2);
|
|
}
|
|
|
|
final returnStructAlignmentInt64 = ffiTestFunctions.lookupFunction<
|
|
StructAlignmentInt64 Function(Int8, Int64, Int8),
|
|
StructAlignmentInt64 Function(int, int, int)>("ReturnStructAlignmentInt64");
|
|
|
|
/// Test alignment and padding of 64 byte int within struct.
|
|
void testReturnStructAlignmentInt64() {
|
|
int a0;
|
|
int a1;
|
|
int a2;
|
|
|
|
a0 = -1;
|
|
a1 = 2;
|
|
a2 = -3;
|
|
|
|
final result = returnStructAlignmentInt64(a0, a1, a2);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.equals(a0, result.a0);
|
|
Expect.equals(a1, result.a1);
|
|
Expect.equals(a2, result.a2);
|
|
}
|
|
|
|
final returnStruct8BytesNestedInt = ffiTestFunctions.lookupFunction<
|
|
Struct8BytesNestedInt Function(
|
|
Struct4BytesHomogeneousInt16, Struct4BytesHomogeneousInt16),
|
|
Struct8BytesNestedInt Function(Struct4BytesHomogeneousInt16,
|
|
Struct4BytesHomogeneousInt16)>("ReturnStruct8BytesNestedInt");
|
|
|
|
/// Simple nested struct.
|
|
void testReturnStruct8BytesNestedInt() {
|
|
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 = returnStruct8BytesNestedInt(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);
|
|
}
|
|
|
|
final returnStruct8BytesNestedFloat = ffiTestFunctions.lookupFunction<
|
|
Struct8BytesNestedFloat Function(Struct4BytesFloat, Struct4BytesFloat),
|
|
Struct8BytesNestedFloat Function(
|
|
Struct4BytesFloat, Struct4BytesFloat)>("ReturnStruct8BytesNestedFloat");
|
|
|
|
/// Simple nested struct with floats.
|
|
void testReturnStruct8BytesNestedFloat() {
|
|
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 = returnStruct8BytesNestedFloat(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);
|
|
}
|
|
|
|
final returnStruct8BytesNestedFloat2 = ffiTestFunctions.lookupFunction<
|
|
Struct8BytesNestedFloat2 Function(Struct4BytesFloat, Float),
|
|
Struct8BytesNestedFloat2 Function(
|
|
Struct4BytesFloat, double)>("ReturnStruct8BytesNestedFloat2");
|
|
|
|
/// The nesting is irregular, testing homogenous float rules on arm and arm64,
|
|
/// and the fpu register usage on x64.
|
|
void testReturnStruct8BytesNestedFloat2() {
|
|
final a0Pointer = calloc<Struct4BytesFloat>();
|
|
final Struct4BytesFloat a0 = a0Pointer.ref;
|
|
double a1;
|
|
|
|
a0.a0 = -1.0;
|
|
a1 = 2.0;
|
|
|
|
final result = returnStruct8BytesNestedFloat2(a0, a1);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.approxEquals(a0.a0, result.a0.a0);
|
|
Expect.approxEquals(a1, result.a1);
|
|
|
|
calloc.free(a0Pointer);
|
|
}
|
|
|
|
final returnStruct8BytesNestedMixed = ffiTestFunctions.lookupFunction<
|
|
Struct8BytesNestedMixed Function(
|
|
Struct4BytesHomogeneousInt16, Struct4BytesFloat),
|
|
Struct8BytesNestedMixed Function(Struct4BytesHomogeneousInt16,
|
|
Struct4BytesFloat)>("ReturnStruct8BytesNestedMixed");
|
|
|
|
/// Simple nested struct with mixed members.
|
|
void testReturnStruct8BytesNestedMixed() {
|
|
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 = returnStruct8BytesNestedMixed(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);
|
|
}
|
|
|
|
final returnStruct16BytesNestedInt = ffiTestFunctions.lookupFunction<
|
|
Struct16BytesNestedInt Function(
|
|
Struct8BytesNestedInt, Struct8BytesNestedInt),
|
|
Struct16BytesNestedInt Function(Struct8BytesNestedInt,
|
|
Struct8BytesNestedInt)>("ReturnStruct16BytesNestedInt");
|
|
|
|
/// Deeper nested struct to test recursive member access.
|
|
void testReturnStruct16BytesNestedInt() {
|
|
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 = returnStruct16BytesNestedInt(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);
|
|
}
|
|
|
|
final returnStruct32BytesNestedInt = ffiTestFunctions.lookupFunction<
|
|
Struct32BytesNestedInt Function(
|
|
Struct16BytesNestedInt, Struct16BytesNestedInt),
|
|
Struct32BytesNestedInt Function(Struct16BytesNestedInt,
|
|
Struct16BytesNestedInt)>("ReturnStruct32BytesNestedInt");
|
|
|
|
/// Even deeper nested struct to test recursive member access.
|
|
void testReturnStruct32BytesNestedInt() {
|
|
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 = returnStruct32BytesNestedInt(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);
|
|
}
|
|
|
|
final returnStructNestedIntStructAlignmentInt16 =
|
|
ffiTestFunctions.lookupFunction<
|
|
StructNestedIntStructAlignmentInt16 Function(
|
|
StructAlignmentInt16, StructAlignmentInt16),
|
|
StructNestedIntStructAlignmentInt16 Function(StructAlignmentInt16,
|
|
StructAlignmentInt16)>("ReturnStructNestedIntStructAlignmentInt16");
|
|
|
|
/// Test alignment and padding of nested struct with 16 byte int.
|
|
void testReturnStructNestedIntStructAlignmentInt16() {
|
|
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 = returnStructNestedIntStructAlignmentInt16(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);
|
|
}
|
|
|
|
final returnStructNestedIntStructAlignmentInt32 =
|
|
ffiTestFunctions.lookupFunction<
|
|
StructNestedIntStructAlignmentInt32 Function(
|
|
StructAlignmentInt32, StructAlignmentInt32),
|
|
StructNestedIntStructAlignmentInt32 Function(StructAlignmentInt32,
|
|
StructAlignmentInt32)>("ReturnStructNestedIntStructAlignmentInt32");
|
|
|
|
/// Test alignment and padding of nested struct with 32 byte int.
|
|
void testReturnStructNestedIntStructAlignmentInt32() {
|
|
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 = returnStructNestedIntStructAlignmentInt32(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);
|
|
}
|
|
|
|
final returnStructNestedIntStructAlignmentInt64 =
|
|
ffiTestFunctions.lookupFunction<
|
|
StructNestedIntStructAlignmentInt64 Function(
|
|
StructAlignmentInt64, StructAlignmentInt64),
|
|
StructNestedIntStructAlignmentInt64 Function(StructAlignmentInt64,
|
|
StructAlignmentInt64)>("ReturnStructNestedIntStructAlignmentInt64");
|
|
|
|
/// Test alignment and padding of nested struct with 64 byte int.
|
|
void testReturnStructNestedIntStructAlignmentInt64() {
|
|
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 = returnStructNestedIntStructAlignmentInt64(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);
|
|
}
|
|
|
|
final returnStructNestedIrregularEvenBigger = ffiTestFunctions.lookupFunction<
|
|
StructNestedIrregularEvenBigger Function(Uint64,
|
|
StructNestedIrregularBigger, StructNestedIrregularBigger, Double),
|
|
StructNestedIrregularEvenBigger Function(
|
|
int,
|
|
StructNestedIrregularBigger,
|
|
StructNestedIrregularBigger,
|
|
double)>("ReturnStructNestedIrregularEvenBigger");
|
|
|
|
/// Return big irregular struct as smoke test.
|
|
void testReturnStructNestedIrregularEvenBigger() {
|
|
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 = returnStructNestedIrregularEvenBigger(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);
|
|
}
|