blob: 1e882494432ab9e2684248c84e11c6302cf9b3c9 [file] [log] [blame]
// 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.
#include <stddef.h>
#include <stdlib.h>
#include <sys/types.h>
#include <cmath>
#include <iostream>
#include <limits>
#if defined(_WIN32)
#define DART_EXPORT extern "C" __declspec(dllexport)
#else
#define DART_EXPORT \
extern "C" __attribute__((visibility("default"))) __attribute((used))
#endif
namespace dart {
#define CHECK(X) \
if (!(X)) { \
fprintf(stderr, "%s\n", "Check failed: " #X); \
return 1; \
}
#define CHECK_EQ(X, Y) CHECK((X) == (Y))
// Works for positive, negative and zero.
#define CHECK_APPROX(EXPECTED, ACTUAL) \
CHECK(((EXPECTED * 0.99) <= (ACTUAL) && (EXPECTED * 1.01) >= (ACTUAL)) || \
((EXPECTED * 0.99) >= (ACTUAL) && (EXPECTED * 1.01) <= (ACTUAL)))
struct Struct1ByteInt {
int8_t a0;
};
struct Struct3BytesHomogeneousUint8 {
uint8_t a0;
uint8_t a1;
uint8_t a2;
};
struct Struct3BytesInt2ByteAligned {
int16_t a0;
int8_t a1;
};
struct Struct4BytesHomogeneousInt16 {
int16_t a0;
int16_t a1;
};
struct Struct4BytesFloat {
float a0;
};
struct Struct7BytesHomogeneousUint8 {
uint8_t a0;
uint8_t a1;
uint8_t a2;
uint8_t a3;
uint8_t a4;
uint8_t a5;
uint8_t a6;
};
struct Struct7BytesInt4ByteAligned {
int32_t a0;
int16_t a1;
int8_t a2;
};
struct Struct8BytesInt {
int16_t a0;
int16_t a1;
int32_t a2;
};
struct Struct8BytesHomogeneousFloat {
float a0;
float a1;
};
struct Struct8BytesFloat {
double a0;
};
struct Struct8BytesMixed {
float a0;
int16_t a1;
int16_t a2;
};
struct Struct9BytesHomogeneousUint8 {
uint8_t a0;
uint8_t a1;
uint8_t a2;
uint8_t a3;
uint8_t a4;
uint8_t a5;
uint8_t a6;
uint8_t a7;
uint8_t a8;
};
struct Struct9BytesInt4Or8ByteAligned {
int64_t a0;
int8_t a1;
};
struct Struct12BytesHomogeneousFloat {
float a0;
float a1;
float a2;
};
struct Struct16BytesHomogeneousFloat {
float a0;
float a1;
float a2;
float a3;
};
struct Struct16BytesMixed {
double a0;
int64_t a1;
};
struct Struct16BytesMixed2 {
float a0;
float a1;
float a2;
int32_t a3;
};
struct Struct17BytesInt {
int64_t a0;
int64_t a1;
int8_t a2;
};
struct Struct19BytesHomogeneousUint8 {
uint8_t a0;
uint8_t a1;
uint8_t a2;
uint8_t a3;
uint8_t a4;
uint8_t a5;
uint8_t a6;
uint8_t a7;
uint8_t a8;
uint8_t a9;
uint8_t a10;
uint8_t a11;
uint8_t a12;
uint8_t a13;
uint8_t a14;
uint8_t a15;
uint8_t a16;
uint8_t a17;
uint8_t a18;
};
struct Struct20BytesHomogeneousInt32 {
int32_t a0;
int32_t a1;
int32_t a2;
int32_t a3;
int32_t a4;
};
struct Struct20BytesHomogeneousFloat {
float a0;
float a1;
float a2;
float a3;
float a4;
};
struct Struct32BytesHomogeneousDouble {
double a0;
double a1;
double a2;
double a3;
};
struct Struct40BytesHomogeneousDouble {
double a0;
double a1;
double a2;
double a3;
double a4;
};
struct Struct1024BytesHomogeneousUint64 {
uint64_t a0;
uint64_t a1;
uint64_t a2;
uint64_t a3;
uint64_t a4;
uint64_t a5;
uint64_t a6;
uint64_t a7;
uint64_t a8;
uint64_t a9;
uint64_t a10;
uint64_t a11;
uint64_t a12;
uint64_t a13;
uint64_t a14;
uint64_t a15;
uint64_t a16;
uint64_t a17;
uint64_t a18;
uint64_t a19;
uint64_t a20;
uint64_t a21;
uint64_t a22;
uint64_t a23;
uint64_t a24;
uint64_t a25;
uint64_t a26;
uint64_t a27;
uint64_t a28;
uint64_t a29;
uint64_t a30;
uint64_t a31;
uint64_t a32;
uint64_t a33;
uint64_t a34;
uint64_t a35;
uint64_t a36;
uint64_t a37;
uint64_t a38;
uint64_t a39;
uint64_t a40;
uint64_t a41;
uint64_t a42;
uint64_t a43;
uint64_t a44;
uint64_t a45;
uint64_t a46;
uint64_t a47;
uint64_t a48;
uint64_t a49;
uint64_t a50;
uint64_t a51;
uint64_t a52;
uint64_t a53;
uint64_t a54;
uint64_t a55;
uint64_t a56;
uint64_t a57;
uint64_t a58;
uint64_t a59;
uint64_t a60;
uint64_t a61;
uint64_t a62;
uint64_t a63;
uint64_t a64;
uint64_t a65;
uint64_t a66;
uint64_t a67;
uint64_t a68;
uint64_t a69;
uint64_t a70;
uint64_t a71;
uint64_t a72;
uint64_t a73;
uint64_t a74;
uint64_t a75;
uint64_t a76;
uint64_t a77;
uint64_t a78;
uint64_t a79;
uint64_t a80;
uint64_t a81;
uint64_t a82;
uint64_t a83;
uint64_t a84;
uint64_t a85;
uint64_t a86;
uint64_t a87;
uint64_t a88;
uint64_t a89;
uint64_t a90;
uint64_t a91;
uint64_t a92;
uint64_t a93;
uint64_t a94;
uint64_t a95;
uint64_t a96;
uint64_t a97;
uint64_t a98;
uint64_t a99;
uint64_t a100;
uint64_t a101;
uint64_t a102;
uint64_t a103;
uint64_t a104;
uint64_t a105;
uint64_t a106;
uint64_t a107;
uint64_t a108;
uint64_t a109;
uint64_t a110;
uint64_t a111;
uint64_t a112;
uint64_t a113;
uint64_t a114;
uint64_t a115;
uint64_t a116;
uint64_t a117;
uint64_t a118;
uint64_t a119;
uint64_t a120;
uint64_t a121;
uint64_t a122;
uint64_t a123;
uint64_t a124;
uint64_t a125;
uint64_t a126;
uint64_t a127;
};
struct StructAlignmentInt16 {
int8_t a0;
int16_t a1;
int8_t a2;
};
struct StructAlignmentInt32 {
int8_t a0;
int32_t a1;
int8_t a2;
};
struct StructAlignmentInt64 {
int8_t a0;
int64_t a1;
int8_t a2;
};
struct Struct8BytesNestedInt {
Struct4BytesHomogeneousInt16 a0;
Struct4BytesHomogeneousInt16 a1;
};
struct Struct8BytesNestedFloat {
Struct4BytesFloat a0;
Struct4BytesFloat a1;
};
struct Struct8BytesNestedFloat2 {
Struct4BytesFloat a0;
float a1;
};
struct Struct8BytesNestedMixed {
Struct4BytesHomogeneousInt16 a0;
Struct4BytesFloat a1;
};
struct Struct16BytesNestedInt {
Struct8BytesNestedInt a0;
Struct8BytesNestedInt a1;
};
struct Struct32BytesNestedInt {
Struct16BytesNestedInt a0;
Struct16BytesNestedInt a1;
};
struct StructNestedIntStructAlignmentInt16 {
StructAlignmentInt16 a0;
StructAlignmentInt16 a1;
};
struct StructNestedIntStructAlignmentInt32 {
StructAlignmentInt32 a0;
StructAlignmentInt32 a1;
};
struct StructNestedIntStructAlignmentInt64 {
StructAlignmentInt64 a0;
StructAlignmentInt64 a1;
};
struct StructNestedIrregularBig {
uint16_t a0;
Struct8BytesNestedMixed a1;
uint16_t a2;
Struct8BytesNestedFloat2 a3;
uint16_t a4;
Struct8BytesNestedFloat a5;
uint16_t a6;
};
struct StructNestedIrregularBigger {
StructNestedIrregularBig a0;
Struct8BytesNestedMixed a1;
float a2;
double a3;
};
struct StructNestedIrregularEvenBigger {
uint64_t a0;
StructNestedIrregularBigger a1;
StructNestedIrregularBigger a2;
double a3;
};
struct Struct8BytesInlineArrayInt {
uint8_t a0[8];
};
struct StructInlineArrayIrregular {
Struct3BytesInt2ByteAligned a0[2];
uint8_t a1;
};
struct StructInlineArray100Bytes {
uint8_t a0[100];
};
struct StructInlineArrayBig {
uint32_t a0;
uint32_t a1;
uint8_t a2[4000];
};
struct StructStruct16BytesHomogeneousFloat2 {
Struct4BytesFloat a0;
Struct4BytesFloat a1[2];
float a2;
};
struct StructStruct32BytesHomogeneousDouble2 {
Struct8BytesFloat a0;
Struct8BytesFloat a1[2];
double a2;
};
struct StructStruct16BytesMixed3 {
Struct4BytesFloat a0;
Struct8BytesMixed a1[1];
int16_t a2[2];
};
struct Struct8BytesInlineArrayMultiDimensionalInt {
uint8_t a0[2][2][2];
};
struct Struct32BytesInlineArrayMultiDimensionalInt {
uint8_t a0[2][2][2][2][2];
};
struct Struct64BytesInlineArrayMultiDimensionalInt {
uint8_t a0[2][2][2][2][2][2];
};
struct Struct4BytesInlineArrayMultiDimensionalInt {
Struct1ByteInt a0[2][2];
};
#pragma pack(push, 1)
struct Struct3BytesPackedInt {
int8_t a0;
int16_t a1;
};
#pragma pack(pop)
#pragma pack(push, 1)
struct Struct3BytesPackedIntMembersAligned {
int8_t a0;
int16_t a1;
};
#pragma pack(pop)
#pragma pack(push, 1)
struct Struct5BytesPackedMixed {
float a0;
uint8_t a1;
};
#pragma pack(pop)
struct StructNestedAlignmentStruct5BytesPackedMixed {
uint8_t a0;
Struct5BytesPackedMixed a1;
};
struct Struct6BytesInlineArrayInt {
Struct3BytesPackedIntMembersAligned a0[2];
};
#pragma pack(push, 1)
struct Struct8BytesPackedInt {
uint8_t a0;
uint32_t a1;
uint8_t a2;
uint8_t a3;
uint8_t a4;
};
#pragma pack(pop)
#pragma pack(push, 1)
struct Struct9BytesPackedMixed {
uint8_t a0;
double a1;
};
#pragma pack(pop)
struct Struct15BytesInlineArrayMixed {
Struct5BytesPackedMixed a0[3];
};
union Union4BytesMixed {
uint32_t a0;
float a1;
};
union Union8BytesNestedFloat {
double a0;
Struct8BytesHomogeneousFloat a1;
};
union Union9BytesNestedInt {
Struct8BytesInt a0;
Struct9BytesHomogeneousUint8 a1;
};
union Union16BytesNestedInlineArrayFloat {
float a0[4];
Struct16BytesHomogeneousFloat a1;
};
union Union16BytesNestedFloat {
Struct8BytesHomogeneousFloat a0;
Struct12BytesHomogeneousFloat a1;
Struct16BytesHomogeneousFloat a2;
};
// Used for testing structs and unions by value.
// Smallest struct with data.
// 10 struct arguments will exhaust available registers.
DART_EXPORT int64_t PassStruct1ByteIntx10(Struct1ByteInt a0,
Struct1ByteInt a1,
Struct1ByteInt a2,
Struct1ByteInt a3,
Struct1ByteInt a4,
Struct1ByteInt a5,
Struct1ByteInt a6,
Struct1ByteInt a7,
Struct1ByteInt a8,
Struct1ByteInt a9) {
std::cout << "PassStruct1ByteIntx10"
<< "((" << static_cast<int>(a0.a0) << "), ("
<< static_cast<int>(a1.a0) << "), (" << static_cast<int>(a2.a0)
<< "), (" << static_cast<int>(a3.a0) << "), ("
<< static_cast<int>(a4.a0) << "), (" << static_cast<int>(a5.a0)
<< "), (" << static_cast<int>(a6.a0) << "), ("
<< static_cast<int>(a7.a0) << "), (" << static_cast<int>(a8.a0)
<< "), (" << static_cast<int>(a9.a0) << "))"
<< "\n";
int64_t result = 0;
result += a0.a0;
result += a1.a0;
result += a2.a0;
result += a3.a0;
result += a4.a0;
result += a5.a0;
result += a6.a0;
result += a7.a0;
result += a8.a0;
result += a9.a0;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Not a multiple of word size, not a power of two.
// 10 struct arguments will exhaust available registers.
DART_EXPORT int64_t
PassStruct3BytesHomogeneousUint8x10(Struct3BytesHomogeneousUint8 a0,
Struct3BytesHomogeneousUint8 a1,
Struct3BytesHomogeneousUint8 a2,
Struct3BytesHomogeneousUint8 a3,
Struct3BytesHomogeneousUint8 a4,
Struct3BytesHomogeneousUint8 a5,
Struct3BytesHomogeneousUint8 a6,
Struct3BytesHomogeneousUint8 a7,
Struct3BytesHomogeneousUint8 a8,
Struct3BytesHomogeneousUint8 a9) {
std::cout << "PassStruct3BytesHomogeneousUint8x10"
<< "((" << static_cast<int>(a0.a0) << ", "
<< static_cast<int>(a0.a1) << ", " << static_cast<int>(a0.a2)
<< "), (" << static_cast<int>(a1.a0) << ", "
<< static_cast<int>(a1.a1) << ", " << static_cast<int>(a1.a2)
<< "), (" << static_cast<int>(a2.a0) << ", "
<< static_cast<int>(a2.a1) << ", " << static_cast<int>(a2.a2)
<< "), (" << static_cast<int>(a3.a0) << ", "
<< static_cast<int>(a3.a1) << ", " << static_cast<int>(a3.a2)
<< "), (" << static_cast<int>(a4.a0) << ", "
<< static_cast<int>(a4.a1) << ", " << static_cast<int>(a4.a2)
<< "), (" << static_cast<int>(a5.a0) << ", "
<< static_cast<int>(a5.a1) << ", " << static_cast<int>(a5.a2)
<< "), (" << static_cast<int>(a6.a0) << ", "
<< static_cast<int>(a6.a1) << ", " << static_cast<int>(a6.a2)
<< "), (" << static_cast<int>(a7.a0) << ", "
<< static_cast<int>(a7.a1) << ", " << static_cast<int>(a7.a2)
<< "), (" << static_cast<int>(a8.a0) << ", "
<< static_cast<int>(a8.a1) << ", " << static_cast<int>(a8.a2)
<< "), (" << static_cast<int>(a9.a0) << ", "
<< static_cast<int>(a9.a1) << ", " << static_cast<int>(a9.a2)
<< "))"
<< "\n";
int64_t result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a1.a0;
result += a1.a1;
result += a1.a2;
result += a2.a0;
result += a2.a1;
result += a2.a2;
result += a3.a0;
result += a3.a1;
result += a3.a2;
result += a4.a0;
result += a4.a1;
result += a4.a2;
result += a5.a0;
result += a5.a1;
result += a5.a2;
result += a6.a0;
result += a6.a1;
result += a6.a2;
result += a7.a0;
result += a7.a1;
result += a7.a2;
result += a8.a0;
result += a8.a1;
result += a8.a2;
result += a9.a0;
result += a9.a1;
result += a9.a2;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// 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.
DART_EXPORT int64_t
PassStruct3BytesInt2ByteAlignedx10(Struct3BytesInt2ByteAligned a0,
Struct3BytesInt2ByteAligned a1,
Struct3BytesInt2ByteAligned a2,
Struct3BytesInt2ByteAligned a3,
Struct3BytesInt2ByteAligned a4,
Struct3BytesInt2ByteAligned a5,
Struct3BytesInt2ByteAligned a6,
Struct3BytesInt2ByteAligned a7,
Struct3BytesInt2ByteAligned a8,
Struct3BytesInt2ByteAligned a9) {
std::cout << "PassStruct3BytesInt2ByteAlignedx10"
<< "((" << a0.a0 << ", " << static_cast<int>(a0.a1) << "), ("
<< a1.a0 << ", " << static_cast<int>(a1.a1) << "), (" << a2.a0
<< ", " << static_cast<int>(a2.a1) << "), (" << a3.a0 << ", "
<< static_cast<int>(a3.a1) << "), (" << a4.a0 << ", "
<< static_cast<int>(a4.a1) << "), (" << a5.a0 << ", "
<< static_cast<int>(a5.a1) << "), (" << a6.a0 << ", "
<< static_cast<int>(a6.a1) << "), (" << a7.a0 << ", "
<< static_cast<int>(a7.a1) << "), (" << a8.a0 << ", "
<< static_cast<int>(a8.a1) << "), (" << a9.a0 << ", "
<< static_cast<int>(a9.a1) << "))"
<< "\n";
int64_t result = 0;
result += a0.a0;
result += a0.a1;
result += a1.a0;
result += a1.a1;
result += a2.a0;
result += a2.a1;
result += a3.a0;
result += a3.a1;
result += a4.a0;
result += a4.a1;
result += a5.a0;
result += a5.a1;
result += a6.a0;
result += a6.a1;
result += a7.a0;
result += a7.a1;
result += a8.a0;
result += a8.a1;
result += a9.a0;
result += a9.a1;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Exactly word size on 32-bit architectures.
// 10 struct arguments will exhaust available registers.
DART_EXPORT int64_t
PassStruct4BytesHomogeneousInt16x10(Struct4BytesHomogeneousInt16 a0,
Struct4BytesHomogeneousInt16 a1,
Struct4BytesHomogeneousInt16 a2,
Struct4BytesHomogeneousInt16 a3,
Struct4BytesHomogeneousInt16 a4,
Struct4BytesHomogeneousInt16 a5,
Struct4BytesHomogeneousInt16 a6,
Struct4BytesHomogeneousInt16 a7,
Struct4BytesHomogeneousInt16 a8,
Struct4BytesHomogeneousInt16 a9) {
std::cout << "PassStruct4BytesHomogeneousInt16x10"
<< "((" << a0.a0 << ", " << a0.a1 << "), (" << a1.a0 << ", "
<< a1.a1 << "), (" << a2.a0 << ", " << a2.a1 << "), (" << a3.a0
<< ", " << a3.a1 << "), (" << a4.a0 << ", " << a4.a1 << "), ("
<< a5.a0 << ", " << a5.a1 << "), (" << a6.a0 << ", " << a6.a1
<< "), (" << a7.a0 << ", " << a7.a1 << "), (" << a8.a0 << ", "
<< a8.a1 << "), (" << a9.a0 << ", " << a9.a1 << "))"
<< "\n";
int64_t result = 0;
result += a0.a0;
result += a0.a1;
result += a1.a0;
result += a1.a1;
result += a2.a0;
result += a2.a1;
result += a3.a0;
result += a3.a1;
result += a4.a0;
result += a4.a1;
result += a5.a0;
result += a5.a1;
result += a6.a0;
result += a6.a1;
result += a7.a0;
result += a7.a1;
result += a8.a0;
result += a8.a1;
result += a9.a0;
result += a9.a1;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Sub word size on 64 bit architectures.
// 10 struct arguments will exhaust available registers.
DART_EXPORT int64_t
PassStruct7BytesHomogeneousUint8x10(Struct7BytesHomogeneousUint8 a0,
Struct7BytesHomogeneousUint8 a1,
Struct7BytesHomogeneousUint8 a2,
Struct7BytesHomogeneousUint8 a3,
Struct7BytesHomogeneousUint8 a4,
Struct7BytesHomogeneousUint8 a5,
Struct7BytesHomogeneousUint8 a6,
Struct7BytesHomogeneousUint8 a7,
Struct7BytesHomogeneousUint8 a8,
Struct7BytesHomogeneousUint8 a9) {
std::cout
<< "PassStruct7BytesHomogeneousUint8x10"
<< "((" << static_cast<int>(a0.a0) << ", " << static_cast<int>(a0.a1)
<< ", " << static_cast<int>(a0.a2) << ", " << static_cast<int>(a0.a3)
<< ", " << static_cast<int>(a0.a4) << ", " << static_cast<int>(a0.a5)
<< ", " << static_cast<int>(a0.a6) << "), (" << static_cast<int>(a1.a0)
<< ", " << static_cast<int>(a1.a1) << ", " << static_cast<int>(a1.a2)
<< ", " << static_cast<int>(a1.a3) << ", " << static_cast<int>(a1.a4)
<< ", " << static_cast<int>(a1.a5) << ", " << static_cast<int>(a1.a6)
<< "), (" << static_cast<int>(a2.a0) << ", " << static_cast<int>(a2.a1)
<< ", " << static_cast<int>(a2.a2) << ", " << static_cast<int>(a2.a3)
<< ", " << static_cast<int>(a2.a4) << ", " << static_cast<int>(a2.a5)
<< ", " << static_cast<int>(a2.a6) << "), (" << static_cast<int>(a3.a0)
<< ", " << static_cast<int>(a3.a1) << ", " << static_cast<int>(a3.a2)
<< ", " << static_cast<int>(a3.a3) << ", " << static_cast<int>(a3.a4)
<< ", " << static_cast<int>(a3.a5) << ", " << static_cast<int>(a3.a6)
<< "), (" << static_cast<int>(a4.a0) << ", " << static_cast<int>(a4.a1)
<< ", " << static_cast<int>(a4.a2) << ", " << static_cast<int>(a4.a3)
<< ", " << static_cast<int>(a4.a4) << ", " << static_cast<int>(a4.a5)
<< ", " << static_cast<int>(a4.a6) << "), (" << static_cast<int>(a5.a0)
<< ", " << static_cast<int>(a5.a1) << ", " << static_cast<int>(a5.a2)
<< ", " << static_cast<int>(a5.a3) << ", " << static_cast<int>(a5.a4)
<< ", " << static_cast<int>(a5.a5) << ", " << static_cast<int>(a5.a6)
<< "), (" << static_cast<int>(a6.a0) << ", " << static_cast<int>(a6.a1)
<< ", " << static_cast<int>(a6.a2) << ", " << static_cast<int>(a6.a3)
<< ", " << static_cast<int>(a6.a4) << ", " << static_cast<int>(a6.a5)
<< ", " << static_cast<int>(a6.a6) << "), (" << static_cast<int>(a7.a0)
<< ", " << static_cast<int>(a7.a1) << ", " << static_cast<int>(a7.a2)
<< ", " << static_cast<int>(a7.a3) << ", " << static_cast<int>(a7.a4)
<< ", " << static_cast<int>(a7.a5) << ", " << static_cast<int>(a7.a6)
<< "), (" << static_cast<int>(a8.a0) << ", " << static_cast<int>(a8.a1)
<< ", " << static_cast<int>(a8.a2) << ", " << static_cast<int>(a8.a3)
<< ", " << static_cast<int>(a8.a4) << ", " << static_cast<int>(a8.a5)
<< ", " << static_cast<int>(a8.a6) << "), (" << static_cast<int>(a9.a0)
<< ", " << static_cast<int>(a9.a1) << ", " << static_cast<int>(a9.a2)
<< ", " << static_cast<int>(a9.a3) << ", " << static_cast<int>(a9.a4)
<< ", " << static_cast<int>(a9.a5) << ", " << static_cast<int>(a9.a6)
<< "))"
<< "\n";
int64_t result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a0.a3;
result += a0.a4;
result += a0.a5;
result += a0.a6;
result += a1.a0;
result += a1.a1;
result += a1.a2;
result += a1.a3;
result += a1.a4;
result += a1.a5;
result += a1.a6;
result += a2.a0;
result += a2.a1;
result += a2.a2;
result += a2.a3;
result += a2.a4;
result += a2.a5;
result += a2.a6;
result += a3.a0;
result += a3.a1;
result += a3.a2;
result += a3.a3;
result += a3.a4;
result += a3.a5;
result += a3.a6;
result += a4.a0;
result += a4.a1;
result += a4.a2;
result += a4.a3;
result += a4.a4;
result += a4.a5;
result += a4.a6;
result += a5.a0;
result += a5.a1;
result += a5.a2;
result += a5.a3;
result += a5.a4;
result += a5.a5;
result += a5.a6;
result += a6.a0;
result += a6.a1;
result += a6.a2;
result += a6.a3;
result += a6.a4;
result += a6.a5;
result += a6.a6;
result += a7.a0;
result += a7.a1;
result += a7.a2;
result += a7.a3;
result += a7.a4;
result += a7.a5;
result += a7.a6;
result += a8.a0;
result += a8.a1;
result += a8.a2;
result += a8.a3;
result += a8.a4;
result += a8.a5;
result += a8.a6;
result += a9.a0;
result += a9.a1;
result += a9.a2;
result += a9.a3;
result += a9.a4;
result += a9.a5;
result += a9.a6;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Sub word size on 64 bit architectures.
// With alignment rules taken into account size is 8 bytes.
// 10 struct arguments will exhaust available registers.
DART_EXPORT int64_t
PassStruct7BytesInt4ByteAlignedx10(Struct7BytesInt4ByteAligned a0,
Struct7BytesInt4ByteAligned a1,
Struct7BytesInt4ByteAligned a2,
Struct7BytesInt4ByteAligned a3,
Struct7BytesInt4ByteAligned a4,
Struct7BytesInt4ByteAligned a5,
Struct7BytesInt4ByteAligned a6,
Struct7BytesInt4ByteAligned a7,
Struct7BytesInt4ByteAligned a8,
Struct7BytesInt4ByteAligned a9) {
std::cout << "PassStruct7BytesInt4ByteAlignedx10"
<< "((" << a0.a0 << ", " << a0.a1 << ", " << static_cast<int>(a0.a2)
<< "), (" << a1.a0 << ", " << a1.a1 << ", "
<< static_cast<int>(a1.a2) << "), (" << a2.a0 << ", " << a2.a1
<< ", " << static_cast<int>(a2.a2) << "), (" << a3.a0 << ", "
<< a3.a1 << ", " << static_cast<int>(a3.a2) << "), (" << a4.a0
<< ", " << a4.a1 << ", " << static_cast<int>(a4.a2) << "), ("
<< a5.a0 << ", " << a5.a1 << ", " << static_cast<int>(a5.a2)
<< "), (" << a6.a0 << ", " << a6.a1 << ", "
<< static_cast<int>(a6.a2) << "), (" << a7.a0 << ", " << a7.a1
<< ", " << static_cast<int>(a7.a2) << "), (" << a8.a0 << ", "
<< a8.a1 << ", " << static_cast<int>(a8.a2) << "), (" << a9.a0
<< ", " << a9.a1 << ", " << static_cast<int>(a9.a2) << "))"
<< "\n";
int64_t result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a1.a0;
result += a1.a1;
result += a1.a2;
result += a2.a0;
result += a2.a1;
result += a2.a2;
result += a3.a0;
result += a3.a1;
result += a3.a2;
result += a4.a0;
result += a4.a1;
result += a4.a2;
result += a5.a0;
result += a5.a1;
result += a5.a2;
result += a6.a0;
result += a6.a1;
result += a6.a2;
result += a7.a0;
result += a7.a1;
result += a7.a2;
result += a8.a0;
result += a8.a1;
result += a8.a2;
result += a9.a0;
result += a9.a1;
result += a9.a2;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Exactly word size struct on 64bit architectures.
// 10 struct arguments will exhaust available registers.
DART_EXPORT int64_t PassStruct8BytesIntx10(Struct8BytesInt a0,
Struct8BytesInt a1,
Struct8BytesInt a2,
Struct8BytesInt a3,
Struct8BytesInt a4,
Struct8BytesInt a5,
Struct8BytesInt a6,
Struct8BytesInt a7,
Struct8BytesInt a8,
Struct8BytesInt a9) {
std::cout << "PassStruct8BytesIntx10"
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << "), ("
<< a1.a0 << ", " << a1.a1 << ", " << a1.a2 << "), (" << a2.a0
<< ", " << a2.a1 << ", " << a2.a2 << "), (" << a3.a0 << ", "
<< a3.a1 << ", " << a3.a2 << "), (" << a4.a0 << ", " << a4.a1
<< ", " << a4.a2 << "), (" << a5.a0 << ", " << a5.a1 << ", "
<< a5.a2 << "), (" << a6.a0 << ", " << a6.a1 << ", " << a6.a2
<< "), (" << a7.a0 << ", " << a7.a1 << ", " << a7.a2 << "), ("
<< a8.a0 << ", " << a8.a1 << ", " << a8.a2 << "), (" << a9.a0
<< ", " << a9.a1 << ", " << a9.a2 << "))"
<< "\n";
int64_t result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a1.a0;
result += a1.a1;
result += a1.a2;
result += a2.a0;
result += a2.a1;
result += a2.a2;
result += a3.a0;
result += a3.a1;
result += a3.a2;
result += a4.a0;
result += a4.a1;
result += a4.a2;
result += a5.a0;
result += a5.a1;
result += a5.a2;
result += a6.a0;
result += a6.a1;
result += a6.a2;
result += a7.a0;
result += a7.a1;
result += a7.a2;
result += a8.a0;
result += a8.a1;
result += a8.a2;
result += a9.a0;
result += a9.a1;
result += a9.a2;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Arguments passed in FP registers as long as they fit.
// 10 struct arguments will exhaust available registers.
DART_EXPORT float PassStruct8BytesHomogeneousFloatx10(
Struct8BytesHomogeneousFloat a0,
Struct8BytesHomogeneousFloat a1,
Struct8BytesHomogeneousFloat a2,
Struct8BytesHomogeneousFloat a3,
Struct8BytesHomogeneousFloat a4,
Struct8BytesHomogeneousFloat a5,
Struct8BytesHomogeneousFloat a6,
Struct8BytesHomogeneousFloat a7,
Struct8BytesHomogeneousFloat a8,
Struct8BytesHomogeneousFloat a9) {
std::cout << "PassStruct8BytesHomogeneousFloatx10"
<< "((" << a0.a0 << ", " << a0.a1 << "), (" << a1.a0 << ", "
<< a1.a1 << "), (" << a2.a0 << ", " << a2.a1 << "), (" << a3.a0
<< ", " << a3.a1 << "), (" << a4.a0 << ", " << a4.a1 << "), ("
<< a5.a0 << ", " << a5.a1 << "), (" << a6.a0 << ", " << a6.a1
<< "), (" << a7.a0 << ", " << a7.a1 << "), (" << a8.a0 << ", "
<< a8.a1 << "), (" << a9.a0 << ", " << a9.a1 << "))"
<< "\n";
float result = 0;
result += a0.a0;
result += a0.a1;
result += a1.a0;
result += a1.a1;
result += a2.a0;
result += a2.a1;
result += a3.a0;
result += a3.a1;
result += a4.a0;
result += a4.a1;
result += a5.a0;
result += a5.a1;
result += a6.a0;
result += a6.a1;
result += a7.a0;
result += a7.a1;
result += a8.a0;
result += a8.a1;
result += a9.a0;
result += a9.a1;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// On x64, arguments go in int registers because it is not only float.
// 10 struct arguments will exhaust available registers.
DART_EXPORT float PassStruct8BytesMixedx10(Struct8BytesMixed a0,
Struct8BytesMixed a1,
Struct8BytesMixed a2,
Struct8BytesMixed a3,
Struct8BytesMixed a4,
Struct8BytesMixed a5,
Struct8BytesMixed a6,
Struct8BytesMixed a7,
Struct8BytesMixed a8,
Struct8BytesMixed a9) {
std::cout << "PassStruct8BytesMixedx10"
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << "), ("
<< a1.a0 << ", " << a1.a1 << ", " << a1.a2 << "), (" << a2.a0
<< ", " << a2.a1 << ", " << a2.a2 << "), (" << a3.a0 << ", "
<< a3.a1 << ", " << a3.a2 << "), (" << a4.a0 << ", " << a4.a1
<< ", " << a4.a2 << "), (" << a5.a0 << ", " << a5.a1 << ", "
<< a5.a2 << "), (" << a6.a0 << ", " << a6.a1 << ", " << a6.a2
<< "), (" << a7.a0 << ", " << a7.a1 << ", " << a7.a2 << "), ("
<< a8.a0 << ", " << a8.a1 << ", " << a8.a2 << "), (" << a9.a0
<< ", " << a9.a1 << ", " << a9.a2 << "))"
<< "\n";
float result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a1.a0;
result += a1.a1;
result += a1.a2;
result += a2.a0;
result += a2.a1;
result += a2.a2;
result += a3.a0;
result += a3.a1;
result += a3.a2;
result += a4.a0;
result += a4.a1;
result += a4.a2;
result += a5.a0;
result += a5.a1;
result += a5.a2;
result += a6.a0;
result += a6.a1;
result += a6.a2;
result += a7.a0;
result += a7.a1;
result += a7.a2;
result += a8.a0;
result += a8.a1;
result += a8.a2;
result += a9.a0;
result += a9.a1;
result += a9.a2;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// 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.
DART_EXPORT int64_t
PassStruct9BytesHomogeneousUint8x10(Struct9BytesHomogeneousUint8 a0,
Struct9BytesHomogeneousUint8 a1,
Struct9BytesHomogeneousUint8 a2,
Struct9BytesHomogeneousUint8 a3,
Struct9BytesHomogeneousUint8 a4,
Struct9BytesHomogeneousUint8 a5,
Struct9BytesHomogeneousUint8 a6,
Struct9BytesHomogeneousUint8 a7,
Struct9BytesHomogeneousUint8 a8,
Struct9BytesHomogeneousUint8 a9) {
std::cout
<< "PassStruct9BytesHomogeneousUint8x10"
<< "((" << static_cast<int>(a0.a0) << ", " << static_cast<int>(a0.a1)
<< ", " << static_cast<int>(a0.a2) << ", " << static_cast<int>(a0.a3)
<< ", " << static_cast<int>(a0.a4) << ", " << static_cast<int>(a0.a5)
<< ", " << static_cast<int>(a0.a6) << ", " << static_cast<int>(a0.a7)
<< ", " << static_cast<int>(a0.a8) << "), (" << static_cast<int>(a1.a0)
<< ", " << static_cast<int>(a1.a1) << ", " << static_cast<int>(a1.a2)
<< ", " << static_cast<int>(a1.a3) << ", " << static_cast<int>(a1.a4)
<< ", " << static_cast<int>(a1.a5) << ", " << static_cast<int>(a1.a6)
<< ", " << static_cast<int>(a1.a7) << ", " << static_cast<int>(a1.a8)
<< "), (" << static_cast<int>(a2.a0) << ", " << static_cast<int>(a2.a1)
<< ", " << static_cast<int>(a2.a2) << ", " << static_cast<int>(a2.a3)
<< ", " << static_cast<int>(a2.a4) << ", " << static_cast<int>(a2.a5)
<< ", " << static_cast<int>(a2.a6) << ", " << static_cast<int>(a2.a7)
<< ", " << static_cast<int>(a2.a8) << "), (" << static_cast<int>(a3.a0)
<< ", " << static_cast<int>(a3.a1) << ", " << static_cast<int>(a3.a2)
<< ", " << static_cast<int>(a3.a3) << ", " << static_cast<int>(a3.a4)
<< ", " << static_cast<int>(a3.a5) << ", " << static_cast<int>(a3.a6)
<< ", " << static_cast<int>(a3.a7) << ", " << static_cast<int>(a3.a8)
<< "), (" << static_cast<int>(a4.a0) << ", " << static_cast<int>(a4.a1)
<< ", " << static_cast<int>(a4.a2) << ", " << static_cast<int>(a4.a3)
<< ", " << static_cast<int>(a4.a4) << ", " << static_cast<int>(a4.a5)
<< ", " << static_cast<int>(a4.a6) << ", " << static_cast<int>(a4.a7)
<< ", " << static_cast<int>(a4.a8) << "), (" << static_cast<int>(a5.a0)
<< ", " << static_cast<int>(a5.a1) << ", " << static_cast<int>(a5.a2)
<< ", " << static_cast<int>(a5.a3) << ", " << static_cast<int>(a5.a4)
<< ", " << static_cast<int>(a5.a5) << ", " << static_cast<int>(a5.a6)
<< ", " << static_cast<int>(a5.a7) << ", " << static_cast<int>(a5.a8)
<< "), (" << static_cast<int>(a6.a0) << ", " << static_cast<int>(a6.a1)
<< ", " << static_cast<int>(a6.a2) << ", " << static_cast<int>(a6.a3)
<< ", " << static_cast<int>(a6.a4) << ", " << static_cast<int>(a6.a5)
<< ", " << static_cast<int>(a6.a6) << ", " << static_cast<int>(a6.a7)
<< ", " << static_cast<int>(a6.a8) << "), (" << static_cast<int>(a7.a0)
<< ", " << static_cast<int>(a7.a1) << ", " << static_cast<int>(a7.a2)
<< ", " << static_cast<int>(a7.a3) << ", " << static_cast<int>(a7.a4)
<< ", " << static_cast<int>(a7.a5) << ", " << static_cast<int>(a7.a6)
<< ", " << static_cast<int>(a7.a7) << ", " << static_cast<int>(a7.a8)
<< "), (" << static_cast<int>(a8.a0) << ", " << static_cast<int>(a8.a1)
<< ", " << static_cast<int>(a8.a2) << ", " << static_cast<int>(a8.a3)
<< ", " << static_cast<int>(a8.a4) << ", " << static_cast<int>(a8.a5)
<< ", " << static_cast<int>(a8.a6) << ", " << static_cast<int>(a8.a7)
<< ", " << static_cast<int>(a8.a8) << "), (" << static_cast<int>(a9.a0)
<< ", " << static_cast<int>(a9.a1) << ", " << static_cast<int>(a9.a2)
<< ", " << static_cast<int>(a9.a3) << ", " << static_cast<int>(a9.a4)
<< ", " << static_cast<int>(a9.a5) << ", " << static_cast<int>(a9.a6)
<< ", " << static_cast<int>(a9.a7) << ", " << static_cast<int>(a9.a8)
<< "))"
<< "\n";
int64_t result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a0.a3;
result += a0.a4;
result += a0.a5;
result += a0.a6;
result += a0.a7;
result += a0.a8;
result += a1.a0;
result += a1.a1;
result += a1.a2;
result += a1.a3;
result += a1.a4;
result += a1.a5;
result += a1.a6;
result += a1.a7;
result += a1.a8;
result += a2.a0;
result += a2.a1;
result += a2.a2;
result += a2.a3;
result += a2.a4;
result += a2.a5;
result += a2.a6;
result += a2.a7;
result += a2.a8;
result += a3.a0;
result += a3.a1;
result += a3.a2;
result += a3.a3;
result += a3.a4;
result += a3.a5;
result += a3.a6;
result += a3.a7;
result += a3.a8;
result += a4.a0;
result += a4.a1;
result += a4.a2;
result += a4.a3;
result += a4.a4;
result += a4.a5;
result += a4.a6;
result += a4.a7;
result += a4.a8;
result += a5.a0;
result += a5.a1;
result += a5.a2;
result += a5.a3;
result += a5.a4;
result += a5.a5;
result += a5.a6;
result += a5.a7;
result += a5.a8;
result += a6.a0;
result += a6.a1;
result += a6.a2;
result += a6.a3;
result += a6.a4;
result += a6.a5;
result += a6.a6;
result += a6.a7;
result += a6.a8;
result += a7.a0;
result += a7.a1;
result += a7.a2;
result += a7.a3;
result += a7.a4;
result += a7.a5;
result += a7.a6;
result += a7.a7;
result += a7.a8;
result += a8.a0;
result += a8.a1;
result += a8.a2;
result += a8.a3;
result += a8.a4;
result += a8.a5;
result += a8.a6;
result += a8.a7;
result += a8.a8;
result += a9.a0;
result += a9.a1;
result += a9.a2;
result += a9.a3;
result += a9.a4;
result += a9.a5;
result += a9.a6;
result += a9.a7;
result += a9.a8;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// 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.
//
DART_EXPORT int64_t
PassStruct9BytesInt4Or8ByteAlignedx10(Struct9BytesInt4Or8ByteAligned a0,
Struct9BytesInt4Or8ByteAligned a1,
Struct9BytesInt4Or8ByteAligned a2,
Struct9BytesInt4Or8ByteAligned a3,
Struct9BytesInt4Or8ByteAligned a4,
Struct9BytesInt4Or8ByteAligned a5,
Struct9BytesInt4Or8ByteAligned a6,
Struct9BytesInt4Or8ByteAligned a7,
Struct9BytesInt4Or8ByteAligned a8,
Struct9BytesInt4Or8ByteAligned a9) {
std::cout << "PassStruct9BytesInt4Or8ByteAlignedx10"
<< "((" << a0.a0 << ", " << static_cast<int>(a0.a1) << "), ("
<< a1.a0 << ", " << static_cast<int>(a1.a1) << "), (" << a2.a0
<< ", " << static_cast<int>(a2.a1) << "), (" << a3.a0 << ", "
<< static_cast<int>(a3.a1) << "), (" << a4.a0 << ", "
<< static_cast<int>(a4.a1) << "), (" << a5.a0 << ", "
<< static_cast<int>(a5.a1) << "), (" << a6.a0 << ", "
<< static_cast<int>(a6.a1) << "), (" << a7.a0 << ", "
<< static_cast<int>(a7.a1) << "), (" << a8.a0 << ", "
<< static_cast<int>(a8.a1) << "), (" << a9.a0 << ", "
<< static_cast<int>(a9.a1) << "))"
<< "\n";
int64_t result = 0;
result += a0.a0;
result += a0.a1;
result += a1.a0;
result += a1.a1;
result += a2.a0;
result += a2.a1;
result += a3.a0;
result += a3.a1;
result += a4.a0;
result += a4.a1;
result += a5.a0;
result += a5.a1;
result += a6.a0;
result += a6.a1;
result += a7.a0;
result += a7.a1;
result += a8.a0;
result += a8.a1;
result += a9.a0;
result += a9.a1;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// 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.
DART_EXPORT float PassStruct12BytesHomogeneousFloatx6(
Struct12BytesHomogeneousFloat a0,
Struct12BytesHomogeneousFloat a1,
Struct12BytesHomogeneousFloat a2,
Struct12BytesHomogeneousFloat a3,
Struct12BytesHomogeneousFloat a4,
Struct12BytesHomogeneousFloat a5) {
std::cout << "PassStruct12BytesHomogeneousFloatx6"
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << "), ("
<< a1.a0 << ", " << a1.a1 << ", " << a1.a2 << "), (" << a2.a0
<< ", " << a2.a1 << ", " << a2.a2 << "), (" << a3.a0 << ", "
<< a3.a1 << ", " << a3.a2 << "), (" << a4.a0 << ", " << a4.a1
<< ", " << a4.a2 << "), (" << a5.a0 << ", " << a5.a1 << ", "
<< a5.a2 << "))"
<< "\n";
float result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a1.a0;
result += a1.a1;
result += a1.a2;
result += a2.a0;
result += a2.a1;
result += a2.a2;
result += a3.a0;
result += a3.a1;
result += a3.a2;
result += a4.a0;
result += a4.a1;
result += a4.a2;
result += a5.a0;
result += a5.a1;
result += a5.a2;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// 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.
DART_EXPORT float PassStruct16BytesHomogeneousFloatx5(
Struct16BytesHomogeneousFloat a0,
Struct16BytesHomogeneousFloat a1,
Struct16BytesHomogeneousFloat a2,
Struct16BytesHomogeneousFloat a3,
Struct16BytesHomogeneousFloat a4) {
std::cout << "PassStruct16BytesHomogeneousFloatx5"
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< "), (" << a1.a0 << ", " << a1.a1 << ", " << a1.a2 << ", "
<< a1.a3 << "), (" << a2.a0 << ", " << a2.a1 << ", " << a2.a2
<< ", " << a2.a3 << "), (" << a3.a0 << ", " << a3.a1 << ", "
<< a3.a2 << ", " << a3.a3 << "), (" << a4.a0 << ", " << a4.a1
<< ", " << a4.a2 << ", " << a4.a3 << "))"
<< "\n";
float result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a0.a3;
result += a1.a0;
result += a1.a1;
result += a1.a2;
result += a1.a3;
result += a2.a0;
result += a2.a1;
result += a2.a2;
result += a2.a3;
result += a3.a0;
result += a3.a1;
result += a3.a2;
result += a3.a3;
result += a4.a0;
result += a4.a1;
result += a4.a2;
result += a4.a3;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// 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.
DART_EXPORT double PassStruct16BytesMixedx10(Struct16BytesMixed a0,
Struct16BytesMixed a1,
Struct16BytesMixed a2,
Struct16BytesMixed a3,
Struct16BytesMixed a4,
Struct16BytesMixed a5,
Struct16BytesMixed a6,
Struct16BytesMixed a7,
Struct16BytesMixed a8,
Struct16BytesMixed a9) {
std::cout << "PassStruct16BytesMixedx10"
<< "((" << a0.a0 << ", " << a0.a1 << "), (" << a1.a0 << ", "
<< a1.a1 << "), (" << a2.a0 << ", " << a2.a1 << "), (" << a3.a0
<< ", " << a3.a1 << "), (" << a4.a0 << ", " << a4.a1 << "), ("
<< a5.a0 << ", " << a5.a1 << "), (" << a6.a0 << ", " << a6.a1
<< "), (" << a7.a0 << ", " << a7.a1 << "), (" << a8.a0 << ", "
<< a8.a1 << "), (" << a9.a0 << ", " << a9.a1 << "))"
<< "\n";
double result = 0;
result += a0.a0;
result += a0.a1;
result += a1.a0;
result += a1.a1;
result += a2.a0;
result += a2.a1;
result += a3.a0;
result += a3.a1;
result += a4.a0;
result += a4.a1;
result += a5.a0;
result += a5.a1;
result += a6.a0;
result += a6.a1;
result += a7.a0;
result += a7.a1;
result += a8.a0;
result += a8.a1;
result += a9.a0;
result += a9.a1;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// 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.
DART_EXPORT float PassStruct16BytesMixed2x10(Struct16BytesMixed2 a0,
Struct16BytesMixed2 a1,
Struct16BytesMixed2 a2,
Struct16BytesMixed2 a3,
Struct16BytesMixed2 a4,
Struct16BytesMixed2 a5,
Struct16BytesMixed2 a6,
Struct16BytesMixed2 a7,
Struct16BytesMixed2 a8,
Struct16BytesMixed2 a9) {
std::cout << "PassStruct16BytesMixed2x10"
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< "), (" << a1.a0 << ", " << a1.a1 << ", " << a1.a2 << ", "
<< a1.a3 << "), (" << a2.a0 << ", " << a2.a1 << ", " << a2.a2
<< ", " << a2.a3 << "), (" << a3.a0 << ", " << a3.a1 << ", "
<< a3.a2 << ", " << a3.a3 << "), (" << a4.a0 << ", " << a4.a1
<< ", " << a4.a2 << ", " << a4.a3 << "), (" << a5.a0 << ", "
<< a5.a1 << ", " << a5.a2 << ", " << a5.a3 << "), (" << a6.a0
<< ", " << a6.a1 << ", " << a6.a2 << ", " << a6.a3 << "), ("
<< a7.a0 << ", " << a7.a1 << ", " << a7.a2 << ", " << a7.a3
<< "), (" << a8.a0 << ", " << a8.a1 << ", " << a8.a2 << ", "
<< a8.a3 << "), (" << a9.a0 << ", " << a9.a1 << ", " << a9.a2
<< ", " << a9.a3 << "))"
<< "\n";
float result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a0.a3;
result += a1.a0;
result += a1.a1;
result += a1.a2;
result += a1.a3;
result += a2.a0;
result += a2.a1;
result += a2.a2;
result += a2.a3;
result += a3.a0;
result += a3.a1;
result += a3.a2;
result += a3.a3;
result += a4.a0;
result += a4.a1;
result += a4.a2;
result += a4.a3;
result += a5.a0;
result += a5.a1;
result += a5.a2;
result += a5.a3;
result += a6.a0;
result += a6.a1;
result += a6.a2;
result += a6.a3;
result += a7.a0;
result += a7.a1;
result += a7.a2;
result += a7.a3;
result += a8.a0;
result += a8.a1;
result += a8.a2;
result += a8.a3;
result += a9.a0;
result += a9.a1;
result += a9.a2;
result += a9.a3;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Arguments are passed as pointer to copy on arm64.
// Tests that the memory allocated for copies are rounded up to word size.
DART_EXPORT int64_t PassStruct17BytesIntx10(Struct17BytesInt a0,
Struct17BytesInt a1,
Struct17BytesInt a2,
Struct17BytesInt a3,
Struct17BytesInt a4,
Struct17BytesInt a5,
Struct17BytesInt a6,
Struct17BytesInt a7,
Struct17BytesInt a8,
Struct17BytesInt a9) {
std::cout << "PassStruct17BytesIntx10"
<< "((" << a0.a0 << ", " << a0.a1 << ", " << static_cast<int>(a0.a2)
<< "), (" << a1.a0 << ", " << a1.a1 << ", "
<< static_cast<int>(a1.a2) << "), (" << a2.a0 << ", " << a2.a1
<< ", " << static_cast<int>(a2.a2) << "), (" << a3.a0 << ", "
<< a3.a1 << ", " << static_cast<int>(a3.a2) << "), (" << a4.a0
<< ", " << a4.a1 << ", " << static_cast<int>(a4.a2) << "), ("
<< a5.a0 << ", " << a5.a1 << ", " << static_cast<int>(a5.a2)
<< "), (" << a6.a0 << ", " << a6.a1 << ", "
<< static_cast<int>(a6.a2) << "), (" << a7.a0 << ", " << a7.a1
<< ", " << static_cast<int>(a7.a2) << "), (" << a8.a0 << ", "
<< a8.a1 << ", " << static_cast<int>(a8.a2) << "), (" << a9.a0
<< ", " << a9.a1 << ", " << static_cast<int>(a9.a2) << "))"
<< "\n";
int64_t result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a1.a0;
result += a1.a1;
result += a1.a2;
result += a2.a0;
result += a2.a1;
result += a2.a2;
result += a3.a0;
result += a3.a1;
result += a3.a2;
result += a4.a0;
result += a4.a1;
result += a4.a2;
result += a5.a0;
result += a5.a1;
result += a5.a2;
result += a6.a0;
result += a6.a1;
result += a6.a2;
result += a7.a0;
result += a7.a1;
result += a7.a2;
result += a8.a0;
result += a8.a1;
result += a8.a2;
result += a9.a0;
result += a9.a1;
result += a9.a2;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// 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.
//
DART_EXPORT int64_t
PassStruct19BytesHomogeneousUint8x10(Struct19BytesHomogeneousUint8 a0,
Struct19BytesHomogeneousUint8 a1,
Struct19BytesHomogeneousUint8 a2,
Struct19BytesHomogeneousUint8 a3,
Struct19BytesHomogeneousUint8 a4,
Struct19BytesHomogeneousUint8 a5,
Struct19BytesHomogeneousUint8 a6,
Struct19BytesHomogeneousUint8 a7,
Struct19BytesHomogeneousUint8 a8,
Struct19BytesHomogeneousUint8 a9) {
std::cout
<< "PassStruct19BytesHomogeneousUint8x10"
<< "((" << static_cast<int>(a0.a0) << ", " << static_cast<int>(a0.a1)
<< ", " << static_cast<int>(a0.a2) << ", " << static_cast<int>(a0.a3)
<< ", " << static_cast<int>(a0.a4) << ", " << static_cast<int>(a0.a5)
<< ", " << static_cast<int>(a0.a6) << ", " << static_cast<int>(a0.a7)
<< ", " << static_cast<int>(a0.a8) << ", " << static_cast<int>(a0.a9)
<< ", " << static_cast<int>(a0.a10) << ", " << static_cast<int>(a0.a11)
<< ", " << static_cast<int>(a0.a12) << ", " << static_cast<int>(a0.a13)
<< ", " << static_cast<int>(a0.a14) << ", " << static_cast<int>(a0.a15)
<< ", " << static_cast<int>(a0.a16) << ", " << static_cast<int>(a0.a17)
<< ", " << static_cast<int>(a0.a18) << "), (" << static_cast<int>(a1.a0)
<< ", " << static_cast<int>(a1.a1) << ", " << static_cast<int>(a1.a2)
<< ", " << static_cast<int>(a1.a3) << ", " << static_cast<int>(a1.a4)
<< ", " << static_cast<int>(a1.a5) << ", " << static_cast<int>(a1.a6)
<< ", " << static_cast<int>(a1.a7) << ", " << static_cast<int>(a1.a8)
<< ", " << static_cast<int>(a1.a9) << ", " << static_cast<int>(a1.a10)
<< ", " << static_cast<int>(a1.a11) << ", " << static_cast<int>(a1.a12)
<< ", " << static_cast<int>(a1.a13) << ", " << static_cast<int>(a1.a14)
<< ", " << static_cast<int>(a1.a15) << ", " << static_cast<int>(a1.a16)
<< ", " << static_cast<int>(a1.a17) << ", " << static_cast<int>(a1.a18)
<< "), (" << static_cast<int>(a2.a0) << ", " << static_cast<int>(a2.a1)
<< ", " << static_cast<int>(a2.a2) << ", " << static_cast<int>(a2.a3)
<< ", " << static_cast<int>(a2.a4) << ", " << static_cast<int>(a2.a5)
<< ", " << static_cast<int>(a2.a6) << ", " << static_cast<int>(a2.a7)
<< ", " << static_cast<int>(a2.a8) << ", " << static_cast<int>(a2.a9)
<< ", " << static_cast<int>(a2.a10) << ", " << static_cast<int>(a2.a11)
<< ", " << static_cast<int>(a2.a12) << ", " << static_cast<int>(a2.a13)
<< ", " << static_cast<int>(a2.a14) << ", " << static_cast<int>(a2.a15)
<< ", " << static_cast<int>(a2.a16) << ", " << static_cast<int>(a2.a17)
<< ", " << static_cast<int>(a2.a18) << "), (" << static_cast<int>(a3.a0)
<< ", " << static_cast<int>(a3.a1) << ", " << static_cast<int>(a3.a2)
<< ", " << static_cast<int>(a3.a3) << ", " << static_cast<int>(a3.a4)
<< ", " << static_cast<int>(a3.a5) << ", " << static_cast<int>(a3.a6)
<< ", " << static_cast<int>(a3.a7) << ", " << static_cast<int>(a3.a8)
<< ", " << static_cast<int>(a3.a9) << ", " << static_cast<int>(a3.a10)
<< ", " << static_cast<int>(a3.a11) << ", " << static_cast<int>(a3.a12)
<< ", " << static_cast<int>(a3.a13) << ", " << static_cast<int>(a3.a14)
<< ", " << static_cast<int>(a3.a15) << ", " << static_cast<int>(a3.a16)
<< ", " << static_cast<int>(a3.a17) << ", " << static_cast<int>(a3.a18)
<< "), (" << static_cast<int>(a4.a0) << ", " << static_cast<int>(a4.a1)
<< ", " << static_cast<int>(a4.a2) << ", " << static_cast<int>(a4.a3)
<< ", " << static_cast<int>(a4.a4) << ", " << static_cast<int>(a4.a5)
<< ", " << static_cast<int>(a4.a6) << ", " << static_cast<int>(a4.a7)
<< ", " << static_cast<int>(a4.a8) << ", " << static_cast<int>(a4.a9)
<< ", " << static_cast<int>(a4.a10) << ", " << static_cast<int>(a4.a11)
<< ", " << static_cast<int>(a4.a12) << ", " << static_cast<int>(a4.a13)
<< ", " << static_cast<int>(a4.a14) << ", " << static_cast<int>(a4.a15)
<< ", " << static_cast<int>(a4.a16) << ", " << static_cast<int>(a4.a17)
<< ", " << static_cast<int>(a4.a18) << "), (" << static_cast<int>(a5.a0)
<< ", " << static_cast<int>(a5.a1) << ", " << static_cast<int>(a5.a2)
<< ", " << static_cast<int>(a5.a3) << ", " << static_cast<int>(a5.a4)
<< ", " << static_cast<int>(a5.a5) << ", " << static_cast<int>(a5.a6)
<< ", " << static_cast<int>(a5.a7) << ", " << static_cast<int>(a5.a8)
<< ", " << static_cast<int>(a5.a9) << ", " << static_cast<int>(a5.a10)
<< ", " << static_cast<int>(a5.a11) << ", " << static_cast<int>(a5.a12)
<< ", " << static_cast<int>(a5.a13) << ", " << static_cast<int>(a5.a14)
<< ", " << static_cast<int>(a5.a15) << ", " << static_cast<int>(a5.a16)
<< ", " << static_cast<int>(a5.a17) << ", " << static_cast<int>(a5.a18)
<< "), (" << static_cast<int>(a6.a0) << ", " << static_cast<int>(a6.a1)
<< ", " << static_cast<int>(a6.a2) << ", " << static_cast<int>(a6.a3)
<< ", " << static_cast<int>(a6.a4) << ", " << static_cast<int>(a6.a5)
<< ", " << static_cast<int>(a6.a6) << ", " << static_cast<int>(a6.a7)
<< ", " << static_cast<int>(a6.a8) << ", " << static_cast<int>(a6.a9)
<< ", " << static_cast<int>(a6.a10) << ", " << static_cast<int>(a6.a11)
<< ", " << static_cast<int>(a6.a12) << ", " << static_cast<int>(a6.a13)
<< ", " << static_cast<int>(a6.a14) << ", " << static_cast<int>(a6.a15)
<< ", " << static_cast<int>(a6.a16) << ", " << static_cast<int>(a6.a17)
<< ", " << static_cast<int>(a6.a18) << "), (" << static_cast<int>(a7.a0)
<< ", " << static_cast<int>(a7.a1) << ", " << static_cast<int>(a7.a2)
<< ", " << static_cast<int>(a7.a3) << ", " << static_cast<int>(a7.a4)
<< ", " << static_cast<int>(a7.a5) << ", " << static_cast<int>(a7.a6)
<< ", " << static_cast<int>(a7.a7) << ", " << static_cast<int>(a7.a8)
<< ", " << static_cast<int>(a7.a9) << ", " << static_cast<int>(a7.a10)
<< ", " << static_cast<int>(a7.a11) << ", " << static_cast<int>(a7.a12)
<< ", " << static_cast<int>(a7.a13) << ", " << static_cast<int>(a7.a14)
<< ", " << static_cast<int>(a7.a15) << ", " << static_cast<int>(a7.a16)
<< ", " << static_cast<int>(a7.a17) << ", " << static_cast<int>(a7.a18)
<< "), (" << static_cast<int>(a8.a0) << ", " << static_cast<int>(a8.a1)
<< ", " << static_cast<int>(a8.a2) << ", " << static_cast<int>(a8.a3)
<< ", " << static_cast<int>(a8.a4) << ", " << static_cast<int>(a8.a5)
<< ", " << static_cast<int>(a8.a6) << ", " << static_cast<int>(a8.a7)
<< ", " << static_cast<int>(a8.a8) << ", " << static_cast<int>(a8.a9)
<< ", " << static_cast<int>(a8.a10) << ", " << static_cast<int>(a8.a11)
<< ", " << static_cast<int>(a8.a12) << ", " << static_cast<int>(a8.a13)
<< ", " << static_cast<int>(a8.a14) << ", " << static_cast<int>(a8.a15)
<< ", " << static_cast<int>(a8.a16) << ", " << static_cast<int>(a8.a17)
<< ", " << static_cast<int>(a8.a18) << "), (" << static_cast<int>(a9.a0)
<< ", " << static_cast<int>(a9.a1) << ", " << static_cast<int>(a9.a2)
<< ", " << static_cast<int>(a9.a3) << ", " << static_cast<int>(a9.a4)
<< ", " << static_cast<int>(a9.a5) << ", " << static_cast<int>(a9.a6)
<< ", " << static_cast<int>(a9.a7) << ", " << static_cast<int>(a9.a8)
<< ", " << static_cast<int>(a9.a9) << ", " << static_cast<int>(a9.a10)
<< ", " << static_cast<int>(a9.a11) << ", " << static_cast<int>(a9.a12)
<< ", " << static_cast<int>(a9.a13) << ", " << static_cast<int>(a9.a14)
<< ", " << static_cast<int>(a9.a15) << ", " << static_cast<int>(a9.a16)
<< ", " << static_cast<int>(a9.a17) << ", " << static_cast<int>(a9.a18)
<< "))"
<< "\n";
int64_t result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a0.a3;
result += a0.a4;
result += a0.a5;
result += a0.a6;
result += a0.a7;
result += a0.a8;
result += a0.a9;
result += a0.a10;
result += a0.a11;
result += a0.a12;
result += a0.a13;
result += a0.a14;
result += a0.a15;
result += a0.a16;
result += a0.a17;
result += a0.a18;
result += a1.a0;
result += a1.a1;
result += a1.a2;
result += a1.a3;
result += a1.a4;
result += a1.a5;
result += a1.a6;
result += a1.a7;
result += a1.a8;
result += a1.a9;
result += a1.a10;
result += a1.a11;
result += a1.a12;
result += a1.a13;
result += a1.a14;
result += a1.a15;
result += a1.a16;
result += a1.a17;
result += a1.a18;
result += a2.a0;
result += a2.a1;
result += a2.a2;
result += a2.a3;
result += a2.a4;
result += a2.a5;
result += a2.a6;
result += a2.a7;
result += a2.a8;
result += a2.a9;
result += a2.a10;
result += a2.a11;
result += a2.a12;
result += a2.a13;
result += a2.a14;
result += a2.a15;
result += a2.a16;
result += a2.a17;
result += a2.a18;
result += a3.a0;
result += a3.a1;
result += a3.a2;
result += a3.a3;
result += a3.a4;
result += a3.a5;
result += a3.a6;
result += a3.a7;
result += a3.a8;
result += a3.a9;
result += a3.a10;
result += a3.a11;
result += a3.a12;
result += a3.a13;
result += a3.a14;
result += a3.a15;
result += a3.a16;
result += a3.a17;
result += a3.a18;
result += a4.a0;
result += a4.a1;
result += a4.a2;
result += a4.a3;
result += a4.a4;
result += a4.a5;
result += a4.a6;
result += a4.a7;
result += a4.a8;
result += a4.a9;
result += a4.a10;
result += a4.a11;
result += a4.a12;
result += a4.a13;
result += a4.a14;
result += a4.a15;
result += a4.a16;
result += a4.a17;
result += a4.a18;
result += a5.a0;
result += a5.a1;
result += a5.a2;
result += a5.a3;
result += a5.a4;
result += a5.a5;
result += a5.a6;
result += a5.a7;
result += a5.a8;
result += a5.a9;
result += a5.a10;
result += a5.a11;
result += a5.a12;
result += a5.a13;
result += a5.a14;
result += a5.a15;
result += a5.a16;
result += a5.a17;
result += a5.a18;
result += a6.a0;
result += a6.a1;
result += a6.a2;
result += a6.a3;
result += a6.a4;
result += a6.a5;
result += a6.a6;
result += a6.a7;
result += a6.a8;
result += a6.a9;
result += a6.a10;
result += a6.a11;
result += a6.a12;
result += a6.a13;
result += a6.a14;
result += a6.a15;
result += a6.a16;
result += a6.a17;
result += a6.a18;
result += a7.a0;
result += a7.a1;
result += a7.a2;
result += a7.a3;
result += a7.a4;
result += a7.a5;
result += a7.a6;
result += a7.a7;
result += a7.a8;
result += a7.a9;
result += a7.a10;
result += a7.a11;
result += a7.a12;
result += a7.a13;
result += a7.a14;
result += a7.a15;
result += a7.a16;
result += a7.a17;
result += a7.a18;
result += a8.a0;
result += a8.a1;
result += a8.a2;
result += a8.a3;
result += a8.a4;
result += a8.a5;
result += a8.a6;
result += a8.a7;
result += a8.a8;
result += a8.a9;
result += a8.a10;
result += a8.a11;
result += a8.a12;
result += a8.a13;
result += a8.a14;
result += a8.a15;
result += a8.a16;
result += a8.a17;
result += a8.a18;
result += a9.a0;
result += a9.a1;
result += a9.a2;
result += a9.a3;
result += a9.a4;
result += a9.a5;
result += a9.a6;
result += a9.a7;
result += a9.a8;
result += a9.a9;
result += a9.a10;
result += a9.a11;
result += a9.a12;
result += a9.a13;
result += a9.a14;
result += a9.a15;
result += a9.a16;
result += a9.a17;
result += a9.a18;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// 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.
DART_EXPORT int32_t
PassStruct20BytesHomogeneousInt32x10(Struct20BytesHomogeneousInt32 a0,
Struct20BytesHomogeneousInt32 a1,
Struct20BytesHomogeneousInt32 a2,
Struct20BytesHomogeneousInt32 a3,
Struct20BytesHomogeneousInt32 a4,
Struct20BytesHomogeneousInt32 a5,
Struct20BytesHomogeneousInt32 a6,
Struct20BytesHomogeneousInt32 a7,
Struct20BytesHomogeneousInt32 a8,
Struct20BytesHomogeneousInt32 a9) {
std::cout << "PassStruct20BytesHomogeneousInt32x10"
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< ", " << a0.a4 << "), (" << a1.a0 << ", " << a1.a1 << ", "
<< a1.a2 << ", " << a1.a3 << ", " << a1.a4 << "), (" << a2.a0
<< ", " << a2.a1 << ", " << a2.a2 << ", " << a2.a3 << ", " << a2.a4
<< "), (" << a3.a0 << ", " << a3.a1 << ", " << a3.a2 << ", "
<< a3.a3 << ", " << a3.a4 << "), (" << a4.a0 << ", " << a4.a1
<< ", " << a4.a2 << ", " << a4.a3 << ", " << a4.a4 << "), ("
<< a5.a0 << ", " << a5.a1 << ", " << a5.a2 << ", " << a5.a3 << ", "
<< a5.a4 << "), (" << a6.a0 << ", " << a6.a1 << ", " << a6.a2
<< ", " << a6.a3 << ", " << a6.a4 << "), (" << a7.a0 << ", "
<< a7.a1 << ", " << a7.a2 << ", " << a7.a3 << ", " << a7.a4
<< "), (" << a8.a0 << ", " << a8.a1 << ", " << a8.a2 << ", "
<< a8.a3 << ", " << a8.a4 << "), (" << a9.a0 << ", " << a9.a1
<< ", " << a9.a2 << ", " << a9.a3 << ", " << a9.a4 << "))"
<< "\n";
int32_t result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a0.a3;
result += a0.a4;
result += a1.a0;
result += a1.a1;
result += a1.a2;
result += a1.a3;
result += a1.a4;
result += a2.a0;
result += a2.a1;
result += a2.a2;
result += a2.a3;
result += a2.a4;
result += a3.a0;
result += a3.a1;
result += a3.a2;
result += a3.a3;
result += a3.a4;
result += a4.a0;
result += a4.a1;
result += a4.a2;
result += a4.a3;
result += a4.a4;
result += a5.a0;
result += a5.a1;
result += a5.a2;
result += a5.a3;
result += a5.a4;
result += a6.a0;
result += a6.a1;
result += a6.a2;
result += a6.a3;
result += a6.a4;
result += a7.a0;
result += a7.a1;
result += a7.a2;
result += a7.a3;
result += a7.a4;
result += a8.a0;
result += a8.a1;
result += a8.a2;
result += a8.a3;
result += a8.a4;
result += a9.a0;
result += a9.a1;
result += a9.a2;
result += a9.a3;
result += a9.a4;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Argument too big to go into FPU registers in hardfp and arm64.
DART_EXPORT float PassStruct20BytesHomogeneousFloat(
Struct20BytesHomogeneousFloat a0) {
std::cout << "PassStruct20BytesHomogeneousFloat"
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< ", " << a0.a4 << "))"
<< "\n";
float result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a0.a3;
result += a0.a4;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Arguments in FPU registers on arm64.
// 5 struct arguments will exhaust available registers.
DART_EXPORT double PassStruct32BytesHomogeneousDoublex5(
Struct32BytesHomogeneousDouble a0,
Struct32BytesHomogeneousDouble a1,
Struct32BytesHomogeneousDouble a2,
Struct32BytesHomogeneousDouble a3,
Struct32BytesHomogeneousDouble a4) {
std::cout << "PassStruct32BytesHomogeneousDoublex5"
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< "), (" << a1.a0 << ", " << a1.a1 << ", " << a1.a2 << ", "
<< a1.a3 << "), (" << a2.a0 << ", " << a2.a1 << ", " << a2.a2
<< ", " << a2.a3 << "), (" << a3.a0 << ", " << a3.a1 << ", "
<< a3.a2 << ", " << a3.a3 << "), (" << a4.a0 << ", " << a4.a1
<< ", " << a4.a2 << ", " << a4.a3 << "))"
<< "\n";
double result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a0.a3;
result += a1.a0;
result += a1.a1;
result += a1.a2;
result += a1.a3;
result += a2.a0;
result += a2.a1;
result += a2.a2;
result += a2.a3;
result += a3.a0;
result += a3.a1;
result += a3.a2;
result += a3.a3;
result += a4.a0;
result += a4.a1;
result += a4.a2;
result += a4.a3;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Argument too big to go into FPU registers in arm64.
DART_EXPORT double PassStruct40BytesHomogeneousDouble(
Struct40BytesHomogeneousDouble a0) {
std::cout << "PassStruct40BytesHomogeneousDouble"
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< ", " << a0.a4 << "))"
<< "\n";
double result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a0.a3;
result += a0.a4;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Test 1kb struct.
DART_EXPORT uint64_t
PassStruct1024BytesHomogeneousUint64(Struct1024BytesHomogeneousUint64 a0) {
std::cout << "PassStruct1024BytesHomogeneousUint64"
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< ", " << a0.a4 << ", " << a0.a5 << ", " << a0.a6 << ", " << a0.a7
<< ", " << a0.a8 << ", " << a0.a9 << ", " << a0.a10 << ", "
<< a0.a11 << ", " << a0.a12 << ", " << a0.a13 << ", " << a0.a14
<< ", " << a0.a15 << ", " << a0.a16 << ", " << a0.a17 << ", "
<< a0.a18 << ", " << a0.a19 << ", " << a0.a20 << ", " << a0.a21
<< ", " << a0.a22 << ", " << a0.a23 << ", " << a0.a24 << ", "
<< a0.a25 << ", " << a0.a26 << ", " << a0.a27 << ", " << a0.a28
<< ", " << a0.a29 << ", " << a0.a30 << ", " << a0.a31 << ", "
<< a0.a32 << ", " << a0.a33 << ", " << a0.a34 << ", " << a0.a35
<< ", " << a0.a36 << ", " << a0.a37 << ", " << a0.a38 << ", "
<< a0.a39 << ", " << a0.a40 << ", " << a0.a41 << ", " << a0.a42
<< ", " << a0.a43 << ", " << a0.a44 << ", " << a0.a45 << ", "
<< a0.a46 << ", " << a0.a47 << ", " << a0.a48 << ", " << a0.a49
<< ", " << a0.a50 << ", " << a0.a51 << ", " << a0.a52 << ", "
<< a0.a53 << ", " << a0.a54 << ", " << a0.a55 << ", " << a0.a56
<< ", " << a0.a57 << ", " << a0.a58 << ", " << a0.a59 << ", "
<< a0.a60 << ", " << a0.a61 << ", " << a0.a62 << ", " << a0.a63
<< ", " << a0.a64 << ", " << a0.a65 << ", " << a0.a66 << ", "
<< a0.a67 << ", " << a0.a68 << ", " << a0.a69 << ", " << a0.a70
<< ", " << a0.a71 << ", " << a0.a72 << ", " << a0.a73 << ", "
<< a0.a74 << ", " << a0.a75 << ", " << a0.a76 << ", " << a0.a77
<< ", " << a0.a78 << ", " << a0.a79 << ", " << a0.a80 << ", "
<< a0.a81 << ", " << a0.a82 << ", " << a0.a83 << ", " << a0.a84
<< ", " << a0.a85 << ", " << a0.a86 << ", " << a0.a87 << ", "
<< a0.a88 << ", " << a0.a89 << ", " << a0.a90 << ", " << a0.a91
<< ", " << a0.a92 << ", " << a0.a93 << ", " << a0.a94 << ", "
<< a0.a95 << ", " << a0.a96 << ", " << a0.a97 << ", " << a0.a98
<< ", " << a0.a99 << ", " << a0.a100 << ", " << a0.a101 << ", "
<< a0.a102 << ", " << a0.a103 << ", " << a0.a104 << ", " << a0.a105
<< ", " << a0.a106 << ", " << a0.a107 << ", " << a0.a108 << ", "
<< a0.a109 << ", " << a0.a110 << ", " << a0.a111 << ", " << a0.a112
<< ", " << a0.a113 << ", " << a0.a114 << ", " << a0.a115 << ", "
<< a0.a116 << ", " << a0.a117 << ", " << a0.a118 << ", " << a0.a119
<< ", " << a0.a120 << ", " << a0.a121 << ", " << a0.a122 << ", "
<< a0.a123 << ", " << a0.a124 << ", " << a0.a125 << ", " << a0.a126
<< ", " << a0.a127 << "))"
<< "\n";
uint64_t result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a0.a3;
result += a0.a4;
result += a0.a5;
result += a0.a6;
result += a0.a7;
result += a0.a8;
result += a0.a9;
result += a0.a10;
result += a0.a11;
result += a0.a12;
result += a0.a13;
result += a0.a14;
result += a0.a15;
result += a0.a16;
result += a0.a17;
result += a0.a18;
result += a0.a19;
result += a0.a20;
result += a0.a21;
result += a0.a22;
result += a0.a23;
result += a0.a24;
result += a0.a25;
result += a0.a26;
result += a0.a27;
result += a0.a28;
result += a0.a29;
result += a0.a30;
result += a0.a31;
result += a0.a32;
result += a0.a33;
result += a0.a34;
result += a0.a35;
result += a0.a36;
result += a0.a37;
result += a0.a38;
result += a0.a39;
result += a0.a40;
result += a0.a41;
result += a0.a42;
result += a0.a43;
result += a0.a44;
result += a0.a45;
result += a0.a46;
result += a0.a47;
result += a0.a48;
result += a0.a49;
result += a0.a50;
result += a0.a51;
result += a0.a52;
result += a0.a53;
result += a0.a54;
result += a0.a55;
result += a0.a56;
result += a0.a57;
result += a0.a58;
result += a0.a59;
result += a0.a60;
result += a0.a61;
result += a0.a62;
result += a0.a63;
result += a0.a64;
result += a0.a65;
result += a0.a66;
result += a0.a67;
result += a0.a68;
result += a0.a69;
result += a0.a70;
result += a0.a71;
result += a0.a72;
result += a0.a73;
result += a0.a74;
result += a0.a75;
result += a0.a76;
result += a0.a77;
result += a0.a78;
result += a0.a79;
result += a0.a80;
result += a0.a81;
result += a0.a82;
result += a0.a83;
result += a0.a84;
result += a0.a85;
result += a0.a86;
result += a0.a87;
result += a0.a88;
result += a0.a89;
result += a0.a90;
result += a0.a91;
result += a0.a92;
result += a0.a93;
result += a0.a94;
result += a0.a95;
result += a0.a96;
result += a0.a97;
result += a0.a98;
result += a0.a99;
result += a0.a100;
result += a0.a101;
result += a0.a102;
result += a0.a103;
result += a0.a104;
result += a0.a105;
result += a0.a106;
result += a0.a107;
result += a0.a108;
result += a0.a109;
result += a0.a110;
result += a0.a111;
result += a0.a112;
result += a0.a113;
result += a0.a114;
result += a0.a115;
result += a0.a116;
result += a0.a117;
result += a0.a118;
result += a0.a119;
result += a0.a120;
result += a0.a121;
result += a0.a122;
result += a0.a123;
result += a0.a124;
result += a0.a125;
result += a0.a126;
result += a0.a127;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Tests the alignment of structs in FPU registers and backfilling.
DART_EXPORT float PassFloatStruct16BytesHomogeneousFloatFloatStruct1(
float a0,
Struct16BytesHomogeneousFloat a1,
float a2,
Struct16BytesHomogeneousFloat a3,
float a4,
Struct16BytesHomogeneousFloat a5,
float a6,
Struct16BytesHomogeneousFloat a7,
float a8) {
std::cout << "PassFloatStruct16BytesHomogeneousFloatFloatStruct1"
<< "(" << a0 << ", (" << a1.a0 << ", " << a1.a1 << ", " << a1.a2
<< ", " << a1.a3 << "), " << a2 << ", (" << a3.a0 << ", " << a3.a1
<< ", " << a3.a2 << ", " << a3.a3 << "), " << a4 << ", (" << a5.a0
<< ", " << a5.a1 << ", " << a5.a2 << ", " << a5.a3 << "), " << a6
<< ", (" << a7.a0 << ", " << a7.a1 << ", " << a7.a2 << ", " << a7.a3
<< "), " << a8 << ")"
<< "\n";
float result = 0;
result += a0;
result += a1.a0;
result += a1.a1;
result += a1.a2;
result += a1.a3;
result += a2;
result += a3.a0;
result += a3.a1;
result += a3.a2;
result += a3.a3;
result += a4;
result += a5.a0;
result += a5.a1;
result += a5.a2;
result += a5.a3;
result += a6;
result += a7.a0;
result += a7.a1;
result += a7.a2;
result += a7.a3;
result += a8;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Tests the alignment of structs in FPU registers and backfilling.
DART_EXPORT double PassFloatStruct32BytesHomogeneousDoubleFloatStruct(
float a0,
Struct32BytesHomogeneousDouble a1,
float a2,
Struct32BytesHomogeneousDouble a3,
float a4,
Struct32BytesHomogeneousDouble a5,
float a6,
Struct32BytesHomogeneousDouble a7,
float a8) {
std::cout << "PassFloatStruct32BytesHomogeneousDoubleFloatStruct"
<< "(" << a0 << ", (" << a1.a0 << ", " << a1.a1 << ", " << a1.a2
<< ", " << a1.a3 << "), " << a2 << ", (" << a3.a0 << ", " << a3.a1
<< ", " << a3.a2 << ", " << a3.a3 << "), " << a4 << ", (" << a5.a0
<< ", " << a5.a1 << ", " << a5.a2 << ", " << a5.a3 << "), " << a6
<< ", (" << a7.a0 << ", " << a7.a1 << ", " << a7.a2 << ", " << a7.a3
<< "), " << a8 << ")"
<< "\n";
double result = 0;
result += a0;
result += a1.a0;
result += a1.a1;
result += a1.a2;
result += a1.a3;
result += a2;
result += a3.a0;
result += a3.a1;
result += a3.a2;
result += a3.a3;
result += a4;
result += a5.a0;
result += a5.a1;
result += a5.a2;
result += a5.a3;
result += a6;
result += a7.a0;
result += a7.a1;
result += a7.a2;
result += a7.a3;
result += a8;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// 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.
DART_EXPORT double PassInt8Struct16BytesMixedInt8Struct16BytesMixedIn(
int8_t a0,
Struct16BytesMixed a1,
int8_t a2,
Struct16BytesMixed a3,
int8_t a4,
Struct16BytesMixed a5,
int8_t a6,
Struct16BytesMixed a7,
int8_t a8) {
std::cout << "PassInt8Struct16BytesMixedInt8Struct16BytesMixedIn"
<< "(" << static_cast<int>(a0) << ", (" << a1.a0 << ", " << a1.a1
<< "), " << static_cast<int>(a2) << ", (" << a3.a0 << ", " << a3.a1
<< "), " << static_cast<int>(a4) << ", (" << a5.a0 << ", " << a5.a1
<< "), " << static_cast<int>(a6) << ", (" << a7.a0 << ", " << a7.a1
<< "), " << static_cast<int>(a8) << ")"
<< "\n";
double result = 0;
result += a0;
result += a1.a0;
result += a1.a1;
result += a2;
result += a3.a0;
result += a3.a1;
result += a4;
result += a5.a0;
result += a5.a1;
result += a6;
result += a7.a0;
result += a7.a1;
result += a8;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// 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.
DART_EXPORT double PassDoublex6Struct16BytesMixedx4Int32(double a0,
double a1,
double a2,
double a3,
double a4,
double a5,
Struct16BytesMixed a6,
Struct16BytesMixed a7,
Struct16BytesMixed a8,
Struct16BytesMixed a9,
int32_t a10) {
std::cout << "PassDoublex6Struct16BytesMixedx4Int32"
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
<< ", " << a5 << ", (" << a6.a0 << ", " << a6.a1 << "), (" << a7.a0
<< ", " << a7.a1 << "), (" << a8.a0 << ", " << a8.a1 << "), ("
<< a9.a0 << ", " << a9.a1 << "), " << a10 << ")"
<< "\n";
double result = 0;
result += a0;
result += a1;
result += a2;
result += a3;
result += a4;
result += a5;
result += a6.a0;
result += a6.a1;
result += a7.a0;
result += a7.a1;
result += a8.a0;
result += a8.a1;
result += a9.a0;
result += a9.a1;
result += a10;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// 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.
DART_EXPORT double PassInt32x4Struct16BytesMixedx4Double(int32_t a0,
int32_t a1,
int32_t a2,
int32_t a3,
Struct16BytesMixed a4,
Struct16BytesMixed a5,
Struct16BytesMixed a6,
Struct16BytesMixed a7,
double a8) {
std::cout << "PassInt32x4Struct16BytesMixedx4Double"
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", ("
<< a4.a0 << ", " << a4.a1 << "), (" << a5.a0 << ", " << a5.a1
<< "), (" << a6.a0 << ", " << a6.a1 << "), (" << a7.a0 << ", "
<< a7.a1 << "), " << a8 << ")"
<< "\n";
double result = 0;
result += a0;
result += a1;
result += a2;
result += a3;
result += a4.a0;
result += a4.a1;
result += a5.a0;
result += a5.a1;
result += a6.a0;
result += a6.a1;
result += a7.a0;
result += a7.a1;
result += a8;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// On various architectures, first struct is allocated on stack.
// Check that the other two arguments are allocated on registers.
DART_EXPORT double PassStruct40BytesHomogeneousDoubleStruct4BytesHomo(
Struct40BytesHomogeneousDouble a0,
Struct4BytesHomogeneousInt16 a1,
Struct8BytesHomogeneousFloat a2) {
std::cout << "PassStruct40BytesHomogeneousDoubleStruct4BytesHomo"
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< ", " << a0.a4 << "), (" << a1.a0 << ", " << a1.a1 << "), ("
<< a2.a0 << ", " << a2.a1 << "))"
<< "\n";
double result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a0.a3;
result += a0.a4;
result += a1.a0;
result += a1.a1;
result += a2.a0;
result += a2.a1;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Test alignment and padding of 16 byte int within struct.
DART_EXPORT double PassInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int(
int32_t a0,
int32_t a1,
int32_t a2,
int32_t a3,
int32_t a4,
int32_t a5,
int32_t a6,
int32_t a7,
double a8,
double a9,
double a10,
double a11,
double a12,
double a13,
double a14,
double a15,
int64_t a16,
int8_t a17,
Struct1ByteInt a18,
int64_t a19,
int8_t a20,
Struct4BytesHomogeneousInt16 a21,
int64_t a22,
int8_t a23,
Struct8BytesInt a24,
int64_t a25,
int8_t a26,
Struct8BytesHomogeneousFloat a27,
int64_t a28,
int8_t a29,
Struct8BytesMixed a30,
int64_t a31,
int8_t a32,
StructAlignmentInt16 a33,
int64_t a34,
int8_t a35,
StructAlignmentInt32 a36,
int64_t a37,
int8_t a38,
StructAlignmentInt64 a39) {
std::cout << "PassInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int"
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
<< ", " << a5 << ", " << a6 << ", " << a7 << ", " << a8 << ", "
<< a9 << ", " << a10 << ", " << a11 << ", " << a12 << ", " << a13
<< ", " << a14 << ", " << a15 << ", " << a16 << ", "
<< static_cast<int>(a17) << ", (" << static_cast<int>(a18.a0)
<< "), " << a19 << ", " << static_cast<int>(a20) << ", (" << a21.a0
<< ", " << a21.a1 << "), " << a22 << ", " << static_cast<int>(a23)
<< ", (" << a24.a0 << ", " << a24.a1 << ", " << a24.a2 << "), "
<< a25 << ", " << static_cast<int>(a26) << ", (" << a27.a0 << ", "
<< a27.a1 << "), " << a28 << ", " << static_cast<int>(a29) << ", ("
<< a30.a0 << ", " << a30.a1 << ", " << a30.a2 << "), " << a31
<< ", " << static_cast<int>(a32) << ", ("
<< static_cast<int>(a33.a0) << ", " << a33.a1 << ", "
<< static_cast<int>(a33.a2) << "), " << a34 << ", "
<< static_cast<int>(a35) << ", (" << static_cast<int>(a36.a0)
<< ", " << a36.a1 << ", " << static_cast<int>(a36.a2) << "), "
<< a37 << ", " << static_cast<int>(a38) << ", ("
<< static_cast<int>(a39.a0) << ", " << a39.a1 << ", "
<< static_cast<int>(a39.a2) << "))"
<< "\n";
double result = 0;
result += a0;
result += a1;
result += a2;
result += a3;
result += a4;
result += a5;
result += a6;
result += a7;
result += a8;
result += a9;
result += a10;
result += a11;
result += a12;
result += a13;
result += a14;
result += a15;
result += a16;
result += a17;
result += a18.a0;
result += a19;
result += a20;
result += a21.a0;
result += a21.a1;
result += a22;
result += a23;
result += a24.a0;
result += a24.a1;
result += a24.a2;
result += a25;
result += a26;
result += a27.a0;
result += a27.a1;
result += a28;
result += a29;
result += a30.a0;
result += a30.a1;
result += a30.a2;
result += a31;
result += a32;
result += a33.a0;
result += a33.a1;
result += a33.a2;
result += a34;
result += a35;
result += a36.a0;
result += a36.a1;
result += a36.a2;
result += a37;
result += a38;
result += a39.a0;
result += a39.a1;
result += a39.a2;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Test alignment and padding of 16 byte int within struct.
DART_EXPORT int64_t PassStructAlignmentInt16(StructAlignmentInt16 a0) {
std::cout << "PassStructAlignmentInt16"
<< "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << ", "
<< static_cast<int>(a0.a2) << "))"
<< "\n";
int64_t result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Test alignment and padding of 32 byte int within struct.
DART_EXPORT int64_t PassStructAlignmentInt32(StructAlignmentInt32 a0) {
std::cout << "PassStructAlignmentInt32"
<< "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << ", "
<< static_cast<int>(a0.a2) << "))"
<< "\n";
int64_t result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Test alignment and padding of 64 byte int within struct.
DART_EXPORT int64_t PassStructAlignmentInt64(StructAlignmentInt64 a0) {
std::cout << "PassStructAlignmentInt64"
<< "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << ", "
<< static_cast<int>(a0.a2) << "))"
<< "\n";
int64_t result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Simple nested struct. No alignment gaps on any architectures.
// 10 arguments exhaust registers on all platforms.
DART_EXPORT int64_t PassStruct8BytesNestedIntx10(Struct8BytesNestedInt a0,
Struct8BytesNestedInt a1,
Struct8BytesNestedInt a2,
Struct8BytesNestedInt a3,
Struct8BytesNestedInt a4,
Struct8BytesNestedInt a5,
Struct8BytesNestedInt a6,
Struct8BytesNestedInt a7,
Struct8BytesNestedInt a8,
Struct8BytesNestedInt a9) {
std::cout << "PassStruct8BytesNestedIntx10"
<< "(((" << a0.a0.a0 << ", " << a0.a0.a1 << "), (" << a0.a1.a0
<< ", " << a0.a1.a1 << ")), ((" << a1.a0.a0 << ", " << a1.a0.a1
<< "), (" << a1.a1.a0 << ", " << a1.a1.a1 << ")), ((" << a2.a0.a0
<< ", " << a2.a0.a1 << "), (" << a2.a1.a0 << ", " << a2.a1.a1
<< ")), ((" << a3.a0.a0 << ", " << a3.a0.a1 << "), (" << a3.a1.a0
<< ", " << a3.a1.a1 << ")), ((" << a4.a0.a0 << ", " << a4.a0.a1
<< "), (" << a4.a1.a0 << ", " << a4.a1.a1 << ")), ((" << a5.a0.a0
<< ", " << a5.a0.a1 << "), (" << a5.a1.a0 << ", " << a5.a1.a1
<< ")), ((" << a6.a0.a0 << ", " << a6.a0.a1 << "), (" << a6.a1.a0
<< ", " << a6.a1.a1 << ")), ((" << a7.a0.a0 << ", " << a7.a0.a1
<< "), (" << a7.a1.a0 << ", " << a7.a1.a1 << ")), ((" << a8.a0.a0
<< ", " << a8.a0.a1 << "), (" << a8.a1.a0 << ", " << a8.a1.a1
<< ")), ((" << a9.a0.a0 << ", " << a9.a0.a1 << "), (" << a9.a1.a0
<< ", " << a9.a1.a1 << ")))"
<< "\n";
int64_t result = 0;
result += a0.a0.a0;
result += a0.a0.a1;
result += a0.a1.a0;
result += a0.a1.a1;
result += a1.a0.a0;
result += a1.a0.a1;
result += a1.a1.a0;
result += a1.a1.a1;
result += a2.a0.a0;
result += a2.a0.a1;
result += a2.a1.a0;
result += a2.a1.a1;
result += a3.a0.a0;
result += a3.a0.a1;
result += a3.a1.a0;
result += a3.a1.a1;
result += a4.a0.a0;
result += a4.a0.a1;
result += a4.a1.a0;
result += a4.a1.a1;
result += a5.a0.a0;
result += a5.a0.a1;
result += a5.a1.a0;
result += a5.a1.a1;
result += a6.a0.a0;
result += a6.a0.a1;
result += a6.a1.a0;
result += a6.a1.a1;
result += a7.a0.a0;
result += a7.a0.a1;
result += a7.a1.a0;
result += a7.a1.a1;
result += a8.a0.a0;
result += a8.a0.a1;
result += a8.a1.a0;
result += a8.a1.a1;
result += a9.a0.a0;
result += a9.a0.a1;
result += a9.a1.a0;
result += a9.a1.a1;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Simple nested struct. No alignment gaps on any architectures.
// 10 arguments exhaust fpu registers on all platforms.
DART_EXPORT float PassStruct8BytesNestedFloatx10(Struct8BytesNestedFloat a0,
Struct8BytesNestedFloat a1,
Struct8BytesNestedFloat a2,
Struct8BytesNestedFloat a3,
Struct8BytesNestedFloat a4,
Struct8BytesNestedFloat a5,
Struct8BytesNestedFloat a6,
Struct8BytesNestedFloat a7,
Struct8BytesNestedFloat a8,
Struct8BytesNestedFloat a9) {
std::cout << "PassStruct8BytesNestedFloatx10"
<< "(((" << a0.a0.a0 << "), (" << a0.a1.a0 << ")), ((" << a1.a0.a0
<< "), (" << a1.a1.a0 << ")), ((" << a2.a0.a0 << "), (" << a2.a1.a0
<< ")), ((" << a3.a0.a0 << "), (" << a3.a1.a0 << ")), (("
<< a4.a0.a0 << "), (" << a4.a1.a0 << ")), ((" << a5.a0.a0 << "), ("
<< a5.a1.a0 << ")), ((" << a6.a0.a0 << "), (" << a6.a1.a0
<< ")), ((" << a7.a0.a0 << "), (" << a7.a1.a0 << ")), (("
<< a8.a0.a0 << "), (" << a8.a1.a0 << ")), ((" << a9.a0.a0 << "), ("
<< a9.a1.a0 << ")))"
<< "\n";
float result = 0;
result += a0.a0.a0;
result += a0.a1.a0;
result += a1.a0.a0;
result += a1.a1.a0;
result += a2.a0.a0;
result += a2.a1.a0;
result += a3.a0.a0;
result += a3.a1.a0;
result += a4.a0.a0;
result += a4.a1.a0;
result += a5.a0.a0;
result += a5.a1.a0;
result += a6.a0.a0;
result += a6.a1.a0;
result += a7.a0.a0;
result += a7.a1.a0;
result += a8.a0.a0;
result += a8.a1.a0;
result += a9.a0.a0;
result += a9.a1.a0;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// 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.
DART_EXPORT float PassStruct8BytesNestedFloat2x10(Struct8BytesNestedFloat2 a0,
Struct8BytesNestedFloat2 a1,
Struct8BytesNestedFloat2 a2,
Struct8BytesNestedFloat2 a3,
Struct8BytesNestedFloat2 a4,
Struct8BytesNestedFloat2 a5,
Struct8BytesNestedFloat2 a6,
Struct8BytesNestedFloat2 a7,
Struct8BytesNestedFloat2 a8,
Struct8BytesNestedFloat2 a9) {
std::cout << "PassStruct8BytesNestedFloat2x10"
<< "(((" << a0.a0.a0 << "), " << a0.a1 << "), ((" << a1.a0.a0
<< "), " << a1.a1 << "), ((" << a2.a0.a0 << "), " << a2.a1
<< "), ((" << a3.a0.a0 << "), " << a3.a1 << "), ((" << a4.a0.a0
<< "), " << a4.a1 << "), ((" << a5.a0.a0 << "), " << a5.a1
<< "), ((" << a6.a0.a0 << "), " << a6.a1 << "), ((" << a7.a0.a0
<< "), " << a7.a1 << "), ((" << a8.a0.a0 << "), " << a8.a1
<< "), ((" << a9.a0.a0 << "), " << a9.a1 << "))"
<< "\n";
float result = 0;
result += a0.a0.a0;
result += a0.a1;
result += a1.a0.a0;
result += a1.a1;
result += a2.a0.a0;
result += a2.a1;
result += a3.a0.a0;
result += a3.a1;
result += a4.a0.a0;
result += a4.a1;
result += a5.a0.a0;
result += a5.a1;
result += a6.a0.a0;
result += a6.a1;
result += a7.a0.a0;
result += a7.a1;
result += a8.a0.a0;
result += a8.a1;
result += a9.a0.a0;
result += a9.a1;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Simple nested struct. No alignment gaps on any architectures.
// 10 arguments exhaust all registers on all platforms.
DART_EXPORT double PassStruct8BytesNestedMixedx10(Struct8BytesNestedMixed a0,
Struct8BytesNestedMixed a1,
Struct8BytesNestedMixed a2,
Struct8BytesNestedMixed a3,
Struct8BytesNestedMixed a4,
Struct8BytesNestedMixed a5,
Struct8BytesNestedMixed a6,
Struct8BytesNestedMixed a7,
Struct8BytesNestedMixed a8,
Struct8BytesNestedMixed a9) {
std::cout << "PassStruct8BytesNestedMixedx10"
<< "(((" << a0.a0.a0 << ", " << a0.a0.a1 << "), (" << a0.a1.a0
<< ")), ((" << a1.a0.a0 << ", " << a1.a0.a1 << "), (" << a1.a1.a0
<< ")), ((" << a2.a0.a0 << ", " << a2.a0.a1 << "), (" << a2.a1.a0
<< ")), ((" << a3.a0.a0 << ", " << a3.a0.a1 << "), (" << a3.a1.a0
<< ")), ((" << a4.a0.a0 << ", " << a4.a0.a1 << "), (" << a4.a1.a0
<< ")), ((" << a5.a0.a0 << ", " << a5.a0.a1 << "), (" << a5.a1.a0
<< ")), ((" << a6.a0.a0 << ", " << a6.a0.a1 << "), (" << a6.a1.a0
<< ")), ((" << a7.a0.a0 << ", " << a7.a0.a1 << "), (" << a7.a1.a0
<< ")), ((" << a8.a0.a0 << ", " << a8.a0.a1 << "), (" << a8.a1.a0
<< ")), ((" << a9.a0.a0 << ", " << a9.a0.a1 << "), (" << a9.a1.a0
<< ")))"
<< "\n";
double result = 0;
result += a0.a0.a0;
result += a0.a0.a1;
result += a0.a1.a0;
result += a1.a0.a0;
result += a1.a0.a1;
result += a1.a1.a0;
result += a2.a0.a0;
result += a2.a0.a1;
result += a2.a1.a0;
result += a3.a0.a0;
result += a3.a0.a1;
result += a3.a1.a0;
result += a4.a0.a0;
result += a4.a0.a1;
result += a4.a1.a0;
result += a5.a0.a0;
result += a5.a0.a1;
result += a5.a1.a0;
result += a6.a0.a0;
result += a6.a0.a1;
result += a6.a1.a0;
result += a7.a0.a0;
result += a7.a0.a1;
result += a7.a1.a0;
result += a8.a0.a0;
result += a8.a0.a1;
result += a8.a1.a0;
result += a9.a0.a0;
result += a9.a0.a1;
result += a9.a1.a0;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Deeper nested struct to test recursive member access.
DART_EXPORT int64_t PassStruct16BytesNestedIntx2(Struct16BytesNestedInt a0,
Struct16BytesNestedInt a1) {
std::cout << "PassStruct16BytesNestedIntx2"
<< "((((" << a0.a0.a0.a0 << ", " << a0.a0.a0.a1 << "), ("
<< a0.a0.a1.a0 << ", " << a0.a0.a1.a1 << ")), ((" << a0.a1.a0.a0
<< ", " << a0.a1.a0.a1 << "), (" << a0.a1.a1.a0 << ", "
<< a0.a1.a1.a1 << "))), (((" << a1.a0.a0.a0 << ", " << a1.a0.a0.a1
<< "), (" << a1.a0.a1.a0 << ", " << a1.a0.a1.a1 << ")), (("
<< a1.a1.a0.a0 << ", " << a1.a1.a0.a1 << "), (" << a1.a1.a1.a0
<< ", " << a1.a1.a1.a1 << "))))"
<< "\n";
int64_t result = 0;
result += a0.a0.a0.a0;
result += a0.a0.a0.a1;
result += a0.a0.a1.a0;
result += a0.a0.a1.a1;
result += a0.a1.a0.a0;
result += a0.a1.a0.a1;
result += a0.a1.a1.a0;
result += a0.a1.a1.a1;
result += a1.a0.a0.a0;
result += a1.a0.a0.a1;
result += a1.a0.a1.a0;
result += a1.a0.a1.a1;
result += a1.a1.a0.a0;
result += a1.a1.a0.a1;
result += a1.a1.a1.a0;
result += a1.a1.a1.a1;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Even deeper nested struct to test recursive member access.
DART_EXPORT int64_t PassStruct32BytesNestedIntx2(Struct32BytesNestedInt a0,
Struct32BytesNestedInt a1) {
std::cout << "PassStruct32BytesNestedIntx2"
<< "(((((" << a0.a0.a0.a0.a0 << ", " << a0.a0.a0.a0.a1 << "), ("
<< a0.a0.a0.a1.a0 << ", " << a0.a0.a0.a1.a1 << ")), (("
<< a0.a0.a1.a0.a0 << ", " << a0.a0.a1.a0.a1 << "), ("
<< a0.a0.a1.a1.a0 << ", " << a0.a0.a1.a1.a1 << "))), ((("
<< a0.a1.a0.a0.a0 << ", " << a0.a1.a0.a0.a1 << "), ("
<< a0.a1.a0.a1.a0 << ", " << a0.a1.a0.a1.a1 << ")), (("
<< a0.a1.a1.a0.a0 << ", " << a0.a1.a1.a0.a1 << "), ("
<< a0.a1.a1.a1.a0 << ", " << a0.a1.a1.a1.a1 << ")))), (((("
<< a1.a0.a0.a0.a0 << ", " << a1.a0.a0.a0.a1 << "), ("
<< a1.a0.a0.a1.a0 << ", " << a1.a0.a0.a1.a1 << ")), (("
<< a1.a0.a1.a0.a0 << ", " << a1.a0.a1.a0.a1 << "), ("
<< a1.a0.a1.a1.a0 << ", " << a1.a0.a1.a1.a1 << "))), ((("
<< a1.a1.a0.a0.a0 << ", " << a1.a1.a0.a0.a1 << "), ("
<< a1.a1.a0.a1.a0 << ", " << a1.a1.a0.a1.a1 << ")), (("
<< a1.a1.a1.a0.a0 << ", " << a1.a1.a1.a0.a1 << "), ("
<< a1.a1.a1.a1.a0 << ", " << a1.a1.a1.a1.a1 << ")))))"
<< "\n";
int64_t result = 0;
result += a0.a0.a0.a0.a0;
result += a0.a0.a0.a0.a1;
result += a0.a0.a0.a1.a0;
result += a0.a0.a0.a1.a1;
result += a0.a0.a1.a0.a0;
result += a0.a0.a1.a0.a1;
result += a0.a0.a1.a1.a0;
result += a0.a0.a1.a1.a1;
result += a0.a1.a0.a0.a0;
result += a0.a1.a0.a0.a1;
result += a0.a1.a0.a1.a0;
result += a0.a1.a0.a1.a1;
result += a0.a1.a1.a0.a0;
result += a0.a1.a1.a0.a1;
result += a0.a1.a1.a1.a0;
result += a0.a1.a1.a1.a1;
result += a1.a0.a0.a0.a0;
result += a1.a0.a0.a0.a1;
result += a1.a0.a0.a1.a0;
result += a1.a0.a0.a1.a1;
result += a1.a0.a1.a0.a0;
result += a1.a0.a1.a0.a1;
result += a1.a0.a1.a1.a0;
result += a1.a0.a1.a1.a1;
result += a1.a1.a0.a0.a0;
result += a1.a1.a0.a0.a1;
result += a1.a1.a0.a1.a0;
result += a1.a1.a0.a1.a1;
result += a1.a1.a1.a0.a0;
result += a1.a1.a1.a0.a1;
result += a1.a1.a1.a1.a0;
result += a1.a1.a1.a1.a1;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Test alignment and padding of nested struct with 16 byte int.
DART_EXPORT int64_t PassStructNestedIntStructAlignmentInt16(
StructNestedIntStructAlignmentInt16 a0) {
std::cout << "PassStructNestedIntStructAlignmentInt16"
<< "(((" << static_cast<int>(a0.a0.a0) << ", " << a0.a0.a1 << ", "
<< static_cast<int>(a0.a0.a2) << "), ("
<< static_cast<int>(a0.a1.a0) << ", " << a0.a1.a1 << ", "
<< static_cast<int>(a0.a1.a2) << ")))"
<< "\n";
int64_t result = 0;
result += a0.a0.a0;
result += a0.a0.a1;
result += a0.a0.a2;
result += a0.a1.a0;
result += a0.a1.a1;
result += a0.a1.a2;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Test alignment and padding of nested struct with 32 byte int.
DART_EXPORT int64_t PassStructNestedIntStructAlignmentInt32(
StructNestedIntStructAlignmentInt32 a0) {
std::cout << "PassStructNestedIntStructAlignmentInt32"
<< "(((" << static_cast<int>(a0.a0.a0) << ", " << a0.a0.a1 << ", "
<< static_cast<int>(a0.a0.a2) << "), ("
<< static_cast<int>(a0.a1.a0) << ", " << a0.a1.a1 << ", "
<< static_cast<int>(a0.a1.a2) << ")))"
<< "\n";
int64_t result = 0;
result += a0.a0.a0;
result += a0.a0.a1;
result += a0.a0.a2;
result += a0.a1.a0;
result += a0.a1.a1;
result += a0.a1.a2;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Test alignment and padding of nested struct with 64 byte int.
DART_EXPORT int64_t PassStructNestedIntStructAlignmentInt64(
StructNestedIntStructAlignmentInt64 a0) {
std::cout << "PassStructNestedIntStructAlignmentInt64"
<< "(((" << static_cast<int>(a0.a0.a0) << ", " << a0.a0.a1 << ", "
<< static_cast<int>(a0.a0.a2) << "), ("
<< static_cast<int>(a0.a1.a0) << ", " << a0.a1.a1 << ", "
<< static_cast<int>(a0.a1.a2) << ")))"
<< "\n";
int64_t result = 0;
result += a0.a0.a0;
result += a0.a0.a1;
result += a0.a0.a2;
result += a0.a1.a0;
result += a0.a1.a1;
result += a0.a1.a2;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Return big irregular struct as smoke test.
DART_EXPORT double PassStructNestedIrregularEvenBiggerx4(
StructNestedIrregularEvenBigger a0,
StructNestedIrregularEvenBigger a1,
StructNestedIrregularEvenBigger a2,
StructNestedIrregularEvenBigger a3) {
std::cout
<< "PassStructNestedIrregularEvenBiggerx4"
<< "((" << a0.a0 << ", ((" << a0.a1.a0.a0 << ", ((" << a0.a1.a0.a1.a0.a0
<< ", " << a0.a1.a0.a1.a0.a1 << "), (" << a0.a1.a0.a1.a1.a0 << ")), "
<< a0.a1.a0.a2 << ", ((" << a0.a1.a0.a3.a0.a0 << "), " << a0.a1.a0.a3.a1
<< "), " << a0.a1.a0.a4 << ", ((" << a0.a1.a0.a5.a0.a0 << "), ("
<< a0.a1.a0.a5.a1.a0 << ")), " << a0.a1.a0.a6 << "), ((" << a0.a1.a1.a0.a0
<< ", " << a0.a1.a1.a0.a1 << "), (" << a0.a1.a1.a1.a0 << ")), "
<< a0.a1.a2 << ", " << a0.a1.a3 << "), ((" << a0.a2.a0.a0 << ", (("
<< a0.a2.a0.a1.a0.a0 << ", " << a0.a2.a0.a1.a0.a1 << "), ("
<< a0.a2.a0.a1.a1.a0 << ")), " << a0.a2.a0.a2 << ", (("
<< a0.a2.a0.a3.a0.a0 << "), " << a0.a2.a0.a3.a1 << "), " << a0.a2.a0.a4
<< ", ((" << a0.a2.a0.a5.a0.a0 << "), (" << a0.a2.a0.a5.a1.a0 << ")), "
<< a0.a2.a0.a6 << "), ((" << a0.a2.a1.a0.a0 << ", " << a0.a2.a1.a0.a1
<< "), (" << a0.a2.a1.a1.a0 << ")), " << a0.a2.a2 << ", " << a0.a2.a3
<< "), " << a0.a3 << "), (" << a1.a0 << ", ((" << a1.a1.a0.a0 << ", (("
<< a1.a1.a0.a1.a0.a0 << ", " << a1.a1.a0.a1.a0.a1 << "), ("
<< a1.a1.a0.a1.a1.a0 << ")), " << a1.a1.a0.a2 << ", (("
<< a1.a1.a0.a3.a0.a0 << "), " << a1.a1.a0.a3.a1 << "), " << a1.a1.a0.a4
<< ", ((" << a1.a1.a0.a5.a0.a0 << "), (" << a1.a1.a0.a5.a1.a0 << ")), "
<< a1.a1.a0.a6 << "), ((" << a1.a1.a1.a0.a0 << ", " << a1.a1.a1.a0.a1
<< "), (" << a1.a1.a1.a1.a0 << ")), " << a1.a1.a2 << ", " << a1.a1.a3
<< "), ((" << a1.a2.a0.a0 << ", ((" << a1.a2.a0.a1.a0.a0 << ", "
<< a1.a2.a0.a1.a0.a1 << "), (" << a1.a2.a0.a1.a1.a0 << ")), "
<< a1.a2.a0.a2 << ", ((" << a1.a2.a0.a3.a0.a0 << "), " << a1.a2.a0.a3.a1
<< "), " << a1.a2.a0.a4 << ", ((" << a1.a2.a0.a5.a0.a0 << "), ("
<< a1.a2.a0.a5.a1.a0 << ")), " << a1.a2.a0.a6 << "), ((" << a1.a2.a1.a0.a0
<< ", " << a1.a2.a1.a0.a1 << "), (" << a1.a2.a1.a1.a0 << ")), "
<< a1.a2.a2 << ", " << a1.a2.a3 << "), " << a1.a3 << "), (" << a2.a0
<< ", ((" << a2.a1.a0.a0 << ", ((" << a2.a1.a0.a1.a0.a0 << ", "
<< a2.a1.a0.a1.a0.a1 << "), (" << a2.a1.a0.a1.a1.a0 << ")), "
<< a2.a1.a0.a2 << ", ((" << a2.a1.a0.a3.a0.a0 << "), " << a2.a1.a0.a3.a1
<< "), " << a2.a1.a0.a4 << ", ((" << a2.a1.a0.a5.a0.a0 << "), ("
<< a2.a1.a0.a5.a1.a0 << ")), " << a2.a1.a0.a6 << "), ((" << a2.a1.a1.a0.a0
<< ", " << a2.a1.a1.a0.a1 << "), (" << a2.a1.a1.a1.a0 << ")), "
<< a2.a1.a2 << ", " << a2.a1.a3 << "), ((" << a2.a2.a0.a0 << ", (("
<< a2.a2.a0.a1.a0.a0 << ", " << a2.a2.a0.a1.a0.a1 << "), ("
<< a2.a2.a0.a1.a1.a0 << ")), " << a2.a2.a0.a2 << ", (("
<< a2.a2.a0.a3.a0.a0 << "), " << a2.a2.a0.a3.a1 << "), " << a2.a2.a0.a4
<< ", ((" << a2.a2.a0.a5.a0.a0 << "), (" << a2.a2.a0.a5.a1.a0 << ")), "
<< a2.a2.a0.a6 << "), ((" << a2.a2.a1.a0.a0 << ", " << a2.a2.a1.a0.a1
<< "), (" << a2.a2.a1.a1.a0 << ")), " << a2.a2.a2 << ", " << a2.a2.a3
<< "), " << a2.a3 << "), (" << a3.a0 << ", ((" << a3.a1.a0.a0 << ", (("
<< a3.a1.a0.a1.a0.a0 << ", " << a3.a1.a0.a1.a0.a1 << "), ("
<< a3.a1.a0.a1.a1.a0 << ")), " << a3.a1.a0.a2 << ", (("
<< a3.a1.a0.a3.a0.a0 << "), " << a3.a1.a0.a3.a1 << "), " << a3.a1.a0.a4
<< ", ((" << a3.a1.a0.a5.a0.a0 << "), (" << a3.a1.a0.a5.a1.a0 << ")), "
<< a3.a1.a0.a6 << "), ((" << a3.a1.a1.a0.a0 << ", " << a3.a1.a1.a0.a1
<< "), (" << a3.a1.a1.a1.a0 << ")), " << a3.a1.a2 << ", " << a3.a1.a3
<< "), ((" << a3.a2.a0.a0 << ", ((" << a3.a2.a0.a1.a0.a0 << ", "
<< a3.a2.a0.a1.a0.a1 << "), (" << a3.a2.a0.a1.a1.a0 << ")), "
<< a3.a2.a0.a2 << ", ((" << a3.a2.a0.a3.a0.a0 << "), " << a3.a2.a0.a3.a1
<< "), " << a3.a2.a0.a4 << ", ((" << a3.a2.a0.a5.a0.a0 << "), ("
<< a3.a2.a0.a5.a1.a0 << ")), " << a3.a2.a0.a6 << "), ((" << a3.a2.a1.a0.a0
<< ", " << a3.a2.a1.a0.a1 << "), (" << a3.a2.a1.a1.a0 << ")), "
<< a3.a2.a2 << ", " << a3.a2.a3 << "), " << a3.a3 << "))"
<< "\n";
double result = 0;
result += a0.a0;
result += a0.a1.a0.a0;
result += a0.a1.a0.a1.a0.a0;
result += a0.a1.a0.a1.a0.a1;
result += a0.a1.a0.a1.a1.a0;
result += a0.a1.a0.a2;
result += a0.a1.a0.a3.a0.a0;
result += a0.a1.a0.a3.a1;
result += a0.a1.a0.a4;
result += a0.a1.a0.a5.a0.a0;
result += a0.a1.a0.a5.a1.a0;
result += a0.a1.a0.a6;
result += a0.a1.a1.a0.a0;
result += a0.a1.a1.a0.a1;
result += a0.a1.a1.a1.a0;
result += a0.a1.a2;
result += a0.a1.a3;
result += a0.a2.a0.a0;
result += a0.a2.a0.a1.a0.a0;
result += a0.a2.a0.a1.a0.a1;
result += a0.a2.a0.a1.a1.a0;
result += a0.a2.a0.a2;
result += a0.a2.a0.a3.a0.a0;
result += a0.a2.a0.a3.a1;
result += a0.a2.a0.a4;
result += a0.a2.a0.a5.a0.a0;
result += a0.a2.a0.a5.a1.a0;
result += a0.a2.a0.a6;
result += a0.a2.a1.a0.a0;
result += a0.a2.a1.a0.a1;
result += a0.a2.a1.a1.a0;
result += a0.a2.a2;
result += a0.a2.a3;
result += a0.a3;
result += a1.a0;
result += a1.a1.a0.a0;
result += a1.a1.a0.a1.a0.a0;
result += a1.a1.a0.a1.a0.a1;
result += a1.a1.a0.a1.a1.a0;
result += a1.a1.a0.a2;
result += a1.a1.a0.a3.a0.a0;
result += a1.a1.a0.a3.a1;
result += a1.a1.a0.a4;
result += a1.a1.a0.a5.a0.a0;
result += a1.a1.a0.a5.a1.a0;
result += a1.a1.a0.a6;
result += a1.a1.a1.a0.a0;
result += a1.a1.a1.a0.a1;
result += a1.a1.a1.a1.a0;
result += a1.a1.a2;
result += a1.a1.a3;
result += a1.a2.a0.a0;
result += a1.a2.a0.a1.a0.a0;
result += a1.a2.a0.a1.a0.a1;
result += a1.a2.a0.a1.a1.a0;
result += a1.a2.a0.a2;
result += a1.a2.a0.a3.a0.a0;
result += a1.a2.a0.a3.a1;
result += a1.a2.a0.a4;
result += a1.a2.a0.a5.a0.a0;
result += a1.a2.a0.a5.a1.a0;
result += a1.a2.a0.a6;
result += a1.a2.a1.a0.a0;
result += a1.a2.a1.a0.a1;
result += a1.a2.a1.a1.a0;
result += a1.a2.a2;
result += a1.a2.a3;
result += a1.a3;
result += a2.a0;
result += a2.a1.a0.a0;
result += a2.a1.a0.a1.a0.a0;
result += a2.a1.a0.a1.a0.a1;
result += a2.a1.a0.a1.a1.a0;
result += a2.a1.a0.a2;
result += a2.a1.a0.a3.a0.a0;
result += a2.a1.a0.a3.a1;
result += a2.a1.a0.a4;
result += a2.a1.a0.a5.a0.a0;
result += a2.a1.a0.a5.a1.a0;
result += a2.a1.a0.a6;
result += a2.a1.a1.a0.a0;
result += a2.a1.a1.a0.a1;
result += a2.a1.a1.a1.a0;
result += a2.a1.a2;
result += a2.a1.a3;
result += a2.a2.a0.a0;
result += a2.a2.a0.a1.a0.a0;
result += a2.a2.a0.a1.a0.a1;
result += a2.a2.a0.a1.a1.a0;
result += a2.a2.a0.a2;
result += a2.a2.a0.a3.a0.a0;
result += a2.a2.a0.a3.a1;
result += a2.a2.a0.a4;
result += a2.a2.a0.a5.a0.a0;
result += a2.a2.a0.a5.a1.a0;
result += a2.a2.a0.a6;
result += a2.a2.a1.a0.a0;
result += a2.a2.a1.a0.a1;
result += a2.a2.a1.a1.a0;
result += a2.a2.a2;
result += a2.a2.a3;
result += a2.a3;
result += a3.a0;
result += a3.a1.a0.a0;
result += a3.a1.a0.a1.a0.a0;
result += a3.a1.a0.a1.a0.a1;
result += a3.a1.a0.a1.a1.a0;
result += a3.a1.a0.a2;
result += a3.a1.a0.a3.a0.a0;
result += a3.a1.a0.a3.a1;
result += a3.a1.a0.a4;
result += a3.a1.a0.a5.a0.a0;
result += a3.a1.a0.a5.a1.a0;
result += a3.a1.a0.a6;
result += a3.a1.a1.a0.a0;
result += a3.a1.a1.a0.a1;
result += a3.a1.a1.a1.a0;
result += a3.a1.a2;
result += a3.a1.a3;
result += a3.a2.a0.a0;
result += a3.a2.a0.a1.a0.a0;
result += a3.a2.a0.a1.a0.a1;
result += a3.a2.a0.a1.a1.a0;
result += a3.a2.a0.a2;
result += a3.a2.a0.a3.a0.a0;
result += a3.a2.a0.a3.a1;
result += a3.a2.a0.a4;
result += a3.a2.a0.a5.a0.a0;
result += a3.a2.a0.a5.a1.a0;
result += a3.a2.a0.a6;
result += a3.a2.a1.a0.a0;
result += a3.a2.a1.a0.a1;
result += a3.a2.a1.a1.a0;
result += a3.a2.a2;
result += a3.a2.a3;
result += a3.a3;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Simple struct with inline array.
DART_EXPORT int32_t
PassStruct8BytesInlineArrayIntx4(Struct8BytesInlineArrayInt a0,
Struct8BytesInlineArrayInt a1,
Struct8BytesInlineArrayInt a2,
Struct8BytesInlineArrayInt a3) {
std::cout << "PassStruct8BytesInlineArrayIntx4"
<< "(([" << static_cast<int>(a0.a0[0]) << ", "
<< static_cast<int>(a0.a0[1]) << ", " << static_cast<int>(a0.a0[2])
<< ", " << static_cast<int>(a0.a0[3]) << ", "
<< static_cast<int>(a0.a0[4]) << ", " << static_cast<int>(a0.a0[5])
<< ", " << static_cast<int>(a0.a0[6]) << ", "
<< static_cast<int>(a0.a0[7]) << "]), (["
<< static_cast<int>(a1.a0[0]) << ", " << static_cast<int>(a1.a0[1])
<< ", " << static_cast<int>(a1.a0[2]) << ", "
<< static_cast<int>(a1.a0[3]) << ", " << static_cast<int>(a1.a0[4])
<< ", " << static_cast<int>(a1.a0[5]) << ", "
<< static_cast<int>(a1.a0[6]) << ", " << static_cast<int>(a1.a0[7])
<< "]), ([" << static_cast<int>(a2.a0[0]) << ", "
<< static_cast<int>(a2.a0[1]) << ", " << static_cast<int>(a2.a0[2])
<< ", " << static_cast<int>(a2.a0[3]) << ", "
<< static_cast<int>(a2.a0[4]) << ", " << static_cast<int>(a2.a0[5])
<< ", " << static_cast<int>(a2.a0[6]) << ", "
<< static_cast<int>(a2.a0[7]) << "]), (["
<< static_cast<int>(a3.a0[0]) << ", " << static_cast<int>(a3.a0[1])
<< ", " << static_cast<int>(a3.a0[2]) << ", "
<< static_cast<int>(a3.a0[3]) << ", " << static_cast<int>(a3.a0[4])
<< ", " << static_cast<int>(a3.a0[5]) << ", "
<< static_cast<int>(a3.a0[6]) << ", " << static_cast<int>(a3.a0[7])
<< "]))"
<< "\n";
int32_t result = 0;
result += a0.a0[0];
result += a0.a0[1];
result += a0.a0[2];
result += a0.a0[3];
result += a0.a0[4];
result += a0.a0[5];
result += a0.a0[6];
result += a0.a0[7];
result += a1.a0[0];
result += a1.a0[1];
result += a1.a0[2];
result += a1.a0[3];
result += a1.a0[4];
result += a1.a0[5];
result += a1.a0[6];
result += a1.a0[7];
result += a2.a0[0];
result += a2.a0[1];
result += a2.a0[2];
result += a2.a0[3];
result += a2.a0[4];
result += a2.a0[5];
result += a2.a0[6];
result += a2.a0[7];
result += a3.a0[0];
result += a3.a0[1];
result += a3.a0[2];
result += a3.a0[3];
result += a3.a0[4];
result += a3.a0[5];
result += a3.a0[6];
result += a3.a0[7];
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Irregular struct with inline array.
DART_EXPORT int32_t
PassStructInlineArrayIrregularx4(StructInlineArrayIrregular a0,
StructInlineArrayIrregular a1,
StructInlineArrayIrregular a2,
StructInlineArrayIrregular a3) {
std::cout << "PassStructInlineArrayIrregularx4"
<< "(([(" << a0.a0[0].a0 << ", " << static_cast<int>(a0.a0[0].a1)
<< "), (" << a0.a0[1].a0 << ", " << static_cast<int>(a0.a0[1].a1)
<< ")], " << static_cast<int>(a0.a1) << "), ([(" << a1.a0[0].a0
<< ", " << static_cast<int>(a1.a0[0].a1) << "), (" << a1.a0[1].a0
<< ", " << static_cast<int>(a1.a0[1].a1) << ")], "
<< static_cast<int>(a1.a1) << "), ([(" << a2.a0[0].a0 << ", "
<< static_cast<int>(a2.a0[0].a1) << "), (" << a2.a0[1].a0 << ", "
<< static_cast<int>(a2.a0[1].a1) << ")], "
<< static_cast<int>(a2.a1) << "), ([(" << a3.a0[0].a0 << ", "
<< static_cast<int>(a3.a0[0].a1) << "), (" << a3.a0[1].a0 << ", "
<< static_cast<int>(a3.a0[1].a1) << ")], "
<< static_cast<int>(a3.a1) << "))"
<< "\n";
int32_t result = 0;
result += a0.a0[0].a0;
result += a0.a0[0].a1;
result += a0.a0[1].a0;
result += a0.a0[1].a1;
result += a0.a1;
result += a1.a0[0].a0;
result += a1.a0[0].a1;
result += a1.a0[1].a0;
result += a1.a0[1].a1;
result += a1.a1;
result += a2.a0[0].a0;
result += a2.a0[0].a1;
result += a2.a0[1].a0;
result += a2.a0[1].a1;
result += a2.a1;
result += a3.a0[0].a0;
result += a3.a0[0].a1;
result += a3.a0[1].a0;
result += a3.a0[1].a1;
result += a3.a1;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Regular larger struct with inline array.
DART_EXPORT int32_t
PassStructInlineArray100Bytes(StructInlineArray100Bytes a0) {
std::cout
<< "PassStructInlineArray100Bytes"
<< "(([" << static_cast<int>(a0.a0[0]) << ", "
<< static_cast<int>(a0.a0[1]) << ", " << static_cast<int>(a0.a0[2])
<< ", " << static_cast<int>(a0.a0[3]) << ", "
<< static_cast<int>(a0.a0[4]) << ", " << static_cast<int>(a0.a0[5])
<< ", " << static_cast<int>(a0.a0[6]) << ", "
<< static_cast<int>(a0.a0[7]) << ", " << static_cast<int>(a0.a0[8])
<< ", " << static_cast<int>(a0.a0[9]) << ", "
<< static_cast<int>(a0.a0[10]) << ", " << static_cast<int>(a0.a0[11])
<< ", " << static_cast<int>(a0.a0[12]) << ", "
<< static_cast<int>(a0.a0[13]) << ", " << static_cast<int>(a0.a0[14])
<< ", " << static_cast<int>(a0.a0[15]) << ", "
<< static_cast<int>(a0.a0[16]) << ", " << static_cast<int>(a0.a0[17])
<< ", " << static_cast<int>(a0.a0[18]) << ", "
<< static_cast<int>(a0.a0[19]) << ", " << static_cast<int>(a0.a0[20])
<< ", " << static_cast<int>(a0.a0[21]) << ", "
<< static_cast<int>(a0.a0[22]) << ", " << static_cast<int>(a0.a0[23])
<< ", " << static_cast<int>(a0.a0[24]) << ", "
<< static_cast<int>(a0.a0[25]) << ", " << static_cast<int>(a0.a0[26])
<< ", " << static_cast<int>(a0.a0[27]) << ", "
<< static_cast<int>(a0.a0[28]) << ", " << static_cast<int>(a0.a0[29])
<< ", " << static_cast<int>(a0.a0[30]) << ", "
<< static_cast<int>(a0.a0[31]) << ", " << static_cast<int>(a0.a0[32])
<< ", " << static_cast<int>(a0.a0[33]) << ", "
<< static_cast<int>(a0.a0[34]) << ", " << static_cast<int>(a0.a0[35])
<< ", " << static_cast<int>(a0.a0[36]) << ", "
<< static_cast<int>(a0.a0[37]) << ", " << static_cast<int>(a0.a0[38])
<< ", " << static_cast<int>(a0.a0[39]) << ", "
<< static_cast<int>(a0.a0[40]) << ", " << static_cast<int>(a0.a0[41])
<< ", " << static_cast<int>(a0.a0[42]) << ", "
<< static_cast<int>(a0.a0[43]) << ", " << static_cast<int>(a0.a0[44])
<< ", " << static_cast<int>(a0.a0[45]) << ", "
<< static_cast<int>(a0.a0[46]) << ", " << static_cast<int>(a0.a0[47])
<< ", " << static_cast<int>(a0.a0[48]) << ", "
<< static_cast<int>(a0.a0[49]) << ", " << static_cast<int>(a0.a0[50])
<< ", " << static_cast<int>(a0.a0[51]) << ", "
<< static_cast<int>(a0.a0[52]) << ", " << static_cast<int>(a0.a0[53])
<< ", " << static_cast<int>(a0.a0[54]) << ", "
<< static_cast<int>(a0.a0[55]) << ", " << static_cast<int>(a0.a0[56])
<< ", " << static_cast<int>(a0.a0[57]) << ", "
<< static_cast<int>(a0.a0[58]) << ", " << static_cast<int>(a0.a0[59])
<< ", " << static_cast<int>(a0.a0[60]) << ", "
<< static_cast<int>(a0.a0[61]) << ", " << static_cast<int>(a0.a0[62])
<< ", " << static_cast<int>(a0.a0[63]) << ", "
<< static_cast<int>(a0.a0[64]) << ", " << static_cast<int>(a0.a0[65])
<< ", " << static_cast<int>(a0.a0[66]) << ", "
<< static_cast<int>(a0.a0[67]) << ", " << static_cast<int>(a0.a0[68])
<< ", " << static_cast<int>(a0.a0[69]) << ", "
<< static_cast<int>(a0.a0[70]) << ", " << static_cast<int>(a0.a0[71])
<< ", " << static_cast<int>(a0.a0[72]) << ", "
<< static_cast<int>(a0.a0[73]) << ", " << static_cast<int>(a0.a0[74])
<< ", " << static_cast<int>(a0.a0[75]) << ", "
<< static_cast<int>(a0.a0[76]) << ", " << static_cast<int>(a0.a0[77])
<< ", " << static_cast<int>(a0.a0[78]) << ", "
<< static_cast<int>(a0.a0[79]) << ", " << static_cast<int>(a0.a0[80])
<< ", " << static_cast<int>(a0.a0[81]) << ", "
<< static_cast<int>(a0.a0[82]) << ", " << static_cast<int>(a0.a0[83])
<< ", " << static_cast<int>(a0.a0[84]) << ", "
<< static_cast<int>(a0.a0[85]) << ", " << static_cast<int>(a0.a0[86])
<< ", " << static_cast<int>(a0.a0[87]) << ", "
<< static_cast<int>(a0.a0[88]) << ", " << static_cast<int>(a0.a0[89])
<< ", " << static_cast<int>(a0.a0[90]) << ", "
<< static_cast<int>(a0.a0[91]) << ", " << static_cast<int>(a0.a0[92])
<< ", " << static_cast<int>(a0.a0[93]) << ", "
<< static_cast<int>(a0.a0[94]) << ", " << static_cast<int>(a0.a0[95])
<< ", " << static_cast<int>(a0.a0[96]) << ", "
<< static_cast<int>(a0.a0[97]) << ", " << static_cast<int>(a0.a0[98])
<< ", " << static_cast<int>(a0.a0[99]) << "]))"
<< "\n";
int32_t result = 0;
result += a0.a0[0];
result += a0.a0[1];
result += a0.a0[2];
result += a0.a0[3];
result += a0.a0[4];
result += a0.a0[5];
result += a0.a0[6];
result += a0.a0[7];
result += a0.a0[8];
result += a0.a0[9];
result += a0.a0[10];
result += a0.a0[11];
result += a0.a0[12];
result += a0.a0[13];
result += a0.a0[14];
result += a0.a0[15];
result += a0.a0[16];
result += a0.a0[17];
result += a0.a0[18];
result += a0.a0[19];
result += a0.a0[20];
result += a0.a0[21];
result += a0.a0[22];
result += a0.a0[23];
result += a0.a0[24];
result += a0.a0[25];
result += a0.a0[26];
result += a0.a0[27];
result += a0.a0[28];
result += a0.a0[29];
result += a0.a0[30];
result += a0.a0[31];
result += a0.a0[32];
result += a0.a0[33];
result += a0.a0[34];
result += a0.a0[35];
result += a0.a0[36];
result += a0.a0[37];
result += a0.a0[38];
result += a0.a0[39];
result += a0.a0[40];
result += a0.a0[41];
result += a0.a0[42];
result += a0.a0[43];
result += a0.a0[44];
result += a0.a0[45];
result += a0.a0[46];
result += a0.a0[47];
result += a0.a0[48];
result += a0.a0[49];
result += a0.a0[50];
result += a0.a0[51];
result += a0.a0[52];
result += a0.a0[53];
result += a0.a0[54];
result += a0.a0[55];
result += a0.a0[56];
result += a0.a0[57];
result += a0.a0[58];
result += a0.a0[59];
result += a0.a0[60];
result += a0.a0[61];
result += a0.a0[62];
result += a0.a0[63];
result += a0.a0[64];
result += a0.a0[65];
result += a0.a0[66];
result += a0.a0[67];
result += a0.a0[68];
result += a0.a0[69];
result += a0.a0[70];
result += a0.a0[71];
result += a0.a0[72];
result += a0.a0[73];
result += a0.a0[74];
result += a0.a0[75];
result += a0.a0[76];
result += a0.a0[77];
result += a0.a0[78];
result += a0.a0[79];
result += a0.a0[80];
result += a0.a0[81];
result += a0.a0[82];
result += a0.a0[83];
result += a0.a0[84];
result += a0.a0[85];
result += a0.a0[86];
result += a0.a0[87];
result += a0.a0[88];
result += a0.a0[89];
result += a0.a0[90];
result += a0.a0[91];
result += a0.a0[92];
result += a0.a0[93];
result += a0.a0[94];
result += a0.a0[95];
result += a0.a0[96];
result += a0.a0[97];
result += a0.a0[98];
result += a0.a0[99];
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Arguments in FPU registers on arm hardfp and arm64.
// 5 struct arguments will exhaust available registers.
DART_EXPORT float PassStructStruct16BytesHomogeneousFloat2x5(
StructStruct16BytesHomogeneousFloat2 a0,
StructStruct16BytesHomogeneousFloat2 a1,
StructStruct16BytesHomogeneousFloat2 a2,
StructStruct16BytesHomogeneousFloat2 a3,
StructStruct16BytesHomogeneousFloat2 a4) {
std::cout << "PassStructStruct16BytesHomogeneousFloat2x5"
<< "(((" << a0.a0.a0 << "), [(" << a0.a1[0].a0 << "), ("
<< a0.a1[1].a0 << ")], " << a0.a2 << "), ((" << a1.a0.a0 << "), [("
<< a1.a1[0].a0 << "), (" << a1.a1[1].a0 << ")], " << a1.a2
<< "), ((" << a2.a0.a0 << "), [(" << a2.a1[0].a0 << "), ("
<< a2.a1[1].a0 << ")], " << a2.a2 << "), ((" << a3.a0.a0 << "), [("
<< a3.a1[0].a0 << "), (" << a3.a1[1].a0 << ")], " << a3.a2
<< "), ((" << a4.a0.a0 << "), [(" << a4.a1[0].a0 << "), ("
<< a4.a1[1].a0 << ")], " << a4.a2 << "))"
<< "\n";
float result = 0;
result += a0.a0.a0;
result += a0.a1[0].a0;
result += a0.a1[1].a0;
result += a0.a2;
result += a1.a0.a0;
result += a1.a1[0].a0;
result += a1.a1[1].a0;
result += a1.a2;
result += a2.a0.a0;
result += a2.a1[0].a0;
result += a2.a1[1].a0;
result += a2.a2;
result += a3.a0.a0;
result += a3.a1[0].a0;
result += a3.a1[1].a0;
result += a3.a2;
result += a4.a0.a0;
result += a4.a1[0].a0;
result += a4.a1[1].a0;
result += a4.a2;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Arguments in FPU registers on arm64.
// 5 struct arguments will exhaust available registers.
DART_EXPORT double PassStructStruct32BytesHomogeneousDouble2x5(
StructStruct32BytesHomogeneousDouble2 a0,
StructStruct32BytesHomogeneousDouble2 a1,
StructStruct32BytesHomogeneousDouble2 a2,
StructStruct32BytesHomogeneousDouble2 a3,
StructStruct32BytesHomogeneousDouble2 a4) {
std::cout << "PassStructStruct32BytesHomogeneousDouble2x5"
<< "(((" << a0.a0.a0 << "), [(" << a0.a1[0].a0 << "), ("
<< a0.a1[1].a0 << ")], " << a0.a2 << "), ((" << a1.a0.a0 << "), [("
<< a1.a1[0].a0 << "), (" << a1.a1[1].a0 << ")], " << a1.a2
<< "), ((" << a2.a0.a0 << "), [(" << a2.a1[0].a0 << "), ("
<< a2.a1[1].a0 << ")], " << a2.a2 << "), ((" << a3.a0.a0 << "), [("
<< a3.a1[0].a0 << "), (" << a3.a1[1].a0 << ")], " << a3.a2
<< "), ((" << a4.a0.a0 << "), [(" << a4.a1[0].a0 << "), ("
<< a4.a1[1].a0 << ")], " << a4.a2 << "))"
<< "\n";
double result = 0;
result += a0.a0.a0;
result += a0.a1[0].a0;
result += a0.a1[1].a0;
result += a0.a2;
result += a1.a0.a0;
result += a1.a1[0].a0;
result += a1.a1[1].a0;
result += a1.a2;
result += a2.a0.a0;
result += a2.a1[0].a0;
result += a2.a1[1].a0;
result += a2.a2;
result += a3.a0.a0;
result += a3.a1[0].a0;
result += a3.a1[1].a0;
result += a3.a2;
result += a4.a0.a0;
result += a4.a1[0].a0;
result += a4.a1[1].a0;
result += a4.a2;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// 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.
DART_EXPORT float PassStructStruct16BytesMixed3x10(
StructStruct16BytesMixed3 a0,
StructStruct16BytesMixed3 a1,
StructStruct16BytesMixed3 a2,
StructStruct16BytesMixed3 a3,
StructStruct16BytesMixed3 a4,
StructStruct16BytesMixed3 a5,
StructStruct16BytesMixed3 a6,
StructStruct16BytesMixed3 a7,
StructStruct16BytesMixed3 a8,
StructStruct16BytesMixed3 a9) {
std::cout << "PassStructStruct16BytesMixed3x10"
<< "(((" << a0.a0.a0 << "), [(" << a0.a1[0].a0 << ", "
<< a0.a1[0].a1 << ", " << a0.a1[0].a2 << ")], [" << a0.a2[0] << ", "
<< a0.a2[1] << "]), ((" << a1.a0.a0 << "), [(" << a1.a1[0].a0
<< ", " << a1.a1[0].a1 << ", " << a1.a1[0].a2 << ")], [" << a1.a2[0]
<< ", " << a1.a2[1] << "]), ((" << a2.a0.a0 << "), [("
<< a2.a1[0].a0 << ", " << a2.a1[0].a1 << ", " << a2.a1[0].a2
<< ")], [" << a2.a2[0] << ", " << a2.a2[1] << "]), ((" << a3.a0.a0
<< "), [(" << a3.a1[0].a0 << ", " << a3.a1[0].a1 << ", "
<< a3.a1[0].a2 << ")], [" << a3.a2[0] << ", " << a3.a2[1]
<< "]), ((" << a4.a0.a0 << "), [(" << a4.a1[0].a0 << ", "
<< a4.a1[0].a1 << ", " << a4.a1[0].a2 << ")], [" << a4.a2[0] << ", "
<< a4.a2[1] << "]), ((" << a5.a0.a0 << "), [(" << a5.a1[0].a0
<< ", " << a5.a1[0].a1 << ", " << a5.a1[0].a2 << ")], [" << a5.a2[0]
<< ", " << a5.a2[1] << "]), ((" << a6.a0.a0 << "), [("
<< a6.a1[0].a0 << ", " << a6.a1[0].a1 << ", " << a6.a1[0].a2
<< ")], [" << a6.a2[0] << ", " << a6.a2[1] << "]), ((" << a7.a0.a0
<< "), [(" << a7.a1[0].a0 << ", " << a7.a1[0].a1 << ", "
<< a7.a1[0].a2 << ")], [" << a7.a2[0] << ", " << a7.a2[1]
<< "]), ((" << a8.a0.a0 << "), [(" << a8.a1[0].a0 << ", "
<< a8.a1[0].a1 << ", " << a8.a1[0].a2 << ")], [" << a8.a2[0] << ", "
<< a8.a2[1] << "]), ((" << a9.a0.a0 << "), [(" << a9.a1[0].a0
<< ", " << a9.a1[0].a1 << ", " << a9.a1[0].a2 << ")], [" << a9.a2[0]
<< ", " << a9.a2[1] << "]))"
<< "\n";
float result = 0;
result += a0.a0.a0;
result += a0.a1[0].a0;
result += a0.a1[0].a1;
result += a0.a1[0].a2;
result += a0.a2[0];
result += a0.a2[1];
result += a1.a0.a0;
result += a1.a1[0].a0;
result += a1.a1[0].a1;
result += a1.a1[0].a2;
result += a1.a2[0];
result += a1.a2[1];
result += a2.a0.a0;
result += a2.a1[0].a0;
result += a2.a1[0].a1;
result += a2.a1[0].a2;
result += a2.a2[0];
result += a2.a2[1];
result += a3.a0.a0;
result += a3.a1[0].a0;
result += a3.a1[0].a1;
result += a3.a1[0].a2;
result += a3.a2[0];
result += a3.a2[1];
result += a4.a0.a0;
result += a4.a1[0].a0;
result += a4.a1[0].a1;
result += a4.a1[0].a2;
result += a4.a2[0];
result += a4.a2[1];
result += a5.a0.a0;
result += a5.a1[0].a0;
result += a5.a1[0].a1;
result += a5.a1[0].a2;
result += a5.a2[0];
result += a5.a2[1];
result += a6.a0.a0;
result += a6.a1[0].a0;
result += a6.a1[0].a1;
result += a6.a1[0].a2;
result += a6.a2[0];
result += a6.a2[1];
result += a7.a0.a0;
result += a7.a1[0].a0;
result += a7.a1[0].a1;
result += a7.a1[0].a2;
result += a7.a2[0];
result += a7.a2[1];
result += a8.a0.a0;
result += a8.a1[0].a0;
result += a8.a1[0].a1;
result += a8.a1[0].a2;
result += a8.a2[0];
result += a8.a2[1];
result += a9.a0.a0;
result += a9.a1[0].a0;
result += a9.a1[0].a1;
result += a9.a1[0].a2;
result += a9.a2[0];
result += a9.a2[1];
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Test multi dimensional inline array struct as argument.
DART_EXPORT uint32_t PassUint8Struct32BytesInlineArrayMultiDimensionalI(
uint8_t a0,
Struct32BytesInlineArrayMultiDimensionalInt a1,
uint8_t a2,
Struct8BytesInlineArrayMultiDimensionalInt a3,
uint8_t a4,
Struct8BytesInlineArrayMultiDimensionalInt a5,
uint8_t a6) {
std::cout << "PassUint8Struct32BytesInlineArrayMultiDimensionalI"
<< "(" << static_cast<int>(a0) << ", ([[[[["
<< static_cast<int>(a1.a0[0][0][0][0][0]) << ", "
<< static_cast<int>(a1.a0[0][0][0][0][1]) << "], ["
<< static_cast<int>(a1.a0[0][0][0][1][0]) << ", "
<< static_cast<int>(a1.a0[0][0][0][1][1]) << "]], [["
<< static_cast<int>(a1.a0[0][0][1][0][0]) << ", "
<< static_cast<int>(a1.a0[0][0][1][0][1]) << "], ["
<< static_cast<int>(a1.a0[0][0][1][1][0]) << ", "
<< static_cast<int>(a1.a0[0][0][1][1][1]) << "]]], [[["
<< static_cast<int>(a1.a0[0][1][0][0][0]) << ", "
<< static_cast<int>(a1.a0[0][1][0][0][1]) << "], ["
<< static_cast<int>(a1.a0[0][1][0][1][0]) << ", "
<< static_cast<int>(a1.a0[0][1][0][1][1]) << "]], [["
<< static_cast<int>(a1.a0[0][1][1][0][0]) << ", "
<< static_cast<int>(a1.a0[0][1][1][0][1]) << "], ["
<< static_cast<int>(a1.a0[0][1][1][1][0]) << ", "
<< static_cast<int>(a1.a0[0][1][1][1][1]) << "]]]], [[[["
<< static_cast<int>(a1.a0[1][0][0][0][0]) << ", "
<< static_cast<int>(a1.a0[1][0][0][0][1]) << "], ["
<< static_cast<int>(a1.a0[1][0][0][1][0]) << ", "
<< static_cast<int>(a1.a0[1][0][0][1][1]) << "]], [["
<< static_cast<int>(a1.a0[1][0][1][0][0]) << ", "
<< static_cast<int>(a1.a0[1][0][1][0][1]) << "], ["
<< static_cast<int>(a1.a0[1][0][1][1][0]) << ", "
<< static_cast<int>(a1.a0[1][0][1][1][1]) << "]]], [[["
<< static_cast<int>(a1.a0[1][1][0][0][0]) << ", "
<< static_cast<int>(a1.a0[1][1][0][0][1]) << "], ["
<< static_cast<int>(a1.a0[1][1][0][1][0]) << ", "
<< static_cast<int>(a1.a0[1][1][0][1][1]) << "]], [["
<< static_cast<int>(a1.a0[1][1][1][0][0]) << ", "
<< static_cast<int>(a1.a0[1][1][1][0][1]) << "], ["
<< static_cast<int>(a1.a0[1][1][1][1][0]) << ", "
<< static_cast<int>(a1.a0[1][1][1][1][1]) << "]]]]]), "
<< static_cast<int>(a2) << ", ([[["
<< static_cast<int>(a3.a0[0][0][0]) << ", "
<< static_cast<int>(a3.a0[0][0][1]) << "], ["
<< static_cast<int>(a3.a0[0][1][0]) << ", "
<< static_cast<int>(a3.a0[0][1][1]) << "]], [["
<< static_cast<int>(a3.a0[1][0][0]) << ", "
<< static_cast<int>(a3.a0[1][0][1]) << "], ["
<< static_cast<int>(a3.a0[1][1][0]) << ", "
<< static_cast<int>(a3.a0[1][1][1]) << "]]]), "
<< static_cast<int>(a4) << ", ([[["
<< static_cast<int>(a5.a0[0][0][0]) << ", "
<< static_cast<int>(a5.a0[0][0][1]) << "], ["
<< static_cast<int>(a5.a0[0][1][0]) << ", "
<< static_cast<int>(a5.a0[0][1][1]) << "]], [["
<< static_cast<int>(a5.a0[1][0][0]) << ", "
<< static_cast<int>(a5.a0[1][0][1]) << "], ["
<< static_cast<int>(a5.a0[1][1][0]) << ", "
<< static_cast<int>(a5.a0[1][1][1]) << "]]]), "
<< static_cast<int>(a6) << ")"
<< "\n";
uint32_t result = 0;
result += a0;
result += a1.a0[0][0][0][0][0];
result += a1.a0[0][0][0][0][1];
result += a1.a0[0][0][0][1][0];
result += a1.a0[0][0][0][1][1];
result += a1.a0[0][0][1][0][0];
result += a1.a0[0][0][1][0][1];
result += a1.a0[0][0][1][1][0];
result += a1.a0[0][0][1][1][1];
result += a1.a0[0][1][0][0][0];
result += a1.a0[0][1][0][0][1];
result += a1.a0[0][1][0][1][0];
result += a1.a0[0][1][0][1][1];
result += a1.a0[0][1][1][0][0];
result += a1.a0[0][1][1][0][1];
result += a1.a0[0][1][1][1][0];
result += a1.a0[0][1][1][1][1];
result += a1.a0[1][0][0][0][0];
result += a1.a0[1][0][0][0][1];
result += a1.a0[1][0][0][1][0];
result += a1.a0[1][0][0][1][1];
result += a1.a0[1][0][1][0][0];
result += a1.a0[1][0][1][0][1];
result += a1.a0[1][0][1][1][0];
result += a1.a0[1][0][1][1][1];
result += a1.a0[1][1][0][0][0];
result += a1.a0[1][1][0][0][1];
result += a1.a0[1][1][0][1][0];
result += a1.a0[1][1][0][1][1];
result += a1.a0[1][1][1][0][0];
result += a1.a0[1][1][1][0][1];
result += a1.a0[1][1][1][1][0];
result += a1.a0[1][1][1][1][1];
result += a2;
result += a3.a0[0][0][0];
result += a3.a0[0][0][1];
result += a3.a0[0][1][0];
result += a3.a0[0][1][1];
result += a3.a0[1][0][0];
result += a3.a0[1][0][1];
result += a3.a0[1][1][0];
result += a3.a0[1][1][1];
result += a4;
result += a5.a0[0][0][0];
result += a5.a0[0][0][1];
result += a5.a0[0][1][0];
result += a5.a0[0][1][1];
result += a5.a0[1][0][0];
result += a5.a0[1][0][1];
result += a5.a0[1][1][0];
result += a5.a0[1][1][1];
result += a6;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Test struct in multi dimensional inline array.
DART_EXPORT uint32_t PassUint8Struct4BytesInlineArrayMultiDimensionalIn(
uint8_t a0,
Struct4BytesInlineArrayMultiDimensionalInt a1,
uint8_t a2) {
std::cout << "PassUint8Struct4BytesInlineArrayMultiDimensionalIn"
<< "(" << static_cast<int>(a0) << ", ([[("
<< static_cast<int>(a1.a0[0][0].a0) << "), ("
<< static_cast<int>(a1.a0[0][1].a0) << ")], [("
<< static_cast<int>(a1.a0[1][0].a0) << "), ("
<< static_cast<int>(a1.a0[1][1].a0) << ")]]), "
<< static_cast<int>(a2) << ")"
<< "\n";
uint32_t result = 0;
result += a0;
result += a1.a0[0][0].a0;
result += a1.a0[0][1].a0;
result += a1.a0[1][0].a0;
result += a1.a0[1][1].a0;
result += a2;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Small struct with mis-aligned member.
DART_EXPORT int64_t PassStruct3BytesPackedIntx10(Struct3BytesPackedInt a0,
Struct3BytesPackedInt a1,
Struct3BytesPackedInt a2,
Struct3BytesPackedInt a3,
Struct3BytesPackedInt a4,
Struct3BytesPackedInt a5,
Struct3BytesPackedInt a6,
Struct3BytesPackedInt a7,
Struct3BytesPackedInt a8,
Struct3BytesPackedInt a9) {
std::cout << "PassStruct3BytesPackedIntx10"
<< "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << "), ("
<< static_cast<int>(a1.a0) << ", " << a1.a1 << "), ("
<< static_cast<int>(a2.a0) << ", " << a2.a1 << "), ("
<< static_cast<int>(a3.a0) << ", " << a3.a1 << "), ("
<< static_cast<int>(a4.a0) << ", " << a4.a1 << "), ("
<< static_cast<int>(a5.a0) << ", " << a5.a1 << "), ("
<< static_cast<int>(a6.a0) << ", " << a6.a1 << "), ("
<< static_cast<int>(a7.a0) << ", " << a7.a1 << "), ("
<< static_cast<int>(a8.a0) << ", " << a8.a1 << "), ("
<< static_cast<int>(a9.a0) << ", " << a9.a1 << "))"
<< "\n";
int64_t result = 0;
result += a0.a0;
result += a0.a1;
result += a1.a0;
result += a1.a1;
result += a2.a0;
result += a2.a1;
result += a3.a0;
result += a3.a1;
result += a4.a0;
result += a4.a1;
result += a5.a0;
result += a5.a1;
result += a6.a0;
result += a6.a1;
result += a7.a0;
result += a7.a1;
result += a8.a0;
result += a8.a1;
result += a9.a0;
result += a9.a1;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Struct with mis-aligned member.
DART_EXPORT int64_t PassStruct8BytesPackedIntx10(Struct8BytesPackedInt a0,
Struct8BytesPackedInt a1,
Struct8BytesPackedInt a2,
Struct8BytesPackedInt a3,
Struct8BytesPackedInt a4,
Struct8BytesPackedInt a5,
Struct8BytesPackedInt a6,
Struct8BytesPackedInt a7,
Struct8BytesPackedInt a8,
Struct8BytesPackedInt a9) {
std::cout << "PassStruct8BytesPackedIntx10"
<< "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << ", "
<< static_cast<int>(a0.a2) << ", " << static_cast<int>(a0.a3)
<< ", " << static_cast<int>(a0.a4) << "), ("
<< static_cast<int>(a1.a0) << ", " << a1.a1 << ", "
<< static_cast<int>(a1.a2) << ", " << static_cast<int>(a1.a3)
<< ", " << static_cast<int>(a1.a4) << "), ("
<< static_cast<int>(a2.a0) << ", " << a2.a1 << ", "
<< static_cast<int>(a2.a2) << ", " << static_cast<int>(a2.a3)
<< ", " << static_cast<int>(a2.a4) << "), ("
<< static_cast<int>(a3.a0) << ", " << a3.a1 << ", "
<< static_cast<int>(a3.a2) << ", " << static_cast<int>(a3.a3)
<< ", " << static_cast<int>(a3.a4) << "), ("
<< static_cast<int>(a4.a0) << ", " << a4.a1 << ", "
<< static_cast<int>(a4.a2) << ", " << static_cast<int>(a4.a3)
<< ", " << static_cast<int>(a4.a4) << "), ("
<< static_cast<int>(a5.a0) << ", " << a5.a1 << ", "
<< static_cast<int>(a5.a2) << ", " << static_cast<int>(a5.a3)
<< ", " << static_cast<int>(a5.a4) << "), ("
<< static_cast<int>(a6.a0) << ", " << a6.a1 << ", "
<< static_cast<int>(a6.a2) << ", " << static_cast<int>(a6.a3)
<< ", " << static_cast<int>(a6.a4) << "), ("
<< static_cast<int>(a7.a0) << ", " << a7.a1 << ", "
<< static_cast<int>(a7.a2) << ", " << static_cast<int>(a7.a3)
<< ", " << static_cast<int>(a7.a4) << "), ("
<< static_cast<int>(a8.a0) << ", " << a8.a1 << ", "
<< static_cast<int>(a8.a2) << ", " << static_cast<int>(a8.a3)
<< ", " << static_cast<int>(a8.a4) << "), ("
<< static_cast<int>(a9.a0) << ", " << a9.a1 << ", "
<< static_cast<int>(a9.a2) << ", " << static_cast<int>(a9.a3)
<< ", " << static_cast<int>(a9.a4) << "))"
<< "\n";
int64_t result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a0.a3;
result += a0.a4;
result += a1.a0;
result += a1.a1;
result += a1.a2;
result += a1.a3;
result += a1.a4;
result += a2.a0;
result += a2.a1;
result += a2.a2;
result += a2.a3;
result += a2.a4;
result += a3.a0;
result += a3.a1;
result += a3.a2;
result += a3.a3;
result += a3.a4;
result += a4.a0;
result += a4.a1;
result += a4.a2;
result += a4.a3;
result += a4.a4;
result += a5.a0;
result += a5.a1;
result += a5.a2;
result += a5.a3;
result += a5.a4;
result += a6.a0;
result += a6.a1;
result += a6.a2;
result += a6.a3;
result += a6.a4;
result += a7.a0;
result += a7.a1;
result += a7.a2;
result += a7.a3;
result += a7.a4;
result += a8.a0;
result += a8.a1;
result += a8.a2;
result += a8.a3;
result += a8.a4;
result += a9.a0;
result += a9.a1;
result += a9.a2;
result += a9.a3;
result += a9.a4;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Struct with mis-aligned member.
// Tests backfilling of CPU and FPU registers.
DART_EXPORT double PassStruct9BytesPackedMixedx10DoubleInt32x2(
Struct9BytesPackedMixed a0,
Struct9BytesPackedMixed a1,
Struct9BytesPackedMixed a2,
Struct9BytesPackedMixed a3,
Struct9BytesPackedMixed a4,
Struct9BytesPackedMixed a5,
Struct9BytesPackedMixed a6,
Struct9BytesPackedMixed a7,
Struct9BytesPackedMixed a8,
Struct9BytesPackedMixed a9,
double a10,
int32_t a11,
int32_t a12) {
std::cout << "PassStruct9BytesPackedMixedx10DoubleInt32x2"
<< "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << "), ("
<< static_cast<int>(a1.a0) << ", " << a1.a1 << "), ("
<< static_cast<int>(a2.a0) << ", " << a2.a1 << "), ("
<< static_cast<int>(a3.a0) << ", " << a3.a1 << "), ("
<< static_cast<int>(a4.a0) << ", " << a4.a1 << "), ("
<< static_cast<int>(a5.a0) << ", " << a5.a1 << "), ("
<< static_cast<int>(a6.a0) << ", " << a6.a1 << "), ("
<< static_cast<int>(a7.a0) << ", " << a7.a1 << "), ("
<< static_cast<int>(a8.a0) << ", " << a8.a1 << "), ("
<< static_cast<int>(a9.a0) << ", " << a9.a1 << "), " << a10 << ", "
<< a11 << ", " << a12 << ")"
<< "\n";
double result = 0;
result += a0.a0;
result += a0.a1;
result += a1.a0;
result += a1.a1;
result += a2.a0;
result += a2.a1;
result += a3.a0;
result += a3.a1;
result += a4.a0;
result += a4.a1;
result += a5.a0;
result += a5.a1;
result += a6.a0;
result += a6.a1;
result += a7.a0;
result += a7.a1;
result += a8.a0;
result += a8.a1;
result += a9.a0;
result += a9.a1;
result += a10;
result += a11;
result += a12;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// This packed struct happens to have only aligned members.
DART_EXPORT double PassStruct5BytesPackedMixed(Struct5BytesPackedMixed a0) {
std::cout << "PassStruct5BytesPackedMixed"
<< "((" << a0.a0 << ", " << static_cast<int>(a0.a1) << "))"
<< "\n";
double result = 0;
result += a0.a0;
result += a0.a1;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Check alignment of packed struct in non-packed struct.
DART_EXPORT double PassStructNestedAlignmentStruct5BytesPackedMixed(
StructNestedAlignmentStruct5BytesPackedMixed a0) {
std::cout << "PassStructNestedAlignmentStruct5BytesPackedMixed"
<< "((" << static_cast<int>(a0.a0) << ", (" << a0.a1.a0 << ", "
<< static_cast<int>(a0.a1.a1) << ")))"
<< "\n";
double result = 0;
result += a0.a0;
result += a0.a1.a0;
result += a0.a1.a1;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Check alignment of packed struct array in non-packed struct.
DART_EXPORT double PassStruct6BytesInlineArrayInt(
Struct6BytesInlineArrayInt a0) {
std::cout << "PassStruct6BytesInlineArrayInt"
<< "(([(" << static_cast<int>(a0.a0[0].a0) << ", " << a0.a0[0].a1
<< "), (" << static_cast<int>(a0.a0[1].a0) << ", " << a0.a0[1].a1
<< ")]))"
<< "\n";
double result = 0;
result += a0.a0[0].a0;
result += a0.a0[0].a1;
result += a0.a0[1].a0;
result += a0.a0[1].a1;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Check alignment of packed struct array in non-packed struct.
DART_EXPORT double PassStruct15BytesInlineArrayMixed(
Struct15BytesInlineArrayMixed a0) {
std::cout << "PassStruct15BytesInlineArrayMixed"
<< "(([(" << a0.a0[0].a0 << ", " << static_cast<int>(a0.a0[0].a1)
<< "), (" << a0.a0[1].a0 << ", " << static_cast<int>(a0.a0[1].a1)
<< "), (" << a0.a0[2].a0 << ", " << static_cast<int>(a0.a0[2].a1)
<< ")]))"
<< "\n";
double result = 0;
result += a0.a0[0].a0;
result += a0.a0[0].a1;
result += a0.a0[1].a0;
result += a0.a0[1].a1;
result += a0.a0[2].a0;
result += a0.a0[2].a1;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Check placement of mixed integer/float union.
DART_EXPORT double PassUnion4BytesMixedx10(Union4BytesMixed a0,
Union4BytesMixed a1,
Union4BytesMixed a2,
Union4BytesMixed a3,
Union4BytesMixed a4,
Union4BytesMixed a5,
Union4BytesMixed a6,
Union4BytesMixed a7,
Union4BytesMixed a8,
Union4BytesMixed a9) {
std::cout << "PassUnion4BytesMixedx10"
<< "((" << a0.a0 << ", " << a0.a1 << "), (" << a1.a0 << ", "
<< a1.a1 << "), (" << a2.a0 << ", " << a2.a1 << "), (" << a3.a0
<< ", " << a3.a1 << "), (" << a4.a0 << ", " << a4.a1 << "), ("
<< a5.a0 << ", " << a5.a1 << "), (" << a6.a0 << ", " << a6.a1
<< "), (" << a7.a0 << ", " << a7.a1 << "), (" << a8.a0 << ", "
<< a8.a1 << "), (" << a9.a0 << ", " << a9.a1 << "))"
<< "\n";
double result = 0;
result += a0.a0;
result += a1.a0;
result += a2.a0;
result += a3.a0;
result += a4.a0;
result += a5.a0;
result += a6.a0;
result += a7.a0;
result += a8.a0;
result += a9.a0;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Check placement of mixed floats union.
DART_EXPORT double PassUnion8BytesNestedFloatx10(Union8BytesNestedFloat a0,
Union8BytesNestedFloat a1,
Union8BytesNestedFloat a2,
Union8BytesNestedFloat a3,
Union8BytesNestedFloat a4,
Union8BytesNestedFloat a5,
Union8BytesNestedFloat a6,
Union8BytesNestedFloat a7,
Union8BytesNestedFloat a8,
Union8BytesNestedFloat a9) {
std::cout << "PassUnion8BytesNestedFloatx10"
<< "((" << a0.a0 << ", (" << a0.a1.a0 << ", " << a0.a1.a1 << ")), ("
<< a1.a0 << ", (" << a1.a1.a0 << ", " << a1.a1.a1 << ")), ("
<< a2.a0 << ", (" << a2.a1.a0 << ", " << a2.a1.a1 << ")), ("
<< a3.a0 << ", (" << a3.a1.a0 << ", " << a3.a1.a1 << ")), ("
<< a4.a0 << ", (" << a4.a1.a0 << ", " << a4.a1.a1 << ")), ("
<< a5.a0 << ", (" << a5.a1.a0 << ", " << a5.a1.a1 << ")), ("
<< a6.a0 << ", (" << a6.a1.a0 << ", " << a6.a1.a1 << ")), ("
<< a7.a0 << ", (" << a7.a1.a0 << ", " << a7.a1.a1 << ")), ("
<< a8.a0 << ", (" << a8.a1.a0 << ", " << a8.a1.a1 << ")), ("
<< a9.a0 << ", (" << a9.a1.a0 << ", " << a9.a1.a1 << ")))"
<< "\n";
double result = 0;
result += a0.a0;
result += a1.a0;
result += a2.a0;
result += a3.a0;
result += a4.a0;
result += a5.a0;
result += a6.a0;
result += a7.a0;
result += a8.a0;
result += a9.a0;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Mixed-size union argument.
DART_EXPORT double PassUnion9BytesNestedIntx10(Union9BytesNestedInt a0,
Union9BytesNestedInt a1,
Union9BytesNestedInt a2,
Union9BytesNestedInt a3,
Union9BytesNestedInt a4,
Union9BytesNestedInt a5,
Union9BytesNestedInt a6,
Union9BytesNestedInt a7,
Union9BytesNestedInt a8,
Union9BytesNestedInt a9) {
std::cout << "PassUnion9BytesNestedIntx10"
<< "(((" << a0.a0.a0 << ", " << a0.a0.a1 << ", " << a0.a0.a2
<< "), (" << static_cast<int>(a0.a1.a0) << ", "
<< static_cast<int>(a0.a1.a1) << ", " << static_cast<int>(a0.a1.a2)
<< ", " << static_cast<int>(a0.a1.a3) << ", "
<< static_cast<int>(a0.a1.a4) << ", " << static_cast<int>(a0.a1.a5)
<< ", " << static_cast<int>(a0.a1.a6) << ", "
<< static_cast<int>(a0.a1.a7) << ", " << static_cast<int>(a0.a1.a8)
<< ")), ((" << a1.a0.a0 << ", " << a1.a0.a1 << ", " << a1.a0.a2
<< "), (" << static_cast<int>(a1.a1.a0) << ", "
<< static_cast<int>(a1.a1.a1) << ", " << static_cast<int>(a1.a1.a2)
<< ", " << static_cast<int>(a1.a1.a3) << ", "
<< static_cast<int>(a1.a1.a4) << ", " << static_cast<int>(a1.a1.a5)
<< ", " << static_cast<int>(a1.a1.a6) << ", "
<< static_cast<int>(a1.a1.a7) << ", " << static_cast<int>(a1.a1.a8)
<< ")), ((" << a2.a0.a0 << ", " << a2.a0.a1 << ", " << a2.a0.a2
<< "), (" << static_cast<int>(a2.a1.a0) << ", "
<< static_cast<int>(a2.a1.a1) << ", " << static_cast<int>(a2.a1.a2)
<< ", " << static_cast<int>(a2.a1.a3) << ", "
<< static_cast<int>(a2.a1.a4) << ", " << static_cast<int>(a2.a1.a5)
<< ", " << static_cast<int>(a2.a1.a6) << ", "
<< static_cast<int>(a2.a1.a7) << ", " << static_cast<int>(a2.a1.a8)
<< ")), ((" << a3.a0.a0 << ", " << a3.a0.a1 << ", " << a3.a0.a2
<< "), (" << static_cast<int>(a3.a1.a0) << ", "
<< static_cast<int>(a3.a1.a1) << ", " << static_cast<int>(a3.a1.a2)
<< ", " << static_cast<int>(a3.a1.a3) << ", "
<< static_cast<int>(a3.a1.a4) << ", " << static_cast<int>(a3.a1.a5)
<< ", " << static_cast<int>(a3.a1.a6) << ", "
<< static_cast<int>(a3.a1.a7) << ", " << static_cast<int>(a3.a1.a8)
<< ")), ((" << a4.a0.a0 << ", " << a4.a0.a1 << ", " << a4.a0.a2
<< "), (" << static_cast<int>(a4.a1.a0) << ", "
<< static_cast<int>(a4.a1.a1) << ", " << static_cast<int>(a4.a1.a2)
<< ", " << static_cast<int>(a4.a1.a3) << ", "
<< static_cast<int>(a4.a1.a4) << ", " << static_cast<int>(a4.a1.a5)
<< ", " << static_cast<int>(a4.a1.a6) << ", "
<< static_cast<int>(a4.a1.a7) << ", " << static_cast<int>(a4.a1.a8)
<< ")), ((" << a5.a0.a0 << ", " << a5.a0.a1 << ", " << a5.a0.a2
<< "), (" << static_cast<int>(a5.a1.a0) << ", "
<< static_cast<int>(a5.a1.a1) << ", " << static_cast<int>(a5.a1.a2)
<< ", " << static_cast<int>(a5.a1.a3) << ", "
<< static_cast<int>(a5.a1.a4) << ", " << static_cast<int>(a5.a1.a5)
<< ", " << static_cast<int>(a5.a1.a6) << ", "
<< static_cast<int>(a5.a1.a7) << ", " << static_cast<int>(a5.a1.a8)
<< ")), ((" << a6.a0.a0 << ", " << a6.a0.a1 << ", " << a6.a0.a2
<< "), (" << static_cast<int>(a6.a1.a0) << ", "
<< static_cast<int>(a6.a1.a1) << ", " << static_cast<int>(a6.a1.a2)
<< ", " << static_cast<int>(a6.a1.a3) << ", "
<< static_cast<int>(a6.a1.a4) << ", " << static_cast<int>(a6.a1.a5)
<< ", " << static_cast<int>(a6.a1.a6) << ", "
<< static_cast<int>(a6.a1.a7) << ", " << static_cast<int>(a6.a1.a8)
<< ")), ((" << a7.a0.a0 << ", " << a7.a0.a1 << ", " << a7.a0.a2
<< "), (" << static_cast<int>(a7.a1.a0) << ", "
<< static_cast<int>(a7.a1.a1) << ", " << static_cast<int>(a7.a1.a2)
<< ", " << static_cast<int>(a7.a1.a3) << ", "
<< static_cast<int>(a7.a1.a4) << ", " << static_cast<int>(a7.a1.a5)
<< ", " << static_cast<int>(a7.a1.a6) << ", "
<< static_cast<int>(a7.a1.a7) << ", " << static_cast<int>(a7.a1.a8)
<< ")), ((" << a8.a0.a0 << ", " << a8.a0.a1 << ", " << a8.a0.a2
<< "), (" << static_cast<int>(a8.a1.a0) << ", "
<< static_cast<int>(a8.a1.a1) << ", " << static_cast<int>(a8.a1.a2)
<< ", " << static_cast<int>(a8.a1.a3) << ", "
<< static_cast<int>(a8.a1.a4) << ", " << static_cast<int>(a8.a1.a5)
<< ", " << static_cast<int>(a8.a1.a6) << ", "
<< static_cast<int>(a8.a1.a7) << ", " << static_cast<int>(a8.a1.a8)
<< ")), ((" << a9.a0.a0 << ", " << a9.a0.a1 << ", " << a9.a0.a2
<< "), (" << static_cast<int>(a9.a1.a0) << ", "
<< static_cast<int>(a9.a1.a1) << ", " << static_cast<int>(a9.a1.a2)
<< ", " << static_cast<int>(a9.a1.a3) << ", "
<< static_cast<int>(a9.a1.a4) << ", " << static_cast<int>(a9.a1.a5)
<< ", " << static_cast<int>(a9.a1.a6) << ", "
<< static_cast<int>(a9.a1.a7) << ", " << static_cast<int>(a9.a1.a8)
<< ")))"
<< "\n";
double result = 0;
result += a0.a0.a0;
result += a0.a0.a1;
result += a0.a0.a2;
result += a1.a0.a0;
result += a1.a0.a1;
result += a1.a0.a2;
result += a2.a0.a0;
result += a2.a0.a1;
result += a2.a0.a2;
result += a3.a0.a0;
result += a3.a0.a1;
result += a3.a0.a2;
result += a4.a0.a0;
result += a4.a0.a1;
result += a4.a0.a2;
result += a5.a0.a0;
result += a5.a0.a1;
result += a5.a0.a2;
result += a6.a0.a0;
result += a6.a0.a1;
result += a6.a0.a2;
result += a7.a0.a0;
result += a7.a0.a1;
result += a7.a0.a2;
result += a8.a0.a0;
result += a8.a0.a1;
result += a8.a0.a2;
result += a9.a0.a0;
result += a9.a0.a1;
result += a9.a0.a2;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Union with homogenous floats.
DART_EXPORT double PassUnion16BytesNestedInlineArrayFloatx10(
Union16BytesNestedInlineArrayFloat a0,
Union16BytesNestedInlineArrayFloat a1,
Union16BytesNestedInlineArrayFloat a2,
Union16BytesNestedInlineArrayFloat a3,
Union16BytesNestedInlineArrayFloat a4,
Union16BytesNestedInlineArrayFloat a5,
Union16BytesNestedInlineArrayFloat a6,
Union16BytesNestedInlineArrayFloat a7,
Union16BytesNestedInlineArrayFloat a8,
Union16BytesNestedInlineArrayFloat a9) {
std::cout << "PassUnion16BytesNestedInlineArrayFloatx10"
<< "(([" << a0.a0[0] << ", " << a0.a0[1] << ", " << a0.a0[2] << ", "
<< a0.a0[3] << "], (" << a0.a1.a0 << ", " << a0.a1.a1 << ", "
<< a0.a1.a2 << ", " << a0.a1.a3 << ")), ([" << a1.a0[0] << ", "
<< a1.a0[1] << ", " << a1.a0[2] << ", " << a1.a0[3] << "], ("
<< a1.a1.a0 << ", " << a1.a1.a1 << ", " << a1.a1.a2 << ", "
<< a1.a1.a3 << ")), ([" << a2.a0[0] << ", " << a2.a0[1] << ", "
<< a2.a0[2] << ", " << a2.a0[3] << "], (" << a2.a1.a0 << ", "
<< a2.a1.a1 << ", " << a2.a1.a2 << ", " << a2.a1.a3 << ")), (["
<< a3.a0[0] << ", " << a3.a0[1] << ", " << a3.a0[2] << ", "
<< a3.a0[3] << "], (" << a3.a1.a0 << ", " << a3.a1.a1 << ", "
<< a3.a1.a2 << ", " << a3.a1.a3 << ")), ([" << a4.a0[0] << ", "
<< a4.a0[1] << ", " << a4.a0[2] << ", " << a4.a0[3] << "], ("
<< a4.a1.a0 << ", " << a4.a1.a1 << ", " << a4.a1.a2 << ", "
<< a4.a1.a3 << ")), ([" << a5.a0[0] << ", " << a5.a0[1] << ", "
<< a5.a0[2] << ", " << a5.a0[3] << "], (" << a5.a1.a0 << ", "
<< a5.a1.a1 << ", " << a5.a1.a2 << ", " << a5.a1.a3 << ")), (["
<< a6.a0[0] << ", " << a6.a0[1] << ", " << a6.a0[2] << ", "
<< a6.a0[3] << "], (" << a6.a1.a0 << ", " << a6.a1.a1 << ", "
<< a6.a1.a2 << ", " << a6.a1.a3 << ")), ([" << a7.a0[0] << ", "
<< a7.a0[1] << ", " << a7.a0[2] << ", " << a7.a0[3] << "], ("
<< a7.a1.a0 << ", " << a7.a1.a1 << ", " << a7.a1.a2 << ", "
<< a7.a1.a3 << ")), ([" << a8.a0[0] << ", " << a8.a0[1] << ", "
<< a8.a0[2] << ", " << a8.a0[3] << "], (" << a8.a1.a0 << ", "
<< a8.a1.a1 << ", " << a8.a1.a2 << ", " << a8.a1.a3 << ")), (["
<< a9.a0[0] << ", " << a9.a0[1] << ", " << a9.a0[2] << ", "
<< a9.a0[3] << "], (" << a9.a1.a0 << ", " << a9.a1.a1 << ", "
<< a9.a1.a2 << ", " << a9.a1.a3 << ")))"
<< "\n";
double result = 0;
result += a0.a0[0];
result += a0.a0[1];
result += a0.a0[2];
result += a0.a0[3];
result += a1.a0[0];
result += a1.a0[1];
result += a1.a0[2];
result += a1.a0[3];
result += a2.a0[0];
result += a2.a0[1];
result += a2.a0[2];
result += a2.a0[3];
result += a3.a0[0];
result += a3.a0[1];
result += a3.a0[2];
result += a3.a0[3];
result += a4.a0[0];
result += a4.a0[1];
result += a4.a0[2];
result += a4.a0[3];
result += a5.a0[0];
result += a5.a0[1];
result += a5.a0[2];
result += a5.a0[3];
result += a6.a0[0];
result += a6.a0[1];
result += a6.a0[2];
result += a6.a0[3];
result += a7.a0[0];
result += a7.a0[1];
result += a7.a0[2];
result += a7.a0[3];
result += a8.a0[0];
result += a8.a0[1];
result += a8.a0[2];
result += a8.a0[3];
result += a9.a0[0];
result += a9.a0[1];
result += a9.a0[2];
result += a9.a0[3];
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Union with homogenous floats.
DART_EXPORT double PassUnion16BytesNestedFloatx10(Union16BytesNestedFloat a0,
Union16BytesNestedFloat a1,
Union16BytesNestedFloat a2,
Union16BytesNestedFloat a3,
Union16BytesNestedFloat a4,
Union16BytesNestedFloat a5,
Union16BytesNestedFloat a6,
Union16BytesNestedFloat a7,
Union16BytesNestedFloat a8,
Union16BytesNestedFloat a9) {
std::cout << "PassUnion16BytesNestedFloatx10"
<< "(((" << a0.a0.a0 << ", " << a0.a0.a1 << "), (" << a0.a1.a0
<< ", " << a0.a1.a1 << ", " << a0.a1.a2 << "), (" << a0.a2.a0
<< ", " << a0.a2.a1 << ", " << a0.a2.a2 << ", " << a0.a2.a3
<< ")), ((" << a1.a0.a0 << ", " << a1.a0.a1 << "), (" << a1.a1.a0
<< ", " << a1.a1.a1 << ", " << a1.a1.a2 << "), (" << a1.a2.a0
<< ", " << a1.a2.a1 << ", " << a1.a2.a2 << ", " << a1.a2.a3
<< ")), ((" << a2.a0.a0 << ", " << a2.a0.a1 << "), (" << a2.a1.a0
<< ", " << a2.a1.a1 << ", " << a2.a1.a2 << "), (" << a2.a2.a0
<< ", " << a2.a2.a1 << ", " << a2.a2.a2 << ", " << a2.a2.a3
<< ")), ((" << a3.a0.a0 << ", " << a3.a0.a1 << "), (" << a3.a1.a0
<< ", " << a3.a1.a1 << ", " << a3.a1.a2 << "), (" << a3.a2.a0
<< ", " << a3.a2.a1 << ", " << a3.a2.a2 << ", " << a3.a2.a3
<< ")), ((" << a4.a0.a0 << ", " << a4.a0.a1 << "), (" << a4.a1.a0
<< ", " << a4.a1.a1 << ", " << a4.a1.a2 << "), (" << a4.a2.a0
<< ", " << a4.a2.a1 << ", " << a4.a2.a2 << ", " << a4.a2.a3
<< ")), ((" << a5.a0.a0 << ", " << a5.a0.a1 << "), (" << a5.a1.a0
<< ", " << a5.a1.a1 << ", " << a5.a1.a2 << "), (" << a5.a2.a0
<< ", " << a5.a2.a1 << ", " << a5.a2.a2 << ", " << a5.a2.a3
<< ")), ((" << a6.a0.a0 << ", " << a6.a0.a1 << "), (" << a6.a1.a0
<< ", " << a6.a1.a1 << ", " << a6.a1.a2 << "), (" << a6.a2.a0
<< ", " << a6.a2.a1 << ", " << a6.a2.a2 << ", " << a6.a2.a3
<< ")), ((" << a7.a0.a0 << ", " << a7.a0.a1 << "), (" << a7.a1.a0
<< ", " << a7.a1.a1 << ", " << a7.a1.a2 << "), (" << a7.a2.a0
<< ", " << a7.a2.a1 << ", " << a7.a2.a2 << ", " << a7.a2.a3
<< ")), ((" << a8.a0.a0 << ", " << a8.a0.a1 << "), (" << a8.a1.a0
<< ", " << a8.a1.a1 << ", " << a8.a1.a2 << "), (" << a8.a2.a0
<< ", " << a8.a2.a1 << ", " << a8.a2.a2 << ", " << a8.a2.a3
<< ")), ((" << a9.a0.a0 << ", " << a9.a0.a1 << "), (" << a9.a1.a0
<< ", " << a9.a1.a1 << ", " << a9.a1.a2 << "), (" << a9.a2.a0
<< ", " << a9.a2.a1 << ", " << a9.a2.a2 << ", " << a9.a2.a3 << ")))"
<< "\n";
double result = 0;
result += a0.a0.a0;
result += a0.a0.a1;
result += a1.a0.a0;
result += a1.a0.a1;
result += a2.a0.a0;
result += a2.a0.a1;
result += a3.a0.a0;
result += a3.a0.a1;
result += a4.a0.a0;
result += a4.a0.a1;
result += a5.a0.a0;
result += a5.a0.a1;
result += a6.a0.a0;
result += a6.a0.a1;
result += a7.a0.a0;
result += a7.a0.a1;
result += a8.a0.a0;
result += a8.a0.a1;
result += a9.a0.a0;
result += a9.a0.a1;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs and unions by value.
// Smallest struct with data.
DART_EXPORT Struct1ByteInt ReturnStruct1ByteInt(int8_t a0) {
std::cout << "ReturnStruct1ByteInt"
<< "(" << static_cast<int>(a0) << ")"
<< "\n";
Struct1ByteInt result;
result.a0 = a0;
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Smaller than word size return value on all architectures.
DART_EXPORT Struct3BytesHomogeneousUint8
ReturnStruct3BytesHomogeneousUint8(uint8_t a0, uint8_t a1, uint8_t a2) {
std::cout << "ReturnStruct3BytesHomogeneousUint8"
<< "(" << static_cast<int>(a0) << ", " << static_cast<int>(a1)
<< ", " << static_cast<int>(a2) << ")"
<< "\n";
Struct3BytesHomogeneousUint8 result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ", "
<< static_cast<int>(result.a1) << ", "
<< static_cast<int>(result.a2) << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Smaller than word size return value on all architectures.
// With alignment rules taken into account size is 4 bytes.
DART_EXPORT Struct3BytesInt2ByteAligned
ReturnStruct3BytesInt2ByteAligned(int16_t a0, int8_t a1) {
std::cout << "ReturnStruct3BytesInt2ByteAligned"
<< "(" << a0 << ", " << static_cast<int>(a1) << ")"
<< "\n";
Struct3BytesInt2ByteAligned result;
result.a0 = a0;
result.a1 = a1;
std::cout << "result = "
<< "(" << result.a0 << ", " << static_cast<int>(result.a1) << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Word size return value on 32 bit architectures..
DART_EXPORT Struct4BytesHomogeneousInt16
ReturnStruct4BytesHomogeneousInt16(int16_t a0, int16_t a1) {
std::cout << "ReturnStruct4BytesHomogeneousInt16"
<< "(" << a0 << ", " << a1 << ")"
<< "\n";
Struct4BytesHomogeneousInt16 result;
result.a0 = a0;
result.a1 = a1;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Non-wordsize return value.
DART_EXPORT Struct7BytesHomogeneousUint8
ReturnStruct7BytesHomogeneousUint8(uint8_t a0,
uint8_t a1,
uint8_t a2,
uint8_t a3,
uint8_t a4,
uint8_t a5,
uint8_t a6) {
std::cout << "ReturnStruct7BytesHomogeneousUint8"
<< "(" << static_cast<int>(a0) << ", " << static_cast<int>(a1)
<< ", " << static_cast<int>(a2) << ", " << static_cast<int>(a3)
<< ", " << static_cast<int>(a4) << ", " << static_cast<int>(a5)
<< ", " << static_cast<int>(a6) << ")"
<< "\n";
Struct7BytesHomogeneousUint8 result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
result.a3 = a3;
result.a4 = a4;
result.a5 = a5;
result.a6 = a6;
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ", "
<< static_cast<int>(result.a1) << ", "
<< static_cast<int>(result.a2) << ", "
<< static_cast<int>(result.a3) << ", "
<< static_cast<int>(result.a4) << ", "
<< static_cast<int>(result.a5) << ", "
<< static_cast<int>(result.a6) << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Non-wordsize return value.
// With alignment rules taken into account size is 8 bytes.
DART_EXPORT Struct7BytesInt4ByteAligned
ReturnStruct7BytesInt4ByteAligned(int32_t a0, int16_t a1, int8_t a2) {
std::cout << "ReturnStruct7BytesInt4ByteAligned"
<< "(" << a0 << ", " << a1 << ", " << static_cast<int>(a2) << ")"
<< "\n";
Struct7BytesInt4ByteAligned result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", "
<< static_cast<int>(result.a2) << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Return value in integer registers on many architectures.
DART_EXPORT Struct8BytesInt ReturnStruct8BytesInt(int16_t a0,
int16_t a1,
int32_t a2) {
std::cout << "ReturnStruct8BytesInt"
<< "(" << a0 << ", " << a1 << ", " << a2 << ")"
<< "\n";
Struct8BytesInt result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2 << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Return value in FP registers on many architectures.
DART_EXPORT Struct8BytesHomogeneousFloat
ReturnStruct8BytesHomogeneousFloat(float a0, float a1) {
std::cout << "ReturnStruct8BytesHomogeneousFloat"
<< "(" << a0 << ", " << a1 << ")"
<< "\n";
Struct8BytesHomogeneousFloat result;
result.a0 = a0;
result.a1 = a1;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Return value split over FP and integer register in x64.
DART_EXPORT Struct8BytesMixed ReturnStruct8BytesMixed(float a0,
int16_t a1,
int16_t a2) {
std::cout << "ReturnStruct8BytesMixed"
<< "(" << a0 << ", " << a1 << ", " << a2 << ")"
<< "\n";
Struct8BytesMixed result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2 << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// 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.
DART_EXPORT Struct9BytesHomogeneousUint8
ReturnStruct9BytesHomogeneousUint8(uint8_t a0,
uint8_t a1,
uint8_t a2,
uint8_t a3,
uint8_t a4,
uint8_t a5,
uint8_t a6,
uint8_t a7,
uint8_t a8) {
std::cout << "ReturnStruct9BytesHomogeneousUint8"
<< "(" << static_cast<int>(a0) << ", " << static_cast<int>(a1)
<< ", " << static_cast<int>(a2) << ", " << static_cast<int>(a3)
<< ", " << static_cast<int>(a4) << ", " << static_cast<int>(a5)
<< ", " << static_cast<int>(a6) << ", " << static_cast<int>(a7)
<< ", " << static_cast<int>(a8) << ")"
<< "\n";
Struct9BytesHomogeneousUint8 result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
result.a3 = a3;
result.a4 = a4;
result.a5 = a5;
result.a6 = a6;
result.a7 = a7;
result.a8 = a8;
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ", "
<< static_cast<int>(result.a1) << ", "
<< static_cast<int>(result.a2) << ", "
<< static_cast<int>(result.a3) << ", "
<< static_cast<int>(result.a4) << ", "
<< static_cast<int>(result.a5) << ", "
<< static_cast<int>(result.a6) << ", "
<< static_cast<int>(result.a7) << ", "
<< static_cast<int>(result.a8) << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Return value in two integer registers on x64.
// With alignment rules taken into account size is 12 or 16 bytes.
DART_EXPORT Struct9BytesInt4Or8ByteAligned
ReturnStruct9BytesInt4Or8ByteAligned(int64_t a0, int8_t a1) {
std::cout << "ReturnStruct9BytesInt4Or8ByteAligned"
<< "(" << a0 << ", " << static_cast<int>(a1) << ")"
<< "\n";
Struct9BytesInt4Or8ByteAligned result;
result.a0 = a0;
result.a1 = a1;
std::cout << "result = "
<< "(" << result.a0 << ", " << static_cast<int>(result.a1) << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Return value in FPU registers, but does not use all registers on arm hardfp
// and arm64.
DART_EXPORT Struct12BytesHomogeneousFloat
ReturnStruct12BytesHomogeneousFloat(float a0, float a1, float a2) {
std::cout << "ReturnStruct12BytesHomogeneousFloat"
<< "(" << a0 << ", " << a1 << ", " << a2 << ")"
<< "\n";
Struct12BytesHomogeneousFloat result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2 << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Return value in FPU registers on arm hardfp and arm64.
DART_EXPORT Struct16BytesHomogeneousFloat
ReturnStruct16BytesHomogeneousFloat(float a0, float a1, float a2, float a3) {
std::cout << "ReturnStruct16BytesHomogeneousFloat"
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ")"
<< "\n";
Struct16BytesHomogeneousFloat result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
result.a3 = a3;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Return value split over FP and integer register in x64.
DART_EXPORT Struct16BytesMixed ReturnStruct16BytesMixed(double a0, int64_t a1) {
std::cout << "ReturnStruct16BytesMixed"
<< "(" << a0 << ", " << a1 << ")"
<< "\n";
Struct16BytesMixed result;
result.a0 = a0;
result.a1 = a1;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Return value split over FP and integer register in x64.
// The integer register contains half float half int.
DART_EXPORT Struct16BytesMixed2 ReturnStruct16BytesMixed2(float a0,
float a1,
float a2,
int32_t a3) {
std::cout << "ReturnStruct16BytesMixed2"
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ")"
<< "\n";
Struct16BytesMixed2 result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
result.a3 = a3;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// 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.
DART_EXPORT Struct17BytesInt ReturnStruct17BytesInt(int64_t a0,
int64_t a1,
int8_t a2) {
std::cout << "ReturnStruct17BytesInt"
<< "(" << a0 << ", " << a1 << ", " << static_cast<int>(a2) << ")"
<< "\n";
Struct17BytesInt result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", "
<< static_cast<int>(result.a2) << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// 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.
DART_EXPORT Struct19BytesHomogeneousUint8
ReturnStruct19BytesHomogeneousUint8(uint8_t a0,
uint8_t a1,
uint8_t a2,
uint8_t a3,
uint8_t a4,
uint8_t a5,
uint8_t a6,
uint8_t a7,
uint8_t a8,
uint8_t a9,
uint8_t a10,
uint8_t a11,
uint8_t a12,
uint8_t a13,
uint8_t a14,
uint8_t a15,
uint8_t a16,
uint8_t a17,
uint8_t a18) {
std::cout << "ReturnStruct19BytesHomogeneousUint8"
<< "(" << static_cast<int>(a0) << ", " << static_cast<int>(a1)
<< ", " << static_cast<int>(a2) << ", " << static_cast<int>(a3)
<< ", " << static_cast<int>(a4) << ", " << static_cast<int>(a5)
<< ", " << static_cast<int>(a6) << ", " << static_cast<int>(a7)
<< ", " << static_cast<int>(a8) << ", " << static_cast<int>(a9)
<< ", " << static_cast<int>(a10) << ", " << static_cast<int>(a11)
<< ", " << static_cast<int>(a12) << ", " << static_cast<int>(a13)
<< ", " << static_cast<int>(a14) << ", " << static_cast<int>(a15)
<< ", " << static_cast<int>(a16) << ", " << static_cast<int>(a17)
<< ", " << static_cast<int>(a18) << ")"
<< "\n";
Struct19BytesHomogeneousUint8 result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
result.a3 = a3;
result.a4 = a4;
result.a5 = a5;
result.a6 = a6;
result.a7 = a7;
result.a8 = a8;
result.a9 = a9;
result.a10 = a10;
result.a11 = a11;
result.a12 = a12;
result.a13 = a13;
result.a14 = a14;
result.a15 = a15;
result.a16 = a16;
result.a17 = a17;
result.a18 = a18;
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ", "
<< static_cast<int>(result.a1) << ", "
<< static_cast<int>(result.a2) << ", "
<< static_cast<int>(result.a3) << ", "
<< static_cast<int>(result.a4) << ", "
<< static_cast<int>(result.a5) << ", "
<< static_cast<int>(result.a6) << ", "
<< static_cast<int>(result.a7) << ", "
<< static_cast<int>(result.a8) << ", "
<< static_cast<int>(result.a9) << ", "
<< static_cast<int>(result.a10) << ", "
<< static_cast<int>(result.a11) << ", "
<< static_cast<int>(result.a12) << ", "
<< static_cast<int>(result.a13) << ", "
<< static_cast<int>(result.a14) << ", "
<< static_cast<int>(result.a15) << ", "
<< static_cast<int>(result.a16) << ", "
<< static_cast<int>(result.a17) << ", "
<< static_cast<int>(result.a18) << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Return value too big to go in cpu registers on arm64.
DART_EXPORT Struct20BytesHomogeneousInt32
ReturnStruct20BytesHomogeneousInt32(int32_t a0,
int32_t a1,
int32_t a2,
int32_t a3,
int32_t a4) {
std::cout << "ReturnStruct20BytesHomogeneousInt32"
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
<< ")"
<< "\n";
Struct20BytesHomogeneousInt32 result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
result.a3 = a3;
result.a4 = a4;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ", " << result.a4 << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Return value too big to go in FPU registers on x64, arm hardfp and arm64.
DART_EXPORT Struct20BytesHomogeneousFloat
ReturnStruct20BytesHomogeneousFloat(float a0,
float a1,
float a2,
float a3,
float a4) {
std::cout << "ReturnStruct20BytesHomogeneousFloat"
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
<< ")"
<< "\n";
Struct20BytesHomogeneousFloat result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
result.a3 = a3;
result.a4 = a4;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ", " << result.a4 << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Return value in FPU registers on arm64.
DART_EXPORT Struct32BytesHomogeneousDouble
ReturnStruct32BytesHomogeneousDouble(double a0,
double a1,
double a2,
double a3) {
std::cout << "ReturnStruct32BytesHomogeneousDouble"
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ")"
<< "\n";
Struct32BytesHomogeneousDouble result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
result.a3 = a3;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Return value too big to go in FPU registers on arm64.
DART_EXPORT Struct40BytesHomogeneousDouble
ReturnStruct40BytesHomogeneousDouble(double a0,
double a1,
double a2,
double a3,
double a4) {
std::cout << "ReturnStruct40BytesHomogeneousDouble"
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
<< ")"
<< "\n";
Struct40BytesHomogeneousDouble result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
result.a3 = a3;
result.a4 = a4;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ", " << result.a4 << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Test 1kb struct.
DART_EXPORT Struct1024BytesHomogeneousUint64
ReturnStruct1024BytesHomogeneousUint64(uint64_t a0,
uint64_t a1,
uint64_t a2,
uint64_t a3,
uint64_t a4,
uint64_t a5,
uint64_t a6,
uint64_t a7,
uint64_t a8,
uint64_t a9,
uint64_t a10,
uint64_t a11,
uint64_t a12,
uint64_t a13,
uint64_t a14,
uint64_t a15,
uint64_t a16,
uint64_t a17,
uint64_t a18,
uint64_t a19,
uint64_t a20,
uint64_t a21,
uint64_t a22,
uint64_t a23,
uint64_t a24,
uint64_t a25,
uint64_t a26,
uint64_t a27,
uint64_t a28,
uint64_t a29,
uint64_t a30,
uint64_t a31,
uint64_t a32,
uint64_t a33,
uint64_t a34,
uint64_t a35,
uint64_t a36,
uint64_t a37,
uint64_t a38,
uint64_t a39,
uint64_t a40,
uint64_t a41,
uint64_t a42,
uint64_t a43,
uint64_t a44,
uint64_t a45,
uint64_t a46,
uint64_t a47,
uint64_t a48,
uint64_t a49,
uint64_t a50,
uint64_t a51,
uint64_t a52,
uint64_t a53,
uint64_t a54,
uint64_t a55,
uint64_t a56,
uint64_t a57,
uint64_t a58,
uint64_t a59,
uint64_t a60,
uint64_t a61,
uint64_t a62,
uint64_t a63,
uint64_t a64,
uint64_t a65,
uint64_t a66,
uint64_t a67,
uint64_t a68,
uint64_t a69,
uint64_t a70,
uint64_t a71,
uint64_t a72,
uint64_t a73,
uint64_t a74,
uint64_t a75,
uint64_t a76,
uint64_t a77,
uint64_t a78,
uint64_t a79,
uint64_t a80,
uint64_t a81,
uint64_t a82,
uint64_t a83,
uint64_t a84,
uint64_t a85,
uint64_t a86,
uint64_t a87,
uint64_t a88,
uint64_t a89,
uint64_t a90,
uint64_t a91,
uint64_t a92,
uint64_t a93,
uint64_t a94,
uint64_t a95,
uint64_t a96,
uint64_t a97,
uint64_t a98,
uint64_t a99,
uint64_t a100,
uint64_t a101,
uint64_t a102,
uint64_t a103,
uint64_t a104,
uint64_t a105,
uint64_t a106,
uint64_t a107,
uint64_t a108,
uint64_t a109,
uint64_t a110,
uint64_t a111,
uint64_t a112,
uint64_t a113,
uint64_t a114,
uint64_t a115,
uint64_t a116,
uint64_t a117,
uint64_t a118,
uint64_t a119,
uint64_t a120,
uint64_t a121,
uint64_t a122,
uint64_t a123,
uint64_t a124,
uint64_t a125,
uint64_t a126,
uint64_t a127) {
std::cout << "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 << ")"
<< "\n";
Struct1024BytesHomogeneousUint64 result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
result.a3 = a3;
result.a4 = a4;
result.a5 = a5;
result.a6 = a6;
result.a7 = a7;
result.a8 = a8;
result.a9 = a9;
result.a10 = a10;
result.a11 = a11;
result.a12 = a12;
result.a13 = a13;
result.a14 = a14;
result.a15 = a15;
result.a16 = a16;
result.a17 = a17;
result.a18 = a18;
result.a19 = a19;
result.a20 = a20;
result.a21 = a21;
result.a22 = a22;
result.a23 = a23;
result.a24 = a24;
result.a25 = a25;
result.a26 = a26;
result.a27 = a27;
result.a28 = a28;
result.a29 = a29;
result.a30 = a30;
result.a31 = a31;
result.a32 = a32;
result.a33 = a33;
result.a34 = a34;
result.a35 = a35;
result.a36 = a36;
result.a37 = a37;
result.a38 = a38;
result.a39 = a39;
result.a40 = a40;
result.a41 = a41;
result.a42 = a42;
result.a43 = a43;
result.a44 = a44;
result.a45 = a45;
result.a46 = a46;
result.a47 = a47;
result.a48 = a48;
result.a49 = a49;
result.a50 = a50;
result.a51 = a51;
result.a52 = a52;
result.a53 = a53;
result.a54 = a54;
result.a55 = a55;
result.a56 = a56;
result.a57 = a57;
result.a58 = a58;
result.a59 = a59;
result.a60 = a60;
result.a61 = a61;
result.a62 = a62;
result.a63 = a63;
result.a64 = a64;
result.a65 = a65;
result.a66 = a66;
result.a67 = a67;
result.a68 = a68;
result.a69 = a69;
result.a70 = a70;
result.a71 = a71;
result.a72 = a72;
result.a73 = a73;
result.a74 = a74;
result.a75 = a75;
result.a76 = a76;
result.a77 = a77;
result.a78 = a78;
result.a79 = a79;
result.a80 = a80;
result.a81 = a81;
result.a82 = a82;
result.a83 = a83;
result.a84 = a84;
result.a85 = a85;
result.a86 = a86;
result.a87 = a87;
result.a88 = a88;
result.a89 = a89;
result.a90 = a90;
result.a91 = a91;
result.a92 = a92;
result.a93 = a93;
result.a94 = a94;
result.a95 = a95;
result.a96 = a96;
result.a97 = a97;
result.a98 = a98;
result.a99 = a99;
result.a100 = a100;
result.a101 = a101;
result.a102 = a102;
result.a103 = a103;
result.a104 = a104;
result.a105 = a105;
result.a106 = a106;
result.a107 = a107;
result.a108 = a108;
result.a109 = a109;
result.a110 = a110;
result.a111 = a111;
result.a112 = a112;
result.a113 = a113;
result.a114 = a114;
result.a115 = a115;
result.a116 = a116;
result.a117 = a117;
result.a118 = a118;
result.a119 = a119;
result.a120 = a120;
result.a121 = a121;
result.a122 = a122;
result.a123 = a123;
result.a124 = a124;
result.a125 = a125;
result.a126 = a126;
result.a127 = a127;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ", " << result.a4 << ", " << result.a5
<< ", " << result.a6 << ", " << result.a7 << ", " << result.a8
<< ", " << result.a9 << ", " << result.a10 << ", " << result.a11
<< ", " << result.a12 << ", " << result.a13 << ", " << result.a14
<< ", " << result.a15 << ", " << result.a16 << ", " << result.a17
<< ", " << result.a18 << ", " << result.a19 << ", " << result.a20
<< ", " << result.a21 << ", " << result.a22 << ", " << result.a23
<< ", " << result.a24 << ", " << result.a25 << ", " << result.a26
<< ", " << result.a27 << ", " << result.a28 << ", " << result.a29
<< ", " << result.a30 << ", " << result.a31 << ", " << result.a32
<< ", " << result.a33 << ", " << result.a34 << ", " << result.a35
<< ", " << result.a36 << ", " << result.a37 << ", " << result.a38
<< ", " << result.a39 << ", " << result.a40 << ", " << result.a41
<< ", " << result.a42 << ", " << result.a43 << ", " << result.a44
<< ", " << result.a45 << ", " << result.a46 << ", " << result.a47
<< ", " << result.a48 << ", " << result.a49 << ", " << result.a50
<< ", " << result.a51 << ", " << result.a52 << ", " << result.a53
<< ", " << result.a54 << ", " << result.a55 << ", " << result.a56
<< ", " << result.a57 << ", " << result.a58 << ", " << result.a59
<< ", " << result.a60 << ", " << result.a61 << ", " << result.a62
<< ", " << result.a63 << ", " << result.a64 << ", " << result.a65
<< ", " << result.a66 << ", " << result.a67 << ", " << result.a68
<< ", " << result.a69 << ", " << result.a70 << ", " << result.a71
<< ", " << result.a72 << ", " << result.a73 << ", " << result.a74
<< ", " << result.a75 << ", " << result.a76 << ", " << result.a77
<< ", " << result.a78 << ", " << result.a79 << ", " << result.a80
<< ", " << result.a81 << ", " << result.a82 << ", " << result.a83
<< ", " << result.a84 << ", " << result.a85 << ", " << result.a86
<< ", " << result.a87 << ", " << result.a88 << ", " << result.a89
<< ", " << result.a90 << ", " << result.a91 << ", " << result.a92
<< ", " << result.a93 << ", " << result.a94 << ", " << result.a95
<< ", " << result.a96 << ", " << result.a97 << ", " << result.a98
<< ", " << result.a99 << ", " << result.a100 << ", " << result.a101
<< ", " << result.a102 << ", " << result.a103 << ", " << result.a104
<< ", " << result.a105 << ", " << result.a106 << ", " << result.a107
<< ", " << result.a108 << ", " << result.a109 << ", " << result.a110
<< ", " << result.a111 << ", " << result.a112 << ", " << result.a113
<< ", " << result.a114 << ", " << result.a115 << ", " << result.a116
<< ", " << result.a117 << ", " << result.a118 << ", " << result.a119
<< ", " << result.a120 << ", " << result.a121 << ", " << result.a122
<< ", " << result.a123 << ", " << result.a124 << ", " << result.a125
<< ", " << result.a126 << ", " << result.a127 << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Small struct with mis-aligned member.
DART_EXPORT Struct3BytesPackedInt ReturnStruct3BytesPackedInt(int8_t a0,
int16_t a1) {
std::cout << "ReturnStruct3BytesPackedInt"
<< "(" << static_cast<int>(a0) << ", " << a1 << ")"
<< "\n";
Struct3BytesPackedInt result;
result.a0 = a0;
result.a1 = a1;
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ", " << result.a1 << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Struct with mis-aligned member.
DART_EXPORT Struct8BytesPackedInt ReturnStruct8BytesPackedInt(uint8_t a0,
uint32_t a1,
uint8_t a2,
uint8_t a3,
uint8_t a4) {
std::cout << "ReturnStruct8BytesPackedInt"
<< "(" << static_cast<int>(a0) << ", " << a1 << ", "
<< static_cast<int>(a2) << ", " << static_cast<int>(a3) << ", "
<< static_cast<int>(a4) << ")"
<< "\n";
Struct8BytesPackedInt result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
result.a3 = a3;
result.a4 = a4;
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ", " << result.a1 << ", "
<< static_cast<int>(result.a2) << ", "
<< static_cast<int>(result.a3) << ", "
<< static_cast<int>(result.a4) << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Struct with mis-aligned member.
// Tests backfilling of CPU and FPU registers.
DART_EXPORT Struct9BytesPackedMixed ReturnStruct9BytesPackedMixed(uint8_t a0,
double a1) {
std::cout << "ReturnStruct9BytesPackedMixed"
<< "(" << static_cast<int>(a0) << ", " << a1 << ")"
<< "\n";
Struct9BytesPackedMixed result;
result.a0 = a0;
result.a1 = a1;
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ", " << result.a1 << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Returning a mixed integer/float union.
DART_EXPORT Union4BytesMixed ReturnUnion4BytesMixed(uint32_t a0) {
std::cout << "ReturnUnion4BytesMixed"
<< "(" << a0 << ")"
<< "\n";
Union4BytesMixed result;
result.a0 = a0;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Returning a floating point only union.
DART_EXPORT Union8BytesNestedFloat ReturnUnion8BytesNestedFloat(double a0) {
std::cout << "ReturnUnion8BytesNestedFloat"
<< "(" << a0 << ")"
<< "\n";
Union8BytesNestedFloat result;
result.a0 = a0;
std::cout << "result = "
<< "(" << result.a0 << ", (" << result.a1.a0 << ", " << result.a1.a1
<< "))"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Returning a mixed-size union.
DART_EXPORT Union9BytesNestedInt
ReturnUnion9BytesNestedInt(Struct8BytesInt a0) {
std::cout << "ReturnUnion9BytesNestedInt"
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << "))"
<< "\n";
Union9BytesNestedInt result;
result.a0.a0 = a0.a0;
result.a0.a1 = a0.a1;
result.a0.a2 = a0.a2;
std::cout << "result = "
<< "((" << result.a0.a0 << ", " << result.a0.a1 << ", "
<< result.a0.a2 << "), (" << static_cast<int>(result.a1.a0) << ", "
<< static_cast<int>(result.a1.a1) << ", "
<< static_cast<int>(result.a1.a2) << ", "
<< static_cast<int>(result.a1.a3) << ", "
<< static_cast<int>(result.a1.a4) << ", "
<< static_cast<int>(result.a1.a5) << ", "
<< static_cast<int>(result.a1.a6) << ", "
<< static_cast<int>(result.a1.a7) << ", "
<< static_cast<int>(result.a1.a8) << "))"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Returning union with homogenous floats.
DART_EXPORT Union16BytesNestedFloat
ReturnUnion16BytesNestedFloat(Struct8BytesHomogeneousFloat a0) {
std::cout << "ReturnUnion16BytesNestedFloat"
<< "((" << a0.a0 << ", " << a0.a1 << "))"
<< "\n";
Union16BytesNestedFloat result;
result.a0.a0 = a0.a0;
result.a0.a1 = a0.a1;
std::cout << "result = "
<< "((" << result.a0.a0 << ", " << result.a0.a1 << "), ("
<< result.a1.a0 << ", " << result.a1.a1 << ", " << result.a1.a2
<< "), (" << result.a2.a0 << ", " << result.a2.a1 << ", "
<< result.a2.a2 << ", " << result.a2.a3 << "))"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Test that a struct passed in as argument can be returned.
// Especially for ffi callbacks.
// Struct is passed in int registers in most ABIs.
DART_EXPORT Struct1ByteInt
ReturnStructArgumentStruct1ByteInt(Struct1ByteInt a0) {
std::cout << "ReturnStructArgumentStruct1ByteInt"
<< "((" << static_cast<int>(a0.a0) << "))"
<< "\n";
Struct1ByteInt result = a0;
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Test that a struct passed in as argument can be returned.
// Especially for ffi callbacks.
// Struct is passed on stack on all ABIs.
DART_EXPORT Struct1ByteInt
ReturnStructArgumentInt32x8Struct1ByteInt(int32_t a0,
int32_t a1,
int32_t a2,
int32_t a3,
int32_t a4,
int32_t a5,
int32_t a6,
int32_t a7,
Struct1ByteInt a8) {
std::cout << "ReturnStructArgumentInt32x8Struct1ByteInt"
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
<< ", " << a5 << ", " << a6 << ", " << a7 << ", ("
<< static_cast<int>(a8.a0) << "))"
<< "\n";
Struct1ByteInt result = a8;
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Test that a struct passed in as argument can be returned.
// Especially for ffi callbacks.
// Struct is passed in float registers in most ABIs.
DART_EXPORT Struct8BytesHomogeneousFloat
ReturnStructArgumentStruct8BytesHomogeneousFloat(
Struct8BytesHomogeneousFloat a0) {
std::cout << "ReturnStructArgumentStruct8BytesHomogeneousFloat"
<< "((" << a0.a0 << ", " << a0.a1 << "))"
<< "\n";
Struct8BytesHomogeneousFloat result = a0;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// On arm64, both argument and return value are passed in by pointer.
DART_EXPORT Struct20BytesHomogeneousInt32
ReturnStructArgumentStruct20BytesHomogeneousInt32(
Struct20BytesHomogeneousInt32 a0) {
std::cout << "ReturnStructArgumentStruct20BytesHomogeneousInt32"
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< ", " << a0.a4 << "))"
<< "\n";
Struct20BytesHomogeneousInt32 result = a0;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ", " << result.a4 << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// On arm64, both argument and return value are passed in by pointer.
// Ints exhaust registers, so that pointer is passed on stack.
DART_EXPORT Struct20BytesHomogeneousInt32
ReturnStructArgumentInt32x8Struct20BytesHomogeneou(
int32_t a0,
int32_t a1,
int32_t a2,
int32_t a3,
int32_t a4,
int32_t a5,
int32_t a6,
int32_t a7,
Struct20BytesHomogeneousInt32 a8) {
std::cout << "ReturnStructArgumentInt32x8Struct20BytesHomogeneou"
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
<< ", " << a5 << ", " << a6 << ", " << a7 << ", (" << a8.a0 << ", "
<< a8.a1 << ", " << a8.a2 << ", " << a8.a3 << ", " << a8.a4 << "))"
<< "\n";
Struct20BytesHomogeneousInt32 result = a8;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ", " << result.a4 << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Test returning struct with inline array.
DART_EXPORT Struct8BytesInlineArrayInt
ReturnStructArgumentStruct8BytesInlineArrayInt(Struct8BytesInlineArrayInt a0) {
std::cout << "ReturnStructArgumentStruct8BytesInlineArrayInt"
<< "(([" << static_cast<int>(a0.a0[0]) << ", "
<< static_cast<int>(a0.a0[1]) << ", " << static_cast<int>(a0.a0[2])
<< ", " << static_cast<int>(a0.a0[3]) << ", "
<< static_cast<int>(a0.a0[4]) << ", " << static_cast<int>(a0.a0[5])
<< ", " << static_cast<int>(a0.a0[6]) << ", "
<< static_cast<int>(a0.a0[7]) << "]))"
<< "\n";
Struct8BytesInlineArrayInt result = a0;
std::cout << "result = "
<< "([" << static_cast<int>(result.a0[0]) << ", "
<< static_cast<int>(result.a0[1]) << ", "
<< static_cast<int>(result.a0[2]) << ", "
<< static_cast<int>(result.a0[3]) << ", "
<< static_cast<int>(result.a0[4]) << ", "
<< static_cast<int>(result.a0[5]) << ", "
<< static_cast<int>(result.a0[6]) << ", "
<< static_cast<int>(result.a0[7]) << "])"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Return value in FPU registers on arm hardfp and arm64.
DART_EXPORT StructStruct16BytesHomogeneousFloat2
ReturnStructArgumentStructStruct16BytesHomogeneous(
StructStruct16BytesHomogeneousFloat2 a0) {
std::cout << "ReturnStructArgumentStructStruct16BytesHomogeneous"
<< "(((" << a0.a0.a0 << "), [(" << a0.a1[0].a0 << "), ("
<< a0.a1[1].a0 << ")], " << a0.a2 << "))"
<< "\n";
StructStruct16BytesHomogeneousFloat2 result = a0;
std::cout << "result = "
<< "((" << result.a0.a0 << "), [(" << result.a1[0].a0 << "), ("
<< result.a1[1].a0 << ")], " << result.a2 << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Return value in FPU registers on arm64.
DART_EXPORT StructStruct32BytesHomogeneousDouble2
ReturnStructArgumentStructStruct32BytesHomogeneous(
StructStruct32BytesHomogeneousDouble2 a0) {
std::cout << "ReturnStructArgumentStructStruct32BytesHomogeneous"
<< "(((" << a0.a0.a0 << "), [(" << a0.a1[0].a0 << "), ("
<< a0.a1[1].a0 << ")], " << a0.a2 << "))"
<< "\n";
StructStruct32BytesHomogeneousDouble2 result = a0;
std::cout << "result = "
<< "((" << result.a0.a0 << "), [(" << result.a1[0].a0 << "), ("
<< result.a1[1].a0 << ")], " << result.a2 << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// On x64 Linux, return value is split over FP and int registers.
DART_EXPORT StructStruct16BytesMixed3
ReturnStructArgumentStructStruct16BytesMixed3(StructStruct16BytesMixed3 a0) {
std::cout << "ReturnStructArgumentStructStruct16BytesMixed3"
<< "(((" << a0.a0.a0 << "), [(" << a0.a1[0].a0 << ", "
<< a0.a1[0].a1 << ", " << a0.a1[0].a2 << ")], [" << a0.a2[0] << ", "
<< a0.a2[1] << "]))"
<< "\n";
StructStruct16BytesMixed3 result = a0;
std::cout << "result = "
<< "((" << result.a0.a0 << "), [(" << result.a1[0].a0 << ", "
<< result.a1[0].a1 << ", " << result.a1[0].a2 << ")], ["
<< result.a2[0] << ", " << result.a2[1] << "])"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Test alignment and padding of 16 byte int within struct.
DART_EXPORT StructAlignmentInt16 ReturnStructAlignmentInt16(int8_t a0,
int16_t a1,
int8_t a2) {
std::cout << "ReturnStructAlignmentInt16"
<< "(" << static_cast<int>(a0) << ", " << a1 << ", "
<< static_cast<int>(a2) << ")"
<< "\n";
StructAlignmentInt16 result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ", " << result.a1 << ", "
<< static_cast<int>(result.a2) << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Test alignment and padding of 32 byte int within struct.
DART_EXPORT StructAlignmentInt32 ReturnStructAlignmentInt32(int8_t a0,
int32_t a1,
int8_t a2) {
std::cout << "ReturnStructAlignmentInt32"
<< "(" << static_cast<int>(a0) << ", " << a1 << ", "
<< static_cast<int>(a2) << ")"
<< "\n";
StructAlignmentInt32 result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ", " << result.a1 << ", "
<< static_cast<int>(result.a2) << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Test alignment and padding of 64 byte int within struct.
DART_EXPORT StructAlignmentInt64 ReturnStructAlignmentInt64(int8_t a0,
int64_t a1,
int8_t a2) {
std::cout << "ReturnStructAlignmentInt64"
<< "(" << static_cast<int>(a0) << ", " << a1 << ", "
<< static_cast<int>(a2) << ")"
<< "\n";
StructAlignmentInt64 result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ", " << result.a1 << ", "
<< static_cast<int>(result.a2) << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Simple nested struct.
DART_EXPORT Struct8BytesNestedInt
ReturnStruct8BytesNestedInt(Struct4BytesHomogeneousInt16 a0,
Struct4BytesHomogeneousInt16 a1) {
std::cout << "ReturnStruct8BytesNestedInt"
<< "((" << a0.a0 << ", " << a0.a1 << "), (" << a1.a0 << ", "
<< a1.a1 << "))"
<< "\n";
Struct8BytesNestedInt result;
result.a0.a0 = a0.a0;
result.a0.a1 = a0.a1;
result.a1.a0 = a1.a0;
result.a1.a1 = a1.a1;
std::cout << "result = "
<< "((" << result.a0.a0 << ", " << result.a0.a1 << "), ("
<< result.a1.a0 << ", " << result.a1.a1 << "))"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Simple nested struct with floats.
DART_EXPORT Struct8BytesNestedFloat
ReturnStruct8BytesNestedFloat(Struct4BytesFloat a0, Struct4BytesFloat a1) {
std::cout << "ReturnStruct8BytesNestedFloat"
<< "((" << a0.a0 << "), (" << a1.a0 << "))"
<< "\n";
Struct8BytesNestedFloat result;
result.a0.a0 = a0.a0;
result.a1.a0 = a1.a0;
std::cout << "result = "
<< "((" << result.a0.a0 << "), (" << result.a1.a0 << "))"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// The nesting is irregular, testing homogenous float rules on arm and arm64,
// and the fpu register usage on x64.
DART_EXPORT Struct8BytesNestedFloat2
ReturnStruct8BytesNestedFloat2(Struct4BytesFloat a0, float a1) {
std::cout << "ReturnStruct8BytesNestedFloat2"
<< "((" << a0.a0 << "), " << a1 << ")"
<< "\n";
Struct8BytesNestedFloat2 result;
result.a0.a0 = a0.a0;
result.a1 = a1;
std::cout << "result = "
<< "((" << result.a0.a0 << "), " << result.a1 << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Simple nested struct with mixed members.
DART_EXPORT Struct8BytesNestedMixed
ReturnStruct8BytesNestedMixed(Struct4BytesHomogeneousInt16 a0,
Struct4BytesFloat a1) {
std::cout << "ReturnStruct8BytesNestedMixed"
<< "((" << a0.a0 << ", " << a0.a1 << "), (" << a1.a0 << "))"
<< "\n";
Struct8BytesNestedMixed result;
result.a0.a0 = a0.a0;
result.a0.a1 = a0.a1;
result.a1.a0 = a1.a0;
std::cout << "result = "
<< "((" << result.a0.a0 << ", " << result.a0.a1 << "), ("
<< result.a1.a0 << "))"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Deeper nested struct to test recursive member access.
DART_EXPORT Struct16BytesNestedInt
ReturnStruct16BytesNestedInt(Struct8BytesNestedInt a0,
Struct8BytesNestedInt a1) {
std::cout << "ReturnStruct16BytesNestedInt"
<< "(((" << a0.a0.a0 << ", " << a0.a0.a1 << "), (" << a0.a1.a0
<< ", " << a0.a1.a1 << ")), ((" << a1.a0.a0 << ", " << a1.a0.a1
<< "), (" << a1.a1.a0 << ", " << a1.a1.a1 << ")))"
<< "\n";
Struct16BytesNestedInt result;
result.a0.a0.a0 = a0.a0.a0;
result.a0.a0.a1 = a0.a0.a1;
result.a0.a1.a0 = a0.a1.a0;
result.a0.a1.a1 = a0.a1.a1;
result.a1.a0.a0 = a1.a0.a0;
result.a1.a0.a1 = a1.a0.a1;
result.a1.a1.a0 = a1.a1.a0;
result.a1.a1.a1 = a1.a1.a1;
std::cout << "result = "
<< "(((" << result.a0.a0.a0 << ", " << result.a0.a0.a1 << "), ("
<< result.a0.a1.a0 << ", " << result.a0.a1.a1 << ")), (("
<< result.a1.a0.a0 << ", " << result.a1.a0.a1 << "), ("
<< result.a1.a1.a0 << ", " << result.a1.a1.a1 << ")))"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Even deeper nested struct to test recursive member access.
DART_EXPORT Struct32BytesNestedInt
ReturnStruct32BytesNestedInt(Struct16BytesNestedInt a0,
Struct16BytesNestedInt a1) {
std::cout << "ReturnStruct32BytesNestedInt"
<< "((((" << a0.a0.a0.a0 << ", " << a0.a0.a0.a1 << "), ("
<< a0.a0.a1.a0 << ", " << a0.a0.a1.a1 << ")), ((" << a0.a1.a0.a0
<< ", " << a0.a1.a0.a1 << "), (" << a0.a1.a1.a0 << ", "
<< a0.a1.a1.a1 << "))), (((" << a1.a0.a0.a0 << ", " << a1.a0.a0.a1
<< "), (" << a1.a0.a1.a0 << ", " << a1.a0.a1.a1 << ")), (("
<< a1.a1.a0.a0 << ", " << a1.a1.a0.a1 << "), (" << a1.a1.a1.a0
<< ", " << a1.a1.a1.a1 << "))))"
<< "\n";
Struct32BytesNestedInt result;
result.a0.a0.a0.a0 = a0.a0.a0.a0;
result.a0.a0.a0.a1 = a0.a0.a0.a1;
result.a0.a0.a1.a0 = a0.a0.a1.a0;
result.a0.a0.a1.a1 = a0.a0.a1.a1;
result.a0.a1.a0.a0 = a0.a1.a0.a0;
result.a0.a1.a0.a1 = a0.a1.a0.a1;
result.a0.a1.a1.a0 = a0.a1.a1.a0;
result.a0.a1.a1.a1 = a0.a1.a1.a1;
result.a1.a0.a0.a0 = a1.a0.a0.a0;
result.a1.a0.a0.a1 = a1.a0.a0.a1;
result.a1.a0.a1.a0 = a1.a0.a1.a0;
result.a1.a0.a1.a1 = a1.a0.a1.a1;
result.a1.a1.a0.a0 = a1.a1.a0.a0;
result.a1.a1.a0.a1 = a1.a1.a0.a1;
result.a1.a1.a1.a0 = a1.a1.a1.a0;
result.a1.a1.a1.a1 = a1.a1.a1.a1;
std::cout << "result = "
<< "((((" << result.a0.a0.a0.a0 << ", " << result.a0.a0.a0.a1
<< "), (" << result.a0.a0.a1.a0 << ", " << result.a0.a0.a1.a1
<< ")), ((" << result.a0.a1.a0.a0 << ", " << result.a0.a1.a0.a1
<< "), (" << result.a0.a1.a1.a0 << ", " << result.a0.a1.a1.a1
<< "))), (((" << result.a1.a0.a0.a0 << ", " << result.a1.a0.a0.a1
<< "), (" << result.a1.a0.a1.a0 << ", " << result.a1.a0.a1.a1
<< ")), ((" << result.a1.a1.a0.a0 << ", " << result.a1.a1.a0.a1
<< "), (" << result.a1.a1.a1.a0 << ", " << result.a1.a1.a1.a1
<< "))))"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Test alignment and padding of nested struct with 16 byte int.
DART_EXPORT StructNestedIntStructAlignmentInt16
ReturnStructNestedIntStructAlignmentInt16(StructAlignmentInt16 a0,
StructAlignmentInt16 a1) {
std::cout << "ReturnStructNestedIntStructAlignmentInt16"
<< "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << ", "
<< static_cast<int>(a0.a2) << "), (" << static_cast<int>(a1.a0)
<< ", " << a1.a1 << ", " << static_cast<int>(a1.a2) << "))"
<< "\n";
StructNestedIntStructAlignmentInt16 result;
result.a0.a0 = a0.a0;
result.a0.a1 = a0.a1;
result.a0.a2 = a0.a2;
result.a1.a0 = a1.a0;
result.a1.a1 = a1.a1;
result.a1.a2 = a1.a2;
std::cout << "result = "
<< "((" << static_cast<int>(result.a0.a0) << ", " << result.a0.a1
<< ", " << static_cast<int>(result.a0.a2) << "), ("
<< static_cast<int>(result.a1.a0) << ", " << result.a1.a1 << ", "
<< static_cast<int>(result.a1.a2) << "))"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Test alignment and padding of nested struct with 32 byte int.
DART_EXPORT StructNestedIntStructAlignmentInt32
ReturnStructNestedIntStructAlignmentInt32(StructAlignmentInt32 a0,
StructAlignmentInt32 a1) {
std::cout << "ReturnStructNestedIntStructAlignmentInt32"
<< "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << ", "
<< static_cast<int>(a0.a2) << "), (" << static_cast<int>(a1.a0)
<< ", " << a1.a1 << ", " << static_cast<int>(a1.a2) << "))"
<< "\n";
StructNestedIntStructAlignmentInt32 result;
result.a0.a0 = a0.a0;
result.a0.a1 = a0.a1;
result.a0.a2 = a0.a2;
result.a1.a0 = a1.a0;
result.a1.a1 = a1.a1;
result.a1.a2 = a1.a2;
std::cout << "result = "
<< "((" << static_cast<int>(result.a0.a0) << ", " << result.a0.a1
<< ", " << static_cast<int>(result.a0.a2) << "), ("
<< static_cast<int>(result.a1.a0) << ", " << result.a1.a1 << ", "
<< static_cast<int>(result.a1.a2) << "))"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Test alignment and padding of nested struct with 64 byte int.
DART_EXPORT StructNestedIntStructAlignmentInt64
ReturnStructNestedIntStructAlignmentInt64(StructAlignmentInt64 a0,
StructAlignmentInt64 a1) {
std::cout << "ReturnStructNestedIntStructAlignmentInt64"
<< "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << ", "
<< static_cast<int>(a0.a2) << "), (" << static_cast<int>(a1.a0)
<< ", " << a1.a1 << ", " << static_cast<int>(a1.a2) << "))"
<< "\n";
StructNestedIntStructAlignmentInt64 result;
result.a0.a0 = a0.a0;
result.a0.a1 = a0.a1;
result.a0.a2 = a0.a2;
result.a1.a0 = a1.a0;
result.a1.a1 = a1.a1;
result.a1.a2 = a1.a2;
std::cout << "result = "
<< "((" << static_cast<int>(result.a0.a0) << ", " << result.a0.a1
<< ", " << static_cast<int>(result.a0.a2) << "), ("
<< static_cast<int>(result.a1.a0) << ", " << result.a1.a1 << ", "
<< static_cast<int>(result.a1.a2) << "))"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Return big irregular struct as smoke test.
DART_EXPORT StructNestedIrregularEvenBigger
ReturnStructNestedIrregularEvenBigger(uint64_t a0,
StructNestedIrregularBigger a1,
StructNestedIrregularBigger a2,
double a3) {
std::cout << "ReturnStructNestedIrregularEvenBigger"
<< "(" << a0 << ", ((" << a1.a0.a0 << ", ((" << a1.a0.a1.a0.a0
<< ", " << a1.a0.a1.a0.a1 << "), (" << a1.a0.a1.a1.a0 << ")), "
<< a1.a0.a2 << ", ((" << a1.a0.a3.a0.a0 << "), " << a1.a0.a3.a1
<< "), " << a1.a0.a4 << ", ((" << a1.a0.a5.a0.a0 << "), ("
<< a1.a0.a5.a1.a0 << ")), " << a1.a0.a6 << "), ((" << a1.a1.a0.a0
<< ", " << a1.a1.a0.a1 << "), (" << a1.a1.a1.a0 << ")), " << a1.a2
<< ", " << a1.a3 << "), ((" << a2.a0.a0 << ", ((" << a2.a0.a1.a0.a0
<< ", " << a2.a0.a1.a0.a1 << "), (" << a2.a0.a1.a1.a0 << ")), "
<< a2.a0.a2 << ", ((" << a2.a0.a3.a0.a0 << "), " << a2.a0.a3.a1
<< "), " << a2.a0.a4 << ", ((" << a2.a0.a5.a0.a0 << "), ("
<< a2.a0.a5.a1.a0 << ")), " << a2.a0.a6 << "), ((" << a2.a1.a0.a0
<< ", " << a2.a1.a0.a1 << "), (" << a2.a1.a1.a0 << ")), " << a2.a2
<< ", " << a2.a3 << "), " << a3 << ")"
<< "\n";
StructNestedIrregularEvenBigger result;
result.a0 = a0;
result.a1.a0.a0 = a1.a0.a0;
result.a1.a0.a1.a0.a0 = a1.a0.a1.a0.a0;
result.a1.a0.a1.a0.a1 = a1.a0.a1.a0.a1;
result.a1.a0.a1.a1.a0 = a1.a0.a1.a1.a0;
result.a1.a0.a2 = a1.a0.a2;
result.a1.a0.a3.a0.a0 = a1.a0.a3.a0.a0;
result.a1.a0.a3.a1 = a1.a0.a3.a1;
result.a1.a0.a4 = a1.a0.a4;
result.a1.a0.a5.a0.a0 = a1.a0.a5.a0.a0;
result.a1.a0.a5.a1.a0 = a1.a0.a5.a1.a0;
result.a1.a0.a6 = a1.a0.a6;
result.a1.a1.a0.a0 = a1.a1.a0.a0;
result.a1.a1.a0.a1 = a1.a1.a0.a1;
result.a1.a1.a1.a0 = a1.a1.a1.a0;
result.a1.a2 = a1.a2;
result.a1.a3 = a1.a3;
result.a2.a0.a0 = a2.a0.a0;
result.a2.a0.a1.a0.a0 = a2.a0.a1.a0.a0;
result.a2.a0.a1.a0.a1 = a2.a0.a1.a0.a1;
result.a2.a0.a1.a1.a0 = a2.a0.a1.a1.a0;
result.a2.a0.a2 = a2.a0.a2;
result.a2.a0.a3.a0.a0 = a2.a0.a3.a0.a0;
result.a2.a0.a3.a1 = a2.a0.a3.a1;
result.a2.a0.a4 = a2.a0.a4;
result.a2.a0.a5.a0.a0 = a2.a0.a5.a0.a0;
result.a2.a0.a5.a1.a0 = a2.a0.a5.a1.a0;
result.a2.a0.a6 = a2.a0.a6;
result.a2.a1.a0.a0 = a2.a1.a0.a0;
result.a2.a1.a0.a1 = a2.a1.a0.a1;
result.a2.a1.a1.a0 = a2.a1.a1.a0;
result.a2.a2 = a2.a2;
result.a2.a3 = a2.a3;
result.a3 = a3;
std::cout << "result = "
<< "(" << result.a0 << ", ((" << result.a1.a0.a0 << ", (("
<< result.a1.a0.a1.a0.a0 << ", " << result.a1.a0.a1.a0.a1 << "), ("
<< result.a1.a0.a1.a1.a0 << ")), " << result.a1.a0.a2 << ", (("
<< result.a1.a0.a3.a0.a0 << "), " << result.a1.a0.a3.a1 << "), "
<< result.a1.a0.a4 << ", ((" << result.a1.a0.a5.a0.a0 << "), ("
<< result.a1.a0.a5.a1.a0 << ")), " << result.a1.a0.a6 << "), (("
<< result.a1.a1.a0.a0 << ", " << result.a1.a1.a0.a1 << "), ("
<< result.a1.a1.a1.a0 << ")), " << result.a1.a2 << ", "
<< result.a1.a3 << "), ((" << result.a2.a0.a0 << ", (("
<< result.a2.a0.a1.a0.a0 << ", " << result.a2.a0.a1.a0.a1 << "), ("
<< result.a2.a0.a1.a1.a0 << ")), " << result.a2.a0.a2 << ", (("
<< result.a2.a0.a3.a0.a0 << "), " << result.a2.a0.a3.a1 << "), "
<< result.a2.a0.a4 << ", ((" << result.a2.a0.a5.a0.a0 << "), ("
<< result.a2.a0.a5.a1.a0 << ")), " << result.a2.a0.a6 << "), (("
<< result.a2.a1.a0.a0 << ", " << result.a2.a1.a0.a1 << "), ("
<< result.a2.a1.a1.a0 << ")), " << result.a2.a2 << ", "
<< result.a2.a3 << "), " << result.a3 << ")"
<< "\n";
return result;
}
// Used for testing structs and unions by value.
// Smallest struct with data.
// 10 struct arguments will exhaust available registers.
DART_EXPORT intptr_t TestPassStruct1ByteIntx10(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(Struct1ByteInt a0,
Struct1ByteInt a1,
Struct1ByteInt a2,
Struct1ByteInt a3,
Struct1ByteInt a4,
Struct1ByteInt a5,
Struct1ByteInt a6,
Struct1ByteInt a7,
Struct1ByteInt a8,
Struct1ByteInt a9)) {
Struct1ByteInt a0;
Struct1ByteInt a1;
Struct1ByteInt a2;
Struct1ByteInt a3;
Struct1ByteInt a4;
Struct1ByteInt a5;
Struct1ByteInt a6;
Struct1ByteInt a7;
Struct1ByteInt a8;
Struct1ByteInt a9;
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;
std::cout << "Calling TestPassStruct1ByteIntx10("
<< "((" << static_cast<int>(a0.a0) << "), ("
<< static_cast<int>(a1.a0) << "), (" << static_cast<int>(a2.a0)
<< "), (" << static_cast<int>(a3.a0) << "), ("
<< static_cast<int>(a4.a0) << "), (" << static_cast<int>(a5.a0)
<< "), (" << static_cast<int>(a6.a0) << "), ("
<< static_cast<int>(a7.a0) << "), (" << static_cast<int>(a8.a0)
<< "), (" << static_cast<int>(a9.a0) << "))"
<< ")\n";
int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_EQ(5, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs and unions by value.
// Not a multiple of word size, not a power of two.
// 10 struct arguments will exhaust available registers.
DART_EXPORT intptr_t TestPassStruct3BytesHomogeneousUint8x10(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(Struct3BytesHomogeneousUint8 a0,
Struct3BytesHomogeneousUint8 a1,
Struct3BytesHomogeneousUint8 a2,
Struct3BytesHomogeneousUint8 a3,
Struct3BytesHomogeneousUint8 a4,
Struct3BytesHomogeneousUint8 a5,
Struct3BytesHomogeneousUint8 a6,
Struct3BytesHomogeneousUint8 a7,
Struct3BytesHomogeneousUint8 a8,
Struct3BytesHomogeneousUint8 a9)) {
Struct3BytesHomogeneousUint8 a0;
Struct3BytesHomogeneousUint8 a1;
Struct3BytesHomogeneousUint8 a2;
Struct3BytesHomogeneousUint8 a3;
Struct3BytesHomogeneousUint8 a4;
Struct3BytesHomogeneousUint8 a5;
Struct3BytesHomogeneousUint8 a6;
Struct3BytesHomogeneousUint8 a7;
Struct3BytesHomogeneousUint8 a8;
Struct3BytesHomogeneousUint8 a9;
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;
std::cout << "Calling TestPassStruct3BytesHomogeneousUint8x10("
<< "((" << static_cast<int>(a0.a0) << ", "
<< static_cast<int>(a0.a1) << ", " << static_cast<int>(a0.a2)
<< "), (" << static_cast<int>(a1.a0) << ", "
<< static_cast<int>(a1.a1) << ", " << static_cast<int>(a1.a2)
<< "), (" << static_cast<int>(a2.a0) << ", "
<< static_cast<int>(a2.a1) << ", " << static_cast<int>(a2.a2)
<< "), (" << static_cast<int>(a3.a0) << ", "
<< static_cast<int>(a3.a1) << ", " << static_cast<int>(a3.a2)
<< "), (" << static_cast<int>(a4.a0) << ", "
<< static_cast<int>(a4.a1) << ", " << static_cast<int>(a4.a2)
<< "), (" << static_cast<int>(a5.a0) << ", "
<< static_cast<int>(a5.a1) << ", " << static_cast<int>(a5.a2)
<< "), (" << static_cast<int>(a6.a0) << ", "
<< static_cast<int>(a6.a1) << ", " << static_cast<int>(a6.a2)
<< "), (" << static_cast<int>(a7.a0) << ", "
<< static_cast<int>(a7.a1) << ", " << static_cast<int>(a7.a2)
<< "), (" << static_cast<int>(a8.a0) << ", "
<< static_cast<int>(a8.a1) << ", " << static_cast<int>(a8.a2)
<< "), (" << static_cast<int>(a9.a0) << ", "
<< static_cast<int>(a9.a1) << ", " << static_cast<int>(a9.a2)
<< "))"
<< ")\n";
int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_EQ(465, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs and unions by value.
// 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.
DART_EXPORT intptr_t TestPassStruct3BytesInt2ByteAlignedx10(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(Struct3BytesInt2ByteAligned a0,
Struct3BytesInt2ByteAligned a1,
Struct3BytesInt2ByteAligned a2,
Struct3BytesInt2ByteAligned a3,
Struct3BytesInt2ByteAligned a4,
Struct3BytesInt2ByteAligned a5,
Struct3BytesInt2ByteAligned a6,
Struct3BytesInt2ByteAligned a7,
Struct3BytesInt2ByteAligned a8,
Struct3BytesInt2ByteAligned a9)) {
Struct3BytesInt2ByteAligned a0;
Struct3BytesInt2ByteAligned a1;
Struct3BytesInt2ByteAligned a2;
Struct3BytesInt2ByteAligned a3;
Struct3BytesInt2ByteAligned a4;
Struct3BytesInt2ByteAligned a5;
Struct3BytesInt2ByteAligned a6;
Struct3BytesInt2ByteAligned a7;
Struct3BytesInt2ByteAligned a8;
Struct3BytesInt2ByteAligned a9;
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;
std::cout << "Calling TestPassStruct3BytesInt2ByteAlignedx10("
<< "((" << a0.a0 << ", " << static_cast<int>(a0.a1) << "), ("
<< a1.a0 << ", " << static_cast<int>(a1.a1) << "), (" << a2.a0
<< ", " << static_cast<int>(a2.a1) << "), (" << a3.a0 << ", "
<< static_cast<int>(a3.a1) << "), (" << a4.a0 << ", "
<< static_cast<int>(a4.a1) << "), (" << a5.a0 << ", "
<< static_cast<int>(a5.a1) << "), (" << a6.a0 << ", "
<< static_cast<int>(a6.a1) << "), (" << a7.a0 << ", "
<< static_cast<int>(a7.a1) << "), (" << a8.a0 << ", "
<< static_cast<int>(a8.a1) << "), (" << a9.a0 << ", "
<< static_cast<int>(a9.a1) << "))"
<< ")\n";
int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_EQ(10, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs and unions by value.
// Exactly word size on 32-bit architectures.
// 10 struct arguments will exhaust available registers.
DART_EXPORT intptr_t TestPassStruct4BytesHomogeneousInt16x10(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(Struct4BytesHomogeneousInt16 a0,
Struct4BytesHomogeneousInt16 a1,
Struct4BytesHomogeneousInt16 a2,
Struct4BytesHomogeneousInt16 a3,
Struct4BytesHomogeneousInt16 a4,
Struct4BytesHomogeneousInt16 a5,
Struct4BytesHomogeneousInt16 a6,
Struct4BytesHomogeneousInt16 a7,
Struct4BytesHomogeneousInt16 a8,
Struct4BytesHomogeneousInt16 a9)) {
Struct4BytesHomogeneousInt16 a0;
Struct4BytesHomogeneousInt16 a1;
Struct4BytesHomogeneousInt16 a2;
Struct4BytesHomogeneousInt16 a3;
Struct4BytesHomogeneousInt16 a4;
Struct4BytesHomogeneousInt16 a5;
Struct4BytesHomogeneousInt16 a6;
Struct4BytesHomogeneousInt16 a7;
Struct4BytesHomogeneousInt16 a8;
Struct4BytesHomogeneousInt16 a9;
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;
std::cout << "Calling TestPassStruct4BytesHomogeneousInt16x10("
<< "((" << a0.a0 << ", " << a0.a1 << "), (" << a1.a0 << ", "
<< a1.a1 << "), (" << a2.a0 << ", " << a2.a1 << "), (" << a3.a0
<< ", " << a3.a1 << "), (" << a4.a0 << ", " << a4.a1 << "), ("
<< a5.a0 << ", " << a5.a1 << "), (" << a6.a0 << ", " << a6.a1
<< "), (" << a7.a0 << ", " << a7.a1 << "), (" << a8.a0 << ", "
<< a8.a1 << "), (" << a9.a0 << ", " << a9.a1 << "))"
<< ")\n";
int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_EQ(10, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs and unions by value.
// Sub word size on 64 bit architectures.
// 10 struct arguments will exhaust available registers.
DART_EXPORT intptr_t TestPassStruct7BytesHomogeneousUint8x10(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(Struct7BytesHomogeneousUint8 a0,
Struct7BytesHomogeneousUint8 a1,
Struct7BytesHomogeneousUint8 a2,
Struct7BytesHomogeneousUint8 a3,
Struct7BytesHomogeneousUint8 a4,
Struct7BytesHomogeneousUint8 a5,
Struct7BytesHomogeneousUint8 a6,
Struct7BytesHomogeneousUint8 a7,
Struct7BytesHomogeneousUint8 a8,
Struct7BytesHomogeneousUint8 a9)) {
Struct7BytesHomogeneousUint8 a0;
Struct7BytesHomogeneousUint8 a1;
Struct7BytesHomogeneousUint8 a2;
Struct7BytesHomogeneousUint8 a3;
Struct7BytesHomogeneousUint8 a4;
Struct7BytesHomogeneousUint8 a5;
Struct7BytesHomogeneousUint8 a6;
Struct7BytesHomogeneousUint8 a7;
Struct7BytesHomogeneousUint8 a8;
Struct7BytesHomogeneousUint8 a9;
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;
std::cout
<< "Calling TestPassStruct7BytesHomogeneousUint8x10("
<< "((" << static_cast<int>(a0.a0) << ", " << static_cast<int>(a0.a1)
<< ", " << static_cast<int>(a0.a2) << ", " << static_cast<int>(a0.a3)
<< ", " << static_cast<int>(a0.a4) << ", " << static_cast<int>(a0.a5)
<< ", " << static_cast<int>(a0.a6) << "), (" << static_cast<int>(a1.a0)
<< ", " << static_cast<int>(a1.a1) << ", " << static_cast<int>(a1.a2)
<< ", " << static_cast<int>(a1.a3) << ", " << static_cast<int>(a1.a4)
<< ", " << static_cast<int>(a1.a5) << ", " << static_cast<int>(a1.a6)
<< "), (" << static_cast<int>(a2.a0) << ", " << static_cast<int>(a2.a1)
<< ", " << static_cast<int>(a2.a2) << ", " << static_cast<int>(a2.a3)
<< ", " << static_cast<int>(a2.a4) << ", " << static_cast<int>(a2.a5)
<< ", " << static_cast<int>(a2.a6) << "), (" << static_cast<int>(a3.a0)
<< ", " << static_cast<int>(a3.a1) << ", " << static_cast<int>(a3.a2)
<< ", " << static_cast<int>(a3.a3) << ", " << static_cast<int>(a3.a4)
<< ", " << static_cast<int>(a3.a5) << ", " << static_cast<int>(a3.a6)
<< "), (" << static_cast<int>(a4.a0) << ", " << static_cast<int>(a4.a1)
<< ", " << static_cast<int>(a4.a2) << ", " << static_cast<int>(a4.a3)
<< ", " << static_cast<int>(a4.a4) << ", " << static_cast<int>(a4.a5)
<< ", " << static_cast<int>(a4.a6) << "), (" << static_cast<int>(a5.a0)
<< ", " << static_cast<int>(a5.a1) << ", " << static_cast<int>(a5.a2)
<< ", " << static_cast<int>(a5.a3) << ", " << static_cast<int>(a5.a4)
<< ", " << static_cast<int>(a5.a5) << ", " << static_cast<int>(a5.a6)
<< "), (" << static_cast<int>(a6.a0) << ", " << static_cast<int>(a6.a1)
<< ", " << static_cast<int>(a6.a2) << ", " << static_cast<int>(a6.a3)
<< ", " << static_cast<int>(a6.a4) << ", " << static_cast<int>(a6.a5)
<< ", " << static_cast<int>(a6.a6) << "), (" << static_cast<int>(a7.a0)
<< ", " << static_cast<int>(a7.a1) << ", " << static_cast<int>(a7.a2)
<< ", " << static_cast<int>(a7.a3) << ", " << static_cast<int>(a7.a4)
<< ", " << static_cast<int>(a7.a5) << ", " << static_cast<int>(a7.a6)
<< "), (" << static_cast<int>(a8.a0) << ", " << static_cast<int>(a8.a1)
<< ", " << static_cast<int>(a8.a2) << ", " << static_cast<int>(a8.a3)
<< ", " << static_cast<int>(a8.a4) << ", " << static_cast<int>(a8.a5)
<< ", " << static_cast<int>(a8.a6) << "), (" << static_cast<int>(a9.a0)
<< ", " << static_cast<int>(a9.a1) << ", " << static_cast<int>(a9.a2)
<< ", " << static_cast<int>(a9.a3) << ", " << static_cast<int>(a9.a4)
<< ", " << static_cast<int>(a9.a5) << ", " << static_cast<int>(a9.a6)
<< "))"
<< ")\n";
int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_EQ(2485, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs and unions by value.
// Sub word size on 64 bit architectures.
// With alignment rules taken into account size is 8 bytes.
// 10 struct arguments will exhaust available registers.
DART_EXPORT intptr_t TestPassStruct7BytesInt4ByteAlignedx10(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(Struct7BytesInt4ByteAligned a0,
Struct7BytesInt4ByteAligned a1,
Struct7BytesInt4ByteAligned a2,
Struct7BytesInt4ByteAligned a3,
Struct7BytesInt4ByteAligned a4,
Struct7BytesInt4ByteAligned a5,
Struct7BytesInt4ByteAligned a6,
Struct7BytesInt4ByteAligned a7,
Struct7BytesInt4ByteAligned a8,
Struct7BytesInt4ByteAligned a9)) {
Struct7BytesInt4ByteAligned a0;
Struct7BytesInt4ByteAligned a1;
Struct7BytesInt4ByteAligned a2;
Struct7BytesInt4ByteAligned a3;
Struct7BytesInt4ByteAligned a4;
Struct7BytesInt4ByteAligned a5;
Struct7BytesInt4ByteAligned a6;
Struct7BytesInt4ByteAligned a7;
Struct7BytesInt4ByteAligned a8;
Struct7BytesInt4ByteAligned a9;
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;
std::cout << "Calling TestPassStruct7BytesInt4ByteAlignedx10("
<< "((" << a0.a0 << ", " << a0.a1 << ", " << static_cast<int>(a0.a2)
<< "), (" << a1.a0 << ", " << a1.a1 << ", "
<< static_cast<int>(a1.a2) << "), (" << a2.a0 << ", " << a2.a1
<< ", " << static_cast<int>(a2.a2) << "), (" << a3.a0 << ", "
<< a3.a1 << ", " << static_cast<int>(a3.a2) << "), (" << a4.a0
<< ", " << a4.a1 << ", " << static_cast<int>(a4.a2) << "), ("
<< a5.a0 << ", " << a5.a1 << ", " << static_cast<int>(a5.a2)
<< "), (" << a6.a0 << ", " << a6.a1 << ", "
<< static_cast<int>(a6.a2) << "), (" << a7.a0 << ", " << a7.a1
<< ", " << static_cast<int>(a7.a2) << "), (" << a8.a0 << ", "
<< a8.a1 << ", " << static_cast<int>(a8.a2) << "), (" << a9.a0
<< ", " << a9.a1 << ", " << static_cast<int>(a9.a2) << "))"
<< ")\n";
int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_EQ(15, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs and unions by value.
// Exactly word size struct on 64bit architectures.
// 10 struct arguments will exhaust available registers.
DART_EXPORT intptr_t TestPassStruct8BytesIntx10(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(Struct8BytesInt a0,
Struct8BytesInt a1,
Struct8BytesInt a2,
Struct8BytesInt a3,
Struct8BytesInt a4,
Struct8BytesInt a5,
Struct8BytesInt a6,
Struct8BytesInt a7,
Struct8BytesInt a8,
Struct8BytesInt a9)) {
Struct8BytesInt a0;
Struct8BytesInt a1;
Struct8BytesInt a2;
Struct8BytesInt a3;
Struct8BytesInt a4;
Struct8BytesInt a5;
Struct8BytesInt a6;
Struct8BytesInt a7;
Struct8BytesInt a8;
Struct8BytesInt a9;
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;
std::cout << "Calling TestPassStruct8BytesIntx10("
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << "), ("
<< a1.a0 << ", " << a1.a1 << ", " << a1.a2 << "), (" << a2.a0
<< ", " << a2.a1 << ", " << a2.a2 << "), (" << a3.a0 << ", "
<< a3.a1 << ", " << a3.a2 << "), (" << a4.a0 << ", " << a4.a1
<< ", " << a4.a2 << "), (" << a5.a0 << ", " << a5.a1 << ", "
<< a5.a2 << "), (" << a6.a0 << ", " << a6.a1 << ", " << a6.a2
<< "), (" << a7.a0 << ", " << a7.a1 << ", " << a7.a2 << "), ("
<< a8.a0 << ", " << a8.a1 << ", " << a8.a2 << "), (" << a9.a0
<< ", " << a9.a1 << ", " << a9.a2 << "))"
<< ")\n";
int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_EQ(15, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs and unions by value.
// Arguments passed in FP registers as long as they fit.
// 10 struct arguments will exhaust available registers.
DART_EXPORT intptr_t TestPassStruct8BytesHomogeneousFloatx10(
// NOLINTNEXTLINE(whitespace/parens)
float (*f)(Struct8BytesHomogeneousFloat a0,
Struct8BytesHomogeneousFloat a1,
Struct8BytesHomogeneousFloat a2,
Struct8BytesHomogeneousFloat a3,
Struct8BytesHomogeneousFloat a4,
Struct8BytesHomogeneousFloat a5,
Struct8BytesHomogeneousFloat a6,
Struct8BytesHomogeneousFloat a7,
Struct8BytesHomogeneousFloat a8,
Struct8BytesHomogeneousFloat a9)) {
Struct8BytesHomogeneousFloat a0;
Struct8BytesHomogeneousFloat a1;
Struct8BytesHomogeneousFloat a2;
Struct8BytesHomogeneousFloat a3;
Struct8BytesHomogeneousFloat a4;
Struct8BytesHomogeneousFloat a5;
Struct8BytesHomogeneousFloat a6;
Struct8BytesHomogeneousFloat a7;
Struct8BytesHomogeneousFloat a8;
Struct8BytesHomogeneousFloat a9;
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;
std::cout << "Calling TestPassStruct8BytesHomogeneousFloatx10("
<< "((" << a0.a0 << ", " << a0.a1 << "), (" << a1.a0 << ", "
<< a1.a1 << "), (" << a2.a0 << ", " << a2.a1 << "), (" << a3.a0
<< ", " << a3.a1 << "), (" << a4.a0 << ", " << a4.a1 << "), ("
<< a5.a0 << ", " << a5.a1 << "), (" << a6.a0 << ", " << a6.a1
<< "), (" << a7.a0 << ", " << a7.a1 << "), (" << a8.a0 << ", "
<< a8.a1 << "), (" << a9.a0 << ", " << a9.a1 << "))"
<< ")\n";
float result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_APPROX(10.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs and unions by value.
// On x64, arguments go in int registers because it is not only float.
// 10 struct arguments will exhaust available registers.
DART_EXPORT intptr_t TestPassStruct8BytesMixedx10(
// NOLINTNEXTLINE(whitespace/parens)
float (*f)(Struct8BytesMixed a0,
Struct8BytesMixed a1,
Struct8BytesMixed a2,
Struct8BytesMixed a3,
Struct8BytesMixed a4,
Struct8BytesMixed a5,
Struct8BytesMixed a6,
Struct8BytesMixed a7,
Struct8BytesMixed a8,
Struct8BytesMixed a9)) {
Struct8BytesMixed a0;
Struct8BytesMixed a1;
Struct8BytesMixed a2;
Struct8BytesMixed a3;
Struct8BytesMixed a4;
Struct8BytesMixed a5;
Struct8BytesMixed a6;
Struct8BytesMixed a7;
Struct8BytesMixed a8;
Struct8BytesMixed a9;
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;
std::cout << "Calling TestPassStruct8BytesMixedx10("
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << "), ("
<< a1.a0 << ", " << a1.a1 << ", " << a1.a2 << "), (" << a2.a0
<< ", " << a2.a1 << ", " << a2.a2 << "), (" << a3.a0 << ", "
<< a3.a1 << ", " << a3.a2 << "), (" << a4.a0 << ", " << a4.a1
<< ", " << a4.a2 << "), (" << a5.a0 << ", " << a5.a1 << ", "
<< a5.a2 << "), (" << a6.a0 << ", " << a6.a1 << ", " << a6.a2
<< "), (" << a7.a0 << ", " << a7.a1 << ", " << a7.a2 << "), ("
<< a8.a0 << ", " << a8.a1 << ", " << a8.a2 << "), (" << a9.a0
<< ", " << a9.a1 << ", " << a9.a2 << "))"
<< ")\n";
float result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_APPROX(15.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs and unions by value.
// 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.
DART_EXPORT intptr_t TestPassStruct9BytesHomogeneousUint8x10(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(Struct9BytesHomogeneousUint8 a0,
Struct9BytesHomogeneousUint8 a1,
Struct9BytesHomogeneousUint8 a2,
Struct9BytesHomogeneousUint8 a3,
Struct9BytesHomogeneousUint8 a4,
Struct9BytesHomogeneousUint8 a5,
Struct9BytesHomogeneousUint8 a6,
Struct9BytesHomogeneousUint8 a7,
Struct9BytesHomogeneousUint8 a8,
Struct9BytesHomogeneousUint8 a9)) {
Struct9BytesHomogeneousUint8 a0;
Struct9BytesHomogeneousUint8 a1;
Struct9BytesHomogeneousUint8 a2;
Struct9BytesHomogeneousUint8 a3;
Struct9BytesHomogeneousUint8 a4;
Struct9BytesHomogeneousUint8 a5;
Struct9BytesHomogeneousUint8 a6;
Struct9BytesHomogeneousUint8 a7;
Struct9BytesHomogeneousUint8 a8;
Struct9BytesHomogeneousUint8 a9;
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;
std::cout
<< "Calling TestPassStruct9BytesHomogeneousUint8x10("
<< "((" << static_cast<int>(a0.a0) << ", " << static_cast<int>(a0.a1)
<< ", " << static_cast<int>(a0.a2) << ", " << static_cast<int>(a0.a3)
<< ", " << static_cast<int>(a0.a4) << ", " << static_cast<int>(a0.a5)
<< ", " << static_cast<int>(a0.a6) << ", " << static_cast<int>(a0.a7)
<< ", " << static_cast<int>(a0.a8) << "), (" << static_cast<int>(a1.a0)
<< ", " << static_cast<int>(a1.a1) << ", " << static_cast<int>(a1.a2)
<< ", " << static_cast<int>(a1.a3) << ", " << static_cast<int>(a1.a4)
<< ", " << static_cast<int>(a1.a5) << ", " << static_cast<int>(a1.a6)
<< ", " << static_cast<int>(a1.a7) << ", " << static_cast<int>(a1.a8)
<< "), (" << static_cast<int>(a2.a0) << ", " << static_cast<int>(a2.a1)
<< ", " << static_cast<int>(a2.a2) << ", " << static_cast<int>(a2.a3)
<< ", " << static_cast<int>(a2.a4) << ", " << static_cast<int>(a2.a5)
<< ", " << static_cast<int>(a2.a6) << ", " << static_cast<int>(a2.a7)
<< ", " << static_cast<int>(a2.a8) << "), (" << static_cast<int>(a3.a0)
<< ", " << static_cast<int>(a3.a1) << ", " << static_cast<int>(a3.a2)
<< ", " << static_cast<int>(a3.a3) << ", " << static_cast<int>(a3.a4)
<< ", " << static_cast<int>(a3.a5) << ", " << static_cast<int>(a3.a6)
<< ", " << static_cast<int>(a3.a7) << ", " << static_cast<int>(a3.a8)
<< "), (" << static_cast<int>(a4.a0) << ", " << static_cast<int>(a4.a1)
<< ", " << static_cast<int>(a4.a2) << ", " << static_cast<int>(a4.a3)
<< ", " << static_cast<int>(a4.a4) << ", " << static_cast<int>(a4.a5)
<< ", " << static_cast<int>(a4.a6) << ", " << static_cast<int>(a4.a7)
<< ", " << static_cast<int>(a4.a8) << "), (" << static_cast<int>(a5.a0)
<< ", " << static_cast<int>(a5.a1) << ", " << static_cast<int>(a5.a2)
<< ", " << static_cast<int>(a5.a3) << ", " << static_cast<int>(a5.a4)
<< ", " << static_cast<int>(a5.a5) << ", " << static_cast<int>(a5.a6)
<< ", " << static_cast<int>(a5.a7) << ", " << static_cast<int>(a5.a8)
<< "), (" << static_cast<int>(a6.a0) << ", " << static_cast<int>(a6.a1)
<< ", " << static_cast<int>(a6.a2) << ", " << static_cast<int>(a6.a3)
<< ", " << static_cast<int>(a6.a4) << ", " << static_cast<int>(a6.a5)
<< ", " << static_cast<int>(a6.a6) << ", " << static_cast<int>(a6.a7)
<< ", " << static_cast<int>(a6.a8) << "), (" << static_cast<int>(a7.a0)
<< ", " << static_cast<int>(a7.a1) << ", " << static_cast<int>(a7.a2)
<< ", " << static_cast<int>(a7.a3) << ", " << static_cast<int>(a7.a4)
<< ", " << static_cast<int>(a7.a5) << ", " << static_cast<int>(a7.a6)
<< ", " << static_cast<int>(a7.a7) << ", " << static_cast<int>(a7.a8)
<< "), (" << static_cast<int>(a8.a0) << ", " << static_cast<int>(a8.a1)
<< ", " << static_cast<int>(a8.a2) << ", " << static_cast<int>(a8.a3)
<< ", " << static_cast<int>(a8.a4) << ", " << static_cast<int>(a8.a5)
<< ", " << static_cast<int>(a8.a6) << ", " << static_cast<int>(a8.a7)
<< ", " << static_cast<int>(a8.a8) << "), (" << static_cast<int>(a9.a0)
<< ", " << static_cast<int>(a9.a1) << ", " << static_cast<int>(a9.a2)
<< ", " << static_cast<int>(a9.a3) << ", " << static_cast<int>(a9.a4)
<< ", " << static_cast<int>(a9.a5) << ", " << static_cast<int>(a9.a6)
<< ", " << static_cast<int>(a9.a7) << ", " << static_cast<int>(a9.a8)
<< "))"
<< ")\n";
int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_EQ(4095, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs and unions by value.
// 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.
//
DART_EXPORT intptr_t TestPassStruct9BytesInt4Or8ByteAlignedx10(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(Struct9BytesInt4Or8ByteAligned a0,
Struct9BytesInt4Or8ByteAligned a1,
Struct9BytesInt4Or8ByteAligned a2,
Struct9BytesInt4Or8ByteAligned a3,
Struct9BytesInt4Or8ByteAligned a4,
Struct9BytesInt4Or8ByteAligned a5,
Struct9BytesInt4Or8ByteAligned a6,
Struct9BytesInt4Or8ByteAligned a7,
Struct9BytesInt4Or8ByteAligned a8,
Struct9BytesInt4Or8ByteAligned a9)) {
Struct9BytesInt4Or8ByteAligned a0;
Struct9BytesInt4Or8ByteAligned a1;
Struct9BytesInt4Or8ByteAligned a2;
Struct9BytesInt4Or8ByteAligned a3;
Struct9BytesInt4Or8ByteAligned a4;
Struct9BytesInt4Or8ByteAligned a5;
Struct9BytesInt4Or8ByteAligned a6;
Struct9BytesInt4Or8ByteAligned a7;
Struct9BytesInt4Or8ByteAligned a8;
Struct9BytesInt4Or8ByteAligned a9;
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;
std::cout << "Calling TestPassStruct9BytesInt4Or8ByteAlignedx10("
<< "((" << a0.a0 << ", " << static_cast<int>(a0.a1) << "), ("
<< a1.a0 << ", " << static_cast<int>(a1.a1) << "), (" << a2.a0
<< ", " << static_cast<int>(a2.a1) << "), (" << a3.a0 << ", "
<< static_cast<int>(a3.a1) << "), (" << a4.a0 << ", "
<< static_cast<int>(a4.a1) << "), (" << a5.a0 << ", "
<< static_cast<int>(a5.a1) << "), (" << a6.a0 << ", "
<< static_cast<int>(a6.a1) << "), (" << a7.a0 << ", "
<< static_cast<int>(a7.a1) << "), (" << a8.a0 << ", "
<< static_cast<int>(a8.a1) << "), (" << a9.a0 << ", "
<< static_cast<int>(a9.a1) << "))"
<< ")\n";
int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_EQ(10, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs and unions by value.
// 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.
DART_EXPORT intptr_t TestPassStruct12BytesHomogeneousFloatx6(
// NOLINTNEXTLINE(whitespace/parens)
float (*f)(Struct12BytesHomogeneousFloat a0,
Struct12BytesHomogeneousFloat a1,
Struct12BytesHomogeneousFloat a2,
Struct12BytesHomogeneousFloat a3,
Struct12BytesHomogeneousFloat a4,
Struct12BytesHomogeneousFloat a5)) {
Struct12BytesHomogeneousFloat a0;
Struct12BytesHomogeneousFloat a1;
Struct12BytesHomogeneousFloat a2;
Struct12BytesHomogeneousFloat a3;
Struct12BytesHomogeneousFloat a4;
Struct12BytesHomogeneousFloat a5;
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;
std::cout << "Calling TestPassStruct12BytesHomogeneousFloatx6("
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << "), ("
<< a1.a0 << ", " << a1.a1 << ", " << a1.a2 << "), (" << a2.a0
<< ", " << a2.a1 << ", " << a2.a2 << "), (" << a3.a0 << ", "
<< a3.a1 << ", " << a3.a2 << "), (" << a4.a0 << ", " << a4.a1
<< ", " << a4.a2 << "), (" << a5.a0 << ", " << a5.a1 << ", "
<< a5.a2 << "))"
<< ")\n";
float result = f(a0, a1, a2, a3, a4, a5);
std::cout << "result = " << result << "\n";
CHECK_APPROX(9.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs and unions by value.
// 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.
DART_EXPORT intptr_t TestPassStruct16BytesHomogeneousFloatx5(
// NOLINTNEXTLINE(whitespace/parens)
float (*f)(Struct16BytesHomogeneousFloat a0,
Struct16BytesHomogeneousFloat a1,
Struct16BytesHomogeneousFloat a2,
Struct16BytesHomogeneousFloat a3,
Struct16BytesHomogeneousFloat a4)) {
Struct16BytesHomogeneousFloat a0;
Struct16BytesHomogeneousFloat a1;
Struct16BytesHomogeneousFloat a2;
Struct16BytesHomogeneousFloat a3;
Struct16BytesHomogeneousFloat a4;
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;
std::cout << "Calling TestPassStruct16BytesHomogeneousFloatx5("
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< "), (" << a1.a0 << ", " << a1.a1 << ", " << a1.a2 << ", "
<< a1.a3 << "), (" << a2.a0 << ", " << a2.a1 << ", " << a2.a2
<< ", " << a2.a3 << "), (" << a3.a0 << ", " << a3.a1 << ", "
<< a3.a2 << ", " << a3.a3 << "), (" << a4.a0 << ", " << a4.a1
<< ", " << a4.a2 << ", " << a4.a3 << "))"
<< ")\n";
float result = f(a0, a1, a2, a3, a4);
std::cout << "result = " << result << "\n";
CHECK_APPROX(10.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs and unions by value.
// 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.
DART_EXPORT intptr_t TestPassStruct16BytesMixedx10(
// NOLINTNEXTLINE(whitespace/parens)
double (*f)(Struct16BytesMixed a0,
Struct16BytesMixed a1,
Struct16BytesMixed a2,
Struct16BytesMixed a3,
Struct16BytesMixed a4,
Struct16BytesMixed a5,
Struct16BytesMixed a6,
Struct16BytesMixed a7,
Struct16BytesMixed a8,
Struct16BytesMixed a9)) {
Struct16BytesMixed a0;
Struct16BytesMixed a1;
Struct16BytesMixed a2;
Struct16BytesMixed a3;
Struct16BytesMixed a4;
Struct16BytesMixed a5;
Struct16BytesMixed a6;
Struct16BytesMixed a7;
Struct16BytesMixed a8;
Struct16BytesMixed a9;
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;
std::cout << "Calling TestPassStruct16BytesMixedx10("
<< "((" << a0.a0 << ", " << a0.a1 << "), (" << a1.a0 << ", "
<< a1.a1 << "), (" << a2.a0 << ", " << a2.a1 << "), (" << a3.a0
<< ", " << a3.a1 << "), (" << a4.a0 << ", " << a4.a1 << "), ("
<< a5.a0 << ", " << a5.a1 << "), (" << a6.a0 << ", " << a6.a1
<< "), (" << a7.a0 << ", " << a7.a1 << "), (" << a8.a0 << ", "
<< a8.a1 << "), (" << a9.a0 << ", " << a9.a1 << "))"
<< ")\n";
double result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_APPROX(10.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs and unions by value.
// 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.
DART_EXPORT intptr_t TestPassStruct16BytesMixed2x10(
// NOLINTNEXTLINE(whitespace/parens)
float (*f)(Struct16BytesMixed2 a0,
Struct16BytesMixed2 a1,
Struct16BytesMixed2 a2,
Struct16BytesMixed2 a3,
Struct16BytesMixed2 a4,
Struct16BytesMixed2 a5,
Struct16BytesMixed2 a6,
Struct16BytesMixed2 a7,
Struct16BytesMixed2 a8,
Struct16BytesMixed2 a9)) {
Struct16BytesMixed2 a0;
Struct16BytesMixed2 a1;
Struct16BytesMixed2 a2;
Struct16BytesMixed2 a3;
Struct16BytesMixed2 a4;
Struct16BytesMixed2 a5;
Struct16BytesMixed2 a6;
Struct16BytesMixed2 a7;
Struct16BytesMixed2 a8;
Struct16BytesMixed2 a9;
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;
std::cout << "Calling TestPassStruct16BytesMixed2x10("
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< "), (" << a1.a0 << ", " << a1.a1 << ", " << a1.a2 << ", "
<< a1.a3 << "), (" << a2.a0 << ", " << a2.a1 << ", " << a2.a2
<< ", " << a2.a3 << "), (" << a3.a0 << ", " << a3.a1 << ", "
<< a3.a2 << ", " << a3.a3 << "), (" << a4.a0 << ", " << a4.a1
<< ", " << a4.a2 << ", " << a4.a3 << "), (" << a5.a0 << ", "
<< a5.a1 << ", " << a5.a2 << ", " << a5.a3 << "), (" << a6.a0
<< ", " << a6.a1 << ", " << a6.a2 << ", " << a6.a3 << "), ("
<< a7.a0 << ", " << a7.a1 << ", " << a7.a2 << ", " << a7.a3
<< "), (" << a8.a0 << ", " << a8.a1 << ", " << a8.a2 << ", "
<< a8.a3 << "), (" << a9.a0 << ", " << a9.a1 << ", " << a9.a2
<< ", " << a9.a3 << "))"
<< ")\n";
float result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_APPROX(20.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs and unions by value.
// Arguments are passed as pointer to copy on arm64.
// Tests that the memory allocated for copies are rounded up to word size.
DART_EXPORT intptr_t TestPassStruct17BytesIntx10(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(Struct17BytesInt a0,
Struct17BytesInt a1,
Struct17BytesInt a2,
Struct17BytesInt a3,
Struct17BytesInt a4,
Struct17BytesInt a5,
Struct17BytesInt a6,
Struct17BytesInt a7,
Struct17BytesInt a8,
Struct17BytesInt a9)) {
Struct17BytesInt a0;
Struct17BytesInt a1;
Struct17BytesInt a2;
Struct17BytesInt a3;
Struct17BytesInt a4;
Struct17BytesInt a5;
Struct17BytesInt a6;
Struct17BytesInt a7;
Struct17BytesInt a8;
Struct17BytesInt a9;
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;
std::cout << "Calling TestPassStruct17BytesIntx10("
<< "((" << a0.a0 << ", " << a0.a1 << ", " << static_cast<int>(a0.a2)
<< "), (" << a1.a0 << ", " << a1.a1 << ", "
<< static_cast<int>(a1.a2) << "), (" << a2.a0 << ", " << a2.a1
<< ", " << static_cast<int>(a2.a2) << "), (" << a3.a0 << ", "
<< a3.a1 << ", " << static_cast<int>(a3.a2) << "), (" << a4.a0
<< ", " << a4.a1 << ", " << static_cast<int>(a4.a2) << "), ("
<< a5.a0 << ", " << a5.a1 << ", " << static_cast<int>(a5.a2)
<< "), (" << a6.a0 << ", " << a6.a1 << ", "
<< static_cast<int>(a6.a2) << "), (" << a7.a0 << ", " << a7.a1
<< ", " << static_cast<int>(a7.a2) << "), (" << a8.a0 << ", "
<< a8.a1 << ", " << static_cast<int>(a8.a2) << "), (" << a9.a0
<< ", " << a9.a1 << ", " << static_cast<int>(a9.a2) << "))"
<< ")\n";
int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_EQ(15, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs and unions by value.
// 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.
//
DART_EXPORT intptr_t TestPassStruct19BytesHomogeneousUint8x10(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(Struct19BytesHomogeneousUint8 a0,
Struct19BytesHomogeneousUint8 a1,
Struct19BytesHomogeneousUint8 a2,
Struct19BytesHomogeneousUint8 a3,
Struct19BytesHomogeneousUint8 a4,
Struct19BytesHomogeneousUint8 a5,
Struct19BytesHomogeneousUint8 a6,
Struct19BytesHomogeneousUint8 a7,
Struct19BytesHomogeneousUint8 a8,
Struct19BytesHomogeneousUint8 a9)) {
Struct19BytesHomogeneousUint8 a0;
Struct19BytesHomogeneousUint8 a1;
Struct19BytesHomogeneousUint8 a2;
Struct19BytesHomogeneousUint8 a3;
Struct19BytesHomogeneousUint8 a4;
Struct19BytesHomogeneousUint8 a5;
Struct19BytesHomogeneousUint8 a6;
Struct19BytesHomogeneousUint8 a7;
Struct19BytesHomogeneousUint8 a8;
Struct19BytesHomogeneousUint8 a9;
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;
std::cout
<< "Calling TestPassStruct19BytesHomogeneousUint8x10("
<< "((" << static_cast<int>(a0.a0) << ", " << static_cast<int>(a0.a1)
<< ", " << static_cast<int>(a0.a2) << ", " << static_cast<int>(a0.a3)
<< ", " << static_cast<int>(a0.a4) << ", " << static_cast<int>(a0.a5)
<< ", " << static_cast<int>(a0.a6) << ", " << static_cast<int>(a0.a7)
<< ", " << static_cast<int>(a0.a8) << ", " << static_cast<int>(a0.a9)
<< ", " << static_cast<int>(a0.a10) << ", " << static_cast<int>(a0.a11)
<< ", " << static_cast<int>(a0.a12) << ", " << static_cast<int>(a0.a13)
<< ", " << static_cast<int>(a0.a14) << ", " << static_cast<int>(a0.a15)
<< ", " << static_cast<int>(a0.a16) << ", " << static_cast<int>(a0.a17)
<< ", " << static_cast<int>(a0.a18) << "), (" << static_cast<int>(a1.a0)
<< ", " << static_cast<int>(a1.a1) << ", " << static_cast<int>(a1.a2)
<< ", " << static_cast<int>(a1.a3) << ", " << static_cast<int>(a1.a4)
<< ", " << static_cast<int>(a1.a5) << ", " << static_cast<int>(a1.a6)
<< ", " << static_cast<int>(a1.a7) << ", " << static_cast<int>(a1.a8)
<< ", " << static_cast<int>(a1.a9) << ", " << static_cast<int>(a1.a10)
<< ", " << static_cast<int>(a1.a11) << ", " << static_cast<int>(a1.a12)
<< ", " << static_cast<int>(a1.a13) << ", " << static_cast<int>(a1.a14)
<< ", " << static_cast<int>(a1.a15) << ", " << static_cast<int>(a1.a16)
<< ", " << static_cast<int>(a1.a17) << ", " << static_cast<int>(a1.a18)
<< "), (" << static_cast<int>(a2.a0) << ", " << static_cast<int>(a2.a1)
<< ", " << static_cast<int>(a2.a2) << ", " << static_cast<int>(a2.a3)
<< ", " << static_cast<int>(a2.a4) << ", " << static_cast<int>(a2.a5)
<< ", " << static_cast<int>(a2.a6) << ", " << static_cast<int>(a2.a7)
<< ", " << static_cast<int>(a2.a8) << ", " << static_cast<int>(a2.a9)
<< ", " << static_cast<int>(a2.a10) << ", " << static_cast<int>(a2.a11)
<< ", " << static_cast<int>(a2.a12) << ", " << static_cast<int>(a2.a13)
<< ", " << static_cast<int>(a2.a14) << ", " << static_cast<int>(a2.a15)
<< ", " << static_cast<int>(a2.a16) << ", " << static_cast<int>(a2.a17)
<< ", " << static_cast<int>(a2.a18) << "), (" << static_cast<int>(a3.a0)
<< ", " << static_cast<int>(a3.a1) << ", " << static_cast<int>(a3.a2)
<< ", " << static_cast<int>(a3.a3) << ", " << static_cast<int>(a3.a4)
<< ", " << static_cast<int>(a3.a5) << ", " << static_cast<int>(a3.a6)
<< ", " << static_cast<int>(a3.a7) << ", " << static_cast<int>(a3.a8)
<< ", " << static_cast<int>(a3.a9) << ", " << static_cast<int>(a3.a10)
<< ", " << static_cast<int>(a3.a11) << ", " << static_cast<int>(a3.a12)
<< ", " << static_cast<int>(a3.a13) << ", " << static_cast<int>(a3.a14)
<< ", " << static_cast<int>(a3.a15) << ", " << static_cast<int>(a3.a16)
<< ", " << static_cast<int>(a3.a17) << ", " << static_cast<int>(a3.a18)
<< "), (" << static_cast<int>(a4.a0) << ", " << static_cast<int>(a4.a1)
<< ", " << static_cast<int>(a4.a2) << ", " << static_cast<int>(a4.a3)
<< ", " << static_cast<int>(a4.a4) << ", " << static_cast<int>(a4.a5)
<< ", " << static_cast<int>(a4.a6) << ", " << static_cast<int>(a4.a7)
<< ", " << static_cast<int>(a4.a8) << ", " << static_cast<int>(a4.a9)
<< ", " << static_cast<int>(a4.a10) << ", " << static_cast<int>(a4.a11)
<< ", " << static_cast<int>(a4.a12) << ", " << static_cast<int>(a4.a13)
<< ", " << static_cast<int>(a4.a14) << ", " << static_cast<int>(a4.a15)
<< ", " << static_cast<int>(a4.a16) << ", " << static_cast<int>(a4.a17)
<< ", " << static_cast<int>(a4.a18) << "), (" << static_cast<int>(a5.a0)
<< ", " << static_cast<int>(a5.a1) << ", " << static_cast<int>(a5.a2)
<< ", " << static_cast<int>(a5.a3) << ", " << static_cast<int>(a5.a4)
<< ", " << static_cast<int>(a5.a5) << ", " << static_cast<int>(a5.a6)
<< ", " << static_cast<int>(a5.a7) << ", " << static_cast<int>(a5.a8)
<< ", " << static_cast<int>(a5.a9) << ", " << static_cast<int>(a5.a10)
<< ", " << static_cast<int>(a5.a11) << ", " << static_cast<int>(a5.a12)
<< ", " << static_cast<int>(a5.a13) << ", " << static_cast<int>(a5.a14)
<< ", " << static_cast<int>(a5.a15) << ", " << static_cast<int>(a5.a16)
<< ", " << static_cast<int>(a5.a17) << ", " << static_cast<int>(a5.a18)
<< "), (" << static_cast<int>(a6.a0) << ", " << static_cast<int>(a6.a1)
<< ", " << static_cast<int>(a6.a2) << ", " << static_cast<int>(a6.a3)
<< ", " << static_cast<int>(a6.a4) << ", " << static_cast<int>(a6.a5)
<< ", " << static_cast<int>(a6.a6) << ", " << static_cast<int>(a6.a7)
<< ", " << static_cast<int>(a6.a8) << ", " << static_cast<int>(a6.a9)
<< ", " << static_cast<int>(a6.a10) << ", " << static_cast<int>(a6.a11)
<< ", " << static_cast<int>(a6.a12) << ", " << static_cast<int>(a6.a13)
<< ", " << static_cast<int>(a6.a14) << ", " << static_cast<int>(a6.a15)
<< ", " << static_cast<int>(a6.a16) << ", " << static_cast<int>(a6.a17)
<< ", " << static_cast<int>(a6.a18) << "), (" << static_cast<int>(a7.a0)
<< ", " << static_cast<int>(a7.a1) << ", " << static_cast<int>(a7.a2)
<< ", " << static_cast<int>(a7.a3) << ", " << static_cast<int>(a7.a4)
<< ", " << static_cast<int>(a7.a5) << ", " << static_cast<int>(a7.a6)
<< ", " << static_cast<int>(a7.a7) << ", " << static_cast<int>(a7.a8)
<< ", " << static_cast<int>(a7.a9) << ", " << static_cast<int>(a7.a10)
<< ", " << static_cast<int>(a7.a11) << ", " << static_cast<int>(a7.a12)
<< ", " << static_cast<int>(a7.a13) << ", " << static_cast<int>(a7.a14)
<< ", " << static_cast<int>(a7.a15) << ", " << static_cast<int>(a7.a16)
<< ", " << static_cast<int>(a7.a17) << ", " << static_cast<int>(a7.a18)
<< "), (" << static_cast<int>(a8.a0) << ", " << static_cast<int>(a8.a1)
<< ", " << static_cast<int>(a8.a2) << ", " << static_cast<int>(a8.a3)
<< ", " << static_cast<int>(a8.a4) << ", " << static_cast<int>(a8.a5)
<< ", " << static_cast<int>(a8.a6) << ", " << static_cast<int>(a8.a7)
<< ", " << static_cast<int>(a8.a8) << ", " << static_cast<int>(a8.a9)
<< ", " << static_cast<int>(a8.a10) << ", " << static_cast<int>(a8.a11)
<< ", " << static_cast<int>(a8.a12) << ", " << static_cast<int>(a8.a13)
<< ", " << static_cast<int>(a8.a14) << ", " << static_cast<int>(a8.a15)
<< ", " << static_cast<int>(a8.a16) << ", " << static_cast<int>(a8.a17)
<< ", " << static_cast<int>(a8.a18) << "), (" << static_cast<int>(a9.a0)
<< ", " << static_cast<int>(a9.a1) << ", " << static_cast<int>(a9.a2)
<< ", " << static_cast<int>(a9.a3) << ", " << static_cast<int>(a9.a4)
<< ", " << static_cast<int>(a9.a5) << ", " << static_cast<int>(a9.a6)
<< ", " << static_cast<int>(a9.a7) << ", " << static_cast<int>(a9.a8)
<< ", " << static_cast<int>(a9.a9) << ", " << static_cast<int>(a9.a10)
<< ", " << static_cast<int>(a9.a11) << ", " << static_cast<int>(a9.a12)
<< ", " << static_cast<int>(a9.a13) << ", " << static_cast<int>(a9.a14)
<< ", " << static_cast<int>(a9.a15) << ", " << static_cast<int>(a9.a16)
<< ", " << static_cast<int>(a9.a17) << ", " << static_cast<int>(a9.a18)
<< "))"
<< ")\n";
int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_EQ(18145, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs and unions by value.
// 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.
DART_EXPORT intptr_t TestPassStruct20BytesHomogeneousInt32x10(
// NOLINTNEXTLINE(whitespace/parens)
int32_t (*f)(Struct20BytesHomogeneousInt32 a0,
Struct20BytesHomogeneousInt32 a1,
Struct20BytesHomogeneousInt32 a2,
Struct20BytesHomogeneousInt32 a3,
Struct20BytesHomogeneousInt32 a4,
Struct20BytesHomogeneousInt32 a5,
Struct20BytesHomogeneousInt32 a6,
Struct20BytesHomogeneousInt32 a7,
Struct20BytesHomogeneousInt32 a8,
Struct20BytesHomogeneousInt32 a9)) {
Struct20BytesHomogeneousInt32 a0;
Struct20BytesHomogeneousInt32 a1;
Struct20BytesHomogeneousInt32 a2;
Struct20BytesHomogeneousInt32 a3;
Struct20BytesHomogeneousInt32 a4;
Struct20BytesHomogeneousInt32 a5;
Struct20BytesHomogeneousInt32 a6;
Struct20BytesHomogeneousInt32 a7;
Struct20BytesHomogeneousInt32 a8;
Struct20BytesHomogeneousInt32 a9;
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;
std::cout << "Calling TestPassStruct20BytesHomogeneousInt32x10("
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< ", " << a0.a4 << "), (" << a1.a0 << ", " << a1.a1 << ", "
<< a1.a2 << ", " << a1.a3 << ", " << a1.a4 << "), (" << a2.a0
<< ", " << a2.a1 << ", " << a2.a2 << ", " << a2.a3 << ", " << a2.a4
<< "), (" << a3.a0 << ", " << a3.a1 << ", " << a3.a2 << ", "
<< a3.a3 << ", " << a3.a4 << "), (" << a4.a0 << ", " << a4.a1
<< ", " << a4.a2 << ", " << a4.a3 << ", " << a4.a4 << "), ("
<< a5.a0 << ", " << a5.a1 << ", " << a5.a2 << ", " << a5.a3 << ", "
<< a5.a4 << "), (" << a6.a0 << ", " << a6.a1 << ", " << a6.a2
<< ", " << a6.a3 << ", " << a6.a4 << "), (" << a7.a0 << ", "
<< a7.a1 << ", " << a7.a2 << ", " << a7.a3 << ", " << a7.a4
<< "), (" << a8.a0 << ", " << a8.a1 << ", " << a8.a2 << ", "
<< a8.a3 << ", " << a8.a4 << "), (" << a9.a0 << ", " << a9.a1
<< ", " << a9.a2 << ", " << a9.a3 << ", " << a9.a4 << "))"
<< ")\n";
int32_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_EQ(25, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs and unions by value.
// Argument too big to go into FPU registers in hardfp and arm64.
DART_EXPORT intptr_t TestPassStruct20BytesHomogeneousFloat(
// NOLINTNEXTLINE(whitespace/parens)
float (*f)(Struct20BytesHomogeneousFloat a0)) {
Struct20BytesHomogeneousFloat a0;
a0.a0 = -1.0;
a0.a1 = 2.0;
a0.a2 = -3.0;
a0.a3 = 4.0;
a0.a4 = -5.0;
std::cout << "Calling TestPassStruct20BytesHomogeneousFloat("
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< ", " << a0.a4 << "))"
<< ")\n";
float result = f(a0);
std::cout << "result = " << result << "\n";
CHECK_APPROX(-3.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs and unions by value.
// Arguments in FPU registers on arm64.
// 5 struct arguments will exhaust available registers.
DART_EXPORT intptr_t TestPassStruct32BytesHomogeneousDoublex5(
// NOLINTNEXTLINE(whitespace/parens)
double (*f)(Struct32BytesHomogeneousDouble a0,
Struct32BytesHomogeneousDouble a1,
Struct32BytesHomogeneousDouble a2,
Struct32BytesHomogeneousDouble a3,
Struct32BytesHomogeneousDouble a4)) {
Struct32BytesHomogeneousDouble a0;
Struct32BytesHomogeneousDouble a1;
Struct32BytesHomogeneousDouble a2;
Struct32BytesHomogeneousDouble a3;
Struct32BytesHomogeneousDouble a4;
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;
std::cout << "Calling TestPassStruct32BytesHomogeneousDoublex5("
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< "), (" << a1.a0 << ", " << a1.a1 << ", " << a1.a2 << ", "
<< a1.a3 << "), (" << a2.a0 << ", " << a2.a1 << ", " << a2.a2
<< ", " << a2.a3 << "), (" << a3.a0 << ", " << a3.a1 << ", "
<< a3.a2 << ", " << a3.a3 << "), (" << a4.a0 << ", " << a4.a1
<< ", " << a4.a2 << ", " << a4.a3 << "))"
<< ")\n";
double result = f(a0, a1, a2, a3, a4);
std::cout << "result = " << result << "\n";
CHECK_APPROX(10.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs and unions by value.
// Argument too big to go into FPU registers in arm64.
DART_EXPORT intptr_t TestPassStruct40BytesHomogeneousDouble(
// NOLINTNEXTLINE(whitespace/parens)
double (*f)(Struct40BytesHomogeneousDouble a0)) {
Struct40BytesHomogeneousDouble a0;
a0.a0 = -1.0;
a0.a1 = 2.0;
a0.a2 = -3.0;
a0.a3 = 4.0;
a0.a4 = -5.0;
std::cout << "Calling TestPassStruct40BytesHomogeneousDouble("
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< ", " << a0.a4 << "))"
<< ")\n";
double result = f(a0);
std::cout << "result = " << result << "\n";
CHECK_APPROX(-3.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs and unions by value.
// Test 1kb struct.
DART_EXPORT intptr_t TestPassStruct1024BytesHomogeneousUint64(
// NOLINTNEXTLINE(whitespace/parens)
uint64_t (*f)(Struct1024BytesHomogeneousUint64 a0)) {
Struct1024BytesHomogeneousUint64 a0;
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;
std::cout << "Calling TestPassStruct1024BytesHomogeneousUint64("
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< ", " << a0.a4 << ", " << a0.a5 << ", " << a0.a6 << ", " << a0.a7
<< ", " << a0.a8 << ", " << a0.a9 << ", " << a0.a10 << ", "
<< a0.a11 << ", " << a0.a12 << ", " << a0.a13 << ", " << a0.a14
<< ", " << a0.a15 << ", " << a0.a16 << ", " << a0.a17 << ", "
<< a0.a18 << ", " << a0.a19 << ", " << a0.a20 << ", " << a0.a21
<< ", " << a0.a22 << ", " << a0.a23 << ", " << a0.a24 << ", "
<< a0.a25 << ", " << a0.a26 << ", " << a0.a27 << ", " << a0.a28
<< ", " << a0.a29 << ", " << a0.a30 << ", " << a0.a31 << ", "
<< a0.a32 << ", " << a0.a33 << ", " << a0.a34 << ", " << a0.a35
<< ", " << a0.a36 << ", " << a0.a37 << ", " << a0.a38 << ", "
<< a0.a39 << ", " << a0.a40 << ", " << a0.a41 << ", " << a0.a42
<< ", " << a0.a43 << ", " << a0.a44 << ", " << a0.a45 << ", "
<< a0.a46 << ", " << a0.a47 << ", " << a0.a48 << ", " << a0.a49
<< ", " << a0.a50 << ", " << a0.a51 << ", " << a0.a52 << ", "
<< a0.a53 << ", " << a0.a54 << ", " << a0.a55 << ", " << a0.a56
<< ", " << a0.a57 << ", " << a0.a58 << ", " << a0.a59 << ", "
<< a0.a60 << ", " << a0.a61 << ", " << a0.a62 << ", " << a0.a63
<< ", " << a0.a64 << ", " << a0.a65 << ", " << a0.a66 << ", "
<< a0.a67 << ", " << a0.a68 << ", " << a0.a69 << ", " << a0.a70
<< ", " << a0.a71 << ", " << a0.a72 << ", " << a0.a73 << ", "
<< a0.a74 << ", " << a0.a75 << ", " << a0.a76 << ", " << a0.a77
<< ", " << a0.a78 << ", " << a0.a79 << ", " << a0.a80 << ", "
<< a0.a81 << ", " << a0.a82 << ", " << a0.a83 << ", " << a0.a84
<< ", " << a0.a85 << ", " << a0.a86 << ", " << a0.a87 << ", "
<< a0.a88 << ", " << a0.a89 << ", " << a0.a90 << ", " << a0.a91
<< ", " << a0.a92 << ", " << a0.a93 << ", " << a0.a94 << ", "
<< a0.a95 << ", " << a0.a96 << ", " << a0.a97 << ", " << a0.a98
<< ", " << a0.a99 << ", " << a0.a100 << ", " << a0.a101 << ", "
<< a0.a102 << ", " << a0.a103 << ", " << a0.a104 << ", " << a0.a105
<< ", " << a0.a106 << ", " << a0.a107 << ", " << a0.a108 << ", "
<< a0.a109 << ", " << a0.a110 << ", " << a0.a111 << ", " << a0.a112
<< ", " << a0.a113 << ", " << a0.a114 << ", " << a0.a115 << ", "
<< a0.a116 << ", " << a0.a117 << ", " << a0.a118 << ", " << a0.a119
<< ", " << a0.a120 << ", " << a0.a121 << ", " << a0.a122 << ", "
<< a0.a123 << ", " << a0.a124 << ", " << a0.a125 << ", " << a0.a126
<< ", " << a0.a127 << "))"
<< ")\n";
uint64_t result = f(a0);
std::cout << "result = " << result << "\n";
CHECK_EQ(8256, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs and unions by value.
// Tests the alignment of structs in FPU registers and backfilling.
DART_EXPORT intptr_t TestPassFloatStruct16BytesHomogeneousFloatFloatStruct1(
// NOLINTNEXTLINE(whitespace/parens)
float (*f)(float a0,
Struct16BytesHomogeneousFloat a1,
float a2,
Struct16BytesHomogeneousFloat a3,
float a4,
Struct16BytesHomogeneousFloat a5,
float a6,
Struct16BytesHomogeneousFloat a7,
float a8)) {
float a0;
Struct16BytesHomogeneousFloat a1;
float a2;
Struct16BytesHomogeneousFloat a3;
float a4;
Struct16BytesHomogeneousFloat a5;
float a6;
Struct16BytesHomogeneousFloat a7;
float 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;
std::cout << "Calling TestPassFloatStruct16BytesHomogeneousFloatFloatStruct1("
<< "(" << a0 << ", (" << a1.a0 << ", " << a1.a1 << ", " << a1.a2
<< ", " << a1.a3 << "), " << a2 << ", (" << a3.a0 << ", " << a3.a1
<< ", " << a3.a2 << ", " << a3.a3 << "), " << a4 << ", (" << a5.a0
<< ", " << a5.a1 << ", " << a5.a2 << ", " << a5.a3 << "), " << a6
<< ", (" << a7.a0 << ", " << a7.a1 << ", " << a7.a2 << ", " << a7.a3
<< "), " << a8 << ")"
<< ")\n";
float result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
std::cout << "result = " << result << "\n";
CHECK_APPROX(-11.0, result);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs and unions by value.
// Tests the alignment of structs in FPU registers and backfilling.
DART_EXPORT intptr_t TestPassFloatStruct32BytesHomogeneousDoubleFloatStruct(
// NOLINTNEXTLINE(whitespace/parens)
double (*f)(float a0,
Struct32BytesHomogeneousDouble a1,
float a2,
Struct32BytesHomogeneousDouble a3,
float a4,
Struct32BytesHomogeneousDouble a5,
float a6,
Struct32BytesHomogeneousDouble a7,
float a8)) {
float a0;
Struct32BytesHomogeneousDouble a1;
float a2;
Struct32BytesHomogeneousDouble a3;
float a4;
Struct32BytesHomogeneousDouble a5;
float a6;
Struct32BytesHomogeneousDouble a7;
float 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;
std::cout << "Calling TestPassFloatStruct32BytesHomogeneousDoubleFloatStruct("
<< "(" << a0 << ", (" << a1.a0 << ", " << a1.a1 << ", " << a1.a2
<< ", " << a1.a3 << "), " << a2 << ", (" << a3.a0 << ", " << a3.a1
<< ", " << a3.a2 << ", " << a3.a3 << "), " << a4 << ", (" << a5.a0
<< ", " << a5.a1 << ", " << a5.a2 << ", " << a5.a3 << "), " << a6
<< ", (" << a7.a0 << ", " << a7.a1 << ", " << a7.a2 << ", " << a7.a3
<< "), " << a8 << ")"
<< ")\n";
double result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
std::cout << "result = " << result << "\n";
CHECK_APPROX(-11.0, result);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs and unions by value.
// 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.
DART_EXPORT intptr_t TestPassInt8Struct16BytesMixedInt8Struct16BytesMixedIn(
// NOLINTNEXTLINE(whitespace/parens)
double (*f)(int8_t a0,
Struct16BytesMixed a1,
int8_t a2,
Struct16BytesMixed a3,
int8_t a4,
Struct16BytesMixed a5,
int8_t a6,
Struct16BytesMixed a7,
int8_t a8)) {
int8_t a0;
Struct16BytesMixed a1;
int8_t a2;
Struct16BytesMixed a3;
int8_t a4;
Struct16BytesMixed a5;
int8_t a6;
Struct16BytesMixed a7;
int8_t 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;
std::cout << "Calling TestPassInt8Struct16BytesMixedInt8Struct16BytesMixedIn("
<< "(" << static_cast<int>(a0) << ", (" << a1.a0 << ", " << a1.a1
<< "), " << static_cast<int>(a2) << ", (" << a3.a0 << ", " << a3.a1
<< "), " << static_cast<int>(a4) << ", (" << a5.a0 << ", " << a5.a1
<< "), " << static_cast<int>(a6) << ", (" << a7.a0 << ", " << a7.a1
<< "), " << static_cast<int>(a8) << ")"
<< ")\n";
double result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
std::cout << "result = " << result << "\n";
CHECK_APPROX(-7.0, result);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs and unions by value.
// 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.
DART_EXPORT intptr_t TestPassDoublex6Struct16BytesMixedx4Int32(
// NOLINTNEXTLINE(whitespace/parens)
double (*f)(double a0,
double a1,
double a2,
double a3,
double a4,
double a5,
Struct16BytesMixed a6,
Struct16BytesMixed a7,
Struct16BytesMixed a8,
Struct16BytesMixed a9,
int32_t a10)) {
double a0;
double a1;
double a2;
double a3;
double a4;
double a5;
Struct16BytesMixed a6;
Struct16BytesMixed a7;
Struct16BytesMixed a8;
Struct16BytesMixed a9;
int32_t 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;
std::cout << "Calling TestPassDoublex6Struct16BytesMixedx4Int32("
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
<< ", " << a5 << ", (" << a6.a0 << ", " << a6.a1 << "), (" << a7.a0
<< ", " << a7.a1 << "), (" << a8.a0 << ", " << a8.a1 << "), ("
<< a9.a0 << ", " << a9.a1 << "), " << a10 << ")"
<< ")\n";
double result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
std::cout << "result = " << result << "\n";
CHECK_APPROX(-8.0, result);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs and unions by value.
// 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.
DART_EXPORT intptr_t TestPassInt32x4Struct16BytesMixedx4Double(
// NOLINTNEXTLINE(whitespace/parens)
double (*f)(int32_t a0,
int32_t a1,
int32_t a2,
int32_t a3,
Struct16BytesMixed a4,
Struct16BytesMixed a5,
Struct16BytesMixed a6,
Struct16BytesMixed a7,
double a8)) {
int32_t a0;
int32_t a1;
int32_t a2;
int32_t a3;
Struct16BytesMixed a4;
Struct16BytesMixed a5;
Struct16BytesMixed a6;
Struct16BytesMixed a7;
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;
std::cout << "Calling TestPassInt32x4Struct16BytesMixedx4Double("
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", ("
<< a4.a0 << ", " << a4.a1 << "), (" << a5.a0 << ", " << a5.a1
<< "), (" << a6.a0 << ", " << a6.a1 << "), (" << a7.a0 << ", "
<< a7.a1 << "), " << a8 << ")"
<< ")\n";
double result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
std::cout << "result = " << result << "\n";
CHECK_APPROX(-7.0, result);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs and unions by value.
// On various architectures, first struct is allocated on stack.
// Check that the other two arguments are allocated on registers.
DART_EXPORT intptr_t TestPassStruct40BytesHomogeneousDoubleStruct4BytesHomo(
// NOLINTNEXTLINE(whitespace/parens)
double (*f)(Struct40BytesHomogeneousDouble a0,
Struct4BytesHomogeneousInt16 a1,
Struct8BytesHomogeneousFloat a2)) {
Struct40BytesHomogeneousDouble a0;
Struct4BytesHomogeneousInt16 a1;
Struct8BytesHomogeneousFloat a2;
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;
std::cout << "Calling TestPassStruct40BytesHomogeneousDoubleStruct4BytesHomo("
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< ", " << a0.a4 << "), (" << a1.a0 << ", " << a1.a1 << "), ("
<< a2.a0 << ", " << a2.a1 << "))"
<< ")\n";
double result = f(a0, a1, a2);
std::cout << "result = " << result << "\n";
CHECK_APPROX(-5.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs and unions by value.
// Test alignment and padding of 16 byte int within struct.
DART_EXPORT intptr_t TestPassInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int(
// NOLINTNEXTLINE(whitespace/parens)
double (*f)(int32_t a0,
int32_t a1,
int32_t a2,
int32_t a3,
int32_t a4,
int32_t a5,
int32_t a6,
int32_t a7,
double a8,
double a9,
double a10,
double a11,
double a12,
double a13,
double a14,
double a15,
int64_t a16,
int8_t a17,
Struct1ByteInt a18,
int64_t a19,
int8_t a20,
Struct4BytesHomogeneousInt16 a21,
int64_t a22,
int8_t a23,
Struct8BytesInt a24,
int64_t a25,
int8_t a26,
Struct8BytesHomogeneousFloat a27,
int64_t a28,
int8_t a29,
Struct8BytesMixed a30,
int64_t a31,
int8_t a32,
StructAlignmentInt16 a33,
int64_t a34,
int8_t a35,
StructAlignmentInt32 a36,
int64_t a37,
int8_t a38,
StructAlignmentInt64 a39)) {
int32_t a0;
int32_t a1;
int32_t a2;
int32_t a3;
int32_t a4;
int32_t a5;
int32_t a6;
int32_t a7;
double a8;
double a9;
double a10;
double a11;
double a12;
double a13;
double a14;
double a15;
int64_t a16;
int8_t a17;
Struct1ByteInt a18;
int64_t a19;
int8_t a20;
Struct4BytesHomogeneousInt16 a21;
int64_t a22;
int8_t a23;
Struct8BytesInt a24;
int64_t a25;
int8_t a26;
Struct8BytesHomogeneousFloat a27;
int64_t a28;
int8_t a29;
Struct8BytesMixed a30;
int64_t a31;
int8_t a32;
StructAlignmentInt16 a33;
int64_t a34;
int8_t a35;
StructAlignmentInt32 a36;
int64_t a37;
int8_t a38;
StructAlignmentInt64 a39;
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;
std::cout << "Calling TestPassInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int("
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
<< ", " << a5 << ", " << a6 << ", " << a7 << ", " << a8 << ", "
<< a9 << ", " << a10 << ", " << a11 << ", " << a12 << ", " << a13
<< ", " << a14 << ", " << a15 << ", " << a16 << ", "
<< static_cast<int>(a17) << ", (" << static_cast<int>(a18.a0)
<< "), " << a19 << ", " << static_cast<int>(a20) << ", (" << a21.a0
<< ", " << a21.a1 << "), " << a22 << ", " << static_cast<int>(a23)
<< ", (" << a24.a0 << ", " << a24.a1 << ", " << a24.a2 << "), "
<< a25 << ", " << static_cast<int>(a26) << ", (" << a27.a0 << ", "
<< a27.a1 << "), " << a28 << ", " << static_cast<int>(a29) << ", ("
<< a30.a0 << ", " << a30.a1 << ", " << a30.a2 << "), " << a31
<< ", " << static_cast<int>(a32) << ", ("
<< static_cast<int>(a33.a0) << ", " << a33.a1 << ", "
<< static_cast<int>(a33.a2) << "), " << a34 << ", "
<< static_cast<int>(a35) << ", (" << static_cast<int>(a36.a0)
<< ", " << a36.a1 << ", " << static_cast<int>(a36.a2) << "), "
<< a37 << ", " << static_cast<int>(a38) << ", ("
<< static_cast<int>(a39.a0) << ", " << a39.a1 << ", "
<< static_cast<int>(a39.a2) << "))"
<< ")\n";
double result =
f(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);
std::cout << "result = " << result << "\n";
CHECK_APPROX(26.0, result);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(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);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(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);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs and unions by value.
// Test alignment and padding of 16 byte int within struct.
DART_EXPORT intptr_t TestPassStructAlignmentInt16(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(StructAlignmentInt16 a0)) {
StructAlignmentInt16 a0;
a0.a0 = -1;
a0.a1 = 2;
a0.a2 = -3;
std::cout << "Calling TestPassStructAlignmentInt16("
<< "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << ", "
<< static_cast<int>(a0.a2) << "))"
<< ")\n";
int64_t result = f(a0);
std::cout << "result = " << result << "\n";
CHECK_EQ(-2, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs and unions by value.
// Test alignment and padding of 32 byte int within struct.
DART_EXPORT intptr_t TestPassStructAlignmentInt32(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(StructAlignmentInt32 a0)) {
StructAlignmentInt32 a0;
a0.a0 = -1;
a0.a1 = 2;
a0.a2 = -3;
std::cout << "Calling TestPassStructAlignmentInt32("
<< "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << ", "
<< static_cast<int>(a0.a2) << "))"
<< ")\n";
int64_t result = f(a0);
std::cout << "result = " << result << "\n";
CHECK_EQ(-2, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs and unions by value.
// Test alignment and padding of 64 byte int within struct.
DART_EXPORT intptr_t TestPassStructAlignmentInt64(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(StructAlignmentInt64 a0)) {
StructAlignmentInt64 a0;
a0.a0 = -1;
a0.a1 = 2;
a0.a2 = -3;
std::cout << "Calling TestPassStructAlignmentInt64("
<< "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << ", "
<< static_cast<int>(a0.a2) << "))"
<< ")\n";
int64_t result = f(a0);
std::cout << "result = " << result << "\n";
CHECK_EQ(-2, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs and unions by value.
// Simple nested struct. No alignment gaps on any architectures.
// 10 arguments exhaust registers on all platforms.
DART_EXPORT intptr_t TestPassStruct8BytesNestedIntx10(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(Struct8BytesNestedInt a0,
Struct8BytesNestedInt a1,
Struct8BytesNestedInt a2,
Struct8BytesNestedInt a3,
Struct8BytesNestedInt a4,
Struct8BytesNestedInt a5,
Struct8BytesNestedInt a6,
Struct8BytesNestedInt a7,
Struct8BytesNestedInt a8,
Struct8BytesNestedInt a9)) {
Struct8BytesNestedInt a0;
Struct8BytesNestedInt a1;
Struct8BytesNestedInt a2;
Struct8BytesNestedInt a3;
Struct8BytesNestedInt a4;
Struct8BytesNestedInt a5;
Struct8BytesNestedInt a6;
Struct8BytesNestedInt a7;
Struct8BytesNestedInt a8;
Struct8BytesNestedInt a9;
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;
std::cout << "Calling TestPassStruct8BytesNestedIntx10("
<< "(((" << a0.a0.a0 << ", " << a0.a0.a1 << "), (" << a0.a1.a0
<< ", " << a0.a1.a1 << ")), ((" << a1.a0.a0 << ", " << a1.a0.a1
<< "), (" << a1.a1.a0 << ", " << a1.a1.a1 << ")), ((" << a2.a0.a0
<< ", " << a2.a0.a1 << "), (" << a2.a1.a0 << ", " << a2.a1.a1
<< ")), ((" << a3.a0.a0 << ", " << a3.a0.a1 << "), (" << a3.a1.a0
<< ", " << a3.a1.a1 << ")), ((" << a4.a0.a0 << ", " << a4.a0.a1
<< "), (" << a4.a1.a0 << ", " << a4.a1.a1 << ")), ((" << a5.a0.a0
<< ", " << a5.a0.a1 << "), (" << a5.a1.a0 << ", " << a5.a1.a1
<< ")), ((" << a6.a0.a0 << ", " << a6.a0.a1 << "), (" << a6.a1.a0
<< ", " << a6.a1.a1 << ")), ((" << a7.a0.a0 << ", " << a7.a0.a1
<< "), (" << a7.a1.a0 << ", " << a7.a1.a1 << ")), ((" << a8.a0.a0
<< ", " << a8.a0.a1 << "), (" << a8.a1.a0 << ", " << a8.a1.a1
<< ")), ((" << a9.a0.a0 << ", " << a9.a0.a1 << "), (" << a9.a1.a0
<< ", " << a9.a1.a1 << ")))"
<< ")\n";
int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_EQ(20, result);
// Pass argument that will make the Dart callback throw.
a0.a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs and unions by value.
// Simple nested struct. No alignment gaps on any architectures.
// 10 arguments exhaust fpu registers on all platforms.
DART_EXPORT intptr_t TestPassStruct8BytesNestedFloatx10(
// NOLINTNEXTLINE(whitespace/parens)
float (*f)(Struct8BytesNestedFloat a0,
Struct8BytesNestedFloat a1,
Struct8BytesNestedFloat a2,
Struct8BytesNestedFloat a3,
Struct8BytesNestedFloat a4,
Struct8BytesNestedFloat a5,
Struct8BytesNestedFloat a6,
Struct8BytesNestedFloat a7,
Struct8BytesNestedFloat a8,
Struct8BytesNestedFloat a9)) {
Struct8BytesNestedFloat a0;
Struct8BytesNestedFloat a1;
Struct8BytesNestedFloat a2;
Struct8BytesNestedFloat a3;
Struct8BytesNestedFloat a4;
Struct8BytesNestedFloat a5;
Struct8BytesNestedFloat a6;
Struct8BytesNestedFloat a7;
Struct8BytesNestedFloat a8;
Struct8BytesNestedFloat a9;
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;
std::cout << "Calling TestPassStruct8BytesNestedFloatx10("
<< "(((" << a0.a0.a0 << "), (" << a0.a1.a0 << ")), ((" << a1.a0.a0
<< "), (" << a1.a1.a0 << ")), ((" << a2.a0.a0 << "), (" << a2.a1.a0
<< ")), ((" << a3.a0.a0 << "), (" << a3.a1.a0 << ")), (("
<< a4.a0.a0 << "), (" << a4.a1.a0 << ")), ((" << a5.a0.a0 << "), ("
<< a5.a1.a0 << ")), ((" << a6.a0.a0 << "), (" << a6.a1.a0
<< ")), ((" << a7.a0.a0 << "), (" << a7.a1.a0 << ")), (("
<< a8.a0.a0 << "), (" << a8.a1.a0 << ")), ((" << a9.a0.a0 << "), ("
<< a9.a1.a0 << ")))"
<< ")\n";
float result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_APPROX(10.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs and unions by value.
// 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.
DART_EXPORT intptr_t TestPassStruct8BytesNestedFloat2x10(
// NOLINTNEXTLINE(whitespace/parens)
float (*f)(Struct8BytesNestedFloat2 a0,
Struct8BytesNestedFloat2 a1,
Struct8BytesNestedFloat2 a2,
Struct8BytesNestedFloat2 a3,
Struct8BytesNestedFloat2 a4,
Struct8BytesNestedFloat2 a5,
Struct8BytesNestedFloat2 a6,
Struct8BytesNestedFloat2 a7,
Struct8BytesNestedFloat2 a8,
Struct8BytesNestedFloat2 a9)) {
Struct8BytesNestedFloat2 a0;
Struct8BytesNestedFloat2 a1;
Struct8BytesNestedFloat2 a2;
Struct8BytesNestedFloat2 a3;
Struct8BytesNestedFloat2 a4;
Struct8BytesNestedFloat2 a5;
Struct8BytesNestedFloat2 a6;
Struct8BytesNestedFloat2 a7;
Struct8BytesNestedFloat2 a8;
Struct8BytesNestedFloat2 a9;
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;
std::cout << "Calling TestPassStruct8BytesNestedFloat2x10("
<< "(((" << a0.a0.a0 << "), " << a0.a1 << "), ((" << a1.a0.a0
<< "), " << a1.a1 << "), ((" << a2.a0.a0 << "), " << a2.a1
<< "), ((" << a3.a0.a0 << "), " << a3.a1 << "), ((" << a4.a0.a0
<< "), " << a4.a1 << "), ((" << a5.a0.a0 << "), " << a5.a1
<< "), ((" << a6.a0.a0 << "), " << a6.a1 << "), ((" << a7.a0.a0
<< "), " << a7.a1 << "), ((" << a8.a0.a0 << "), " << a8.a1
<< "), ((" << a9.a0.a0 << "), " << a9.a1 << "))"
<< ")\n";
float result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_APPROX(10.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs and unions by value.
// Simple nested struct. No alignment gaps on any architectures.
// 10 arguments exhaust all registers on all platforms.
DART_EXPORT intptr_t TestPassStruct8BytesNestedMixedx10(
// NOLINTNEXTLINE(whitespace/parens)
double (*f)(Struct8BytesNestedMixed a0,
Struct8BytesNestedMixed a1,
Struct8BytesNestedMixed a2,
Struct8BytesNestedMixed a3,
Struct8BytesNestedMixed a4,
Struct8BytesNestedMixed a5,
Struct8BytesNestedMixed a6,
Struct8BytesNestedMixed a7,
Struct8BytesNestedMixed a8,
Struct8BytesNestedMixed a9)) {
Struct8BytesNestedMixed a0;
Struct8BytesNestedMixed a1;
Struct8BytesNestedMixed a2;
Struct8BytesNestedMixed a3;
Struct8BytesNestedMixed a4;
Struct8BytesNestedMixed a5;
Struct8BytesNestedMixed a6;
Struct8BytesNestedMixed a7;
Struct8BytesNestedMixed a8;
Struct8BytesNestedMixed a9;
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;
std::cout << "Calling TestPassStruct8BytesNestedMixedx10("
<< "(((" << a0.a0.a0 << ", " << a0.a0.a1 << "), (" << a0.a1.a0
<< ")), ((" << a1.a0.a0 << ", " << a1.a0.a1 << "), (" << a1.a1.a0
<< ")), ((" << a2.a0.a0 << ", " << a2.a0.a1 << "), (" << a2.a1.a0
<< ")), ((" << a3.a0.a0 << ", " << a3.a0.a1 << "), (" << a3.a1.a0
<< ")), ((" << a4.a0.a0 << ", " << a4.a0.a1 << "), (" << a4.a1.a0
<< ")), ((" << a5.a0.a0 << ", " << a5.a0.a1 << "), (" << a5.a1.a0
<< ")), ((" << a6.a0.a0 << ", " << a6.a0.a1 << "), (" << a6.a1.a0
<< ")), ((" << a7.a0.a0 << ", " << a7.a0.a1 << "), (" << a7.a1.a0
<< ")), ((" << a8.a0.a0 << ", " << a8.a0.a1 << "), (" << a8.a1.a0
<< ")), ((" << a9.a0.a0 << ", " << a9.a0.a1 << "), (" << a9.a1.a0
<< ")))"
<< ")\n";
double result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_APPROX(15.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs and unions by value.
// Deeper nested struct to test recursive member access.
DART_EXPORT intptr_t TestPassStruct16BytesNestedIntx2(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(Struct16BytesNestedInt a0, Struct16BytesNestedInt a1)) {
Struct16BytesNestedInt a0;
Struct16BytesNestedInt a1;
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;
std::cout << "Calling TestPassStruct16BytesNestedIntx2("
<< "((((" << a0.a0.a0.a0 << ", " << a0.a0.a0.a1 << "), ("
<< a0.a0.a1.a0 << ", " << a0.a0.a1.a1 << ")), ((" << a0.a1.a0.a0
<< ", " << a0.a1.a0.a1 << "), (" << a0.a1.a1.a0 << ", "
<< a0.a1.a1.a1 << "))), (((" << a1.a0.a0.a0 << ", " << a1.a0.a0.a1
<< "), (" << a1.a0.a1.a0 << ", " << a1.a0.a1.a1 << ")), (("
<< a1.a1.a0.a0 << ", " << a1.a1.a0.a1 << "), (" << a1.a1.a1.a0
<< ", " << a1.a1.a1.a1 << "))))"
<< ")\n";
int64_t result = f(a0, a1);
std::cout << "result = " << result << "\n";
CHECK_EQ(8, result);
// Pass argument that will make the Dart callback throw.
a0.a0.a0.a0 = 42;
result = f(a0, a1);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0.a0.a0 = 84;
result = f(a0, a1);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs and unions by value.
// Even deeper nested struct to test recursive member access.
DART_EXPORT intptr_t TestPassStruct32BytesNestedIntx2(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(Struct32BytesNestedInt a0, Struct32BytesNestedInt a1)) {
Struct32BytesNestedInt a0;
Struct32BytesNestedInt a1;
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;
std::cout << "Calling TestPassStruct32BytesNestedIntx2("
<< "(((((" << a0.a0.a0.a0.a0 << ", " << a0.a0.a0.a0.a1 << "), ("
<< a0.a0.a0.a1.a0 << ", " << a0.a0.a0.a1.a1 << ")), (("
<< a0.a0.a1.a0.a0 << ", " << a0.a0.a1.a0.a1 << "), ("
<< a0.a0.a1.a1.a0 << ", " << a0.a0.a1.a1.a1 << "))), ((("
<< a0.a1.a0.a0.a0 << ", " << a0.a1.a0.a0.a1 << "), ("
<< a0.a1.a0.a1.a0 << ", " << a0.a1.a0.a1.a1 << ")), (("
<< a0.a1.a1.a0.a0 << ", " << a0.a1.a1.a0.a1 << "), ("
<< a0.a1.a1.a1.a0 << ", " << a0.a1.a1.a1.a1 << ")))), (((("
<< a1.a0.a0.a0.a0 << ", " << a1.a0.a0.a0.a1 << "), ("
<< a1.a0.a0.a1.a0 << ", " << a1.a0.a0.a1.a1 << ")), (("
<< a1.a0.a1.a0.a0 << ", " << a1.a0.a1.a0.a1 << "), ("
<< a1.a0.a1.a1.a0 << ", " << a1.a0.a1.a1.a1 << "))), ((("
<< a1.a1.a0.a0.a0 << ", " << a1.a1.a0.a0.a1 << "), ("
<< a1.a1.a0.a1.a0 << ", " << a1.a1.a0.a1.a1 << ")), (("
<< a1.a1.a1.a0.a0 << ", " << a1.a1.a1.a0.a1 << "), ("
<< a1.a1.a1.a1.a0 << ", " << a1.a1.a1.a1.a1 << ")))))"
<< ")\n";
int64_t result = f(a0, a1);
std::cout << "result = " << result << "\n";
CHECK_EQ(16, result);
// Pass argument that will make the Dart callback throw.
a0.a0.a0.a0.a0 = 42;
result = f(a0, a1);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0.a0.a0.a0 = 84;
result = f(a0, a1);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs and unions by value.
// Test alignment and padding of nested struct with 16 byte int.
DART_EXPORT intptr_t TestPassStructNestedIntStructAlignmentInt16(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(StructNestedIntStructAlignmentInt16 a0)) {
StructNestedIntStructAlignmentInt16 a0;
a0.a0.a0 = -1;
a0.a0.a1 = 2;
a0.a0.a2 = -3;
a0.a1.a0 = 4;
a0.a1.a1 = -5;
a0.a1.a2 = 6;
std::cout << "Calling TestPassStructNestedIntStructAlignmentInt16("
<< "(((" << static_cast<int>(a0.a0.a0) << ", " << a0.a0.a1 << ", "
<< static_cast<int>(a0.a0.a2) << "), ("
<< static_cast<int>(a0.a1.a0) << ", " << a0.a1.a1 << ", "
<< static_cast<int>(a0.a1.a2) << ")))"
<< ")\n";
int64_t result = f(a0);
std::cout << "result = " << result << "\n";
CHECK_EQ(3, result);
// Pass argument that will make the Dart callback throw.
a0.a0.a0 = 42;
result = f(a0);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0.a0 = 84;
result = f(a0);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs and unions by value.
// Test alignment and padding of nested struct with 32 byte int.
DART_EXPORT intptr_t TestPassStructNestedIntStructAlignmentInt32(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(StructNestedIntStructAlignmentInt32 a0)) {
StructNestedIntStructAlignmentInt32 a0;
a0.a0.a0 = -1;
a0.a0.a1 = 2;
a0.a0.a2 = -3;
a0.a1.a0 = 4;
a0.a1.a1 = -5;
a0.a1.a2 = 6;
std::cout << "Calling TestPassStructNestedIntStructAlignmentInt32("
<< "(((" << static_cast<int>(a0.a0.a0) << ", " << a0.a0.a1 << ", "
<< static_cast<int>(a0.a0.a2) << "), ("
<< static_cast<int>(a0.a1.a0) << ", " << a0.a1.a1 << ", "
<< static_cast<int>(a0.a1.a2) << ")))"
<< ")\n";
int64_t result = f(a0);
std::cout << "result = " << result << "\n";
CHECK_EQ(3, result);
// Pass argument that will make the Dart callback throw.
a0.a0.a0 = 42;
result = f(a0);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0.a0 = 84;
result = f(a0);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs and unions by value.
// Test alignment and padding of nested struct with 64 byte int.
DART_EXPORT intptr_t TestPassStructNestedIntStructAlignmentInt64(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(StructNestedIntStructAlignmentInt64 a0)) {
StructNestedIntStructAlignmentInt64 a0;
a0.a0.a0 = -1;
a0.a0.a1 = 2;
a0.a0.a2 = -3;
a0.a1.a0 = 4;
a0.a1.a1 = -5;
a0.a1.a2 = 6;
std::cout << "Calling TestPassStructNestedIntStructAlignmentInt64("
<< "(((" << static_cast<int>(a0.a0.a0) << ", " << a0.a0.a1 << ", "
<< static_cast<int>(a0.a0.a2) << "), ("
<< static_cast<int>(a0.a1.a0) << ", " << a0.a1.a1 << ", "
<< static_cast<int>(a0.a1.a2) << ")))"
<< ")\n";
int64_t result = f(a0);
std::cout << "result = " << result << "\n";
CHECK_EQ(3, result);
// Pass argument that will make the Dart callback throw.
a0.a0.a0 = 42;
result = f(a0);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0.a0 = 84;
result = f(a0);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs and unions by value.
// Return big irregular struct as smoke test.
DART_EXPORT intptr_t TestPassStructNestedIrregularEvenBiggerx4(
// NOLINTNEXTLINE(whitespace/parens)
double (*f)(StructNestedIrregularEvenBigger a0,
StructNestedIrregularEvenBigger a1,
StructNestedIrregularEvenBigger a2,
StructNestedIrregularEvenBigger a3)) {
StructNestedIrregularEvenBigger a0;
StructNestedIrregularEvenBigger a1;
StructNestedIrregularEvenBigger a2;
StructNestedIrregularEvenBigger a3;
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;
std::cout
<< "Calling TestPassStructNestedIrregularEvenBiggerx4("
<< "((" << a0.a0 << ", ((" << a0.a1.a0.a0 << ", ((" << a0.a1.a0.a1.a0.a0
<< ", " << a0.a1.a0.a1.a0.a1 << "), (" << a0.a1.a0.a1.a1.a0 << ")), "
<< a0.a1.a0.a2 << ", ((" << a0.a1.a0.a3.a0.a0 << "), " << a0.a1.a0.a3.a1
<< "), " << a0.a1.a0.a4 << ", ((" << a0.a1.a0.a5.a0.a0 << "), ("
<< a0.a1.a0.a5.a1.a0 << ")), " << a0.a1.a0.a6 << "), ((" << a0.a1.a1.a0.a0
<< ", " << a0.a1.a1.a0.a1 << "), (" << a0.a1.a1.a1.a0 << ")), "
<< a0.a1.a2 << ", " << a0.a1.a3 << "), ((" << a0.a2.a0.a0 << ", (("
<< a0.a2.a0.a1.a0.a0 << ", " << a0.a2.a0.a1.a0.a1 << "), ("
<< a0.a2.a0.a1.a1.a0 << ")), " << a0.a2.a0.a2 << ", (("
<< a0.a2.a0.a3.a0.a0 << "), " << a0.a2.a0.a3.a1 << "), " << a0.a2.a0.a4
<< ", ((" << a0.a2.a0.a5.a0.a0 << "), (" << a0.a2.a0.a5.a1.a0 << ")), "
<< a0.a2.a0.a6 << "), ((" << a0.a2.a1.a0.a0 << ", " << a0.a2.a1.a0.a1
<< "), (" << a0.a2.a1.a1.a0 << ")), " << a0.a2.a2 << ", " << a0.a2.a3
<< "), " << a0.a3 << "), (" << a1.a0 << ", ((" << a1.a1.a0.a0 << ", (("
<< a1.a1.a0.a1.a0.a0 << ", " << a1.a1.a0.a1.a0.a1 << "), ("
<< a1.a1.a0.a1.a1.a0 << ")), " << a1.a1.a0.a2 << ", (("
<< a1.a1.a0.a3.a0.a0 << "), " << a1.a1.a0.a3.a1 << "), " << a1.a1.a0.a4
<< ", ((" << a1.a1.a0.a5.a0.a0 << "), (" << a1.a1.a0.a5.a1.a0 << ")), "
<< a1.a1.a0.a6 << "), ((" << a1.a1.a1.a0.a0 << ", " << a1.a1.a1.a0.a1
<< "), (" << a1.a1.a1.a1.a0 << ")), " << a1.a1.a2 << ", " << a1.a1.a3
<< "), ((" << a1.a2.a0.a0 << ", ((" << a1.a2.a0.a1.a0.a0 << ", "
<< a1.a2.a0.a1.a0.a1 << "), (" << a1.a2.a0.a1.a1.a0 << ")), "
<< a1.a2.a0.a2 << ", ((" << a1.a2.a0.a3.a0.a0 << "), " << a1.a2.a0.a3.a1
<< "), " << a1.a2.a0.a4 << ", ((" << a1.a2.a0.a5.a0.a0 << "), ("
<< a1.a2.a0.a5.a1.a0 << ")), " << a1.a2.a0.a6 << "), ((" << a1.a2.a1.a0.a0
<< ", " << a1.a2.a1.a0.a1 << "), (" << a1.a2.a1.a1.a0 << ")), "
<< a1.a2.a2 << ", " << a1.a2.a3 << "), " << a1.a3 << "), (" << a2.a0
<< ", ((" << a2.a1.a0.a0 << ", ((" << a2.a1.a0.a1.a0.a0 << ", "
<< a2.a1.a0.a1.a0.a1 << "), (" << a2.a1.a0.a1.a1.a0 << ")), "
<< a2.a1.a0.a2 << ", ((" << a2.a1.a0.a3.a0.a0 << "), " << a2.a1.a0.a3.a1
<< "), " << a2.a1.a0.a4 << ", ((" << a2.a1.a0.a5.a0.a0 << "), ("
<< a2.a1.a0.a5.a1.a0 << ")), " << a2.a1.a0.a6 << "), ((" << a2.a1.a1.a0.a0
<< ", " << a2.a1.a1.a0.a1 << "), (" << a2.a1.a1.a1.a0 << ")), "
<< a2.a1.a2 << ", " << a2.a1.a3 << "), ((" << a2.a2.a0.a0 << ", (("
<< a2.a2.a0.a1.a0.a0 << ", " << a2.a2.a0.a1.a0.a1 << "), ("
<< a2.a2.a0.a1.a1.a0 << ")), " << a2.a2.a0.a2 << ", (("
<< a2.a2.a0.a3.a0.a0 << "), " << a2.a2.a0.a3.a1 << "), " << a2.a2.a0.a4
<< ", ((" << a2.a2.a0.a5.a0.a0 << "), (" << a2.a2.a0.a5.a1.a0 << ")), "
<< a2.a2.a0.a6 << "), ((" << a2.a2.a1.a0.a0 << ", " << a2.a2.a1.a0.a1
<< "), (" << a2.a2.a1.a1.a0 << ")), " << a2.a2.a2 << ", " << a2.a2.a3
<< "), " << a2.a3 << "), (" << a3.a0 << ", ((" << a3.a1.a0.a0 << ", (("
<< a3.a1.a0.a1.a0.a0 << ", " << a3.a1.a0.a1.a0.a1 << "), ("
<< a3.a1.a0.a1.a1.a0 << ")), " << a3.a1.a0.a2 << ", (("
<< a3.a1.a0.a3.a0.a0 << "), " << a3.a1.a0.a3.a1 << "), " << a3.a1.a0.a4
<< ", ((" << a3.a1.a0.a5.a0.a0 << "), (" << a3.a1.a0.a5.a1.a0 << ")), "
<< a3.a1.a0.a6 << "), ((" << a3.a1.a1.a0.a0 << ", " << a3.a1.a1.a0.a1
<< "), (" << a3.a1.a1.a1.a0 << ")), " << a3.a1.a2 << ", " << a3.a1.a3
<< "), ((" << a3.a2.a0.a0 << ", ((" << a3.a2.a0.a1.a0.a0 << ", "
<< a3.a2.a0.a1.a0.a1 << "), (" << a3.a2.a0.a1.a1.a0 << ")), "
<< a3.a2.a0.a2 << ", ((" << a3.a2.a0.a3.a0.a0 << "), " << a3.a2.a0.a3.a1
<< "), " << a3.a2.a0.a4 << ", ((" << a3.a2.a0.a5.a0.a0 << "), ("
<< a3.a2.a0.a5.a1.a0 << ")), " << a3.a2.a0.a6 << "), ((" << a3.a2.a1.a0.a0
<< ", " << a3.a2.a1.a0.a1 << "), (" << a3.a2.a1.a1.a0 << ")), "
<< a3.a2.a2 << ", " << a3.a2.a3 << "), " << a3.a3 << "))"
<< ")\n";
double result = f(a0, a1, a2, a3);
std::cout << "result = " << result << "\n";
CHECK_APPROX(1572.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs and unions by value.
// Simple struct with inline array.
DART_EXPORT intptr_t TestPassStruct8BytesInlineArrayIntx4(
// NOLINTNEXTLINE(whitespace/parens)
int32_t (*f)(Struct8BytesInlineArrayInt a0,
Struct8BytesInlineArrayInt a1,
Struct8BytesInlineArrayInt a2,
Struct8BytesInlineArrayInt a3)) {
Struct8BytesInlineArrayInt a0;
Struct8BytesInlineArrayInt a1;
Struct8BytesInlineArrayInt a2;
Struct8BytesInlineArrayInt a3;
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;
std::cout << "Calling TestPassStruct8BytesInlineArrayIntx4("
<< "(([" << static_cast<int>(a0.a0[0]) << ", "
<< static_cast<int>(a0.a0[1]) << ", " << static_cast<int>(a0.a0[2])
<< ", " << static_cast<int>(a0.a0[3]) << ", "
<< static_cast<int>(a0.a0[4]) << ", " << static_cast<int>(a0.a0[5])
<< ", " << static_cast<int>(a0.a0[6]) << ", "
<< static_cast<int>(a0.a0[7]) << "]), (["
<< static_cast<int>(a1.a0[0]) << ", " << static_cast<int>(a1.a0[1])
<< ", " << static_cast<int>(a1.a0[2]) << ", "
<< static_cast<int>(a1.a0[3]) << ", " << static_cast<int>(a1.a0[4])
<< ", " << static_cast<int>(a1.a0[5]) << ", "
<< static_cast<int>(a1.a0[6]) << ", " << static_cast<int>(a1.a0[7])
<< "]), ([" << static_cast<int>(a2.a0[0]) << ", "
<< static_cast<int>(a2.a0[1]) << ", " << static_cast<int>(a2.a0[2])
<< ", " << static_cast<int>(a2.a0[3]) << ", "
<< static_cast<int>(a2.a0[4]) << ", " << static_cast<int>(a2.a0[5])
<< ", " << static_cast<int>(a2.a0[6]) << ", "
<< static_cast<int>(a2.a0[7]) << "]), (["
<< static_cast<int>(a3.a0[0]) << ", " << static_cast<int>(a3.a0[1])
<< ", " << static_cast<int>(a3.a0[2]) << ", "
<< static_cast<int>(a3.a0[3]) << ", " << static_cast<int>(a3.a0[4])
<< ", " << static_cast<int>(a3.a0[5]) << ", "
<< static_cast<int>(a3.a0[6]) << ", " << static_cast<int>(a3.a0[7])
<< "]))"
<< ")\n";
int32_t result = f(a0, a1, a2, a3);
std::cout << "result = " << result << "\n";
CHECK_EQ(528, result);
// Pass argument that will make the Dart callback throw.
a0.a0[0] = 42;
result = f(a0, a1, a2, a3);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0[0] = 84;
result = f(a0, a1, a2, a3);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs and unions by value.
// Irregular struct with inline array.
DART_EXPORT intptr_t TestPassStructInlineArrayIrregularx4(
// NOLINTNEXTLINE(whitespace/parens)
int32_t (*f)(StructInlineArrayIrregular a0,
StructInlineArrayIrregular a1,
StructInlineArrayIrregular a2,
StructInlineArrayIrregular a3)) {
StructInlineArrayIrregular a0;
StructInlineArrayIrregular a1;
StructInlineArrayIrregular a2;
StructInlineArrayIrregular a3;
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;
std::cout << "Calling TestPassStructInlineArrayIrregularx4("
<< "(([(" << a0.a0[0].a0 << ", " << static_cast<int>(a0.a0[0].a1)
<< "), (" << a0.a0[1].a0 << ", " << static_cast<int>(a0.a0[1].a1)
<< ")], " << static_cast<int>(a0.a1) << "), ([(" << a1.a0[0].a0
<< ", " << static_cast<int>(a1.a0[0].a1) << "), (" << a1.a0[1].a0
<< ", " << static_cast<int>(a1.a0[1].a1) << ")], "
<< static_cast<int>(a1.a1) << "), ([(" << a2.a0[0].a0 << ", "
<< static_cast<int>(a2.a0[0].a1) << "), (" << a2.a0[1].a0 << ", "
<< static_cast<int>(a2.a0[1].a1) << ")], "
<< static_cast<int>(a2.a1) << "), ([(" << a3.a0[0].a0 << ", "
<< static_cast<int>(a3.a0[0].a1) << "), (" << a3.a0[1].a0 << ", "
<< static_cast<int>(a3.a0[1].a1) << ")], "
<< static_cast<int>(a3.a1) << "))"
<< ")\n";
int32_t result = f(a0, a1, a2, a3);
std::cout << "result = " << result << "\n";
CHECK_EQ(50, result);
// Pass argument that will make the Dart callback throw.
a0.a0[0].a0 = 42;
result = f(a0, a1, a2, a3);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0[0].a0 = 84;
result = f(a0, a1, a2, a3);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs and unions by value.
// Regular larger struct with inline array.
DART_EXPORT intptr_t TestPassStructInlineArray100Bytes(
// NOLINTNEXTLINE(whitespace/parens)
int32_t (*f)(StructInlineArray100Bytes a0)) {
StructInlineArray100Bytes a0;
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;
std::cout
<< "Calling TestPassStructInlineArray100Bytes("
<< "(([" << static_cast<int>(a0.a0[0]) << ", "
<< static_cast<int>(a0.a0[1]) << ", " << static_cast<int>(a0.a0[2])
<< ", " << static_cast<int>(a0.a0[3]) << ", "
<< static_cast<int>(a0.a0[4]) << ", " << static_cast<int>(a0.a0[5])
<< ", " << static_cast<int>(a0.a0[6]) << ", "
<< static_cast<int>(a0.a0[7]) << ", " << static_cast<int>(a0.a0[8])
<< ", " << static_cast<int>(a0.a0[9]) << ", "
<< static_cast<int>(a0.a0[10]) << ", " << static_cast<int>(a0.a0[11])
<< ", " << static_cast<int>(a0.a0[12]) << ", "
<< static_cast<int>(a0.a0[13]) << ", " << static_cast<int>(a0.a0[14])
<< ", " << static_cast<int>(a0.a0[15]) << ", "
<< static_cast<int>(a0.a0[16]) << ", " << static_cast<int>(a0.a0[17])
<< ", " << static_cast<int>(a0.a0[18]) << ", "
<< static_cast<int>(a0.a0[19]) << ", " << static_cast<int>(a0.a0[20])
<< ", " << static_cast<int>(a0.a0[21]) << ", "
<< static_cast<int>(a0.a0[22]) << ", " << static_cast<int>(a0.a0[23])
<< ", " << static_cast<int>(a0.a0[24]) << ", "
<< static_cast<int>(a0.a0[25]) << ", " << static_cast<int>(a0.a0[26])
<< ", " << static_cast<int>(a0.a0[27]) << ", "
<< static_cast<int>(a0.a0[28]) << ", " << static_cast<int>(a0.a0[29])
<< ", " << static_cast<int>(a0.a0[30]) << ", "
<< static_cast<int>(a0.a0[31]) << ", " << static_cast<int>(a0.a0[32])
<< ", " << static_cast<int>(a0.a0[33]) << ", "
<< static_cast<int>(a0.a0[34]) << ", " << static_cast<int>(a0.a0[35])
<< ", " << static_cast<int>(a0.a0[36]) << ", "
<< static_cast<int>(a0.a0[37]) << ", " << static_cast<int>(a0.a0[38])
<< ", " << static_cast<int>(a0.a0[39]) << ", "
<< static_cast<int>(a0.a0[40]) << ", " << static_cast<int>(a0.a0[41])
<< ", " << static_cast<int>(a0.a0[42]) << ", "
<< static_cast<int>(a0.a0[43]) << ", " << static_cast<int>(a0.a0[44])
<< ", " << static_cast<int>(a0.a0[45]) << ", "
<< static_cast<int>(a0.a0[46]) << ", " << static_cast<int>(a0.a0[47])
<< ", " << static_cast<int>(a0.a0[48]) << ", "
<< static_cast<int>(a0.a0[49]) << ", " << static_cast<int>(a0.a0[50])
<< ", " << static_cast<int>(a0.a0[51]) << ", "
<< static_cast<int>(a0.a0[52]) << ", " << static_cast<int>(a0.a0[53])
<< ", " << static_cast<int>(a0.a0[54]) << ", "
<< static_cast<int>(a0.a0[55]) << ", " << static_cast<int>(a0.a0[56])
<< ", " << static_cast<int>(a0.a0[57]) << ", "
<< static_cast<int>(a0.a0[58]) << ", " << static_cast<int>(a0.a0[59])
<< ", " << static_cast<int>(a0.a0[60]) << ", "
<< static_cast<int>(a0.a0[61]) << ", " << static_cast<int>(a0.a0[62])
<< ", " << static_cast<int>(a0.a0[63]) << ", "
<< static_cast<int>(a0.a0[64]) << ", " << static_cast<int>(a0.a0[65])
<< ", " << static_cast<int>(a0.a0[66]) << ", "
<< static_cast<int>(a0.a0[67]) << ", " << static_cast<int>(a0.a0[68])
<< ", " << static_cast<int>(a0.a0[69]) << ", "
<< static_cast<int>(a0.a0[70]) << ", " << static_cast<int>(a0.a0[71])
<< ", " << static_cast<int>(a0.a0[72]) << ", "
<< static_cast<int>(a0.a0[73]) << ", " << static_cast<int>(a0.a0[74])
<< ", " << static_cast<int>(a0.a0[75]) << ", "
<< static_cast<int>(a0.a0[76]) << ", " << static_cast<int>(a0.a0[77])
<< ", " << static_cast<int>(a0.a0[78]) << ", "
<< static_cast<int>(a0.a0[79]) << ", " << static_cast<int>(a0.a0[80])
<< ", " << static_cast<int>(a0.a0[81]) << ", "
<< static_cast<int>(a0.a0[82]) << ", " << static_cast<int>(a0.a0[83])
<< ", " << static_cast<int>(a0.a0[84]) << ", "
<< static_cast<int>(a0.a0[85]) << ", " << static_cast<int>(a0.a0[86])
<< ", " << static_cast<int>(a0.a0[87]) << ", "
<< static_cast<int>(a0.a0[88]) << ", " << static_cast<int>(a0.a0[89])
<< ", " << static_cast<int>(a0.a0[90]) << ", "
<< static_cast<int>(a0.a0[91]) << ", " << static_cast<int>(a0.a0[92])
<< ", " << static_cast<int>(a0.a0[93]) << ", "
<< static_cast<int>(a0.a0[94]) << ", " << static_cast<int>(a0.a0[95])
<< ", " << static_cast<int>(a0.a0[96]) << ", "
<< static_cast<int>(a0.a0[97]) << ", " << static_cast<int>(a0.a0[98])
<< ", " << static_cast<int>(a0.a0[99]) << "]))"
<< ")\n";
int32_t result = f(a0);
std::cout << "result = " << result << "\n";
CHECK_EQ(5050, result);
// Pass argument that will make the Dart callback throw.
a0.a0[0] = 42;
result = f(a0);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0[0] = 84;
result = f(a0);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs and unions by value.
// Arguments in FPU registers on arm hardfp and arm64.
// 5 struct arguments will exhaust available registers.
DART_EXPORT intptr_t TestPassStructStruct16BytesHomogeneousFloat2x5(
// NOLINTNEXTLINE(whitespace/parens)
float (*f)(StructStruct16BytesHomogeneousFloat2 a0,
StructStruct16BytesHomogeneousFloat2 a1,
StructStruct16BytesHomogeneousFloat2 a2,
StructStruct16BytesHomogeneousFloat2 a3,
StructStruct16BytesHomogeneousFloat2 a4)) {
StructStruct16BytesHomogeneousFloat2 a0;
StructStruct16BytesHomogeneousFloat2 a1;
StructStruct16BytesHomogeneousFloat2 a2;
StructStruct16BytesHomogeneousFloat2 a3;
StructStruct16BytesHomogeneousFloat2 a4;
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;
std::cout << "Calling TestPassStructStruct16BytesHomogeneousFloat2x5("
<< "(((" << a0.a0.a0 << "), [(" << a0.a1[0].a0 << "), ("
<< a0.a1[1].a0 << ")], " << a0.a2 << "), ((" << a1.a0.a0 << "), [("
<< a1.a1[0].a0 << "), (" << a1.a1[1].a0 << ")], " << a1.a2
<< "), ((" << a2.a0.a0 << "), [(" << a2.a1[0].a0 << "), ("
<< a2.a1[1].a0 << ")], " << a2.a2 << "), ((" << a3.a0.a0 << "), [("
<< a3.a1[0].a0 << "), (" << a3.a1[1].a0 << ")], " << a3.a2
<< "), ((" << a4.a0.a0 << "), [(" << a4.a1[0].a0 << "), ("
<< a4.a1[1].a0 << ")], " << a4.a2 << "))"
<< ")\n";
float result = f(a0, a1, a2, a3, a4);
std::cout << "result = " << result << "\n";
CHECK_APPROX(10.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0.a0 = 42;
result = f(a0, a1, a2, a3, a4);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0.a0 = 84;
result = f(a0, a1, a2, a3, a4);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs and unions by value.
// Arguments in FPU registers on arm64.
// 5 struct arguments will exhaust available registers.
DART_EXPORT intptr_t TestPassStructStruct32BytesHomogeneousDouble2x5(
// NOLINTNEXTLINE(whitespace/parens)
double (*f)(StructStruct32BytesHomogeneousDouble2 a0,
StructStruct32BytesHomogeneousDouble2 a1,
StructStruct32BytesHomogeneousDouble2 a2,
StructStruct32BytesHomogeneousDouble2 a3,
StructStruct32BytesHomogeneousDouble2 a4)) {
StructStruct32BytesHomogeneousDouble2 a0;
StructStruct32BytesHomogeneousDouble2 a1;
StructStruct32BytesHomogeneousDouble2 a2;
StructStruct32BytesHomogeneousDouble2 a3;
StructStruct32BytesHomogeneousDouble2 a4;
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;
std::cout << "Calling TestPassStructStruct32BytesHomogeneousDouble2x5("
<< "(((" << a0.a0.a0 << "), [(" << a0.a1[0].a0 << "), ("
<< a0.a1[1].a0 << ")], " << a0.a2 << "), ((" << a1.a0.a0 << "), [("
<< a1.a1[0].a0 << "), (" << a1.a1[1].a0 << ")], " << a1.a2
<< "), ((" << a2.a0.a0 << "), [(" << a2.a1[0].a0 << "), ("
<< a2.a1[1].a0 << ")], " << a2.a2 << "), ((" << a3.a0.a0 << "), [("
<< a3.a1[0].a0 << "), (" << a3.a1[1].a0 << ")], " << a3.a2
<< "), ((" << a4.a0.a0 << "), [(" << a4.a1[0].a0 << "), ("
<< a4.a1[1].a0 << ")], " << a4.a2 << "))"
<< ")\n";
double result = f(a0, a1, a2, a3, a4);
std::cout << "result = " << result << "\n";
CHECK_APPROX(10.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0.a0 = 42;
result = f(a0, a1, a2, a3, a4);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0.a0 = 84;
result = f(a0, a1, a2, a3, a4);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs and unions by value.
// 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.
DART_EXPORT intptr_t TestPassStructStruct16BytesMixed3x10(
// NOLINTNEXTLINE(whitespace/parens)
float (*f)(StructStruct16BytesMixed3 a0,
StructStruct16BytesMixed3 a1,
StructStruct16BytesMixed3 a2,
StructStruct16BytesMixed3 a3,
StructStruct16BytesMixed3 a4,
StructStruct16BytesMixed3 a5,
StructStruct16BytesMixed3 a6,
StructStruct16BytesMixed3 a7,
StructStruct16BytesMixed3 a8,
StructStruct16BytesMixed3 a9)) {
StructStruct16BytesMixed3 a0;
StructStruct16BytesMixed3 a1;
StructStruct16BytesMixed3 a2;
StructStruct16BytesMixed3 a3;
StructStruct16BytesMixed3 a4;
StructStruct16BytesMixed3 a5;
StructStruct16BytesMixed3 a6;
StructStruct16BytesMixed3 a7;
StructStruct16BytesMixed3 a8;
StructStruct16BytesMixed3 a9;
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;
std::cout << "Calling TestPassStructStruct16BytesMixed3x10("
<< "(((" << a0.a0.a0 << "), [(" << a0.a1[0].a0 << ", "
<< a0.a1[0].a1 << ", " << a0.a1[0].a2 << ")], [" << a0.a2[0] << ", "
<< a0.a2[1] << "]), ((" << a1.a0.a0 << "), [(" << a1.a1[0].a0
<< ", " << a1.a1[0].a1 << ", " << a1.a1[0].a2 << ")], [" << a1.a2[0]
<< ", " << a1.a2[1] << "]), ((" << a2.a0.a0 << "), [("
<< a2.a1[0].a0 << ", " << a2.a1[0].a1 << ", " << a2.a1[0].a2
<< ")], [" << a2.a2[0] << ", " << a2.a2[1] << "]), ((" << a3.a0.a0
<< "), [(" << a3.a1[0].a0 << ", " << a3.a1[0].a1 << ", "
<< a3.a1[0].a2 << ")], [" << a3.a2[0] << ", " << a3.a2[1]
<< "]), ((" << a4.a0.a0 << "), [(" << a4.a1[0].a0 << ", "
<< a4.a1[0].a1 << ", " << a4.a1[0].a2 << ")], [" << a4.a2[0] << ", "
<< a4.a2[1] << "]), ((" << a5.a0.a0 << "), [(" << a5.a1[0].a0
<< ", " << a5.a1[0].a1 << ", " << a5.a1[0].a2 << ")], [" << a5.a2[0]
<< ", " << a5.a2[1] << "]), ((" << a6.a0.a0 << "), [("
<< a6.a1[0].a0 << ", " << a6.a1[0].a1 << ", " << a6.a1[0].a2
<< ")], [" << a6.a2[0] << ", " << a6.a2[1] << "]), ((" << a7.a0.a0
<< "), [(" << a7.a1[0].a0 << ", " << a7.a1[0].a1 << ", "
<< a7.a1[0].a2 << ")], [" << a7.a2[0] << ", " << a7.a2[1]
<< "]), ((" << a8.a0.a0 << "), [(" << a8.a1[0].a0 << ", "
<< a8.a1[0].a1 << ", " << a8.a1[0].a2 << ")], [" << a8.a2[0] << ", "
<< a8.a2[1] << "]), ((" << a9.a0.a0 << "), [(" << a9.a1[0].a0
<< ", " << a9.a1[0].a1 << ", " << a9.a1[0].a2 << ")], [" << a9.a2[0]
<< ", " << a9.a2[1] << "]))"
<< ")\n";
float result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_APPROX(30.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs and unions by value.
// Test multi dimensional inline array struct as argument.
DART_EXPORT intptr_t TestPassUint8Struct32BytesInlineArrayMultiDimensionalI(
// NOLINTNEXTLINE(whitespace/parens)
uint32_t (*f)(uint8_t a0,
Struct32BytesInlineArrayMultiDimensionalInt a1,
uint8_t a2,
Struct8BytesInlineArrayMultiDimensionalInt a3,
uint8_t a4,
Struct8BytesInlineArrayMultiDimensionalInt a5,
uint8_t a6)) {
uint8_t a0;
Struct32BytesInlineArrayMultiDimensionalInt a1;
uint8_t a2;
Struct8BytesInlineArrayMultiDimensionalInt a3;
uint8_t a4;
Struct8BytesInlineArrayMultiDimensionalInt a5;
uint8_t 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;
std::cout << "Calling TestPassUint8Struct32BytesInlineArrayMultiDimensionalI("
<< "(" << static_cast<int>(a0) << ", ([[[[["
<< static_cast<int>(a1.a0[0][0][0][0][0]) << ", "
<< static_cast<int>(a1.a0[0][0][0][0][1]) << "], ["
<< static_cast<int>(a1.a0[0][0][0][1][0]) << ", "
<< static_cast<int>(a1.a0[0][0][0][1][1]) << "]], [["
<< static_cast<int>(a1.a0[0][0][1][0][0]) << ", "
<< static_cast<int>(a1.a0[0][0][1][0][1]) << "], ["
<< static_cast<int>(a1.a0[0][0][1][1][0]) << ", "
<< static_cast<int>(a1.a0[0][0][1][1][1]) << "]]], [[["
<< static_cast<int>(a1.a0[0][1][0][0][0]) << ", "
<< static_cast<int>(a1.a0[0][1][0][0][1]) << "], ["
<< static_cast<int>(a1.a0[0][1][0][1][0]) << ", "
<< static_cast<int>(a1.a0[0][1][0][1][1]) << "]], [["
<< static_cast<int>(a1.a0[0][1][1][0][0]) << ", "
<< static_cast<int>(a1.a0[0][1][1][0][1]) << "], ["
<< static_cast<int>(a1.a0[0][1][1][1][0]) << ", "
<< static_cast<int>(a1.a0[0][1][1][1][1]) << "]]]], [[[["
<< static_cast<int>(a1.a0[1][0][0][0][0]) << ", "
<< static_cast<int>(a1.a0[1][0][0][0][1]) << "], ["
<< static_cast<int>(a1.a0[1][0][0][1][0]) << ", "
<< static_cast<int>(a1.a0[1][0][0][1][1]) << "]], [["
<< static_cast<int>(a1.a0[1][0][1][0][0]) << ", "
<< static_cast<int>(a1.a0[1][0][1][0][1]) << "], ["
<< static_cast<int>(a1.a0[1][0][1][1][0]) << ", "
<< static_cast<int>(a1.a0[1][0][1][1][1]) << "]]], [[["
<< static_cast<int>(a1.a0[1][1][0][0][0]) << ", "
<< static_cast<int>(a1.a0[1][1][0][0][1]) << "], ["
<< static_cast<int>(a1.a0[1][1][0][1][0]) << ", "
<< static_cast<int>(a1.a0[1][1][0][1][1]) << "]], [["
<< static_cast<int>(a1.a0[1][1][1][0][0]) << ", "
<< static_cast<int>(a1.a0[1][1][1][0][1]) << "], ["
<< static_cast<int>(a1.a0[1][1][1][1][0]) << ", "
<< static_cast<int>(a1.a0[1][1][1][1][1]) << "]]]]]), "
<< static_cast<int>(a2) << ", ([[["
<< static_cast<int>(a3.a0[0][0][0]) << ", "
<< static_cast<int>(a3.a0[0][0][1]) << "], ["
<< static_cast<int>(a3.a0[0][1][0]) << ", "
<< static_cast<int>(a3.a0[0][1][1]) << "]], [["
<< static_cast<int>(a3.a0[1][0][0]) << ", "
<< static_cast<int>(a3.a0[1][0][1]) << "], ["
<< static_cast<int>(a3.a0[1][1][0]) << ", "
<< static_cast<int>(a3.a0[1][1][1]) << "]]]), "
<< static_cast<int>(a4) << ", ([[["
<< static_cast<int>(a5.a0[0][0][0]) << ", "
<< static_cast<int>(a5.a0[0][0][1]) << "], ["
<< static_cast<int>(a5.a0[0][1][0]) << ", "
<< static_cast<int>(a5.a0[0][1][1]) << "]], [["
<< static_cast<int>(a5.a0[1][0][0]) << ", "
<< static_cast<int>(a5.a0[1][0][1]) << "], ["
<< static_cast<int>(a5.a0[1][1][0]) << ", "
<< static_cast<int>(a5.a0[1][1][1]) << "]]]), "
<< static_cast<int>(a6) << ")"
<< ")\n";
uint32_t result = f(a0, a1, a2, a3, a4, a5, a6);
std::cout << "result = " << result << "\n";
CHECK_EQ(1378, result);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs and unions by value.
// Test struct in multi dimensional inline array.
DART_EXPORT intptr_t TestPassUint8Struct4BytesInlineArrayMultiDimensionalIn(
// NOLINTNEXTLINE(whitespace/parens)
uint32_t (*f)(uint8_t a0,
Struct4BytesInlineArrayMultiDimensionalInt a1,
uint8_t a2)) {
uint8_t a0;
Struct4BytesInlineArrayMultiDimensionalInt a1;
uint8_t 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;
std::cout << "Calling TestPassUint8Struct4BytesInlineArrayMultiDimensionalIn("
<< "(" << static_cast<int>(a0) << ", ([[("
<< static_cast<int>(a1.a0[0][0].a0) << "), ("
<< static_cast<int>(a1.a0[0][1].a0) << ")], [("
<< static_cast<int>(a1.a0[1][0].a0) << "), ("
<< static_cast<int>(a1.a0[1][1].a0) << ")]]), "
<< static_cast<int>(a2) << ")"
<< ")\n";
uint32_t result = f(a0, a1, a2);
std::cout << "result = " << result << "\n";
CHECK_EQ(5, result);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs and unions by value.
// Small struct with mis-aligned member.
DART_EXPORT intptr_t TestPassStruct3BytesPackedIntx10(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(Struct3BytesPackedInt a0,
Struct3BytesPackedInt a1,
Struct3BytesPackedInt a2,
Struct3BytesPackedInt a3,
Struct3BytesPackedInt a4,
Struct3BytesPackedInt a5,
Struct3BytesPackedInt a6,
Struct3BytesPackedInt a7,
Struct3BytesPackedInt a8,
Struct3BytesPackedInt a9)) {
Struct3BytesPackedInt a0;
Struct3BytesPackedInt a1;
Struct3BytesPackedInt a2;
Struct3BytesPackedInt a3;
Struct3BytesPackedInt a4;
Struct3BytesPackedInt a5;
Struct3BytesPackedInt a6;
Struct3BytesPackedInt a7;
Struct3BytesPackedInt a8;
Struct3BytesPackedInt a9;
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;
std::cout << "Calling TestPassStruct3BytesPackedIntx10("
<< "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << "), ("
<< static_cast<int>(a1.a0) << ", " << a1.a1 << "), ("
<< static_cast<int>(a2.a0) << ", " << a2.a1 << "), ("
<< static_cast<int>(a3.a0) << ", " << a3.a1 << "), ("
<< static_cast<int>(a4.a0) << ", " << a4.a1 << "), ("
<< static_cast<int>(a5.a0) << ", " << a5.a1 << "), ("
<< static_cast<int>(a6.a0) << ", " << a6.a1 << "), ("
<< static_cast<int>(a7.a0) << ", " << a7.a1 << "), ("
<< static_cast<int>(a8.a0) << ", " << a8.a1 << "), ("
<< static_cast<int>(a9.a0) << ", " << a9.a1 << "))"
<< ")\n";
int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_EQ(10, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs and unions by value.
// Struct with mis-aligned member.
DART_EXPORT intptr_t TestPassStruct8BytesPackedIntx10(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(Struct8BytesPackedInt a0,
Struct8BytesPackedInt a1,
Struct8BytesPackedInt a2,
Struct8BytesPackedInt a3,
Struct8BytesPackedInt a4,
Struct8BytesPackedInt a5,
Struct8BytesPackedInt a6,
Struct8BytesPackedInt a7,
Struct8BytesPackedInt a8,
Struct8BytesPackedInt a9)) {
Struct8BytesPackedInt a0;
Struct8BytesPackedInt a1;
Struct8BytesPackedInt a2;
Struct8BytesPackedInt a3;
Struct8BytesPackedInt a4;
Struct8BytesPackedInt a5;
Struct8BytesPackedInt a6;
Struct8BytesPackedInt a7;
Struct8BytesPackedInt a8;
Struct8BytesPackedInt a9;
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;
std::cout << "Calling TestPassStruct8BytesPackedIntx10("
<< "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << ", "
<< static_cast<int>(a0.a2) << ", " << static_cast<int>(a0.a3)
<< ", " << static_cast<int>(a0.a4) << "), ("
<< static_cast<int>(a1.a0) << ", " << a1.a1 << ", "
<< static_cast<int>(a1.a2) << ", " << static_cast<int>(a1.a3)
<< ", " << static_cast<int>(a1.a4) << "), ("
<< static_cast<int>(a2.a0) << ", " << a2.a1 << ", "
<< static_cast<int>(a2.a2) << ", " << static_cast<int>(a2.a3)
<< ", " << static_cast<int>(a2.a4) << "), ("
<< static_cast<int>(a3.a0) << ", " << a3.a1 << ", "
<< static_cast<int>(a3.a2) << ", " << static_cast<int>(a3.a3)
<< ", " << static_cast<int>(a3.a4) << "), ("
<< static_cast<int>(a4.a0) << ", " << a4.a1 << ", "
<< static_cast<int>(a4.a2) << ", " << static_cast<int>(a4.a3)
<< ", " << static_cast<int>(a4.a4) << "), ("
<< static_cast<int>(a5.a0) << ", " << a5.a1 << ", "
<< static_cast<int>(a5.a2) << ", " << static_cast<int>(a5.a3)
<< ", " << static_cast<int>(a5.a4) << "), ("
<< static_cast<int>(a6.a0) << ", " << a6.a1 << ", "
<< static_cast<int>(a6.a2) << ", " << static_cast<int>(a6.a3)
<< ", " << static_cast<int>(a6.a4) << "), ("
<< static_cast<int>(a7.a0) << ", " << a7.a1 << ", "
<< static_cast<int>(a7.a2) << ", " << static_cast<int>(a7.a3)
<< ", " << static_cast<int>(a7.a4) << "), ("
<< static_cast<int>(a8.a0) << ", " << a8.a1 << ", "
<< static_cast<int>(a8.a2) << ", " << static_cast<int>(a8.a3)
<< ", " << static_cast<int>(a8.a4) << "), ("
<< static_cast<int>(a9.a0) << ", " << a9.a1 << ", "
<< static_cast<int>(a9.a2) << ", " << static_cast<int>(a9.a3)
<< ", " << static_cast<int>(a9.a4) << "))"
<< ")\n";
int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_EQ(1275, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs and unions by value.
// Struct with mis-aligned member.
// Tests backfilling of CPU and FPU registers.
DART_EXPORT intptr_t TestPassStruct9BytesPackedMixedx10DoubleInt32x2(
// NOLINTNEXTLINE(whitespace/parens)
double (*f)(Struct9BytesPackedMixed a0,
Struct9BytesPackedMixed a1,
Struct9BytesPackedMixed a2,
Struct9BytesPackedMixed a3,
Struct9BytesPackedMixed a4,
Struct9BytesPackedMixed a5,
Struct9BytesPackedMixed a6,
Struct9BytesPackedMixed a7,
Struct9BytesPackedMixed a8,
Struct9BytesPackedMixed a9,
double a10,
int32_t a11,
int32_t a12)) {
Struct9BytesPackedMixed a0;
Struct9BytesPackedMixed a1;
Struct9BytesPackedMixed a2;
Struct9BytesPackedMixed a3;
Struct9BytesPackedMixed a4;
Struct9BytesPackedMixed a5;
Struct9BytesPackedMixed a6;
Struct9BytesPackedMixed a7;
Struct9BytesPackedMixed a8;
Struct9BytesPackedMixed a9;
double a10;
int32_t a11;
int32_t 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;
std::cout << "Calling TestPassStruct9BytesPackedMixedx10DoubleInt32x2("
<< "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << "), ("
<< static_cast<int>(a1.a0) << ", " << a1.a1 << "), ("
<< static_cast<int>(a2.a0) << ", " << a2.a1 << "), ("
<< static_cast<int>(a3.a0) << ", " << a3.a1 << "), ("
<< static_cast<int>(a4.a0) << ", " << a4.a1 << "), ("
<< static_cast<int>(a5.a0) << ", " << a5.a1 << "), ("
<< static_cast<int>(a6.a0) << ", " << a6.a1 << "), ("
<< static_cast<int>(a7.a0) << ", " << a7.a1 << "), ("
<< static_cast<int>(a8.a0) << ", " << a8.a1 << "), ("
<< static_cast<int>(a9.a0) << ", " << a9.a1 << "), " << a10 << ", "
<< a11 << ", " << a12 << ")"
<< ")\n";
double result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12);
std::cout << "result = " << result << "\n";
CHECK_APPROX(188.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs and unions by value.
// This packed struct happens to have only aligned members.
DART_EXPORT intptr_t TestPassStruct5BytesPackedMixed(
// NOLINTNEXTLINE(whitespace/parens)
double (*f)(Struct5BytesPackedMixed a0)) {
Struct5BytesPackedMixed a0;
a0.a0 = -1.0;
a0.a1 = 2;
std::cout << "Calling TestPassStruct5BytesPackedMixed("
<< "((" << a0.a0 << ", " << static_cast<int>(a0.a1) << "))"
<< ")\n";
double result = f(a0);
std::cout << "result = " << result << "\n";
CHECK_APPROX(1.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs and unions by value.
// Check alignment of packed struct in non-packed struct.
DART_EXPORT intptr_t TestPassStructNestedAlignmentStruct5BytesPackedMixed(
// NOLINTNEXTLINE(whitespace/parens)
double (*f)(StructNestedAlignmentStruct5BytesPackedMixed a0)) {
StructNestedAlignmentStruct5BytesPackedMixed a0;
a0.a0 = 1;
a0.a1.a0 = 2.0;
a0.a1.a1 = 3;
std::cout << "Calling TestPassStructNestedAlignmentStruct5BytesPackedMixed("
<< "((" << static_cast<int>(a0.a0) << ", (" << a0.a1.a0 << ", "
<< static_cast<int>(a0.a1.a1) << ")))"
<< ")\n";
double result = f(a0);
std::cout << "result = " << result << "\n";
CHECK_APPROX(6.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs and unions by value.
// Check alignment of packed struct array in non-packed struct.
DART_EXPORT intptr_t TestPassStruct6BytesInlineArrayInt(
// NOLINTNEXTLINE(whitespace/parens)
double (*f)(Struct6BytesInlineArrayInt a0)) {
Struct6BytesInlineArrayInt a0;
a0.a0[0].a0 = -1;
a0.a0[0].a1 = 2;
a0.a0[1].a0 = -3;
a0.a0[1].a1 = 4;
std::cout << "Calling TestPassStruct6BytesInlineArrayInt("
<< "(([(" << static_cast<int>(a0.a0[0].a0) << ", " << a0.a0[0].a1
<< "), (" << static_cast<int>(a0.a0[1].a0) << ", " << a0.a0[1].a1
<< ")]))"
<< ")\n";
double result = f(a0);
std::cout << "result = " << result << "\n";
CHECK_APPROX(2.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0[0].a0 = 42;
result = f(a0);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0[0].a0 = 84;
result = f(a0);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs and unions by value.
// Check alignment of packed struct array in non-packed struct.
DART_EXPORT intptr_t TestPassStruct15BytesInlineArrayMixed(
// NOLINTNEXTLINE(whitespace/parens)
double (*f)(Struct15BytesInlineArrayMixed a0)) {
Struct15BytesInlineArrayMixed a0;
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;
std::cout << "Calling TestPassStruct15BytesInlineArrayMixed("
<< "(([(" << a0.a0[0].a0 << ", " << static_cast<int>(a0.a0[0].a1)
<< "), (" << a0.a0[1].a0 << ", " << static_cast<int>(a0.a0[1].a1)
<< "), (" << a0.a0[2].a0 << ", " << static_cast<int>(a0.a0[2].a1)
<< ")]))"
<< ")\n";
double result = f(a0);
std::cout << "result = " << result << "\n";
CHECK_APPROX(3.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0[0].a0 = 42;
result = f(a0);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0[0].a0 = 84;
result = f(a0);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs and unions by value.
// Check placement of mixed integer/float union.
DART_EXPORT intptr_t TestPassUnion4BytesMixedx10(
// NOLINTNEXTLINE(whitespace/parens)
double (*f)(Union4BytesMixed a0,
Union4BytesMixed a1,
Union4BytesMixed a2,
Union4BytesMixed a3,
Union4BytesMixed a4,
Union4BytesMixed a5,
Union4BytesMixed a6,
Union4BytesMixed a7,
Union4BytesMixed a8,
Union4BytesMixed a9)) {
Union4BytesMixed a0;
Union4BytesMixed a1;
Union4BytesMixed a2;
Union4BytesMixed a3;
Union4BytesMixed a4;
Union4BytesMixed a5;
Union4BytesMixed a6;
Union4BytesMixed a7;
Union4BytesMixed a8;
Union4BytesMixed a9;
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;
std::cout << "Calling TestPassUnion4BytesMixedx10("
<< "((" << a0.a0 << ", " << a0.a1 << "), (" << a1.a0 << ", "
<< a1.a1 << "), (" << a2.a0 << ", " << a2.a1 << "), (" << a3.a0
<< ", " << a3.a1 << "), (" << a4.a0 << ", " << a4.a1 << "), ("
<< a5.a0 << ", " << a5.a1 << "), (" << a6.a0 << ", " << a6.a1
<< "), (" << a7.a0 << ", " << a7.a1 << "), (" << a8.a0 << ", "
<< a8.a1 << "), (" << a9.a0 << ", " << a9.a1 << "))"
<< ")\n";
double result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_APPROX(55.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs and unions by value.
// Check placement of mixed floats union.
DART_EXPORT intptr_t TestPassUnion8BytesNestedFloatx10(
// NOLINTNEXTLINE(whitespace/parens)
double (*f)(Union8BytesNestedFloat a0,
Union8BytesNestedFloat a1,
Union8BytesNestedFloat a2,
Union8BytesNestedFloat a3,
Union8BytesNestedFloat a4,
Union8BytesNestedFloat a5,
Union8BytesNestedFloat a6,
Union8BytesNestedFloat a7,
Union8BytesNestedFloat a8,
Union8BytesNestedFloat a9)) {
Union8BytesNestedFloat a0;
Union8BytesNestedFloat a1;
Union8BytesNestedFloat a2;
Union8BytesNestedFloat a3;
Union8BytesNestedFloat a4;
Union8BytesNestedFloat a5;
Union8BytesNestedFloat a6;
Union8BytesNestedFloat a7;
Union8BytesNestedFloat a8;
Union8BytesNestedFloat a9;
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;
std::cout << "Calling TestPassUnion8BytesNestedFloatx10("
<< "((" << a0.a0 << ", (" << a0.a1.a0 << ", " << a0.a1.a1 << ")), ("
<< a1.a0 << ", (" << a1.a1.a0 << ", " << a1.a1.a1 << ")), ("
<< a2.a0 << ", (" << a2.a1.a0 << ", " << a2.a1.a1 << ")), ("
<< a3.a0 << ", (" << a3.a1.a0 << ", " << a3.a1.a1 << ")), ("
<< a4.a0 << ", (" << a4.a1.a0 << ", " << a4.a1.a1 << ")), ("
<< a5.a0 << ", (" << a5.a1.a0 << ", " << a5.a1.a1 << ")), ("
<< a6.a0 << ", (" << a6.a1.a0 << ", " << a6.a1.a1 << ")), ("
<< a7.a0 << ", (" << a7.a1.a0 << ", " << a7.a1.a1 << ")), ("
<< a8.a0 << ", (" << a8.a1.a0 << ", " << a8.a1.a1 << ")), ("
<< a9.a0 << ", (" << a9.a1.a0 << ", " << a9.a1.a1 << ")))"
<< ")\n";
double result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_APPROX(5.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs and unions by value.
// Mixed-size union argument.
DART_EXPORT intptr_t TestPassUnion9BytesNestedIntx10(
// NOLINTNEXTLINE(whitespace/parens)
double (*f)(Union9BytesNestedInt a0,
Union9BytesNestedInt a1,
Union9BytesNestedInt a2,
Union9BytesNestedInt a3,
Union9BytesNestedInt a4,
Union9BytesNestedInt a5,
Union9BytesNestedInt a6,
Union9BytesNestedInt a7,
Union9BytesNestedInt a8,
Union9BytesNestedInt a9)) {
Union9BytesNestedInt a0;
Union9BytesNestedInt a1;
Union9BytesNestedInt a2;
Union9BytesNestedInt a3;
Union9BytesNestedInt a4;
Union9BytesNestedInt a5;
Union9BytesNestedInt a6;
Union9BytesNestedInt a7;
Union9BytesNestedInt a8;
Union9BytesNestedInt a9;
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;
std::cout << "Calling TestPassUnion9BytesNestedIntx10("
<< "(((" << a0.a0.a0 << ", " << a0.a0.a1 << ", " << a0.a0.a2
<< "), (" << static_cast<int>(a0.a1.a0) << ", "
<< static_cast<int>(a0.a1.a1) << ", " << static_cast<int>(a0.a1.a2)
<< ", " << static_cast<int>(a0.a1.a3) << ", "
<< static_cast<int>(a0.a1.a4) << ", " << static_cast<int>(a0.a1.a5)
<< ", " << static_cast<int>(a0.a1.a6) << ", "
<< static_cast<int>(a0.a1.a7) << ", " << static_cast<int>(a0.a1.a8)
<< ")), ((" << a1.a0.a0 << ", " << a1.a0.a1 << ", " << a1.a0.a2
<< "), (" << static_cast<int>(a1.a1.a0) << ", "
<< static_cast<int>(a1.a1.a1) << ", " << static_cast<int>(a1.a1.a2)
<< ", " << static_cast<int>(a1.a1.a3) << ", "
<< static_cast<int>(a1.a1.a4) << ", " << static_cast<int>(a1.a1.a5)
<< ", " << static_cast<int>(a1.a1.a6) << ", "
<< static_cast<int>(a1.a1.a7) << ", " << static_cast<int>(a1.a1.a8)
<< ")), ((" << a2.a0.a0 << ", " << a2.a0.a1 << ", " << a2.a0.a2
<< "), (" << static_cast<int>(a2.a1.a0) << ", "
<< static_cast<int>(a2.a1.a1) << ", " << static_cast<int>(a2.a1.a2)
<< ", " << static_cast<int>(a2.a1.a3) << ", "
<< static_cast<int>(a2.a1.a4) << ", " << static_cast<int>(a2.a1.a5)
<< ", " << static_cast<int>(a2.a1.a6) << ", "
<< static_cast<int>(a2.a1.a7) << ", " << static_cast<int>(a2.a1.a8)
<< ")), ((" << a3.a0.a0 << ", " << a3.a0.a1 << ", " << a3.a0.a2
<< "), (" << static_cast<int>(a3.a1.a0) << ", "
<< static_cast<int>(a3.a1.a1) << ", " << static_cast<int>(a3.a1.a2)
<< ", " << static_cast<int>(a3.a1.a3) << ", "
<< static_cast<int>(a3.a1.a4) << ", " << static_cast<int>(a3.a1.a5)
<< ", " << static_cast<int>(a3.a1.a6) << ", "
<< static_cast<int>(a3.a1.a7) << ", " << static_cast<int>(a3.a1.a8)
<< ")), ((" << a4.a0.a0 << ", " << a4.a0.a1 << ", " << a4.a0.a2
<< "), (" << static_cast<int>(a4.a1.a0) << ", "
<< static_cast<int>(a4.a1.a1) << ", " << static_cast<int>(a4.a1.a2)
<< ", " << static_cast<int>(a4.a1.a3) << ", "
<< static_cast<int>(a4.a1.a4) << ", " << static_cast<int>(a4.a1.a5)
<< ", " << static_cast<int>(a4.a1.a6) << ", "
<< static_cast<int>(a4.a1.a7) << ", " << static_cast<int>(a4.a1.a8)
<< ")), ((" << a5.a0.a0 << ", " << a5.a0.a1 << ", " << a5.a0.a2
<< "), (" << static_cast<int>(a5.a1.a0) << ", "
<< static_cast<int>(a5.a1.a1) << ", " << static_cast<int>(a5.a1.a2)
<< ", " << static_cast<int>(a5.a1.a3) << ", "
<< static_cast<int>(a5.a1.a4) << ", " << static_cast<int>(a5.a1.a5)
<< ", " << static_cast<int>(a5.a1.a6) << ", "
<< static_cast<int>(a5.a1.a7) << ", " << static_cast<int>(a5.a1.a8)
<< ")), ((" << a6.a0.a0 << ", " << a6.a0.a1 << ", " << a6.a0.a2
<< "), (" << static_cast<int>(a6.a1.a0) << ", "
<< static_cast<int>(a6.a1.a1) << ", " << static_cast<int>(a6.a1.a2)
<< ", " << static_cast<int>(a6.a1.a3) << ", "
<< static_cast<int>(a6.a1.a4) << ", " << static_cast<int>(a6.a1.a5)
<< ", " << static_cast<int>(a6.a1.a6) << ", "
<< static_cast<int>(a6.a1.a7) << ", " << static_cast<int>(a6.a1.a8)
<< ")), ((" << a7.a0.a0 << ", " << a7.a0.a1 << ", " << a7.a0.a2
<< "), (" << static_cast<int>(a7.a1.a0) << ", "
<< static_cast<int>(a7.a1.a1) << ", " << static_cast<int>(a7.a1.a2)
<< ", " << static_cast<int>(a7.a1.a3) << ", "
<< static_cast<int>(a7.a1.a4) << ", " << static_cast<int>(a7.a1.a5)
<< ", " << static_cast<int>(a7.a1.a6) << ", "
<< static_cast<int>(a7.a1.a7) << ", " << static_cast<int>(a7.a1.a8)
<< ")), ((" << a8.a0.a0 << ", " << a8.a0.a1 << ", " << a8.a0.a2
<< "), (" << static_cast<int>(a8.a1.a0) << ", "
<< static_cast<int>(a8.a1.a1) << ", " << static_cast<int>(a8.a1.a2)
<< ", " << static_cast<int>(a8.a1.a3) << ", "
<< static_cast<int>(a8.a1.a4) << ", " << static_cast<int>(a8.a1.a5)
<< ", " << static_cast<int>(a8.a1.a6) << ", "
<< static_cast<int>(a8.a1.a7) << ", " << static_cast<int>(a8.a1.a8)
<< ")), ((" << a9.a0.a0 << ", " << a9.a0.a1 << ", " << a9.a0.a2
<< "), (" << static_cast<int>(a9.a1.a0) << ", "
<< static_cast<int>(a9.a1.a1) << ", " << static_cast<int>(a9.a1.a2)
<< ", " << static_cast<int>(a9.a1.a3) << ", "
<< static_cast<int>(a9.a1.a4) << ", " << static_cast<int>(a9.a1.a5)
<< ", " << static_cast<int>(a9.a1.a6) << ", "
<< static_cast<int>(a9.a1.a7) << ", " << static_cast<int>(a9.a1.a8)
<< ")))"
<< ")\n";
double result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_APPROX(15.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs and unions by value.
// Union with homogenous floats.
DART_EXPORT intptr_t TestPassUnion16BytesNestedInlineArrayFloatx10(
// NOLINTNEXTLINE(whitespace/parens)
double (*f)(Union16BytesNestedInlineArrayFloat a0,
Union16BytesNestedInlineArrayFloat a1,
Union16BytesNestedInlineArrayFloat a2,
Union16BytesNestedInlineArrayFloat a3,
Union16BytesNestedInlineArrayFloat a4,
Union16BytesNestedInlineArrayFloat a5,
Union16BytesNestedInlineArrayFloat a6,
Union16BytesNestedInlineArrayFloat a7,
Union16BytesNestedInlineArrayFloat a8,
Union16BytesNestedInlineArrayFloat a9)) {
Union16BytesNestedInlineArrayFloat a0;
Union16BytesNestedInlineArrayFloat a1;
Union16BytesNestedInlineArrayFloat a2;
Union16BytesNestedInlineArrayFloat a3;
Union16BytesNestedInlineArrayFloat a4;
Union16BytesNestedInlineArrayFloat a5;
Union16BytesNestedInlineArrayFloat a6;
Union16BytesNestedInlineArrayFloat a7;
Union16BytesNestedInlineArrayFloat a8;
Union16BytesNestedInlineArrayFloat a9;
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;
std::cout << "Calling TestPassUnion16BytesNestedInlineArrayFloatx10("
<< "(([" << a0.a0[0] << ", " << a0.a0[1] << ", " << a0.a0[2] << ", "
<< a0.a0[3] << "], (" << a0.a1.a0 << ", " << a0.a1.a1 << ", "
<< a0.a1.a2 << ", " << a0.a1.a3 << ")), ([" << a1.a0[0] << ", "
<< a1.a0[1] << ", " << a1.a0[2] << ", " << a1.a0[3] << "], ("
<< a1.a1.a0 << ", " << a1.a1.a1 << ", " << a1.a1.a2 << ", "
<< a1.a1.a3 << ")), ([" << a2.a0[0] << ", " << a2.a0[1] << ", "
<< a2.a0[2] << ", " << a2.a0[3] << "], (" << a2.a1.a0 << ", "
<< a2.a1.a1 << ", " << a2.a1.a2 << ", " << a2.a1.a3 << ")), (["
<< a3.a0[0] << ", " << a3.a0[1] << ", " << a3.a0[2] << ", "
<< a3.a0[3] << "], (" << a3.a1.a0 << ", " << a3.a1.a1 << ", "
<< a3.a1.a2 << ", " << a3.a1.a3 << ")), ([" << a4.a0[0] << ", "
<< a4.a0[1] << ", " << a4.a0[2] << ", " << a4.a0[3] << "], ("
<< a4.a1.a0 << ", " << a4.a1.a1 << ", " << a4.a1.a2 << ", "
<< a4.a1.a3 << ")), ([" << a5.a0[0] << ", " << a5.a0[1] << ", "
<< a5.a0[2] << ", " << a5.a0[3] << "], (" << a5.a1.a0 << ", "
<< a5.a1.a1 << ", " << a5.a1.a2 << ", " << a5.a1.a3 << ")), (["
<< a6.a0[0] << ", " << a6.a0[1] << ", " << a6.a0[2] << ", "
<< a6.a0[3] << "], (" << a6.a1.a0 << ", " << a6.a1.a1 << ", "
<< a6.a1.a2 << ", " << a6.a1.a3 << ")), ([" << a7.a0[0] << ", "
<< a7.a0[1] << ", " << a7.a0[2] << ", " << a7.a0[3] << "], ("
<< a7.a1.a0 << ", " << a7.a1.a1 << ", " << a7.a1.a2 << ", "
<< a7.a1.a3 << ")), ([" << a8.a0[0] << ", " << a8.a0[1] << ", "
<< a8.a0[2] << ", " << a8.a0[3] << "], (" << a8.a1.a0 << ", "
<< a8.a1.a1 << ", " << a8.a1.a2 << ", " << a8.a1.a3 << ")), (["
<< a9.a0[0] << ", " << a9.a0[1] << ", " << a9.a0[2] << ", "
<< a9.a0[3] << "], (" << a9.a1.a0 << ", " << a9.a1.a1 << ", "
<< a9.a1.a2 << ", " << a9.a1.a3 << ")))"
<< ")\n";
double result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_APPROX(20.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0[0] = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0[0] = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs and unions by value.
// Union with homogenous floats.
DART_EXPORT intptr_t TestPassUnion16BytesNestedFloatx10(
// NOLINTNEXTLINE(whitespace/parens)
double (*f)(Union16BytesNestedFloat a0,
Union16BytesNestedFloat a1,
Union16BytesNestedFloat a2,
Union16BytesNestedFloat a3,
Union16BytesNestedFloat a4,
Union16BytesNestedFloat a5,
Union16BytesNestedFloat a6,
Union16BytesNestedFloat a7,
Union16BytesNestedFloat a8,
Union16BytesNestedFloat a9)) {
Union16BytesNestedFloat a0;
Union16BytesNestedFloat a1;
Union16BytesNestedFloat a2;
Union16BytesNestedFloat a3;
Union16BytesNestedFloat a4;
Union16BytesNestedFloat a5;
Union16BytesNestedFloat a6;
Union16BytesNestedFloat a7;
Union16BytesNestedFloat a8;
Union16BytesNestedFloat a9;
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;
std::cout << "Calling TestPassUnion16BytesNestedFloatx10("
<< "(((" << a0.a0.a0 << ", " << a0.a0.a1 << "), (" << a0.a1.a0
<< ", " << a0.a1.a1 << ", " << a0.a1.a2 << "), (" << a0.a2.a0
<< ", " << a0.a2.a1 << ", " << a0.a2.a2 << ", " << a0.a2.a3
<< ")), ((" << a1.a0.a0 << ", " << a1.a0.a1 << "), (" << a1.a1.a0
<< ", " << a1.a1.a1 << ", " << a1.a1.a2 << "), (" << a1.a2.a0
<< ", " << a1.a2.a1 << ", " << a1.a2.a2 << ", " << a1.a2.a3
<< ")), ((" << a2.a0.a0 << ", " << a2.a0.a1 << "), (" << a2.a1.a0
<< ", " << a2.a1.a1 << ", " << a2.a1.a2 << "), (" << a2.a2.a0
<< ", " << a2.a2.a1 << ", " << a2.a2.a2 << ", " << a2.a2.a3
<< ")), ((" << a3.a0.a0 << ", " << a3.a0.a1 << "), (" << a3.a1.a0
<< ", " << a3.a1.a1 << ", " << a3.a1.a2 << "), (" << a3.a2.a0
<< ", " << a3.a2.a1 << ", " << a3.a2.a2 << ", " << a3.a2.a3
<< ")), ((" << a4.a0.a0 << ", " << a4.a0.a1 << "), (" << a4.a1.a0
<< ", " << a4.a1.a1 << ", " << a4.a1.a2 << "), (" << a4.a2.a0
<< ", " << a4.a2.a1 << ", " << a4.a2.a2 << ", " << a4.a2.a3
<< ")), ((" << a5.a0.a0 << ", " << a5.a0.a1 << "), (" << a5.a1.a0
<< ", " << a5.a1.a1 << ", " << a5.a1.a2 << "), (" << a5.a2.a0
<< ", " << a5.a2.a1 << ", " << a5.a2.a2 << ", " << a5.a2.a3
<< ")), ((" << a6.a0.a0 << ", " << a6.a0.a1 << "), (" << a6.a1.a0
<< ", " << a6.a1.a1 << ", " << a6.a1.a2 << "), (" << a6.a2.a0
<< ", " << a6.a2.a1 << ", " << a6.a2.a2 << ", " << a6.a2.a3
<< ")), ((" << a7.a0.a0 << ", " << a7.a0.a1 << "), (" << a7.a1.a0
<< ", " << a7.a1.a1 << ", " << a7.a1.a2 << "), (" << a7.a2.a0
<< ", " << a7.a2.a1 << ", " << a7.a2.a2 << ", " << a7.a2.a3
<< ")), ((" << a8.a0.a0 << ", " << a8.a0.a1 << "), (" << a8.a1.a0
<< ", " << a8.a1.a1 << ", " << a8.a1.a2 << "), (" << a8.a2.a0
<< ", " << a8.a2.a1 << ", " << a8.a2.a2 << ", " << a8.a2.a3
<< ")), ((" << a9.a0.a0 << ", " << a9.a0.a1 << "), (" << a9.a1.a0
<< ", " << a9.a1.a1 << ", " << a9.a1.a2 << "), (" << a9.a2.a0
<< ", " << a9.a2.a1 << ", " << a9.a2.a2 << ", " << a9.a2.a3 << ")))"
<< ")\n";
double result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_APPROX(10.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs and unions by value.
// Smallest struct with data.
DART_EXPORT intptr_t TestReturnStruct1ByteInt(
// NOLINTNEXTLINE(whitespace/parens)
Struct1ByteInt (*f)(int8_t a0)) {
int8_t a0;
a0 = -1;
std::cout << "Calling TestReturnStruct1ByteInt("
<< "(" << static_cast<int>(a0) << ")"
<< ")\n";
Struct1ByteInt result = f(a0);
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0);
CHECK_EQ(0, result.a0);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0);
CHECK_EQ(0, result.a0);
return 0;
}
// Used for testing structs and unions by value.
// Smaller than word size return value on all architectures.
DART_EXPORT intptr_t TestReturnStruct3BytesHomogeneousUint8(
// NOLINTNEXTLINE(whitespace/parens)
Struct3BytesHomogeneousUint8 (*f)(uint8_t a0, uint8_t a1, uint8_t a2)) {
uint8_t a0;
uint8_t a1;
uint8_t a2;
a0 = 1;
a1 = 2;
a2 = 3;
std::cout << "Calling TestReturnStruct3BytesHomogeneousUint8("
<< "(" << static_cast<int>(a0) << ", " << static_cast<int>(a1)
<< ", " << static_cast<int>(a2) << ")"
<< ")\n";
Struct3BytesHomogeneousUint8 result = f(a0, a1, a2);
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ", "
<< static_cast<int>(result.a1) << ", "
<< static_cast<int>(result.a2) << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
CHECK_EQ(a1, result.a1);
CHECK_EQ(a2, result.a2);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
return 0;
}
// Used for testing structs and unions by value.
// Smaller than word size return value on all architectures.
// With alignment rules taken into account size is 4 bytes.
DART_EXPORT intptr_t TestReturnStruct3BytesInt2ByteAligned(
// NOLINTNEXTLINE(whitespace/parens)
Struct3BytesInt2ByteAligned (*f)(int16_t a0, int8_t a1)) {
int16_t a0;
int8_t a1;
a0 = -1;
a1 = 2;
std::cout << "Calling TestReturnStruct3BytesInt2ByteAligned("
<< "(" << a0 << ", " << static_cast<int>(a1) << ")"
<< ")\n";
Struct3BytesInt2ByteAligned result = f(a0, a1);
std::cout << "result = "
<< "(" << result.a0 << ", " << static_cast<int>(result.a1) << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
CHECK_EQ(a1, result.a1);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
return 0;
}
// Used for testing structs and unions by value.
// Word size return value on 32 bit architectures..
DART_EXPORT intptr_t TestReturnStruct4BytesHomogeneousInt16(
// NOLINTNEXTLINE(whitespace/parens)
Struct4BytesHomogeneousInt16 (*f)(int16_t a0, int16_t a1)) {
int16_t a0;
int16_t a1;
a0 = -1;
a1 = 2;
std::cout << "Calling TestReturnStruct4BytesHomogeneousInt16("
<< "(" << a0 << ", " << a1 << ")"
<< ")\n";
Struct4BytesHomogeneousInt16 result = f(a0, a1);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
CHECK_EQ(a1, result.a1);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
return 0;
}
// Used for testing structs and unions by value.
// Non-wordsize return value.
DART_EXPORT intptr_t TestReturnStruct7BytesHomogeneousUint8(
// NOLINTNEXTLINE(whitespace/parens)
Struct7BytesHomogeneousUint8 (*f)(uint8_t a0,
uint8_t a1,
uint8_t a2,
uint8_t a3,
uint8_t a4,
uint8_t a5,
uint8_t a6)) {
uint8_t a0;
uint8_t a1;
uint8_t a2;
uint8_t a3;
uint8_t a4;
uint8_t a5;
uint8_t a6;
a0 = 1;
a1 = 2;
a2 = 3;
a3 = 4;
a4 = 5;
a5 = 6;
a6 = 7;
std::cout << "Calling TestReturnStruct7BytesHomogeneousUint8("
<< "(" << static_cast<int>(a0) << ", " << static_cast<int>(a1)
<< ", " << static_cast<int>(a2) << ", " << static_cast<int>(a3)
<< ", " << static_cast<int>(a4) << ", " << static_cast<int>(a5)
<< ", " << static_cast<int>(a6) << ")"
<< ")\n";
Struct7BytesHomogeneousUint8 result = f(a0, a1, a2, a3, a4, a5, a6);
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ", "
<< static_cast<int>(result.a1) << ", "
<< static_cast<int>(result.a2) << ", "
<< static_cast<int>(result.a3) << ", "
<< static_cast<int>(result.a4) << ", "
<< static_cast<int>(result.a5) << ", "
<< static_cast<int>(result.a6) << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
CHECK_EQ(a1, result.a1);
CHECK_EQ(a2, result.a2);
CHECK_EQ(a3, result.a3);
CHECK_EQ(a4, result.a4);
CHECK_EQ(a5, result.a5);
CHECK_EQ(a6, result.a6);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
CHECK_EQ(0, result.a3);
CHECK_EQ(0, result.a4);
CHECK_EQ(0, result.a5);
CHECK_EQ(0, result.a6);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
CHECK_EQ(0, result.a3);
CHECK_EQ(0, result.a4);
CHECK_EQ(0, result.a5);
CHECK_EQ(0, result.a6);
return 0;
}
// Used for testing structs and unions by value.
// Non-wordsize return value.
// With alignment rules taken into account size is 8 bytes.
DART_EXPORT intptr_t TestReturnStruct7BytesInt4ByteAligned(
// NOLINTNEXTLINE(whitespace/parens)
Struct7BytesInt4ByteAligned (*f)(int32_t a0, int16_t a1, int8_t a2)) {
int32_t a0;
int16_t a1;
int8_t a2;
a0 = -1;
a1 = 2;
a2 = -3;
std::cout << "Calling TestReturnStruct7BytesInt4ByteAligned("
<< "(" << a0 << ", " << a1 << ", " << static_cast<int>(a2) << ")"
<< ")\n";
Struct7BytesInt4ByteAligned result = f(a0, a1, a2);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", "
<< static_cast<int>(result.a2) << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
CHECK_EQ(a1, result.a1);
CHECK_EQ(a2, result.a2);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
return 0;
}
// Used for testing structs and unions by value.
// Return value in integer registers on many architectures.
DART_EXPORT intptr_t TestReturnStruct8BytesInt(
// NOLINTNEXTLINE(whitespace/parens)
Struct8BytesInt (*f)(int16_t a0, int16_t a1, int32_t a2)) {
int16_t a0;
int16_t a1;
int32_t a2;
a0 = -1;
a1 = 2;
a2 = -3;
std::cout << "Calling TestReturnStruct8BytesInt("
<< "(" << a0 << ", " << a1 << ", " << a2 << ")"
<< ")\n";
Struct8BytesInt result = f(a0, a1, a2);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2 << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
CHECK_EQ(a1, result.a1);
CHECK_EQ(a2, result.a2);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
return 0;
}
// Used for testing structs and unions by value.
// Return value in FP registers on many architectures.
DART_EXPORT intptr_t TestReturnStruct8BytesHomogeneousFloat(
// NOLINTNEXTLINE(whitespace/parens)
Struct8BytesHomogeneousFloat (*f)(float a0, float a1)) {
float a0;
float a1;
a0 = -1.0;
a1 = 2.0;
std::cout << "Calling TestReturnStruct8BytesHomogeneousFloat("
<< "(" << a0 << ", " << a1 << ")"
<< ")\n";
Struct8BytesHomogeneousFloat result = f(a0, a1);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ")"
<< "\n";
CHECK_APPROX(a0, result.a0);
CHECK_APPROX(a1, result.a1);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1);
CHECK_APPROX(0.0, result.a0);
CHECK_APPROX(0.0, result.a1);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1);
CHECK_APPROX(0.0, result.a0);
CHECK_APPROX(0.0, result.a1);
return 0;
}
// Used for testing structs and unions by value.
// Return value split over FP and integer register in x64.
DART_EXPORT intptr_t TestReturnStruct8BytesMixed(
// NOLINTNEXTLINE(whitespace/parens)
Struct8BytesMixed (*f)(float a0, int16_t a1, int16_t a2)) {
float a0;
int16_t a1;
int16_t a2;
a0 = -1.0;
a1 = 2;
a2 = -3;
std::cout << "Calling TestReturnStruct8BytesMixed("
<< "(" << a0 << ", " << a1 << ", " << a2 << ")"
<< ")\n";
Struct8BytesMixed result = f(a0, a1, a2);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2 << ")"
<< "\n";
CHECK_APPROX(a0, result.a0);
CHECK_EQ(a1, result.a1);
CHECK_EQ(a2, result.a2);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2);
CHECK_APPROX(0.0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2);
CHECK_APPROX(0.0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
return 0;
}
// Used for testing structs and unions by value.
// 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.
DART_EXPORT intptr_t TestReturnStruct9BytesHomogeneousUint8(
// NOLINTNEXTLINE(whitespace/parens)
Struct9BytesHomogeneousUint8 (*f)(uint8_t a0,
uint8_t a1,
uint8_t a2,
uint8_t a3,
uint8_t a4,
uint8_t a5,
uint8_t a6,
uint8_t a7,
uint8_t a8)) {
uint8_t a0;
uint8_t a1;
uint8_t a2;
uint8_t a3;
uint8_t a4;
uint8_t a5;
uint8_t a6;
uint8_t a7;
uint8_t a8;
a0 = 1;
a1 = 2;
a2 = 3;
a3 = 4;
a4 = 5;
a5 = 6;
a6 = 7;
a7 = 8;
a8 = 9;
std::cout << "Calling TestReturnStruct9BytesHomogeneousUint8("
<< "(" << static_cast<int>(a0) << ", " << static_cast<int>(a1)
<< ", " << static_cast<int>(a2) << ", " << static_cast<int>(a3)
<< ", " << static_cast<int>(a4) << ", " << static_cast<int>(a5)
<< ", " << static_cast<int>(a6) << ", " << static_cast<int>(a7)
<< ", " << static_cast<int>(a8) << ")"
<< ")\n";
Struct9BytesHomogeneousUint8 result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ", "
<< static_cast<int>(result.a1) << ", "
<< static_cast<int>(result.a2) << ", "
<< static_cast<int>(result.a3) << ", "
<< static_cast<int>(result.a4) << ", "
<< static_cast<int>(result.a5) << ", "
<< static_cast<int>(result.a6) << ", "
<< static_cast<int>(result.a7) << ", "
<< static_cast<int>(result.a8) << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
CHECK_EQ(a1, result.a1);
CHECK_EQ(a2, result.a2);
CHECK_EQ(a3, result.a3);
CHECK_EQ(a4, result.a4);
CHECK_EQ(a5, result.a5);
CHECK_EQ(a6, result.a6);
CHECK_EQ(a7, result.a7);
CHECK_EQ(a8, result.a8);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
CHECK_EQ(0, result.a3);
CHECK_EQ(0, result.a4);
CHECK_EQ(0, result.a5);
CHECK_EQ(0, result.a6);
CHECK_EQ(0, result.a7);
CHECK_EQ(0, result.a8);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
CHECK_EQ(0, result.a3);
CHECK_EQ(0, result.a4);
CHECK_EQ(0, result.a5);
CHECK_EQ(0, result.a6);
CHECK_EQ(0, result.a7);
CHECK_EQ(0, result.a8);
return 0;
}
// Used for testing structs and unions by value.
// Return value in two integer registers on x64.
// With alignment rules taken into account size is 12 or 16 bytes.
DART_EXPORT intptr_t TestReturnStruct9BytesInt4Or8ByteAligned(
// NOLINTNEXTLINE(whitespace/parens)
Struct9BytesInt4Or8ByteAligned (*f)(int64_t a0, int8_t a1)) {
int64_t a0;
int8_t a1;
a0 = -1;
a1 = 2;
std::cout << "Calling TestReturnStruct9BytesInt4Or8ByteAligned("
<< "(" << a0 << ", " << static_cast<int>(a1) << ")"
<< ")\n";
Struct9BytesInt4Or8ByteAligned result = f(a0, a1);
std::cout << "result = "
<< "(" << result.a0 << ", " << static_cast<int>(result.a1) << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
CHECK_EQ(a1, result.a1);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
return 0;
}
// Used for testing structs and unions by value.
// Return value in FPU registers, but does not use all registers on arm hardfp
// and arm64.
DART_EXPORT intptr_t TestReturnStruct12BytesHomogeneousFloat(
// NOLINTNEXTLINE(whitespace/parens)
Struct12BytesHomogeneousFloat (*f)(float a0, float a1, float a2)) {
float a0;
float a1;
float a2;
a0 = -1.0;
a1 = 2.0;
a2 = -3.0;
std::cout << "Calling TestReturnStruct12BytesHomogeneousFloat("
<< "(" << a0 << ", " << a1 << ", " << a2 << ")"
<< ")\n";
Struct12BytesHomogeneousFloat result = f(a0, a1, a2);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2 << ")"
<< "\n";
CHECK_APPROX(a0, result.a0);
CHECK_APPROX(a1, result.a1);
CHECK_APPROX(a2, result.a2);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2);
CHECK_APPROX(0.0, result.a0);
CHECK_APPROX(0.0, result.a1);
CHECK_APPROX(0.0, result.a2);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2);
CHECK_APPROX(0.0, result.a0);
CHECK_APPROX(0.0, result.a1);
CHECK_APPROX(0.0, result.a2);
return 0;
}
// Used for testing structs and unions by value.
// Return value in FPU registers on arm hardfp and arm64.
DART_EXPORT intptr_t TestReturnStruct16BytesHomogeneousFloat(
// NOLINTNEXTLINE(whitespace/parens)
Struct16BytesHomogeneousFloat (
*f)(float a0, float a1, float a2, float a3)) {
float a0;
float a1;
float a2;
float a3;
a0 = -1.0;
a1 = 2.0;
a2 = -3.0;
a3 = 4.0;
std::cout << "Calling TestReturnStruct16BytesHomogeneousFloat("
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ")"
<< ")\n";
Struct16BytesHomogeneousFloat result = f(a0, a1, a2, a3);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ")"
<< "\n";
CHECK_APPROX(a0, result.a0);
CHECK_APPROX(a1, result.a1);
CHECK_APPROX(a2, result.a2);
CHECK_APPROX(a3, result.a3);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3);
CHECK_APPROX(0.0, result.a0);
CHECK_APPROX(0.0, result.a1);
CHECK_APPROX(0.0, result.a2);
CHECK_APPROX(0.0, result.a3);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3);
CHECK_APPROX(0.0, result.a0);
CHECK_APPROX(0.0, result.a1);
CHECK_APPROX(0.0, result.a2);
CHECK_APPROX(0.0, result.a3);
return 0;
}
// Used for testing structs and unions by value.
// Return value split over FP and integer register in x64.
DART_EXPORT intptr_t TestReturnStruct16BytesMixed(
// NOLINTNEXTLINE(whitespace/parens)
Struct16BytesMixed (*f)(double a0, int64_t a1)) {
double a0;
int64_t a1;
a0 = -1.0;
a1 = 2;
std::cout << "Calling TestReturnStruct16BytesMixed("
<< "(" << a0 << ", " << a1 << ")"
<< ")\n";
Struct16BytesMixed result = f(a0, a1);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ")"
<< "\n";
CHECK_APPROX(a0, result.a0);
CHECK_EQ(a1, result.a1);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1);
CHECK_APPROX(0.0, result.a0);
CHECK_EQ(0, result.a1);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1);
CHECK_APPROX(0.0, result.a0);
CHECK_EQ(0, result.a1);
return 0;
}
// Used for testing structs and unions by value.
// Return value split over FP and integer register in x64.
// The integer register contains half float half int.
DART_EXPORT intptr_t TestReturnStruct16BytesMixed2(
// NOLINTNEXTLINE(whitespace/parens)
Struct16BytesMixed2 (*f)(float a0, float a1, float a2, int32_t a3)) {
float a0;
float a1;
float a2;
int32_t a3;
a0 = -1.0;
a1 = 2.0;
a2 = -3.0;
a3 = 4;
std::cout << "Calling TestReturnStruct16BytesMixed2("
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ")"
<< ")\n";
Struct16BytesMixed2 result = f(a0, a1, a2, a3);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ")"
<< "\n";
CHECK_APPROX(a0, result.a0);
CHECK_APPROX(a1, result.a1);
CHECK_APPROX(a2, result.a2);
CHECK_EQ(a3, result.a3);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3);
CHECK_APPROX(0.0, result.a0);
CHECK_APPROX(0.0, result.a1);
CHECK_APPROX(0.0, result.a2);
CHECK_EQ(0, result.a3);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3);
CHECK_APPROX(0.0, result.a0);
CHECK_APPROX(0.0, result.a1);
CHECK_APPROX(0.0, result.a2);
CHECK_EQ(0, result.a3);
return 0;
}
// Used for testing structs and unions by value.
// 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.
DART_EXPORT intptr_t TestReturnStruct17BytesInt(
// NOLINTNEXTLINE(whitespace/parens)
Struct17BytesInt (*f)(int64_t a0, int64_t a1, int8_t a2)) {
int64_t a0;
int64_t a1;
int8_t a2;
a0 = -1;
a1 = 2;
a2 = -3;
std::cout << "Calling TestReturnStruct17BytesInt("
<< "(" << a0 << ", " << a1 << ", " << static_cast<int>(a2) << ")"
<< ")\n";
Struct17BytesInt result = f(a0, a1, a2);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", "
<< static_cast<int>(result.a2) << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
CHECK_EQ(a1, result.a1);
CHECK_EQ(a2, result.a2);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
return 0;
}
// Used for testing structs and unions by value.
// 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.
DART_EXPORT intptr_t TestReturnStruct19BytesHomogeneousUint8(
// NOLINTNEXTLINE(whitespace/parens)
Struct19BytesHomogeneousUint8 (*f)(uint8_t a0,
uint8_t a1,
uint8_t a2,
uint8_t a3,
uint8_t a4,
uint8_t a5,
uint8_t a6,
uint8_t a7,
uint8_t a8,
uint8_t a9,
uint8_t a10,
uint8_t a11,
uint8_t a12,
uint8_t a13,
uint8_t a14,
uint8_t a15,
uint8_t a16,
uint8_t a17,
uint8_t a18)) {
uint8_t a0;
uint8_t a1;
uint8_t a2;
uint8_t a3;
uint8_t a4;
uint8_t a5;
uint8_t a6;
uint8_t a7;
uint8_t a8;
uint8_t a9;
uint8_t a10;
uint8_t a11;
uint8_t a12;
uint8_t a13;
uint8_t a14;
uint8_t a15;
uint8_t a16;
uint8_t a17;
uint8_t 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;
std::cout << "Calling TestReturnStruct19BytesHomogeneousUint8("
<< "(" << static_cast<int>(a0) << ", " << static_cast<int>(a1)
<< ", " << static_cast<int>(a2) << ", " << static_cast<int>(a3)
<< ", " << static_cast<int>(a4) << ", " << static_cast<int>(a5)
<< ", " << static_cast<int>(a6) << ", " << static_cast<int>(a7)
<< ", " << static_cast<int>(a8) << ", " << static_cast<int>(a9)
<< ", " << static_cast<int>(a10) << ", " << static_cast<int>(a11)
<< ", " << static_cast<int>(a12) << ", " << static_cast<int>(a13)
<< ", " << static_cast<int>(a14) << ", " << static_cast<int>(a15)
<< ", " << static_cast<int>(a16) << ", " << static_cast<int>(a17)
<< ", " << static_cast<int>(a18) << ")"
<< ")\n";
Struct19BytesHomogeneousUint8 result =
f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15,
a16, a17, a18);
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ", "
<< static_cast<int>(result.a1) << ", "
<< static_cast<int>(result.a2) << ", "
<< static_cast<int>(result.a3) << ", "
<< static_cast<int>(result.a4) << ", "
<< static_cast<int>(result.a5) << ", "
<< static_cast<int>(result.a6) << ", "
<< static_cast<int>(result.a7) << ", "
<< static_cast<int>(result.a8) << ", "
<< static_cast<int>(result.a9) << ", "
<< static_cast<int>(result.a10) << ", "
<< static_cast<int>(result.a11) << ", "
<< static_cast<int>(result.a12) << ", "
<< static_cast<int>(result.a13) << ", "
<< static_cast<int>(result.a14) << ", "
<< static_cast<int>(result.a15) << ", "
<< static_cast<int>(result.a16) << ", "
<< static_cast<int>(result.a17) << ", "
<< static_cast<int>(result.a18) << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
CHECK_EQ(a1, result.a1);
CHECK_EQ(a2, result.a2);
CHECK_EQ(a3, result.a3);
CHECK_EQ(a4, result.a4);
CHECK_EQ(a5, result.a5);
CHECK_EQ(a6, result.a6);
CHECK_EQ(a7, result.a7);
CHECK_EQ(a8, result.a8);
CHECK_EQ(a9, result.a9);
CHECK_EQ(a10, result.a10);
CHECK_EQ(a11, result.a11);
CHECK_EQ(a12, result.a12);
CHECK_EQ(a13, result.a13);
CHECK_EQ(a14, result.a14);
CHECK_EQ(a15, result.a15);
CHECK_EQ(a16, result.a16);
CHECK_EQ(a17, result.a17);
CHECK_EQ(a18, result.a18);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14,
a15, a16, a17, a18);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
CHECK_EQ(0, result.a3);
CHECK_EQ(0, result.a4);
CHECK_EQ(0, result.a5);
CHECK_EQ(0, result.a6);
CHECK_EQ(0, result.a7);
CHECK_EQ(0, result.a8);
CHECK_EQ(0, result.a9);
CHECK_EQ(0, result.a10);
CHECK_EQ(0, result.a11);
CHECK_EQ(0, result.a12);
CHECK_EQ(0, result.a13);
CHECK_EQ(0, result.a14);
CHECK_EQ(0, result.a15);
CHECK_EQ(0, result.a16);
CHECK_EQ(0, result.a17);
CHECK_EQ(0, result.a18);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14,
a15, a16, a17, a18);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
CHECK_EQ(0, result.a3);
CHECK_EQ(0, result.a4);
CHECK_EQ(0, result.a5);
CHECK_EQ(0, result.a6);
CHECK_EQ(0, result.a7);
CHECK_EQ(0, result.a8);
CHECK_EQ(0, result.a9);
CHECK_EQ(0, result.a10);
CHECK_EQ(0, result.a11);
CHECK_EQ(0, result.a12);
CHECK_EQ(0, result.a13);
CHECK_EQ(0, result.a14);
CHECK_EQ(0, result.a15);
CHECK_EQ(0, result.a16);
CHECK_EQ(0, result.a17);
CHECK_EQ(0, result.a18);
return 0;
}
// Used for testing structs and unions by value.
// Return value too big to go in cpu registers on arm64.
DART_EXPORT intptr_t TestReturnStruct20BytesHomogeneousInt32(
// NOLINTNEXTLINE(whitespace/parens)
Struct20BytesHomogeneousInt32 (
*f)(int32_t a0, int32_t a1, int32_t a2, int32_t a3, int32_t a4)) {
int32_t a0;
int32_t a1;
int32_t a2;
int32_t a3;
int32_t a4;
a0 = -1;
a1 = 2;
a2 = -3;
a3 = 4;
a4 = -5;
std::cout << "Calling TestReturnStruct20BytesHomogeneousInt32("
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
<< ")"
<< ")\n";
Struct20BytesHomogeneousInt32 result = f(a0, a1, a2, a3, a4);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ", " << result.a4 << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
CHECK_EQ(a1, result.a1);
CHECK_EQ(a2, result.a2);
CHECK_EQ(a3, result.a3);
CHECK_EQ(a4, result.a4);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3, a4);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
CHECK_EQ(0, result.a3);
CHECK_EQ(0, result.a4);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3, a4);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
CHECK_EQ(0, result.a3);
CHECK_EQ(0, result.a4);
return 0;
}
// Used for testing structs and unions by value.
// Return value too big to go in FPU registers on x64, arm hardfp and arm64.
DART_EXPORT intptr_t TestReturnStruct20BytesHomogeneousFloat(
// NOLINTNEXTLINE(whitespace/parens)
Struct20BytesHomogeneousFloat (
*f)(float a0, float a1, float a2, float a3, float a4)) {
float a0;
float a1;
float a2;
float a3;
float a4;
a0 = -1.0;
a1 = 2.0;
a2 = -3.0;
a3 = 4.0;
a4 = -5.0;
std::cout << "Calling TestReturnStruct20BytesHomogeneousFloat("
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
<< ")"
<< ")\n";
Struct20BytesHomogeneousFloat result = f(a0, a1, a2, a3, a4);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ", " << result.a4 << ")"
<< "\n";
CHECK_APPROX(a0, result.a0);
CHECK_APPROX(a1, result.a1);
CHECK_APPROX(a2, result.a2);
CHECK_APPROX(a3, result.a3);
CHECK_APPROX(a4, result.a4);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3, a4);
CHECK_APPROX(0.0, result.a0);
CHECK_APPROX(0.0, result.a1);
CHECK_APPROX(0.0, result.a2);
CHECK_APPROX(0.0, result.a3);
CHECK_APPROX(0.0, result.a4);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3, a4);
CHECK_APPROX(0.0, result.a0);
CHECK_APPROX(0.0, result.a1);
CHECK_APPROX(0.0, result.a2);
CHECK_APPROX(0.0, result.a3);
CHECK_APPROX(0.0, result.a4);
return 0;
}
// Used for testing structs and unions by value.
// Return value in FPU registers on arm64.
DART_EXPORT intptr_t TestReturnStruct32BytesHomogeneousDouble(
// NOLINTNEXTLINE(whitespace/parens)
Struct32BytesHomogeneousDouble (
*f)(double a0, double a1, double a2, double a3)) {
double a0;
double a1;
double a2;
double a3;
a0 = -1.0;
a1 = 2.0;
a2 = -3.0;
a3 = 4.0;
std::cout << "Calling TestReturnStruct32BytesHomogeneousDouble("
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ")"
<< ")\n";
Struct32BytesHomogeneousDouble result = f(a0, a1, a2, a3);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ")"
<< "\n";
CHECK_APPROX(a0, result.a0);
CHECK_APPROX(a1, result.a1);
CHECK_APPROX(a2, result.a2);
CHECK_APPROX(a3, result.a3);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3);
CHECK_APPROX(0.0, result.a0);
CHECK_APPROX(0.0, result.a1);
CHECK_APPROX(0.0, result.a2);
CHECK_APPROX(0.0, result.a3);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3);
CHECK_APPROX(0.0, result.a0);
CHECK_APPROX(0.0, result.a1);
CHECK_APPROX(0.0, result.a2);
CHECK_APPROX(0.0, result.a3);
return 0;
}
// Used for testing structs and unions by value.
// Return value too big to go in FPU registers on arm64.
DART_EXPORT intptr_t TestReturnStruct40BytesHomogeneousDouble(
// NOLINTNEXTLINE(whitespace/parens)
Struct40BytesHomogeneousDouble (
*f)(double a0, double a1, double a2, double a3, double a4)) {
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;
std::cout << "Calling TestReturnStruct40BytesHomogeneousDouble("
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
<< ")"
<< ")\n";
Struct40BytesHomogeneousDouble result = f(a0, a1, a2, a3, a4);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ", " << result.a4 << ")"
<< "\n";
CHECK_APPROX(a0, result.a0);
CHECK_APPROX(a1, result.a1);
CHECK_APPROX(a2, result.a2);
CHECK_APPROX(a3, result.a3);
CHECK_APPROX(a4, result.a4);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3, a4);
CHECK_APPROX(0.0, result.a0);
CHECK_APPROX(0.0, result.a1);
CHECK_APPROX(0.0, result.a2);
CHECK_APPROX(0.0, result.a3);
CHECK_APPROX(0.0, result.a4);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3, a4);
CHECK_APPROX(0.0, result.a0);
CHECK_APPROX(0.0, result.a1);
CHECK_APPROX(0.0, result.a2);
CHECK_APPROX(0.0, result.a3);
CHECK_APPROX(0.0, result.a4);
return 0;
}
// Used for testing structs and unions by value.
// Test 1kb struct.
DART_EXPORT intptr_t TestReturnStruct1024BytesHomogeneousUint64(
// NOLINTNEXTLINE(whitespace/parens)
Struct1024BytesHomogeneousUint64 (*f)(uint64_t a0,
uint64_t a1,
uint64_t a2,
uint64_t a3,
uint64_t a4,
uint64_t a5,
uint64_t a6,
uint64_t a7,
uint64_t a8,
uint64_t a9,
uint64_t a10,
uint64_t a11,
uint64_t a12,
uint64_t a13,
uint64_t a14,
uint64_t a15,
uint64_t a16,
uint64_t a17,
uint64_t a18,
uint64_t a19,
uint64_t a20,
uint64_t a21,
uint64_t a22,
uint64_t a23,
uint64_t a24,
uint64_t a25,
uint64_t a26,
uint64_t a27,
uint64_t a28,
uint64_t a29,
uint64_t a30,
uint64_t a31,
uint64_t a32,
uint64_t a33,
uint64_t a34,
uint64_t a35,
uint64_t a36,
uint64_t a37,
uint64_t a38,
uint64_t a39,
uint64_t a40,
uint64_t a41,
uint64_t a42,
uint64_t a43,
uint64_t a44,
uint64_t a45,
uint64_t a46,
uint64_t a47,
uint64_t a48,
uint64_t a49,
uint64_t a50,
uint64_t a51,
uint64_t a52,
uint64_t a53,
uint64_t a54,
uint64_t a55,
uint64_t a56,
uint64_t a57,
uint64_t a58,
uint64_t a59,
uint64_t a60,
uint64_t a61,
uint64_t a62,
uint64_t a63,
uint64_t a64,
uint64_t a65,
uint64_t a66,
uint64_t a67,
uint64_t a68,
uint64_t a69,
uint64_t a70,
uint64_t a71,
uint64_t a72,
uint64_t a73,
uint64_t a74,
uint64_t a75,
uint64_t a76,
uint64_t a77,
uint64_t a78,
uint64_t a79,
uint64_t a80,
uint64_t a81,
uint64_t a82,
uint64_t a83,
uint64_t a84,
uint64_t a85,
uint64_t a86,
uint64_t a87,
uint64_t a88,
uint64_t a89,
uint64_t a90,
uint64_t a91,
uint64_t a92,
uint64_t a93,
uint64_t a94,
uint64_t a95,
uint64_t a96,
uint64_t a97,
uint64_t a98,
uint64_t a99,
uint64_t a100,
uint64_t a101,
uint64_t a102,
uint64_t a103,
uint64_t a104,
uint64_t a105,
uint64_t a106,
uint64_t a107,
uint64_t a108,
uint64_t a109,
uint64_t a110,
uint64_t a111,
uint64_t a112,
uint64_t a113,
uint64_t a114,
uint64_t a115,
uint64_t a116,
uint64_t a117,
uint64_t a118,
uint64_t a119,
uint64_t a120,
uint64_t a121,
uint64_t a122,
uint64_t a123,
uint64_t a124,
uint64_t a125,
uint64_t a126,
uint64_t a127)) {
uint64_t a0;
uint64_t a1;
uint64_t a2;
uint64_t a3;
uint64_t a4;
uint64_t a5;
uint64_t a6;
uint64_t a7;
uint64_t a8;
uint64_t a9;
uint64_t a10;
uint64_t a11;
uint64_t a12;
uint64_t a13;
uint64_t a14;
uint64_t a15;
uint64_t a16;
uint64_t a17;
uint64_t a18;
uint64_t a19;
uint64_t a20;
uint64_t a21;
uint64_t a22;
uint64_t a23;
uint64_t a24;
uint64_t a25;
uint64_t a26;
uint64_t a27;
uint64_t a28;
uint64_t a29;
uint64_t a30;
uint64_t a31;
uint64_t a32;
uint64_t a33;
uint64_t a34;
uint64_t a35;
uint64_t a36;
uint64_t a37;
uint64_t a38;
uint64_t a39;
uint64_t a40;
uint64_t a41;
uint64_t a42;
uint64_t a43;
uint64_t a44;
uint64_t a45;
uint64_t a46;
uint64_t a47;
uint64_t a48;
uint64_t a49;
uint64_t a50;
uint64_t a51;
uint64_t a52;
uint64_t a53;
uint64_t a54;
uint64_t a55;
uint64_t a56;
uint64_t a57;
uint64_t a58;
uint64_t a59;
uint64_t a60;
uint64_t a61;
uint64_t a62;
uint64_t a63;
uint64_t a64;
uint64_t a65;
uint64_t a66;
uint64_t a67;
uint64_t a68;
uint64_t a69;
uint64_t a70;
uint64_t a71;
uint64_t a72;
uint64_t a73;
uint64_t a74;
uint64_t a75;
uint64_t a76;
uint64_t a77;
uint64_t a78;
uint64_t a79;
uint64_t a80;
uint64_t a81;
uint64_t a82;
uint64_t a83;
uint64_t a84;
uint64_t a85;
uint64_t a86;
uint64_t a87;
uint64_t a88;
uint64_t a89;
uint64_t a90;
uint64_t a91;
uint64_t a92;
uint64_t a93;
uint64_t a94;
uint64_t a95;
uint64_t a96;
uint64_t a97;
uint64_t a98;
uint64_t a99;
uint64_t a100;
uint64_t a101;
uint64_t a102;
uint64_t a103;
uint64_t a104;
uint64_t a105;
uint64_t a106;
uint64_t a107;
uint64_t a108;
uint64_t a109;
uint64_t a110;
uint64_t a111;
uint64_t a112;
uint64_t a113;
uint64_t a114;
uint64_t a115;
uint64_t a116;
uint64_t a117;
uint64_t a118;
uint64_t a119;
uint64_t a120;
uint64_t a121;
uint64_t a122;
uint64_t a123;
uint64_t a124;
uint64_t a125;
uint64_t a126;
uint64_t 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;
std::cout << "Calling TestReturnStruct1024BytesHomogeneousUint64("
<< "(" << 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 << ")"
<< ")\n";
Struct1024BytesHomogeneousUint64 result = f(
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);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ", " << result.a4 << ", " << result.a5
<< ", " << result.a6 << ", " << result.a7 << ", " << result.a8
<< ", " << result.a9 << ", " << result.a10 << ", " << result.a11
<< ", " << result.a12 << ", " << result.a13 << ", " << result.a14
<< ", " << result.a15 << ", " << result.a16 << ", " << result.a17
<< ", " << result.a18 << ", " << result.a19 << ", " << result.a20
<< ", " << result.a21 << ", " << result.a22 << ", " << result.a23
<< ", " << result.a24 << ", " << result.a25 << ", " << result.a26
<< ", " << result.a27 << ", " << result.a28 << ", " << result.a29
<< ", " << result.a30 << ", " << result.a31 << ", " << result.a32
<< ", " << result.a33 << ", " << result.a34 << ", " << result.a35
<< ", " << result.a36 << ", " << result.a37 << ", " << result.a38
<< ", " << result.a39 << ", " << result.a40 << ", " << result.a41
<< ", " << result.a42 << ", " << result.a43 << ", " << result.a44
<< ", " << result.a45 << ", " << result.a46 << ", " << result.a47
<< ", " << result.a48 << ", " << result.a49 << ", " << result.a50
<< ", " << result.a51 << ", " << result.a52 << ", " << result.a53
<< ", " << result.a54 << ", " << result.a55 << ", " << result.a56
<< ", " << result.a57 << ", " << result.a58 << ", " << result.a59
<< ", " << result.a60 << ", " << result.a61 << ", " << result.a62
<< ", " << result.a63 << ", " << result.a64 << ", " << result.a65
<< ", " << result.a66 << ", " << result.a67 << ", " << result.a68
<< ", " << result.a69 << ", " << result.a70 << ", " << result.a71
<< ", " << result.a72 << ", " << result.a73 << ", " << result.a74
<< ", " << result.a75 << ", " << result.a76 << ", " << result.a77
<< ", " << result.a78 << ", " << result.a79 << ", " << result.a80
<< ", " << result.a81 << ", " << result.a82 << ", " << result.a83
<< ", " << result.a84 << ", " << result.a85 << ", " << result.a86
<< ", " << result.a87 << ", " << result.a88 << ", " << result.a89
<< ", " << result.a90 << ", " << result.a91 << ", " << result.a92
<< ", " << result.a93 << ", " << result.a94 << ", " << result.a95
<< ", " << result.a96 << ", " << result.a97 << ", " << result.a98
<< ", " << result.a99 << ", " << result.a100 << ", " << result.a101
<< ", " << result.a102 << ", " << result.a103 << ", " << result.a104
<< ", " << result.a105 << ", " << result.a106 << ", " << result.a107
<< ", " << result.a108 << ", " << result.a109 << ", " << result.a110
<< ", " << result.a111 << ", " << result.a112 << ", " << result.a113
<< ", " << result.a114 << ", " << result.a115 << ", " << result.a116
<< ", " << result.a117 << ", " << result.a118 << ", " << result.a119
<< ", " << result.a120 << ", " << result.a121 << ", " << result.a122
<< ", " << result.a123 << ", " << result.a124 << ", " << result.a125
<< ", " << result.a126 << ", " << result.a127 << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
CHECK_EQ(a1, result.a1);
CHECK_EQ(a2, result.a2);
CHECK_EQ(a3, result.a3);
CHECK_EQ(a4, result.a4);
CHECK_EQ(a5, result.a5);
CHECK_EQ(a6, result.a6);
CHECK_EQ(a7, result.a7);
CHECK_EQ(a8, result.a8);
CHECK_EQ(a9, result.a9);
CHECK_EQ(a10, result.a10);
CHECK_EQ(a11, result.a11);
CHECK_EQ(a12, result.a12);
CHECK_EQ(a13, result.a13);
CHECK_EQ(a14, result.a14);
CHECK_EQ(a15, result.a15);
CHECK_EQ(a16, result.a16);
CHECK_EQ(a17, result.a17);
CHECK_EQ(a18, result.a18);
CHECK_EQ(a19, result.a19);
CHECK_EQ(a20, result.a20);
CHECK_EQ(a21, result.a21);
CHECK_EQ(a22, result.a22);
CHECK_EQ(a23, result.a23);
CHECK_EQ(a24, result.a24);
CHECK_EQ(a25, result.a25);
CHECK_EQ(a26, result.a26);
CHECK_EQ(a27, result.a27);
CHECK_EQ(a28, result.a28);
CHECK_EQ(a29, result.a29);
CHECK_EQ(a30, result.a30);
CHECK_EQ(a31, result.a31);
CHECK_EQ(a32, result.a32);
CHECK_EQ(a33, result.a33);
CHECK_EQ(a34, result.a34);
CHECK_EQ(a35, result.a35);
CHECK_EQ(a36, result.a36);
CHECK_EQ(a37, result.a37);
CHECK_EQ(a38, result.a38);
CHECK_EQ(a39, result.a39);
CHECK_EQ(a40, result.a40);
CHECK_EQ(a41, result.a41);
CHECK_EQ(a42, result.a42);
CHECK_EQ(a43, result.a43);
CHECK_EQ(a44, result.a44);
CHECK_EQ(a45, result.a45);
CHECK_EQ(a46, result.a46);
CHECK_EQ(a47, result.a47);
CHECK_EQ(a48, result.a48);
CHECK_EQ(a49, result.a49);
CHECK_EQ(a50, result.a50);
CHECK_EQ(a51, result.a51);
CHECK_EQ(a52, result.a52);
CHECK_EQ(a53, result.a53);
CHECK_EQ(a54, result.a54);
CHECK_EQ(a55, result.a55);
CHECK_EQ(a56, result.a56);
CHECK_EQ(a57, result.a57);
CHECK_EQ(a58, result.a58);
CHECK_EQ(a59, result.a59);
CHECK_EQ(a60, result.a60);
CHECK_EQ(a61, result.a61);
CHECK_EQ(a62, result.a62);
CHECK_EQ(a63, result.a63);
CHECK_EQ(a64, result.a64);
CHECK_EQ(a65, result.a65);
CHECK_EQ(a66, result.a66);
CHECK_EQ(a67, result.a67);
CHECK_EQ(a68, result.a68);
CHECK_EQ(a69, result.a69);
CHECK_EQ(a70, result.a70);
CHECK_EQ(a71, result.a71);
CHECK_EQ(a72, result.a72);
CHECK_EQ(a73, result.a73);
CHECK_EQ(a74, result.a74);
CHECK_EQ(a75, result.a75);
CHECK_EQ(a76, result.a76);
CHECK_EQ(a77, result.a77);
CHECK_EQ(a78, result.a78);
CHECK_EQ(a79, result.a79);
CHECK_EQ(a80, result.a80);
CHECK_EQ(a81, result.a81);
CHECK_EQ(a82, result.a82);
CHECK_EQ(a83, result.a83);
CHECK_EQ(a84, result.a84);
CHECK_EQ(a85, result.a85);
CHECK_EQ(a86, result.a86);
CHECK_EQ(a87, result.a87);
CHECK_EQ(a88, result.a88);
CHECK_EQ(a89, result.a89);
CHECK_EQ(a90, result.a90);
CHECK_EQ(a91, result.a91);
CHECK_EQ(a92, result.a92);
CHECK_EQ(a93, result.a93);
CHECK_EQ(a94, result.a94);
CHECK_EQ(a95, result.a95);
CHECK_EQ(a96, result.a96);
CHECK_EQ(a97, result.a97);
CHECK_EQ(a98, result.a98);
CHECK_EQ(a99, result.a99);
CHECK_EQ(a100, result.a100);
CHECK_EQ(a101, result.a101);
CHECK_EQ(a102, result.a102);
CHECK_EQ(a103, result.a103);
CHECK_EQ(a104, result.a104);
CHECK_EQ(a105, result.a105);
CHECK_EQ(a106, result.a106);
CHECK_EQ(a107, result.a107);
CHECK_EQ(a108, result.a108);
CHECK_EQ(a109, result.a109);
CHECK_EQ(a110, result.a110);
CHECK_EQ(a111, result.a111);
CHECK_EQ(a112, result.a112);
CHECK_EQ(a113, result.a113);
CHECK_EQ(a114, result.a114);
CHECK_EQ(a115, result.a115);
CHECK_EQ(a116, result.a116);
CHECK_EQ(a117, result.a117);
CHECK_EQ(a118, result.a118);
CHECK_EQ(a119, result.a119);
CHECK_EQ(a120, result.a120);
CHECK_EQ(a121, result.a121);
CHECK_EQ(a122, result.a122);
CHECK_EQ(a123, result.a123);
CHECK_EQ(a124, result.a124);
CHECK_EQ(a125, result.a125);
CHECK_EQ(a126, result.a126);
CHECK_EQ(a127, result.a127);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(
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);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
CHECK_EQ(0, result.a3);
CHECK_EQ(0, result.a4);
CHECK_EQ(0, result.a5);
CHECK_EQ(0, result.a6);
CHECK_EQ(0, result.a7);
CHECK_EQ(0, result.a8);
CHECK_EQ(0, result.a9);
CHECK_EQ(0, result.a10);
CHECK_EQ(0, result.a11);
CHECK_EQ(0, result.a12);
CHECK_EQ(0, result.a13);
CHECK_EQ(0, result.a14);
CHECK_EQ(0, result.a15);
CHECK_EQ(0, result.a16);
CHECK_EQ(0, result.a17);
CHECK_EQ(0, result.a18);
CHECK_EQ(0, result.a19);
CHECK_EQ(0, result.a20);
CHECK_EQ(0, result.a21);
CHECK_EQ(0, result.a22);
CHECK_EQ(0, result.a23);
CHECK_EQ(0, result.a24);
CHECK_EQ(0, result.a25);
CHECK_EQ(0, result.a26);
CHECK_EQ(0, result.a27);
CHECK_EQ(0, result.a28);
CHECK_EQ(0, result.a29);
CHECK_EQ(0, result.a30);
CHECK_EQ(0, result.a31);
CHECK_EQ(0, result.a32);
CHECK_EQ(0, result.a33);
CHECK_EQ(0, result.a34);
CHECK_EQ(0, result.a35);
CHECK_EQ(0, result.a36);
CHECK_EQ(0, result.a37);
CHECK_EQ(0, result.a38);
CHECK_EQ(0, result.a39);
CHECK_EQ(0, result.a40);
CHECK_EQ(0, result.a41);
CHECK_EQ(0, result.a42);
CHECK_EQ(0, result.a43);
CHECK_EQ(0, result.a44);
CHECK_EQ(0, result.a45);
CHECK_EQ(0, result.a46);
CHECK_EQ(0, result.a47);
CHECK_EQ(0, result.a48);
CHECK_EQ(0, result.a49);
CHECK_EQ(0, result.a50);
CHECK_EQ(0, result.a51);
CHECK_EQ(0, result.a52);
CHECK_EQ(0, result.a53);
CHECK_EQ(0, result.a54);
CHECK_EQ(0, result.a55);
CHECK_EQ(0, result.a56);
CHECK_EQ(0, result.a57);
CHECK_EQ(0, result.a58);
CHECK_EQ(0, result.a59);
CHECK_EQ(0, result.a60);
CHECK_EQ(0, result.a61);
CHECK_EQ(0, result.a62);
CHECK_EQ(0, result.a63);
CHECK_EQ(0, result.a64);
CHECK_EQ(0, result.a65);
CHECK_EQ(0, result.a66);
CHECK_EQ(0, result.a67);
CHECK_EQ(0, result.a68);
CHECK_EQ(0, result.a69);
CHECK_EQ(0, result.a70);
CHECK_EQ(0, result.a71);
CHECK_EQ(0, result.a72);
CHECK_EQ(0, result.a73);
CHECK_EQ(0, result.a74);
CHECK_EQ(0, result.a75);
CHECK_EQ(0, result.a76);
CHECK_EQ(0, result.a77);
CHECK_EQ(0, result.a78);
CHECK_EQ(0, result.a79);
CHECK_EQ(0, result.a80);
CHECK_EQ(0, result.a81);
CHECK_EQ(0, result.a82);
CHECK_EQ(0, result.a83);
CHECK_EQ(0, result.a84);
CHECK_EQ(0, result.a85);
CHECK_EQ(0, result.a86);
CHECK_EQ(0, result.a87);
CHECK_EQ(0, result.a88);
CHECK_EQ(0, result.a89);
CHECK_EQ(0, result.a90);
CHECK_EQ(0, result.a91);
CHECK_EQ(0, result.a92);
CHECK_EQ(0, result.a93);
CHECK_EQ(0, result.a94);
CHECK_EQ(0, result.a95);
CHECK_EQ(0, result.a96);
CHECK_EQ(0, result.a97);
CHECK_EQ(0, result.a98);
CHECK_EQ(0, result.a99);
CHECK_EQ(0, result.a100);
CHECK_EQ(0, result.a101);
CHECK_EQ(0, result.a102);
CHECK_EQ(0, result.a103);
CHECK_EQ(0, result.a104);
CHECK_EQ(0, result.a105);
CHECK_EQ(0, result.a106);
CHECK_EQ(0, result.a107);
CHECK_EQ(0, result.a108);
CHECK_EQ(0, result.a109);
CHECK_EQ(0, result.a110);
CHECK_EQ(0, result.a111);
CHECK_EQ(0, result.a112);
CHECK_EQ(0, result.a113);
CHECK_EQ(0, result.a114);
CHECK_EQ(0, result.a115);
CHECK_EQ(0, result.a116);
CHECK_EQ(0, result.a117);
CHECK_EQ(0, result.a118);
CHECK_EQ(0, result.a119);
CHECK_EQ(0, result.a120);
CHECK_EQ(0, result.a121);
CHECK_EQ(0, result.a122);
CHECK_EQ(0, result.a123);
CHECK_EQ(0, result.a124);
CHECK_EQ(0, result.a125);
CHECK_EQ(0, result.a126);
CHECK_EQ(0, result.a127);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(
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);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
CHECK_EQ(0, result.a3);
CHECK_EQ(0, result.a4);
CHECK_EQ(0, result.a5);
CHECK_EQ(0, result.a6);
CHECK_EQ(0, result.a7);
CHECK_EQ(0, result.a8);
CHECK_EQ(0, result.a9);
CHECK_EQ(0, result.a10);
CHECK_EQ(0, result.a11);
CHECK_EQ(0, result.a12);
CHECK_EQ(0, result.a13);
CHECK_EQ(0, result.a14);
CHECK_EQ(0, result.a15);
CHECK_EQ(0, result.a16);
CHECK_EQ(0, result.a17);
CHECK_EQ(0, result.a18);
CHECK_EQ(0, result.a19);
CHECK_EQ(0, result.a20);
CHECK_EQ(0, result.a21);
CHECK_EQ(0, result.a22);
CHECK_EQ(0, result.a23);
CHECK_EQ(0, result.a24);
CHECK_EQ(0, result.a25);
CHECK_EQ(0, result.a26);
CHECK_EQ(0, result.a27);
CHECK_EQ(0, result.a28);
CHECK_EQ(0, result.a29);
CHECK_EQ(0, result.a30);
CHECK_EQ(0, result.a31);
CHECK_EQ(0, result.a32);
CHECK_EQ(0, result.a33);
CHECK_EQ(0, result.a34);
CHECK_EQ(0, result.a35);
CHECK_EQ(0, result.a36);
CHECK_EQ(0, result.a37);
CHECK_EQ(0, result.a38);
CHECK_EQ(0, result.a39);
CHECK_EQ(0, result.a40);
CHECK_EQ(0, result.a41);
CHECK_EQ(0, result.a42);
CHECK_EQ(0, result.a43);
CHECK_EQ(0, result.a44);
CHECK_EQ(0, result.a45);
CHECK_EQ(0, result.a46);
CHECK_EQ(0, result.a47);
CHECK_EQ(0, result.a48);
CHECK_EQ(0, result.a49);
CHECK_EQ(0, result.a50);
CHECK_EQ(0, result.a51);
CHECK_EQ(0, result.a52);
CHECK_EQ(0, result.a53);
CHECK_EQ(0, result.a54);
CHECK_EQ(0, result.a55);
CHECK_EQ(0, result.a56);
CHECK_EQ(0, result.a57);
CHECK_EQ(0, result.a58);
CHECK_EQ(0, result.a59);
CHECK_EQ(0, result.a60);
CHECK_EQ(0, result.a61);
CHECK_EQ(0, result.a62);
CHECK_EQ(0, result.a63);
CHECK_EQ(0, result.a64);
CHECK_EQ(0, result.a65);
CHECK_EQ(0, result.a66);
CHECK_EQ(0, result.a67);
CHECK_EQ(0, result.a68);
CHECK_EQ(0, result.a69);
CHECK_EQ(0, result.a70);
CHECK_EQ(0, result.a71);
CHECK_EQ(0, result.a72);
CHECK_EQ(0, result.a73);
CHECK_EQ(0, result.a74);
CHECK_EQ(0, result.a75);
CHECK_EQ(0, result.a76);
CHECK_EQ(0, result.a77);
CHECK_EQ(0, result.a78);
CHECK_EQ(0, result.a79);
CHECK_EQ(0, result.a80);
CHECK_EQ(0, result.a81);
CHECK_EQ(0, result.a82);
CHECK_EQ(0, result.a83);
CHECK_EQ(0, result.a84);
CHECK_EQ(0, result.a85);
CHECK_EQ(0, result.a86);
CHECK_EQ(0, result.a87);
CHECK_EQ(0, result.a88);
CHECK_EQ(0, result.a89);
CHECK_EQ(0, result.a90);
CHECK_EQ(0, result.a91);
CHECK_EQ(0, result.a92);
CHECK_EQ(0, result.a93);
CHECK_EQ(0, result.a94);
CHECK_EQ(0, result.a95);
CHECK_EQ(0, result.a96);
CHECK_EQ(0, result.a97);
CHECK_EQ(0, result.a98);
CHECK_EQ(0, result.a99);
CHECK_EQ(0, result.a100);
CHECK_EQ(0, result.a101);
CHECK_EQ(0, result.a102);
CHECK_EQ(0, result.a103);
CHECK_EQ(0, result.a104);
CHECK_EQ(0, result.a105);
CHECK_EQ(0, result.a106);
CHECK_EQ(0, result.a107);
CHECK_EQ(0, result.a108);
CHECK_EQ(0, result.a109);
CHECK_EQ(0, result.a110);
CHECK_EQ(0, result.a111);
CHECK_EQ(0, result.a112);
CHECK_EQ(0, result.a113);
CHECK_EQ(0, result.a114);
CHECK_EQ(0, result.a115);
CHECK_EQ(0, result.a116);
CHECK_EQ(0, result.a117);
CHECK_EQ(0, result.a118);
CHECK_EQ(0, result.a119);
CHECK_EQ(0, result.a120);
CHECK_EQ(0, result.a121);
CHECK_EQ(0, result.a122);
CHECK_EQ(0, result.a123);
CHECK_EQ(0, result.a124);
CHECK_EQ(0, result.a125);
CHECK_EQ(0, result.a126);
CHECK_EQ(0, result.a127);
return 0;
}
// Used for testing structs and unions by value.
// Small struct with mis-aligned member.
DART_EXPORT intptr_t TestReturnStruct3BytesPackedInt(
// NOLINTNEXTLINE(whitespace/parens)
Struct3BytesPackedInt (*f)(int8_t a0, int16_t a1)) {
int8_t a0;
int16_t a1;
a0 = -1;
a1 = 2;
std::cout << "Calling TestReturnStruct3BytesPackedInt("
<< "(" << static_cast<int>(a0) << ", " << a1 << ")"
<< ")\n";
Struct3BytesPackedInt result = f(a0, a1);
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ", " << result.a1 << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
CHECK_EQ(a1, result.a1);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
return 0;
}
// Used for testing structs and unions by value.
// Struct with mis-aligned member.
DART_EXPORT intptr_t TestReturnStruct8BytesPackedInt(
// NOLINTNEXTLINE(whitespace/parens)
Struct8BytesPackedInt (
*f)(uint8_t a0, uint32_t a1, uint8_t a2, uint8_t a3, uint8_t a4)) {
uint8_t a0;
uint32_t a1;
uint8_t a2;
uint8_t a3;
uint8_t a4;
a0 = 1;
a1 = 2;
a2 = 3;
a3 = 4;
a4 = 5;
std::cout << "Calling TestReturnStruct8BytesPackedInt("
<< "(" << static_cast<int>(a0) << ", " << a1 << ", "
<< static_cast<int>(a2) << ", " << static_cast<int>(a3) << ", "
<< static_cast<int>(a4) << ")"
<< ")\n";
Struct8BytesPackedInt result = f(a0, a1, a2, a3, a4);
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ", " << result.a1 << ", "
<< static_cast<int>(result.a2) << ", "
<< static_cast<int>(result.a3) << ", "
<< static_cast<int>(result.a4) << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
CHECK_EQ(a1, result.a1);
CHECK_EQ(a2, result.a2);
CHECK_EQ(a3, result.a3);
CHECK_EQ(a4, result.a4);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3, a4);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
CHECK_EQ(0, result.a3);
CHECK_EQ(0, result.a4);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3, a4);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
CHECK_EQ(0, result.a3);
CHECK_EQ(0, result.a4);
return 0;
}
// Used for testing structs and unions by value.
// Struct with mis-aligned member.
// Tests backfilling of CPU and FPU registers.
DART_EXPORT intptr_t TestReturnStruct9BytesPackedMixed(
// NOLINTNEXTLINE(whitespace/parens)
Struct9BytesPackedMixed (*f)(uint8_t a0, double a1)) {
uint8_t a0;
double a1;
a0 = 1;
a1 = 2.0;
std::cout << "Calling TestReturnStruct9BytesPackedMixed("
<< "(" << static_cast<int>(a0) << ", " << a1 << ")"
<< ")\n";
Struct9BytesPackedMixed result = f(a0, a1);
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ", " << result.a1 << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
CHECK_APPROX(a1, result.a1);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1);
CHECK_EQ(0, result.a0);
CHECK_APPROX(0.0, result.a1);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1);
CHECK_EQ(0, result.a0);
CHECK_APPROX(0.0, result.a1);
return 0;
}
// Used for testing structs and unions by value.
// Returning a mixed integer/float union.
DART_EXPORT intptr_t TestReturnUnion4BytesMixed(
// NOLINTNEXTLINE(whitespace/parens)
Union4BytesMixed (*f)(uint32_t a0)) {
uint32_t a0;
a0 = 1;
std::cout << "Calling TestReturnUnion4BytesMixed("
<< "(" << a0 << ")"
<< ")\n";
Union4BytesMixed result = f(a0);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0);
CHECK_EQ(0, result.a0);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0);
CHECK_EQ(0, result.a0);
return 0;
}
// Used for testing structs and unions by value.
// Returning a floating point only union.
DART_EXPORT intptr_t TestReturnUnion8BytesNestedFloat(
// NOLINTNEXTLINE(whitespace/parens)
Union8BytesNestedFloat (*f)(double a0)) {
double a0;
a0 = -1.0;
std::cout << "Calling TestReturnUnion8BytesNestedFloat("
<< "(" << a0 << ")"
<< ")\n";
Union8BytesNestedFloat result = f(a0);
std::cout << "result = "
<< "(" << result.a0 << ", (" << result.a1.a0 << ", " << result.a1.a1
<< "))"
<< "\n";
CHECK_APPROX(a0, result.a0);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0);
CHECK_APPROX(0.0, result.a0);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0);
CHECK_APPROX(0.0, result.a0);
return 0;
}
// Used for testing structs and unions by value.
// Returning a mixed-size union.
DART_EXPORT intptr_t TestReturnUnion9BytesNestedInt(
// NOLINTNEXTLINE(whitespace/parens)
Union9BytesNestedInt (*f)(Struct8BytesInt a0)) {
Struct8BytesInt a0;
a0.a0 = -1;
a0.a1 = 2;
a0.a2 = -3;
std::cout << "Calling TestReturnUnion9BytesNestedInt("
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << "))"
<< ")\n";
Union9BytesNestedInt result = f(a0);
std::cout << "result = "
<< "((" << result.a0.a0 << ", " << result.a0.a1 << ", "
<< result.a0.a2 << "), (" << static_cast<int>(result.a1.a0) << ", "
<< static_cast<int>(result.a1.a1) << ", "
<< static_cast<int>(result.a1.a2) << ", "
<< static_cast<int>(result.a1.a3) << ", "
<< static_cast<int>(result.a1.a4) << ", "
<< static_cast<int>(result.a1.a5) << ", "
<< static_cast<int>(result.a1.a6) << ", "
<< static_cast<int>(result.a1.a7) << ", "
<< static_cast<int>(result.a1.a8) << "))"
<< "\n";
CHECK_EQ(a0.a0, result.a0.a0);
CHECK_EQ(a0.a1, result.a0.a1);
CHECK_EQ(a0.a2, result.a0.a2);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0);
CHECK_EQ(0, result.a0.a0);
CHECK_EQ(0, result.a0.a1);
CHECK_EQ(0, result.a0.a2);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0);
CHECK_EQ(0, result.a0.a0);
CHECK_EQ(0, result.a0.a1);
CHECK_EQ(0, result.a0.a2);
return 0;
}
// Used for testing structs and unions by value.
// Returning union with homogenous floats.
DART_EXPORT intptr_t TestReturnUnion16BytesNestedFloat(
// NOLINTNEXTLINE(whitespace/parens)
Union16BytesNestedFloat (*f)(Struct8BytesHomogeneousFloat a0)) {
Struct8BytesHomogeneousFloat a0;
a0.a0 = -1.0;
a0.a1 = 2.0;
std::cout << "Calling TestReturnUnion16BytesNestedFloat("
<< "((" << a0.a0 << ", " << a0.a1 << "))"
<< ")\n";
Union16BytesNestedFloat result = f(a0);
std::cout << "result = "
<< "((" << result.a0.a0 << ", " << result.a0.a1 << "), ("
<< result.a1.a0 << ", " << result.a1.a1 << ", " << result.a1.a2
<< "), (" << result.a2.a0 << ", " << result.a2.a1 << ", "
<< result.a2.a2 << ", " << result.a2.a3 << "))"
<< "\n";
CHECK_APPROX(a0.a0, result.a0.a0);
CHECK_APPROX(a0.a1, result.a0.a1);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0);
CHECK_APPROX(0.0, result.a0.a0);
CHECK_APPROX(0.0, result.a0.a1);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0);
CHECK_APPROX(0.0, result.a0.a0);
CHECK_APPROX(0.0, result.a0.a1);
return 0;
}
// Used for testing structs and unions by value.
// Test that a struct passed in as argument can be returned.
// Especially for ffi callbacks.
// Struct is passed in int registers in most ABIs.
DART_EXPORT intptr_t TestReturnStructArgumentStruct1ByteInt(
// NOLINTNEXTLINE(whitespace/parens)
Struct1ByteInt (*f)(Struct1ByteInt a0)) {
Struct1ByteInt a0;
a0.a0 = -1;
std::cout << "Calling TestReturnStructArgumentStruct1ByteInt("
<< "((" << static_cast<int>(a0.a0) << "))"
<< ")\n";
Struct1ByteInt result = f(a0);
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ")"
<< "\n";
CHECK_EQ(a0.a0, result.a0);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0);
CHECK_EQ(0, result.a0);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0);
CHECK_EQ(0, result.a0);
return 0;
}
// Used for testing structs and unions by value.
// Test that a struct passed in as argument can be returned.
// Especially for ffi callbacks.
// Struct is passed on stack on all ABIs.
DART_EXPORT intptr_t TestReturnStructArgumentInt32x8Struct1ByteInt(
// NOLINTNEXTLINE(whitespace/parens)
Struct1ByteInt (*f)(int32_t a0,
int32_t a1,
int32_t a2,
int32_t a3,
int32_t a4,
int32_t a5,
int32_t a6,
int32_t a7,
Struct1ByteInt a8)) {
int32_t a0;
int32_t a1;
int32_t a2;
int32_t a3;
int32_t a4;
int32_t a5;
int32_t a6;
int32_t a7;
Struct1ByteInt a8;
a0 = -1;
a1 = 2;
a2 = -3;
a3 = 4;
a4 = -5;
a5 = 6;
a6 = -7;
a7 = 8;
a8.a0 = -9;
std::cout << "Calling TestReturnStructArgumentInt32x8Struct1ByteInt("
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
<< ", " << a5 << ", " << a6 << ", " << a7 << ", ("
<< static_cast<int>(a8.a0) << "))"
<< ")\n";
Struct1ByteInt result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ")"
<< "\n";
CHECK_EQ(a8.a0, result.a0);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
CHECK_EQ(0, result.a0);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
CHECK_EQ(0, result.a0);
return 0;
}
// Used for testing structs and unions by value.
// Test that a struct passed in as argument can be returned.
// Especially for ffi callbacks.
// Struct is passed in float registers in most ABIs.
DART_EXPORT intptr_t TestReturnStructArgumentStruct8BytesHomogeneousFloat(
// NOLINTNEXTLINE(whitespace/parens)
Struct8BytesHomogeneousFloat (*f)(Struct8BytesHomogeneousFloat a0)) {
Struct8BytesHomogeneousFloat a0;
a0.a0 = -1.0;
a0.a1 = 2.0;
std::cout << "Calling TestReturnStructArgumentStruct8BytesHomogeneousFloat("
<< "((" << a0.a0 << ", " << a0.a1 << "))"
<< ")\n";
Struct8BytesHomogeneousFloat result = f(a0);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ")"
<< "\n";
CHECK_APPROX(a0.a0, result.a0);
CHECK_APPROX(a0.a1, result.a1);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0);
CHECK_APPROX(0.0, result.a0);
CHECK_APPROX(0.0, result.a1);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0);
CHECK_APPROX(0.0, result.a0);
CHECK_APPROX(0.0, result.a1);
return 0;
}
// Used for testing structs and unions by value.
// On arm64, both argument and return value are passed in by pointer.
DART_EXPORT intptr_t TestReturnStructArgumentStruct20BytesHomogeneousInt32(
// NOLINTNEXTLINE(whitespace/parens)
Struct20BytesHomogeneousInt32 (*f)(Struct20BytesHomogeneousInt32 a0)) {
Struct20BytesHomogeneousInt32 a0;
a0.a0 = -1;
a0.a1 = 2;
a0.a2 = -3;
a0.a3 = 4;
a0.a4 = -5;
std::cout << "Calling TestReturnStructArgumentStruct20BytesHomogeneousInt32("
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< ", " << a0.a4 << "))"
<< ")\n";
Struct20BytesHomogeneousInt32 result = f(a0);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ", " << result.a4 << ")"
<< "\n";
CHECK_EQ(a0.a0, result.a0);
CHECK_EQ(a0.a1, result.a1);
CHECK_EQ(a0.a2, result.a2);
CHECK_EQ(a0.a3, result.a3);
CHECK_EQ(a0.a4, result.a4);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
CHECK_EQ(0, result.a3);
CHECK_EQ(0, result.a4);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
CHECK_EQ(0, result.a3);
CHECK_EQ(0, result.a4);
return 0;
}
// Used for testing structs and unions by value.
// On arm64, both argument and return value are passed in by pointer.
// Ints exhaust registers, so that pointer is passed on stack.
DART_EXPORT intptr_t TestReturnStructArgumentInt32x8Struct20BytesHomogeneou(
// NOLINTNEXTLINE(whitespace/parens)
Struct20BytesHomogeneousInt32 (*f)(int32_t a0,
int32_t a1,
int32_t a2,
int32_t a3,
int32_t a4,
int32_t a5,
int32_t a6,
int32_t a7,
Struct20BytesHomogeneousInt32 a8)) {
int32_t a0;
int32_t a1;
int32_t a2;
int32_t a3;
int32_t a4;
int32_t a5;
int32_t a6;
int32_t a7;
Struct20BytesHomogeneousInt32 a8;
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;
std::cout << "Calling TestReturnStructArgumentInt32x8Struct20BytesHomogeneou("
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
<< ", " << a5 << ", " << a6 << ", " << a7 << ", (" << a8.a0 << ", "
<< a8.a1 << ", " << a8.a2 << ", " << a8.a3 << ", " << a8.a4 << "))"
<< ")\n";
Struct20BytesHomogeneousInt32 result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ", " << result.a4 << ")"
<< "\n";
CHECK_EQ(a8.a0, result.a0);
CHECK_EQ(a8.a1, result.a1);
CHECK_EQ(a8.a2, result.a2);
CHECK_EQ(a8.a3, result.a3);
CHECK_EQ(a8.a4, result.a4);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
CHECK_EQ(0, result.a3);
CHECK_EQ(0, result.a4);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
CHECK_EQ(0, result.a3);
CHECK_EQ(0, result.a4);
return 0;
}
// Used for testing structs and unions by value.
// Test returning struct with inline array.
DART_EXPORT intptr_t TestReturnStructArgumentStruct8BytesInlineArrayInt(
// NOLINTNEXTLINE(whitespace/parens)
Struct8BytesInlineArrayInt (*f)(Struct8BytesInlineArrayInt a0)) {
Struct8BytesInlineArrayInt a0;
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;
std::cout << "Calling TestReturnStructArgumentStruct8BytesInlineArrayInt("
<< "(([" << static_cast<int>(a0.a0[0]) << ", "
<< static_cast<int>(a0.a0[1]) << ", " << static_cast<int>(a0.a0[2])
<< ", " << static_cast<int>(a0.a0[3]) << ", "
<< static_cast<int>(a0.a0[4]) << ", " << static_cast<int>(a0.a0[5])
<< ", " << static_cast<int>(a0.a0[6]) << ", "
<< static_cast<int>(a0.a0[7]) << "]))"
<< ")\n";
Struct8BytesInlineArrayInt result = f(a0);
std::cout << "result = "
<< "([" << static_cast<int>(result.a0[0]) << ", "
<< static_cast<int>(result.a0[1]) << ", "
<< static_cast<int>(result.a0[2]) << ", "
<< static_cast<int>(result.a0[3]) << ", "
<< static_cast<int>(result.a0[4]) << ", "
<< static_cast<int>(result.a0[5]) << ", "
<< static_cast<int>(result.a0[6]) << ", "
<< static_cast<int>(result.a0[7]) << "])"
<< "\n";
for (intptr_t i = 0; i < 8; i++) {
CHECK_EQ(a0.a0[i], result.a0[i]);
}
// Pass argument that will make the Dart callback throw.
a0.a0[0] = 42;
result = f(a0);
for (intptr_t i = 0; i < 8; i++) {
CHECK_EQ(0, result.a0[i]);
}
// Pass argument that will make the Dart callback return null.
a0.a0[0] = 84;
result = f(a0);
for (intptr_t i = 0; i < 8; i++) {
CHECK_EQ(0, result.a0[i]);
}
return 0;
}
// Used for testing structs and unions by value.
// Return value in FPU registers on arm hardfp and arm64.
DART_EXPORT intptr_t TestReturnStructArgumentStructStruct16BytesHomogeneous(
// NOLINTNEXTLINE(whitespace/parens)
StructStruct16BytesHomogeneousFloat2 (*f)(
StructStruct16BytesHomogeneousFloat2 a0)) {
StructStruct16BytesHomogeneousFloat2 a0;
a0.a0.a0 = -1.0;
a0.a1[0].a0 = 2.0;
a0.a1[1].a0 = -3.0;
a0.a2 = 4.0;
std::cout << "Calling TestReturnStructArgumentStructStruct16BytesHomogeneous("
<< "(((" << a0.a0.a0 << "), [(" << a0.a1[0].a0 << "), ("
<< a0.a1[1].a0 << ")], " << a0.a2 << "))"
<< ")\n";
StructStruct16BytesHomogeneousFloat2 result = f(a0);
std::cout << "result = "
<< "((" << result.a0.a0 << "), [(" << result.a1[0].a0 << "), ("
<< result.a1[1].a0 << ")], " << result.a2 << ")"
<< "\n";
CHECK_APPROX(a0.a0.a0, result.a0.a0);
for (intptr_t i = 0; i < 2; i++) {
CHECK_APPROX(a0.a1[i].a0, result.a1[i].a0);
}
CHECK_APPROX(a0.a2, result.a2);
// Pass argument that will make the Dart callback throw.
a0.a0.a0 = 42;
result = f(a0);
CHECK_APPROX(0.0, result.a0.a0);
for (intptr_t i = 0; i < 2; i++) {
CHECK_APPROX(0.0, result.a1[i].a0);
}
CHECK_APPROX(0.0, result.a2);
// Pass argument that will make the Dart callback return null.
a0.a0.a0 = 84;
result = f(a0);
CHECK_APPROX(0.0, result.a0.a0);
for (intptr_t i = 0; i < 2; i++) {
CHECK_APPROX(0.0, result.a1[i].a0);
}
CHECK_APPROX(0.0, result.a2);
return 0;
}
// Used for testing structs and unions by value.
// Return value in FPU registers on arm64.
DART_EXPORT intptr_t TestReturnStructArgumentStructStruct32BytesHomogeneous(
// NOLINTNEXTLINE(whitespace/parens)
StructStruct32BytesHomogeneousDouble2 (*f)(
StructStruct32BytesHomogeneousDouble2 a0)) {
StructStruct32BytesHomogeneousDouble2 a0;
a0.a0.a0 = -1.0;
a0.a1[0].a0 = 2.0;
a0.a1[1].a0 = -3.0;
a0.a2 = 4.0;
std::cout << "Calling TestReturnStructArgumentStructStruct32BytesHomogeneous("
<< "(((" << a0.a0.a0 << "), [(" << a0.a1[0].a0 << "), ("
<< a0.a1[1].a0 << ")], " << a0.a2 << "))"
<< ")\n";
StructStruct32BytesHomogeneousDouble2 result = f(a0);
std::cout << "result = "
<< "((" << result.a0.a0 << "), [(" << result.a1[0].a0 << "), ("
<< result.a1[1].a0 << ")], " << result.a2 << ")"
<< "\n";
CHECK_APPROX(a0.a0.a0, result.a0.a0);
for (intptr_t i = 0; i < 2; i++) {
CHECK_APPROX(a0.a1[i].a0, result.a1[i].a0);
}
CHECK_APPROX(a0.a2, result.a2);
// Pass argument that will make the Dart callback throw.
a0.a0.a0 = 42;
result = f(a0);
CHECK_APPROX(0.0, result.a0.a0);
for (intptr_t i = 0; i < 2; i++) {
CHECK_APPROX(0.0, result.a1[i].a0);
}
CHECK_APPROX(0.0, result.a2);
// Pass argument that will make the Dart callback return null.
a0.a0.a0 = 84;
result = f(a0);
CHECK_APPROX(0.0, result.a0.a0);
for (intptr_t i = 0; i < 2; i++) {
CHECK_APPROX(0.0, result.a1[i].a0);
}
CHECK_APPROX(0.0, result.a2);
return 0;
}
// Used for testing structs and unions by value.
// On x64 Linux, return value is split over FP and int registers.
DART_EXPORT intptr_t TestReturnStructArgumentStructStruct16BytesMixed3(
// NOLINTNEXTLINE(whitespace/parens)
StructStruct16BytesMixed3 (*f)(StructStruct16BytesMixed3 a0)) {
StructStruct16BytesMixed3 a0;
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;
std::cout << "Calling TestReturnStructArgumentStructStruct16BytesMixed3("
<< "(((" << a0.a0.a0 << "), [(" << a0.a1[0].a0 << ", "
<< a0.a1[0].a1 << ", " << a0.a1[0].a2 << ")], [" << a0.a2[0] << ", "
<< a0.a2[1] << "]))"
<< ")\n";
StructStruct16BytesMixed3 result = f(a0);
std::cout << "result = "
<< "((" << result.a0.a0 << "), [(" << result.a1[0].a0 << ", "
<< result.a1[0].a1 << ", " << result.a1[0].a2 << ")], ["
<< result.a2[0] << ", " << result.a2[1] << "])"
<< "\n";
CHECK_APPROX(a0.a0.a0, result.a0.a0);
for (intptr_t i = 0; i < 1; i++) {
CHECK_APPROX(a0.a1[i].a0, result.a1[i].a0);
CHECK_EQ(a0.a1[i].a1, result.a1[i].a1);
CHECK_EQ(a0.a1[i].a2, result.a1[i].a2);
}
for (intptr_t i = 0; i < 2; i++) {
CHECK_EQ(a0.a2[i], result.a2[i]);
}
// Pass argument that will make the Dart callback throw.
a0.a0.a0 = 42;
result = f(a0);
CHECK_APPROX(0.0, result.a0.a0);
for (intptr_t i = 0; i < 1; i++) {
CHECK_APPROX(0.0, result.a1[i].a0);
CHECK_EQ(0, result.a1[i].a1);
CHECK_EQ(0, result.a1[i].a2);
}
for (intptr_t i = 0; i < 2; i++) {
CHECK_EQ(0, result.a2[i]);
}
// Pass argument that will make the Dart callback return null.
a0.a0.a0 = 84;
result = f(a0);
CHECK_APPROX(0.0, result.a0.a0);
for (intptr_t i = 0; i < 1; i++) {
CHECK_APPROX(0.0, result.a1[i].a0);
CHECK_EQ(0, result.a1[i].a1);
CHECK_EQ(0, result.a1[i].a2);
}
for (intptr_t i = 0; i < 2; i++) {
CHECK_EQ(0, result.a2[i]);
}
return 0;
}
// Used for testing structs and unions by value.
// Test alignment and padding of 16 byte int within struct.
DART_EXPORT intptr_t TestReturnStructAlignmentInt16(
// NOLINTNEXTLINE(whitespace/parens)
StructAlignmentInt16 (*f)(int8_t a0, int16_t a1, int8_t a2)) {
int8_t a0;
int16_t a1;
int8_t a2;
a0 = -1;
a1 = 2;
a2 = -3;
std::cout << "Calling TestReturnStructAlignmentInt16("
<< "(" << static_cast<int>(a0) << ", " << a1 << ", "
<< static_cast<int>(a2) << ")"
<< ")\n";
StructAlignmentInt16 result = f(a0, a1, a2);
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ", " << result.a1 << ", "
<< static_cast<int>(result.a2) << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
CHECK_EQ(a1, result.a1);
CHECK_EQ(a2, result.a2);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
return 0;
}
// Used for testing structs and unions by value.
// Test alignment and padding of 32 byte int within struct.
DART_EXPORT intptr_t TestReturnStructAlignmentInt32(
// NOLINTNEXTLINE(whitespace/parens)
StructAlignmentInt32 (*f)(int8_t a0, int32_t a1, int8_t a2)) {
int8_t a0;
int32_t a1;
int8_t a2;
a0 = -1;
a1 = 2;
a2 = -3;
std::cout << "Calling TestReturnStructAlignmentInt32("
<< "(" << static_cast<int>(a0) << ", " << a1 << ", "
<< static_cast<int>(a2) << ")"
<< ")\n";
StructAlignmentInt32 result = f(a0, a1, a2);
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ", " << result.a1 << ", "
<< static_cast<int>(result.a2) << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
CHECK_EQ(a1, result.a1);
CHECK_EQ(a2, result.a2);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
return 0;
}
// Used for testing structs and unions by value.
// Test alignment and padding of 64 byte int within struct.
DART_EXPORT intptr_t TestReturnStructAlignmentInt64(
// NOLINTNEXTLINE(whitespace/parens)
StructAlignmentInt64 (*f)(int8_t a0, int64_t a1, int8_t a2)) {
int8_t a0;
int64_t a1;
int8_t a2;
a0 = -1;
a1 = 2;
a2 = -3;
std::cout << "Calling TestReturnStructAlignmentInt64("
<< "(" << static_cast<int>(a0) << ", " << a1 << ", "
<< static_cast<int>(a2) << ")"
<< ")\n";
StructAlignmentInt64 result = f(a0, a1, a2);
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ", " << result.a1 << ", "
<< static_cast<int>(result.a2) << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
CHECK_EQ(a1, result.a1);
CHECK_EQ(a2, result.a2);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
return 0;
}
// Used for testing structs and unions by value.
// Simple nested struct.
DART_EXPORT intptr_t TestReturnStruct8BytesNestedInt(
// NOLINTNEXTLINE(whitespace/parens)
Struct8BytesNestedInt (*f)(Struct4BytesHomogeneousInt16 a0,
Struct4BytesHomogeneousInt16 a1)) {
Struct4BytesHomogeneousInt16 a0;
Struct4BytesHomogeneousInt16 a1;
a0.a0 = -1;
a0.a1 = 2;
a1.a0 = -3;
a1.a1 = 4;
std::cout << "Calling TestReturnStruct8BytesNestedInt("
<< "((" << a0.a0 << ", " << a0.a1 << "), (" << a1.a0 << ", "
<< a1.a1 << "))"
<< ")\n";
Struct8BytesNestedInt result = f(a0, a1);
std::cout << "result = "
<< "((" << result.a0.a0 << ", " << result.a0.a1 << "), ("
<< result.a1.a0 << ", " << result.a1.a1 << "))"
<< "\n";
CHECK_EQ(a0.a0, result.a0.a0);
CHECK_EQ(a0.a1, result.a0.a1);
CHECK_EQ(a1.a0, result.a1.a0);
CHECK_EQ(a1.a1, result.a1.a1);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1);
CHECK_EQ(0, result.a0.a0);
CHECK_EQ(0, result.a0.a1);
CHECK_EQ(0, result.a1.a0);
CHECK_EQ(0, result.a1.a1);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1);
CHECK_EQ(0, result.a0.a0);
CHECK_EQ(0, result.a0.a1);
CHECK_EQ(0, result.a1.a0);
CHECK_EQ(0, result.a1.a1);
return 0;
}
// Used for testing structs and unions by value.
// Simple nested struct with floats.
DART_EXPORT intptr_t TestReturnStruct8BytesNestedFloat(
// NOLINTNEXTLINE(whitespace/parens)
Struct8BytesNestedFloat (*f)(Struct4BytesFloat a0, Struct4BytesFloat a1)) {
Struct4BytesFloat a0;
Struct4BytesFloat a1;
a0.a0 = -1.0;
a1.a0 = 2.0;
std::cout << "Calling TestReturnStruct8BytesNestedFloat("
<< "((" << a0.a0 << "), (" << a1.a0 << "))"
<< ")\n";
Struct8BytesNestedFloat result = f(a0, a1);
std::cout << "result = "
<< "((" << result.a0.a0 << "), (" << result.a1.a0 << "))"
<< "\n";
CHECK_APPROX(a0.a0, result.a0.a0);
CHECK_APPROX(a1.a0, result.a1.a0);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1);
CHECK_APPROX(0.0, result.a0.a0);
CHECK_APPROX(0.0, result.a1.a0);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1);
CHECK_APPROX(0.0, result.a0.a0);
CHECK_APPROX(0.0, result.a1.a0);
return 0;
}
// Used for testing structs and unions by value.
// The nesting is irregular, testing homogenous float rules on arm and arm64,
// and the fpu register usage on x64.
DART_EXPORT intptr_t TestReturnStruct8BytesNestedFloat2(
// NOLINTNEXTLINE(whitespace/parens)
Struct8BytesNestedFloat2 (*f)(Struct4BytesFloat a0, float a1)) {
Struct4BytesFloat a0;
float a1;
a0.a0 = -1.0;
a1 = 2.0;
std::cout << "Calling TestReturnStruct8BytesNestedFloat2("
<< "((" << a0.a0 << "), " << a1 << ")"
<< ")\n";
Struct8BytesNestedFloat2 result = f(a0, a1);
std::cout << "result = "
<< "((" << result.a0.a0 << "), " << result.a1 << ")"
<< "\n";
CHECK_APPROX(a0.a0, result.a0.a0);
CHECK_APPROX(a1, result.a1);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1);
CHECK_APPROX(0.0, result.a0.a0);
CHECK_APPROX(0.0, result.a1);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1);
CHECK_APPROX(0.0, result.a0.a0);
CHECK_APPROX(0.0, result.a1);
return 0;
}
// Used for testing structs and unions by value.
// Simple nested struct with mixed members.
DART_EXPORT intptr_t TestReturnStruct8BytesNestedMixed(
// NOLINTNEXTLINE(whitespace/parens)
Struct8BytesNestedMixed (*f)(Struct4BytesHomogeneousInt16 a0,
Struct4BytesFloat a1)) {
Struct4BytesHomogeneousInt16 a0;
Struct4BytesFloat a1;
a0.a0 = -1;
a0.a1 = 2;
a1.a0 = -3.0;
std::cout << "Calling TestReturnStruct8BytesNestedMixed("
<< "((" << a0.a0 << ", " << a0.a1 << "), (" << a1.a0 << "))"
<< ")\n";
Struct8BytesNestedMixed result = f(a0, a1);
std::cout << "result = "
<< "((" << result.a0.a0 << ", " << result.a0.a1 << "), ("
<< result.a1.a0 << "))"
<< "\n";
CHECK_EQ(a0.a0, result.a0.a0);
CHECK_EQ(a0.a1, result.a0.a1);
CHECK_APPROX(a1.a0, result.a1.a0);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1);
CHECK_EQ(0, result.a0.a0);
CHECK_EQ(0, result.a0.a1);
CHECK_APPROX(0.0, result.a1.a0);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1);
CHECK_EQ(0, result.a0.a0);
CHECK_EQ(0, result.a0.a1);
CHECK_APPROX(0.0, result.a1.a0);
return 0;
}
// Used for testing structs and unions by value.
// Deeper nested struct to test recursive member access.
DART_EXPORT intptr_t TestReturnStruct16BytesNestedInt(
// NOLINTNEXTLINE(whitespace/parens)
Struct16BytesNestedInt (*f)(Struct8BytesNestedInt a0,
Struct8BytesNestedInt a1)) {
Struct8BytesNestedInt a0;
Struct8BytesNestedInt a1;
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;
std::cout << "Calling TestReturnStruct16BytesNestedInt("
<< "(((" << a0.a0.a0 << ", " << a0.a0.a1 << "), (" << a0.a1.a0
<< ", " << a0.a1.a1 << ")), ((" << a1.a0.a0 << ", " << a1.a0.a1
<< "), (" << a1.a1.a0 << ", " << a1.a1.a1 << ")))"
<< ")\n";
Struct16BytesNestedInt result = f(a0, a1);
std::cout << "result = "
<< "(((" << result.a0.a0.a0 << ", " << result.a0.a0.a1 << "), ("
<< result.a0.a1.a0 << ", " << result.a0.a1.a1 << ")), (("
<< result.a1.a0.a0 << ", " << result.a1.a0.a1 << "), ("
<< result.a1.a1.a0 << ", " << result.a1.a1.a1 << ")))"
<< "\n";
CHECK_EQ(a0.a0.a0, result.a0.a0.a0);
CHECK_EQ(a0.a0.a1, result.a0.a0.a1);
CHECK_EQ(a0.a1.a0, result.a0.a1.a0);
CHECK_EQ(a0.a1.a1, result.a0.a1.a1);
CHECK_EQ(a1.a0.a0, result.a1.a0.a0);
CHECK_EQ(a1.a0.a1, result.a1.a0.a1);
CHECK_EQ(a1.a1.a0, result.a1.a1.a0);
CHECK_EQ(a1.a1.a1, result.a1.a1.a1);
// Pass argument that will make the Dart callback throw.
a0.a0.a0 = 42;
result = f(a0, a1);
CHECK_EQ(0, result.a0.a0.a0);
CHECK_EQ(0, result.a0.a0.a1);
CHECK_EQ(0, result.a0.a1.a0);
CHECK_EQ(0, result.a0.a1.a1);
CHECK_EQ(0, result.a1.a0.a0);
CHECK_EQ(0, result.a1.a0.a1);
CHECK_EQ(0, result.a1.a1.a0);
CHECK_EQ(0, result.a1.a1.a1);
// Pass argument that will make the Dart callback return null.
a0.a0.a0 = 84;
result = f(a0, a1);
CHECK_EQ(0, result.a0.a0.a0);
CHECK_EQ(0, result.a0.a0.a1);
CHECK_EQ(0, result.a0.a1.a0);
CHECK_EQ(0, result.a0.a1.a1);
CHECK_EQ(0, result.a1.a0.a0);
CHECK_EQ(0, result.a1.a0.a1);
CHECK_EQ(0, result.a1.a1.a0);
CHECK_EQ(0, result.a1.a1.a1);
return 0;
}
// Used for testing structs and unions by value.
// Even deeper nested struct to test recursive member access.
DART_EXPORT intptr_t TestReturnStruct32BytesNestedInt(
// NOLINTNEXTLINE(whitespace/parens)
Struct32BytesNestedInt (*f)(Struct16BytesNestedInt a0,
Struct16BytesNestedInt a1)) {
Struct16BytesNestedInt a0;
Struct16BytesNestedInt a1;
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;
std::cout << "Calling TestReturnStruct32BytesNestedInt("
<< "((((" << a0.a0.a0.a0 << ", " << a0.a0.a0.a1 << "), ("
<< a0.a0.a1.a0 << ", " << a0.a0.a1.a1 << ")), ((" << a0.a1.a0.a0
<< ", " << a0.a1.a0.a1 << "), (" << a0.a1.a1.a0 << ", "
<< a0.a1.a1.a1 << "))), (((" << a1.a0.a0.a0 << ", " << a1.a0.a0.a1
<< "), (" << a1.a0.a1.a0 << ", " << a1.a0.a1.a1 << ")), (("
<< a1.a1.a0.a0 << ", " << a1.a1.a0.a1 << "), (" << a1.a1.a1.a0
<< ", " << a1.a1.a1.a1 << "))))"
<< ")\n";
Struct32BytesNestedInt result = f(a0, a1);
std::cout << "result = "
<< "((((" << result.a0.a0.a0.a0 << ", " << result.a0.a0.a0.a1
<< "), (" << result.a0.a0.a1.a0 << ", " << result.a0.a0.a1.a1
<< ")), ((" << result.a0.a1.a0.a0 << ", " << result.a0.a1.a0.a1
<< "), (" << result.a0.a1.a1.a0 << ", " << result.a0.a1.a1.a1
<< "))), (((" << result.a1.a0.a0.a0 << ", " << result.a1.a0.a0.a1
<< "), (" << result.a1.a0.a1.a0 << ", " << result.a1.a0.a1.a1
<< ")), ((" << result.a1.a1.a0.a0 << ", " << result.a1.a1.a0.a1
<< "), (" << result.a1.a1.a1.a0 << ", " << result.a1.a1.a1.a1
<< "))))"
<< "\n";
CHECK_EQ(a0.a0.a0.a0, result.a0.a0.a0.a0);
CHECK_EQ(a0.a0.a0.a1, result.a0.a0.a0.a1);
CHECK_EQ(a0.a0.a1.a0, result.a0.a0.a1.a0);
CHECK_EQ(a0.a0.a1.a1, result.a0.a0.a1.a1);
CHECK_EQ(a0.a1.a0.a0, result.a0.a1.a0.a0);
CHECK_EQ(a0.a1.a0.a1, result.a0.a1.a0.a1);
CHECK_EQ(a0.a1.a1.a0, result.a0.a1.a1.a0);
CHECK_EQ(a0.a1.a1.a1, result.a0.a1.a1.a1);
CHECK_EQ(a1.a0.a0.a0, result.a1.a0.a0.a0);
CHECK_EQ(a1.a0.a0.a1, result.a1.a0.a0.a1);
CHECK_EQ(a1.a0.a1.a0, result.a1.a0.a1.a0);
CHECK_EQ(a1.a0.a1.a1, result.a1.a0.a1.a1);
CHECK_EQ(a1.a1.a0.a0, result.a1.a1.a0.a0);
CHECK_EQ(a1.a1.a0.a1, result.a1.a1.a0.a1);
CHECK_EQ(a1.a1.a1.a0, result.a1.a1.a1.a0);
CHECK_EQ(a1.a1.a1.a1, result.a1.a1.a1.a1);
// Pass argument that will make the Dart callback throw.
a0.a0.a0.a0 = 42;
result = f(a0, a1);
CHECK_EQ(0, result.a0.a0.a0.a0);
CHECK_EQ(0, result.a0.a0.a0.a1);
CHECK_EQ(0, result.a0.a0.a1.a0);
CHECK_EQ(0, result.a0.a0.a1.a1);
CHECK_EQ(0, result.a0.a1.a0.a0);
CHECK_EQ(0, result.a0.a1.a0.a1);
CHECK_EQ(0, result.a0.a1.a1.a0);
CHECK_EQ(0, result.a0.a1.a1.a1);
CHECK_EQ(0, result.a1.a0.a0.a0);
CHECK_EQ(0, result.a1.a0.a0.a1);
CHECK_EQ(0, result.a1.a0.a1.a0);
CHECK_EQ(0, result.a1.a0.a1.a1);
CHECK_EQ(0, result.a1.a1.a0.a0);
CHECK_EQ(0, result.a1.a1.a0.a1);
CHECK_EQ(0, result.a1.a1.a1.a0);
CHECK_EQ(0, result.a1.a1.a1.a1);
// Pass argument that will make the Dart callback return null.
a0.a0.a0.a0 = 84;
result = f(a0, a1);
CHECK_EQ(0, result.a0.a0.a0.a0);
CHECK_EQ(0, result.a0.a0.a0.a1);
CHECK_EQ(0, result.a0.a0.a1.a0);
CHECK_EQ(0, result.a0.a0.a1.a1);
CHECK_EQ(0, result.a0.a1.a0.a0);
CHECK_EQ(0, result.a0.a1.a0.a1);
CHECK_EQ(0, result.a0.a1.a1.a0);
CHECK_EQ(0, result.a0.a1.a1.a1);
CHECK_EQ(0, result.a1.a0.a0.a0);
CHECK_EQ(0, result.a1.a0.a0.a1);
CHECK_EQ(0, result.a1.a0.a1.a0);
CHECK_EQ(0, result.a1.a0.a1.a1);
CHECK_EQ(0, result.a1.a1.a0.a0);
CHECK_EQ(0, result.a1.a1.a0.a1);
CHECK_EQ(0, result.a1.a1.a1.a0);
CHECK_EQ(0, result.a1.a1.a1.a1);
return 0;
}
// Used for testing structs and unions by value.
// Test alignment and padding of nested struct with 16 byte int.
DART_EXPORT intptr_t TestReturnStructNestedIntStructAlignmentInt16(
// NOLINTNEXTLINE(whitespace/parens)
StructNestedIntStructAlignmentInt16 (*f)(StructAlignmentInt16 a0,
StructAlignmentInt16 a1)) {
StructAlignmentInt16 a0;
StructAlignmentInt16 a1;
a0.a0 = -1;
a0.a1 = 2;
a0.a2 = -3;
a1.a0 = 4;
a1.a1 = -5;
a1.a2 = 6;
std::cout << "Calling TestReturnStructNestedIntStructAlignmentInt16("
<< "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << ", "
<< static_cast<int>(a0.a2) << "), (" << static_cast<int>(a1.a0)
<< ", " << a1.a1 << ", " << static_cast<int>(a1.a2) << "))"
<< ")\n";
StructNestedIntStructAlignmentInt16 result = f(a0, a1);
std::cout << "result = "
<< "((" << static_cast<int>(result.a0.a0) << ", " << result.a0.a1
<< ", " << static_cast<int>(result.a0.a2) << "), ("
<< static_cast<int>(result.a1.a0) << ", " << result.a1.a1 << ", "
<< static_cast<int>(result.a1.a2) << "))"
<< "\n";
CHECK_EQ(a0.a0, result.a0.a0);
CHECK_EQ(a0.a1, result.a0.a1);
CHECK_EQ(a0.a2, result.a0.a2);
CHECK_EQ(a1.a0, result.a1.a0);
CHECK_EQ(a1.a1, result.a1.a1);
CHECK_EQ(a1.a2, result.a1.a2);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1);
CHECK_EQ(0, result.a0.a0);
CHECK_EQ(0, result.a0.a1);
CHECK_EQ(0, result.a0.a2);
CHECK_EQ(0, result.a1.a0);
CHECK_EQ(0, result.a1.a1);
CHECK_EQ(0, result.a1.a2);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1);
CHECK_EQ(0, result.a0.a0);
CHECK_EQ(0, result.a0.a1);
CHECK_EQ(0, result.a0.a2);
CHECK_EQ(0, result.a1.a0);
CHECK_EQ(0, result.a1.a1);
CHECK_EQ(0, result.a1.a2);
return 0;
}
// Used for testing structs and unions by value.
// Test alignment and padding of nested struct with 32 byte int.
DART_EXPORT intptr_t TestReturnStructNestedIntStructAlignmentInt32(
// NOLINTNEXTLINE(whitespace/parens)
StructNestedIntStructAlignmentInt32 (*f)(StructAlignmentInt32 a0,
StructAlignmentInt32 a1)) {
StructAlignmentInt32 a0;
StructAlignmentInt32 a1;
a0.a0 = -1;
a0.a1 = 2;
a0.a2 = -3;
a1.a0 = 4;
a1.a1 = -5;
a1.a2 = 6;
std::cout << "Calling TestReturnStructNestedIntStructAlignmentInt32("
<< "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << ", "
<< static_cast<int>(a0.a2) << "), (" << static_cast<int>(a1.a0)
<< ", " << a1.a1 << ", " << static_cast<int>(a1.a2) << "))"
<< ")\n";
StructNestedIntStructAlignmentInt32 result = f(a0, a1);
std::cout << "result = "
<< "((" << static_cast<int>(result.a0.a0) << ", " << result.a0.a1
<< ", " << static_cast<int>(result.a0.a2) << "), ("
<< static_cast<int>(result.a1.a0) << ", " << result.a1.a1 << ", "
<< static_cast<int>(result.a1.a2) << "))"
<< "\n";
CHECK_EQ(a0.a0, result.a0.a0);
CHECK_EQ(a0.a1, result.a0.a1);
CHECK_EQ(a0.a2, result.a0.a2);
CHECK_EQ(a1.a0, result.a1.a0);
CHECK_EQ(a1.a1, result.a1.a1);
CHECK_EQ(a1.a2, result.a1.a2);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1);
CHECK_EQ(0, result.a0.a0);
CHECK_EQ(0, result.a0.a1);
CHECK_EQ(0, result.a0.a2);
CHECK_EQ(0, result.a1.a0);
CHECK_EQ(0, result.a1.a1);
CHECK_EQ(0, result.a1.a2);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1);
CHECK_EQ(0, result.a0.a0);
CHECK_EQ(0, result.a0.a1);
CHECK_EQ(0, result.a0.a2);
CHECK_EQ(0, result.a1.a0);
CHECK_EQ(0, result.a1.a1);
CHECK_EQ(0, result.a1.a2);
return 0;
}
// Used for testing structs and unions by value.
// Test alignment and padding of nested struct with 64 byte int.
DART_EXPORT intptr_t TestReturnStructNestedIntStructAlignmentInt64(
// NOLINTNEXTLINE(whitespace/parens)
StructNestedIntStructAlignmentInt64 (*f)(StructAlignmentInt64 a0,
StructAlignmentInt64 a1)) {
StructAlignmentInt64 a0;
StructAlignmentInt64 a1;
a0.a0 = -1;
a0.a1 = 2;
a0.a2 = -3;
a1.a0 = 4;
a1.a1 = -5;
a1.a2 = 6;
std::cout << "Calling TestReturnStructNestedIntStructAlignmentInt64("
<< "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << ", "
<< static_cast<int>(a0.a2) << "), (" << static_cast<int>(a1.a0)
<< ", " << a1.a1 << ", " << static_cast<int>(a1.a2) << "))"
<< ")\n";
StructNestedIntStructAlignmentInt64 result = f(a0, a1);
std::cout << "result = "
<< "((" << static_cast<int>(result.a0.a0) << ", " << result.a0.a1
<< ", " << static_cast<int>(result.a0.a2) << "), ("
<< static_cast<int>(result.a1.a0) << ", " << result.a1.a1 << ", "
<< static_cast<int>(result.a1.a2) << "))"
<< "\n";
CHECK_EQ(a0.a0, result.a0.a0);
CHECK_EQ(a0.a1, result.a0.a1);
CHECK_EQ(a0.a2, result.a0.a2);
CHECK_EQ(a1.a0, result.a1.a0);
CHECK_EQ(a1.a1, result.a1.a1);
CHECK_EQ(a1.a2, result.a1.a2);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1);
CHECK_EQ(0, result.a0.a0);
CHECK_EQ(0, result.a0.a1);
CHECK_EQ(0, result.a0.a2);
CHECK_EQ(0, result.a1.a0);
CHECK_EQ(0, result.a1.a1);
CHECK_EQ(0, result.a1.a2);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1);
CHECK_EQ(0, result.a0.a0);
CHECK_EQ(0, result.a0.a1);
CHECK_EQ(0, result.a0.a2);
CHECK_EQ(0, result.a1.a0);
CHECK_EQ(0, result.a1.a1);
CHECK_EQ(0, result.a1.a2);
return 0;
}
// Used for testing structs and unions by value.
// Return big irregular struct as smoke test.
DART_EXPORT intptr_t TestReturnStructNestedIrregularEvenBigger(
// NOLINTNEXTLINE(whitespace/parens)
StructNestedIrregularEvenBigger (*f)(uint64_t a0,
StructNestedIrregularBigger a1,
StructNestedIrregularBigger a2,
double a3)) {
uint64_t a0;
StructNestedIrregularBigger a1;
StructNestedIrregularBigger a2;
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;
std::cout << "Calling TestReturnStructNestedIrregularEvenBigger("
<< "(" << a0 << ", ((" << a1.a0.a0 << ", ((" << a1.a0.a1.a0.a0
<< ", " << a1.a0.a1.a0.a1 << "), (" << a1.a0.a1.a1.a0 << ")), "
<< a1.a0.a2 << ", ((" << a1.a0.a3.a0.a0 << "), " << a1.a0.a3.a1
<< "), " << a1.a0.a4 << ", ((" << a1.a0.a5.a0.a0 << "), ("
<< a1.a0.a5.a1.a0 << ")), " << a1.a0.a6 << "), ((" << a1.a1.a0.a0
<< ", " << a1.a1.a0.a1 << "), (" << a1.a1.a1.a0 << ")), " << a1.a2
<< ", " << a1.a3 << "), ((" << a2.a0.a0 << ", ((" << a2.a0.a1.a0.a0
<< ", " << a2.a0.a1.a0.a1 << "), (" << a2.a0.a1.a1.a0 << ")), "
<< a2.a0.a2 << ", ((" << a2.a0.a3.a0.a0 << "), " << a2.a0.a3.a1
<< "), " << a2.a0.a4 << ", ((" << a2.a0.a5.a0.a0 << "), ("
<< a2.a0.a5.a1.a0 << ")), " << a2.a0.a6 << "), ((" << a2.a1.a0.a0
<< ", " << a2.a1.a0.a1 << "), (" << a2.a1.a1.a0 << ")), " << a2.a2
<< ", " << a2.a3 << "), " << a3 << ")"
<< ")\n";
StructNestedIrregularEvenBigger result = f(a0, a1, a2, a3);
std::cout << "result = "
<< "(" << result.a0 << ", ((" << result.a1.a0.a0 << ", (("
<< result.a1.a0.a1.a0.a0 << ", " << result.a1.a0.a1.a0.a1 << "), ("
<< result.a1.a0.a1.a1.a0 << ")), " << result.a1.a0.a2 << ", (("
<< result.a1.a0.a3.a0.a0 << "), " << result.a1.a0.a3.a1 << "), "
<< result.a1.a0.a4 << ", ((" << result.a1.a0.a5.a0.a0 << "), ("
<< result.a1.a0.a5.a1.a0 << ")), " << result.a1.a0.a6 << "), (("
<< result.a1.a1.a0.a0 << ", " << result.a1.a1.a0.a1 << "), ("
<< result.a1.a1.a1.a0 << ")), " << result.a1.a2 << ", "
<< result.a1.a3 << "), ((" << result.a2.a0.a0 << ", (("
<< result.a2.a0.a1.a0.a0 << ", " << result.a2.a0.a1.a0.a1 << "), ("
<< result.a2.a0.a1.a1.a0 << ")), " << result.a2.a0.a2 << ", (("
<< result.a2.a0.a3.a0.a0 << "), " << result.a2.a0.a3.a1 << "), "
<< result.a2.a0.a4 << ", ((" << result.a2.a0.a5.a0.a0 << "), ("
<< result.a2.a0.a5.a1.a0 << ")), " << result.a2.a0.a6 << "), (("
<< result.a2.a1.a0.a0 << ", " << result.a2.a1.a0.a1 << "), ("
<< result.a2.a1.a1.a0 << ")), " << result.a2.a2 << ", "
<< result.a2.a3 << "), " << result.a3 << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
CHECK_EQ(a1.a0.a0, result.a1.a0.a0);
CHECK_EQ(a1.a0.a1.a0.a0, result.a1.a0.a1.a0.a0);
CHECK_EQ(a1.a0.a1.a0.a1, result.a1.a0.a1.a0.a1);
CHECK_APPROX(a1.a0.a1.a1.a0, result.a1.a0.a1.a1.a0);
CHECK_EQ(a1.a0.a2, result.a1.a0.a2);
CHECK_APPROX(a1.a0.a3.a0.a0, result.a1.a0.a3.a0.a0);
CHECK_APPROX(a1.a0.a3.a1, result.a1.a0.a3.a1);
CHECK_EQ(a1.a0.a4, result.a1.a0.a4);
CHECK_APPROX(a1.a0.a5.a0.a0, result.a1.a0.a5.a0.a0);
CHECK_APPROX(a1.a0.a5.a1.a0, result.a1.a0.a5.a1.a0);
CHECK_EQ(a1.a0.a6, result.a1.a0.a6);
CHECK_EQ(a1.a1.a0.a0, result.a1.a1.a0.a0);
CHECK_EQ(a1.a1.a0.a1, result.a1.a1.a0.a1);
CHECK_APPROX(a1.a1.a1.a0, result.a1.a1.a1.a0);
CHECK_APPROX(a1.a2, result.a1.a2);
CHECK_APPROX(a1.a3, result.a1.a3);
CHECK_EQ(a2.a0.a0, result.a2.a0.a0);
CHECK_EQ(a2.a0.a1.a0.a0, result.a2.a0.a1.a0.a0);
CHECK_EQ(a2.a0.a1.a0.a1, result.a2.a0.a1.a0.a1);
CHECK_APPROX(a2.a0.a1.a1.a0, result.a2.a0.a1.a1.a0);
CHECK_EQ(a2.a0.a2, result.a2.a0.a2);
CHECK_APPROX(a2.a0.a3.a0.a0, result.a2.a0.a3.a0.a0);
CHECK_APPROX(a2.a0.a3.a1, result.a2.a0.a3.a1);
CHECK_EQ(a2.a0.a4, result.a2.a0.a4);
CHECK_APPROX(a2.a0.a5.a0.a0, result.a2.a0.a5.a0.a0);
CHECK_APPROX(a2.a0.a5.a1.a0, result.a2.a0.a5.a1.a0);
CHECK_EQ(a2.a0.a6, result.a2.a0.a6);
CHECK_EQ(a2.a1.a0.a0, result.a2.a1.a0.a0);
CHECK_EQ(a2.a1.a0.a1, result.a2.a1.a0.a1);
CHECK_APPROX(a2.a1.a1.a0, result.a2.a1.a1.a0);
CHECK_APPROX(a2.a2, result.a2.a2);
CHECK_APPROX(a2.a3, result.a2.a3);
CHECK_APPROX(a3, result.a3);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1.a0.a0);
CHECK_EQ(0, result.a1.a0.a1.a0.a0);
CHECK_EQ(0, result.a1.a0.a1.a0.a1);
CHECK_APPROX(0.0, result.a1.a0.a1.a1.a0);
CHECK_EQ(0, result.a1.a0.a2);
CHECK_APPROX(0.0, result.a1.a0.a3.a0.a0);
CHECK_APPROX(0.0, result.a1.a0.a3.a1);
CHECK_EQ(0, result.a1.a0.a4);
CHECK_APPROX(0.0, result.a1.a0.a5.a0.a0);
CHECK_APPROX(0.0, result.a1.a0.a5.a1.a0);
CHECK_EQ(0, result.a1.a0.a6);
CHECK_EQ(0, result.a1.a1.a0.a0);
CHECK_EQ(0, result.a1.a1.a0.a1);
CHECK_APPROX(0.0, result.a1.a1.a1.a0);
CHECK_APPROX(0.0, result.a1.a2);
CHECK_APPROX(0.0, result.a1.a3);
CHECK_EQ(0, result.a2.a0.a0);
CHECK_EQ(0, result.a2.a0.a1.a0.a0);
CHECK_EQ(0, result.a2.a0.a1.a0.a1);
CHECK_APPROX(0.0, result.a2.a0.a1.a1.a0);
CHECK_EQ(0, result.a2.a0.a2);
CHECK_APPROX(0.0, result.a2.a0.a3.a0.a0);
CHECK_APPROX(0.0, result.a2.a0.a3.a1);
CHECK_EQ(0, result.a2.a0.a4);
CHECK_APPROX(0.0, result.a2.a0.a5.a0.a0);
CHECK_APPROX(0.0, result.a2.a0.a5.a1.a0);
CHECK_EQ(0, result.a2.a0.a6);
CHECK_EQ(0, result.a2.a1.a0.a0);
CHECK_EQ(0, result.a2.a1.a0.a1);
CHECK_APPROX(0.0, result.a2.a1.a1.a0);
CHECK_APPROX(0.0, result.a2.a2);
CHECK_APPROX(0.0, result.a2.a3);
CHECK_APPROX(0.0, result.a3);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1.a0.a0);
CHECK_EQ(0, result.a1.a0.a1.a0.a0);
CHECK_EQ(0, result.a1.a0.a1.a0.a1);
CHECK_APPROX(0.0, result.a1.a0.a1.a1.a0);
CHECK_EQ(0, result.a1.a0.a2);
CHECK_APPROX(0.0, result.a1.a0.a3.a0.a0);
CHECK_APPROX(0.0, result.a1.a0.a3.a1);
CHECK_EQ(0, result.a1.a0.a4);
CHECK_APPROX(0.0, result.a1.a0.a5.a0.a0);
CHECK_APPROX(0.0, result.a1.a0.a5.a1.a0);
CHECK_EQ(0, result.a1.a0.a6);
CHECK_EQ(0, result.a1.a1.a0.a0);
CHECK_EQ(0, result.a1.a1.a0.a1);
CHECK_APPROX(0.0, result.a1.a1.a1.a0);
CHECK_APPROX(0.0, result.a1.a2);
CHECK_APPROX(0.0, result.a1.a3);
CHECK_EQ(0, result.a2.a0.a0);
CHECK_EQ(0, result.a2.a0.a1.a0.a0);
CHECK_EQ(0, result.a2.a0.a1.a0.a1);
CHECK_APPROX(0.0, result.a2.a0.a1.a1.a0);
CHECK_EQ(0, result.a2.a0.a2);
CHECK_APPROX(0.0, result.a2.a0.a3.a0.a0);
CHECK_APPROX(0.0, result.a2.a0.a3.a1);
CHECK_EQ(0, result.a2.a0.a4);
CHECK_APPROX(0.0, result.a2.a0.a5.a0.a0);
CHECK_APPROX(0.0, result.a2.a0.a5.a1.a0);
CHECK_EQ(0, result.a2.a0.a6);
CHECK_EQ(0, result.a2.a1.a0.a0);
CHECK_EQ(0, result.a2.a1.a0.a1);
CHECK_APPROX(0.0, result.a2.a1.a1.a0);
CHECK_APPROX(0.0, result.a2.a2);
CHECK_APPROX(0.0, result.a2.a3);
CHECK_APPROX(0.0, result.a3);
return 0;
}
} // namespace dart