mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 09:43:57 +00:00
[vm/ffi] Fix variadic arguments on MacOS Arm64
Non-variadic arguments on the stack on MacOS Arm64 are aligned to the value size (which can be smaller than word size). However, for varargs, the arguments on the stack seem to be aligned to the word size. This CL introduces an alignment strategy constant for primitives on the stack in varargs and uses it in the native calling convention calculation. TEST=runtime/vm/compiler/ffi/native_calling_convention_test.cc with runtime/vm/compiler/ffi/unit_tests/variadic_less_than_word/arm64_macos.expect TEST=tests/ffi/function_varargs_generated_native_leaf_test.dart Closes: https://github.com/dart-lang/sdk/issues/55471 Change-Id: I51d20c3933a2cea9b110954ddec92fb91b9c3ecd Cq-Include-Trybots: dart/try:vm-aot-android-release-arm64c-try,vm-aot-linux-debug-x64-try,vm-aot-linux-debug-x64c-try,vm-aot-mac-release-arm64-try,vm-aot-mac-release-x64-try,vm-aot-obfuscate-linux-release-x64-try,vm-aot-optimization-level-linux-release-x64-try,vm-aot-win-debug-arm64-try,vm-aot-win-debug-x64-try,vm-aot-win-debug-x64c-try,vm-appjit-linux-debug-x64-try,vm-asan-linux-release-x64-try,vm-checked-mac-release-arm64-try,vm-eager-optimization-linux-release-ia32-try,vm-eager-optimization-linux-release-x64-try,vm-ffi-android-debug-arm-try,vm-ffi-android-debug-arm64c-try,vm-ffi-qemu-linux-release-arm-try,vm-ffi-qemu-linux-release-riscv64-try,vm-fuchsia-release-x64-try,vm-linux-debug-ia32-try,vm-linux-debug-x64-try,vm-linux-debug-x64c-try,vm-mac-debug-arm64-try,vm-mac-debug-x64-try,vm-msan-linux-release-x64-try,vm-reload-linux-debug-x64-try,vm-reload-rollback-linux-debug-x64-try,vm-ubsan-linux-release-x64-try,vm-win-debug-arm64-try,vm-win-debug-x64-try,vm-win-debug-x64c-try,vm-win-release-ia32-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/362762 Commit-Queue: Daco Harkes <dacoharkes@google.com> Reviewed-by: Tess Strickland <sstrickl@google.com>
This commit is contained in:
parent
4bb644ce3e
commit
c0b938c228
|
@ -22996,6 +22996,38 @@ DART_EXPORT int64_t VariadicAt1Int64x7Struct12BytesHomogeneousInt32(int64_t a0,
|
|||
return result;
|
||||
}
|
||||
|
||||
// Used for testing structs and unions by value.
|
||||
// Variadic arguments test on macos_arm64.
|
||||
DART_EXPORT int32_t VariadicAt1Struct12BytesHomogeneousInt32Int32x4(
|
||||
Struct12BytesHomogeneousInt32 a0,
|
||||
...) {
|
||||
va_list var_args;
|
||||
va_start(var_args, a0);
|
||||
int32_t a1 = va_arg(var_args, int32_t);
|
||||
int32_t a2 = va_arg(var_args, int32_t);
|
||||
int32_t a3 = va_arg(var_args, int32_t);
|
||||
int32_t a4 = va_arg(var_args, int32_t);
|
||||
va_end(var_args);
|
||||
|
||||
std::cout << "VariadicAt1Struct12BytesHomogeneousInt32Int32x4" << "(("
|
||||
<< a0.a0 << ", " << a0.a1 << ", " << a0.a2 << "), " << a1 << ", "
|
||||
<< a2 << ", " << a3 << ", " << a4 << ")" << "\n";
|
||||
|
||||
int32_t result = 0;
|
||||
|
||||
result += a0.a0;
|
||||
result += a0.a1;
|
||||
result += a0.a2;
|
||||
result += a1;
|
||||
result += a2;
|
||||
result += a3;
|
||||
result += a4;
|
||||
|
||||
std::cout << "result = " << result << "\n";
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Used for testing structs and unions by value.
|
||||
// Single variadic argument.
|
||||
DART_EXPORT intptr_t TestVariadicAt1Int64x2(
|
||||
|
@ -23897,4 +23929,50 @@ DART_EXPORT intptr_t TestVariadicAt1Int64x7Struct12BytesHomogeneousInt32(
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Used for testing structs and unions by value.
|
||||
// Variadic arguments test on macos_arm64.
|
||||
DART_EXPORT intptr_t TestVariadicAt1Struct12BytesHomogeneousInt32Int32x4(
|
||||
// NOLINTNEXTLINE(whitespace/parens)
|
||||
int32_t (*f)(Struct12BytesHomogeneousInt32 a0, ...)) {
|
||||
Struct12BytesHomogeneousInt32 a0 = {};
|
||||
int32_t a1;
|
||||
int32_t a2;
|
||||
int32_t a3;
|
||||
int32_t a4;
|
||||
|
||||
a0.a0 = -1;
|
||||
a0.a1 = 2;
|
||||
a0.a2 = -3;
|
||||
a1 = 4;
|
||||
a2 = -5;
|
||||
a3 = 6;
|
||||
a4 = -7;
|
||||
|
||||
std::cout << "Calling TestVariadicAt1Struct12BytesHomogeneousInt32Int32x4("
|
||||
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << "), " << a1
|
||||
<< ", " << a2 << ", " << a3 << ", " << a4 << ")" << ")\n";
|
||||
|
||||
int32_t result = f(a0, a1, a2, a3, a4);
|
||||
|
||||
std::cout << "result = " << result << "\n";
|
||||
|
||||
CHECK_EQ(-4, result);
|
||||
|
||||
// Pass argument that will make the Dart callback throw.
|
||||
a0.a0 = 42;
|
||||
|
||||
result = f(a0, a1, a2, a3, a4);
|
||||
|
||||
CHECK_EQ(0, result);
|
||||
|
||||
// Pass argument that will make the Dart callback return null.
|
||||
a0.a0 = 84;
|
||||
|
||||
result = f(a0, a1, a2, a3, a4);
|
||||
|
||||
CHECK_EQ(0, result);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace dart
|
||||
|
|
|
@ -242,7 +242,7 @@ class ArgumentAllocator : public ValueObject {
|
|||
zone_, payload_type, container_type, AllocateCpuRegister());
|
||||
}
|
||||
}
|
||||
return AllocateStack(payload_type);
|
||||
return AllocateStack(payload_type, is_vararg);
|
||||
}
|
||||
|
||||
// Constructs a container type.
|
||||
|
|
|
@ -969,6 +969,28 @@ UNIT_TEST_CASE_WITH_ZONE(
|
|||
RunSignatureTest(Z, "variadic_stradle_last_register", native_signature);
|
||||
}
|
||||
|
||||
// Struct parameter that potentially is partially allocated to a register and
|
||||
// partially to the stack. Mainly interesting on ARM64 and RISC-V.
|
||||
//
|
||||
// See the *.expect in ./unit_tests for this behavior.
|
||||
UNIT_TEST_CASE_WITH_ZONE(NativeCallingConvention_variadic_less_than_word) {
|
||||
#if defined(TARGET_ARCH_IS_32_BIT)
|
||||
const auto& halfptr_type = *new (Z) NativePrimitiveType(kInt16);
|
||||
#elif defined(TARGET_ARCH_IS_64_BIT)
|
||||
const auto& halfptr_type = *new (Z) NativePrimitiveType(kInt32);
|
||||
#endif
|
||||
|
||||
auto& arguments = *new (Z) NativeTypes(Z, 12);
|
||||
for (intptr_t i = 0; i < 12; i++) {
|
||||
arguments.Add(&halfptr_type);
|
||||
}
|
||||
|
||||
const auto& native_signature = *new (Z) NativeFunctionType(
|
||||
arguments, halfptr_type, /*variadic_arguments_index=*/1);
|
||||
|
||||
RunSignatureTest(Z, "variadic_less_than_word", native_signature);
|
||||
}
|
||||
|
||||
} // namespace ffi
|
||||
} // namespace compiler
|
||||
} // namespace dart
|
||||
|
|
|
@ -152,7 +152,10 @@ intptr_t NativePrimitiveType::SizeInBytes() const {
|
|||
}
|
||||
|
||||
intptr_t NativePrimitiveType::AlignmentInBytesStack(bool is_vararg) const {
|
||||
switch (CallingConventions::kArgumentStackAlignment) {
|
||||
const auto alignment =
|
||||
is_vararg ? CallingConventions::kArgumentStackAlignmentVarArgs
|
||||
: CallingConventions::kArgumentStackAlignment;
|
||||
switch (alignment) {
|
||||
case kAlignedToWordSize:
|
||||
// The default is to align stack arguments to word size.
|
||||
return compiler::target::kWordSize;
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
r0 int32
|
||||
r1 int32
|
||||
r2 int32
|
||||
r3 int32
|
||||
r4 int32
|
||||
r5 int32
|
||||
r6 int32
|
||||
r7 int32
|
||||
S+0 int32
|
||||
S+8 int32
|
||||
S+16 int32
|
||||
S+24 int32
|
||||
=>
|
||||
r0 int32
|
|
@ -0,0 +1,14 @@
|
|||
r0 int32
|
||||
r1 int32
|
||||
r2 int32
|
||||
r3 int32
|
||||
r4 int32
|
||||
r5 int32
|
||||
r6 int32
|
||||
r7 int32
|
||||
S+0 int32
|
||||
S+8 int32
|
||||
S+16 int32
|
||||
S+24 int32
|
||||
=>
|
||||
r0 int32
|
|
@ -0,0 +1,14 @@
|
|||
r0 int32
|
||||
S+0 int32
|
||||
S+8 int32
|
||||
S+16 int32
|
||||
S+24 int32
|
||||
S+32 int32
|
||||
S+40 int32
|
||||
S+48 int32
|
||||
S+56 int32
|
||||
S+64 int32
|
||||
S+72 int32
|
||||
S+80 int32
|
||||
=>
|
||||
r0 int32
|
|
@ -0,0 +1,14 @@
|
|||
r0 int32
|
||||
r1 int32
|
||||
r2 int32
|
||||
r3 int32
|
||||
r4 int32
|
||||
r5 int32
|
||||
r6 int32
|
||||
r7 int32
|
||||
S+0 int32
|
||||
S+8 int32
|
||||
S+16 int32
|
||||
S+24 int32
|
||||
=>
|
||||
r0 int32
|
|
@ -0,0 +1,14 @@
|
|||
r0 int32
|
||||
S+0 int32
|
||||
S+8 int32
|
||||
S+16 int32
|
||||
S+24 int32
|
||||
S+32 int32
|
||||
S+40 int32
|
||||
S+48 int32
|
||||
S+56 int32
|
||||
S+64 int32
|
||||
S+72 int32
|
||||
S+80 int32
|
||||
=>
|
||||
r0 int32
|
|
@ -0,0 +1,14 @@
|
|||
r0 int32
|
||||
r1 int32
|
||||
r2 int32
|
||||
r3 int32
|
||||
r4 int32
|
||||
r5 int32
|
||||
r6 int32
|
||||
r7 int32
|
||||
S+0 int32
|
||||
S+8 int32
|
||||
S+16 int32
|
||||
S+24 int32
|
||||
=>
|
||||
r0 int32
|
|
@ -0,0 +1,14 @@
|
|||
r0 int32[int16]
|
||||
r1 int32[int16]
|
||||
r2 int32[int16]
|
||||
r3 int32[int16]
|
||||
S+0 int32[int16]
|
||||
S+4 int32[int16]
|
||||
S+8 int32[int16]
|
||||
S+12 int32[int16]
|
||||
S+16 int32[int16]
|
||||
S+20 int32[int16]
|
||||
S+24 int32[int16]
|
||||
S+28 int32[int16]
|
||||
=>
|
||||
r0 int32[int16]
|
|
@ -0,0 +1,14 @@
|
|||
r0 int32[int16]
|
||||
r1 int32[int16]
|
||||
r2 int32[int16]
|
||||
r3 int32[int16]
|
||||
S+0 int32[int16]
|
||||
S+4 int32[int16]
|
||||
S+8 int32[int16]
|
||||
S+12 int32[int16]
|
||||
S+16 int32[int16]
|
||||
S+20 int32[int16]
|
||||
S+24 int32[int16]
|
||||
S+28 int32[int16]
|
||||
=>
|
||||
r0 int32[int16]
|
|
@ -0,0 +1,14 @@
|
|||
r0 int32[int16]
|
||||
r1 int32[int16]
|
||||
r2 int32[int16]
|
||||
r3 int32[int16]
|
||||
S+0 int32[int16]
|
||||
S+4 int32[int16]
|
||||
S+8 int32[int16]
|
||||
S+12 int32[int16]
|
||||
S+16 int32[int16]
|
||||
S+20 int32[int16]
|
||||
S+24 int32[int16]
|
||||
S+28 int32[int16]
|
||||
=>
|
||||
r0 int32[int16]
|
|
@ -0,0 +1,14 @@
|
|||
S+0 int32[int16]
|
||||
S+4 int32[int16]
|
||||
S+8 int32[int16]
|
||||
S+12 int32[int16]
|
||||
S+16 int32[int16]
|
||||
S+20 int32[int16]
|
||||
S+24 int32[int16]
|
||||
S+28 int32[int16]
|
||||
S+32 int32[int16]
|
||||
S+36 int32[int16]
|
||||
S+40 int32[int16]
|
||||
S+44 int32[int16]
|
||||
=>
|
||||
eax int16
|
|
@ -0,0 +1,14 @@
|
|||
S+0 int32[int16]
|
||||
S+4 int32[int16]
|
||||
S+8 int32[int16]
|
||||
S+12 int32[int16]
|
||||
S+16 int32[int16]
|
||||
S+20 int32[int16]
|
||||
S+24 int32[int16]
|
||||
S+28 int32[int16]
|
||||
S+32 int32[int16]
|
||||
S+36 int32[int16]
|
||||
S+40 int32[int16]
|
||||
S+44 int32[int16]
|
||||
=>
|
||||
eax int16
|
|
@ -0,0 +1,14 @@
|
|||
S+0 int32[int16]
|
||||
S+4 int32[int16]
|
||||
S+8 int32[int16]
|
||||
S+12 int32[int16]
|
||||
S+16 int32[int16]
|
||||
S+20 int32[int16]
|
||||
S+24 int32[int16]
|
||||
S+28 int32[int16]
|
||||
S+32 int32[int16]
|
||||
S+36 int32[int16]
|
||||
S+40 int32[int16]
|
||||
S+44 int32[int16]
|
||||
=>
|
||||
eax int16
|
|
@ -0,0 +1,14 @@
|
|||
a0 int32[int16]
|
||||
a1 int32[int16]
|
||||
a2 int32[int16]
|
||||
t3 int32[int16]
|
||||
t4 int32[int16]
|
||||
t5 int32[int16]
|
||||
a6 int32[int16]
|
||||
a7 int32[int16]
|
||||
S+0 int32[int16]
|
||||
S+4 int32[int16]
|
||||
S+8 int32[int16]
|
||||
S+12 int32[int16]
|
||||
=>
|
||||
a0 int32[int16]
|
|
@ -0,0 +1,14 @@
|
|||
a0 int64[int32]
|
||||
a1 int64[int32]
|
||||
a2 int64[int32]
|
||||
t3 int64[int32]
|
||||
t4 int64[int32]
|
||||
t5 int64[int32]
|
||||
a6 int64[int32]
|
||||
a7 int64[int32]
|
||||
S+0 int64[int32]
|
||||
S+8 int64[int32]
|
||||
S+16 int64[int32]
|
||||
S+24 int64[int32]
|
||||
=>
|
||||
a0 int64[int32]
|
|
@ -0,0 +1,14 @@
|
|||
rdi int32
|
||||
rsi int32
|
||||
rdx int32
|
||||
rcx int32
|
||||
r8 int32
|
||||
r9 int32
|
||||
S+0 int32
|
||||
S+8 int32
|
||||
S+16 int32
|
||||
S+24 int32
|
||||
S+32 int32
|
||||
S+40 int32
|
||||
=>
|
||||
rax int32
|
|
@ -0,0 +1,14 @@
|
|||
rdi int32
|
||||
rsi int32
|
||||
rdx int32
|
||||
rcx int32
|
||||
r8 int32
|
||||
r9 int32
|
||||
S+0 int32
|
||||
S+8 int32
|
||||
S+16 int32
|
||||
S+24 int32
|
||||
S+32 int32
|
||||
S+40 int32
|
||||
=>
|
||||
rax int32
|
|
@ -0,0 +1,14 @@
|
|||
rdi int32
|
||||
rsi int32
|
||||
rdx int32
|
||||
rcx int32
|
||||
r8 int32
|
||||
r9 int32
|
||||
S+0 int32
|
||||
S+8 int32
|
||||
S+16 int32
|
||||
S+24 int32
|
||||
S+32 int32
|
||||
S+40 int32
|
||||
=>
|
||||
rax int32
|
|
@ -0,0 +1,14 @@
|
|||
rdi int32
|
||||
rsi int32
|
||||
rdx int32
|
||||
rcx int32
|
||||
r8 int32
|
||||
r9 int32
|
||||
S+0 int32
|
||||
S+8 int32
|
||||
S+16 int32
|
||||
S+24 int32
|
||||
S+32 int32
|
||||
S+40 int32
|
||||
=>
|
||||
rax int32
|
|
@ -0,0 +1,14 @@
|
|||
rcx int32
|
||||
rdx int32
|
||||
r8 int32
|
||||
r9 int32
|
||||
S+0 int32
|
||||
S+8 int32
|
||||
S+16 int32
|
||||
S+24 int32
|
||||
S+32 int32
|
||||
S+40 int32
|
||||
S+48 int32
|
||||
S+56 int32
|
||||
=>
|
||||
rax int32
|
|
@ -718,6 +718,8 @@ class CallingConventions {
|
|||
// How stack arguments are aligned.
|
||||
static constexpr AlignmentStrategy kArgumentStackAlignment =
|
||||
kAlignedToWordSizeAndValueSize;
|
||||
static constexpr AlignmentStrategy kArgumentStackAlignmentVarArgs =
|
||||
kArgumentStackAlignment;
|
||||
|
||||
// How fields in compounds are aligned.
|
||||
#if defined(DART_TARGET_OS_MACOS_IOS)
|
||||
|
|
|
@ -584,9 +584,14 @@ class CallingConventions {
|
|||
// https://developer.apple.com/documentation/xcode/writing_arm64_code_for_apple_platforms
|
||||
static constexpr AlignmentStrategy kArgumentStackAlignment =
|
||||
kAlignedToValueSize;
|
||||
// Varargs are aligned to wordsize.
|
||||
static constexpr AlignmentStrategy kArgumentStackAlignmentVarArgs =
|
||||
kAlignedToWordSize;
|
||||
#else
|
||||
static constexpr AlignmentStrategy kArgumentStackAlignment =
|
||||
kAlignedToWordSize;
|
||||
static constexpr AlignmentStrategy kArgumentStackAlignmentVarArgs =
|
||||
kArgumentStackAlignment;
|
||||
#endif
|
||||
|
||||
// How fields in compounds are aligned.
|
||||
|
|
|
@ -503,6 +503,8 @@ class CallingConventions {
|
|||
// How stack arguments are aligned.
|
||||
static constexpr AlignmentStrategy kArgumentStackAlignment =
|
||||
kAlignedToWordSize;
|
||||
static constexpr AlignmentStrategy kArgumentStackAlignmentVarArgs =
|
||||
kArgumentStackAlignment;
|
||||
|
||||
// How fields in compounds are aligned.
|
||||
#if defined(DART_TARGET_OS_WINDOWS)
|
||||
|
|
|
@ -557,6 +557,8 @@ class CallingConventions {
|
|||
// How stack arguments are aligned.
|
||||
static constexpr AlignmentStrategy kArgumentStackAlignment =
|
||||
kAlignedToWordSizeAndValueSize;
|
||||
static constexpr AlignmentStrategy kArgumentStackAlignmentVarArgs =
|
||||
kArgumentStackAlignment;
|
||||
|
||||
// How fields in compounds are aligned.
|
||||
static constexpr AlignmentStrategy kFieldAlignment = kAlignedToValueSize;
|
||||
|
|
|
@ -571,6 +571,8 @@ class CallingConventions {
|
|||
// How stack arguments are aligned.
|
||||
static constexpr AlignmentStrategy kArgumentStackAlignment =
|
||||
kAlignedToWordSize;
|
||||
static constexpr AlignmentStrategy kArgumentStackAlignmentVarArgs =
|
||||
kArgumentStackAlignment;
|
||||
|
||||
// How fields in compounds are aligned.
|
||||
static constexpr AlignmentStrategy kFieldAlignment = kAlignedToValueSize;
|
||||
|
@ -641,6 +643,8 @@ class CallingConventions {
|
|||
// How stack arguments are aligned.
|
||||
static constexpr AlignmentStrategy kArgumentStackAlignment =
|
||||
kAlignedToWordSize;
|
||||
static constexpr AlignmentStrategy kArgumentStackAlignmentVarArgs =
|
||||
kArgumentStackAlignment;
|
||||
|
||||
// How fields in compounds are aligned.
|
||||
static constexpr AlignmentStrategy kFieldAlignment = kAlignedToValueSize;
|
||||
|
|
|
@ -124,6 +124,11 @@ final testCases = [
|
|||
Pointer.fromFunction<VariadicAt1Int64x7Struct12BytesHomogeneousInt32Type>(
|
||||
variadicAt1Int64x7Struct12BytesHomogeneousInt32, 0),
|
||||
variadicAt1Int64x7Struct12BytesHomogeneousInt32AfterCallback),
|
||||
CallbackTest.withCheck(
|
||||
"VariadicAt1Struct12BytesHomogeneousInt32Int32x4",
|
||||
Pointer.fromFunction<VariadicAt1Struct12BytesHomogeneousInt32Int32x4Type>(
|
||||
variadicAt1Struct12BytesHomogeneousInt32Int32x4, 0),
|
||||
variadicAt1Struct12BytesHomogeneousInt32Int32x4AfterCallback),
|
||||
];
|
||||
typedef VariadicAt1Int64x2Type = Int64 Function(Int64, VarArgs<(Int64,)>);
|
||||
|
||||
|
@ -1488,3 +1493,70 @@ void variadicAt1Int64x7Struct12BytesHomogeneousInt32AfterCallback() {
|
|||
|
||||
Expect.equals(5, result);
|
||||
}
|
||||
|
||||
typedef VariadicAt1Struct12BytesHomogeneousInt32Int32x4Type = Int32 Function(
|
||||
Struct12BytesHomogeneousInt32, VarArgs<(Int32, Int32, Int32, Int32)>);
|
||||
|
||||
// Global variables to be able to test inputs after callback returned.
|
||||
Struct12BytesHomogeneousInt32
|
||||
variadicAt1Struct12BytesHomogeneousInt32Int32x4_a0 =
|
||||
Pointer<Struct12BytesHomogeneousInt32>.fromAddress(0).ref;
|
||||
int variadicAt1Struct12BytesHomogeneousInt32Int32x4_a1 = 0;
|
||||
int variadicAt1Struct12BytesHomogeneousInt32Int32x4_a2 = 0;
|
||||
int variadicAt1Struct12BytesHomogeneousInt32Int32x4_a3 = 0;
|
||||
int variadicAt1Struct12BytesHomogeneousInt32Int32x4_a4 = 0;
|
||||
|
||||
// Result variable also global, so we can delete it after the callback.
|
||||
int variadicAt1Struct12BytesHomogeneousInt32Int32x4Result = 0;
|
||||
|
||||
int variadicAt1Struct12BytesHomogeneousInt32Int32x4CalculateResult() {
|
||||
int result = 0;
|
||||
|
||||
result += variadicAt1Struct12BytesHomogeneousInt32Int32x4_a0.a0;
|
||||
result += variadicAt1Struct12BytesHomogeneousInt32Int32x4_a0.a1;
|
||||
result += variadicAt1Struct12BytesHomogeneousInt32Int32x4_a0.a2;
|
||||
result += variadicAt1Struct12BytesHomogeneousInt32Int32x4_a1;
|
||||
result += variadicAt1Struct12BytesHomogeneousInt32Int32x4_a2;
|
||||
result += variadicAt1Struct12BytesHomogeneousInt32Int32x4_a3;
|
||||
result += variadicAt1Struct12BytesHomogeneousInt32Int32x4_a4;
|
||||
|
||||
variadicAt1Struct12BytesHomogeneousInt32Int32x4Result = result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Variadic arguments test on macos_arm64.
|
||||
int variadicAt1Struct12BytesHomogeneousInt32Int32x4(
|
||||
Struct12BytesHomogeneousInt32 a0, int a1, int a2, int a3, int a4) {
|
||||
print(
|
||||
"variadicAt1Struct12BytesHomogeneousInt32Int32x4(${a0}, ${a1}, ${a2}, ${a3}, ${a4})");
|
||||
|
||||
// Possibly throw.
|
||||
if (a0.a0 == 42 || a0.a0 == 84) {
|
||||
print("throwing!");
|
||||
throw Exception(
|
||||
"VariadicAt1Struct12BytesHomogeneousInt32Int32x4 throwing on purpose!");
|
||||
}
|
||||
|
||||
variadicAt1Struct12BytesHomogeneousInt32Int32x4_a0 = a0;
|
||||
variadicAt1Struct12BytesHomogeneousInt32Int32x4_a1 = a1;
|
||||
variadicAt1Struct12BytesHomogeneousInt32Int32x4_a2 = a2;
|
||||
variadicAt1Struct12BytesHomogeneousInt32Int32x4_a3 = a3;
|
||||
variadicAt1Struct12BytesHomogeneousInt32Int32x4_a4 = a4;
|
||||
|
||||
final result =
|
||||
variadicAt1Struct12BytesHomogeneousInt32Int32x4CalculateResult();
|
||||
|
||||
print("result = $result");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void variadicAt1Struct12BytesHomogeneousInt32Int32x4AfterCallback() {
|
||||
final result =
|
||||
variadicAt1Struct12BytesHomogeneousInt32Int32x4CalculateResult();
|
||||
|
||||
print("after callback result = $result");
|
||||
|
||||
Expect.equals(-4, result);
|
||||
}
|
||||
|
|
|
@ -145,6 +145,13 @@ final testCases = [
|
|||
variadicAt1Int64x7Struct12BytesHomogeneousInt32,
|
||||
exceptionalReturn: 0),
|
||||
variadicAt1Int64x7Struct12BytesHomogeneousInt32AfterCallback),
|
||||
CallbackTest.withCheck(
|
||||
"VariadicAt1Struct12BytesHomogeneousInt32Int32x4",
|
||||
NativeCallable<
|
||||
VariadicAt1Struct12BytesHomogeneousInt32Int32x4Type>.isolateLocal(
|
||||
variadicAt1Struct12BytesHomogeneousInt32Int32x4,
|
||||
exceptionalReturn: 0),
|
||||
variadicAt1Struct12BytesHomogeneousInt32Int32x4AfterCallback),
|
||||
];
|
||||
typedef VariadicAt1Int64x2Type = Int64 Function(Int64, VarArgs<(Int64,)>);
|
||||
|
||||
|
@ -1509,3 +1516,70 @@ void variadicAt1Int64x7Struct12BytesHomogeneousInt32AfterCallback() {
|
|||
|
||||
Expect.equals(5, result);
|
||||
}
|
||||
|
||||
typedef VariadicAt1Struct12BytesHomogeneousInt32Int32x4Type = Int32 Function(
|
||||
Struct12BytesHomogeneousInt32, VarArgs<(Int32, Int32, Int32, Int32)>);
|
||||
|
||||
// Global variables to be able to test inputs after callback returned.
|
||||
Struct12BytesHomogeneousInt32
|
||||
variadicAt1Struct12BytesHomogeneousInt32Int32x4_a0 =
|
||||
Pointer<Struct12BytesHomogeneousInt32>.fromAddress(0).ref;
|
||||
int variadicAt1Struct12BytesHomogeneousInt32Int32x4_a1 = 0;
|
||||
int variadicAt1Struct12BytesHomogeneousInt32Int32x4_a2 = 0;
|
||||
int variadicAt1Struct12BytesHomogeneousInt32Int32x4_a3 = 0;
|
||||
int variadicAt1Struct12BytesHomogeneousInt32Int32x4_a4 = 0;
|
||||
|
||||
// Result variable also global, so we can delete it after the callback.
|
||||
int variadicAt1Struct12BytesHomogeneousInt32Int32x4Result = 0;
|
||||
|
||||
int variadicAt1Struct12BytesHomogeneousInt32Int32x4CalculateResult() {
|
||||
int result = 0;
|
||||
|
||||
result += variadicAt1Struct12BytesHomogeneousInt32Int32x4_a0.a0;
|
||||
result += variadicAt1Struct12BytesHomogeneousInt32Int32x4_a0.a1;
|
||||
result += variadicAt1Struct12BytesHomogeneousInt32Int32x4_a0.a2;
|
||||
result += variadicAt1Struct12BytesHomogeneousInt32Int32x4_a1;
|
||||
result += variadicAt1Struct12BytesHomogeneousInt32Int32x4_a2;
|
||||
result += variadicAt1Struct12BytesHomogeneousInt32Int32x4_a3;
|
||||
result += variadicAt1Struct12BytesHomogeneousInt32Int32x4_a4;
|
||||
|
||||
variadicAt1Struct12BytesHomogeneousInt32Int32x4Result = result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Variadic arguments test on macos_arm64.
|
||||
int variadicAt1Struct12BytesHomogeneousInt32Int32x4(
|
||||
Struct12BytesHomogeneousInt32 a0, int a1, int a2, int a3, int a4) {
|
||||
print(
|
||||
"variadicAt1Struct12BytesHomogeneousInt32Int32x4(${a0}, ${a1}, ${a2}, ${a3}, ${a4})");
|
||||
|
||||
// Possibly throw.
|
||||
if (a0.a0 == 42 || a0.a0 == 84) {
|
||||
print("throwing!");
|
||||
throw Exception(
|
||||
"VariadicAt1Struct12BytesHomogeneousInt32Int32x4 throwing on purpose!");
|
||||
}
|
||||
|
||||
variadicAt1Struct12BytesHomogeneousInt32Int32x4_a0 = a0;
|
||||
variadicAt1Struct12BytesHomogeneousInt32Int32x4_a1 = a1;
|
||||
variadicAt1Struct12BytesHomogeneousInt32Int32x4_a2 = a2;
|
||||
variadicAt1Struct12BytesHomogeneousInt32Int32x4_a3 = a3;
|
||||
variadicAt1Struct12BytesHomogeneousInt32Int32x4_a4 = a4;
|
||||
|
||||
final result =
|
||||
variadicAt1Struct12BytesHomogeneousInt32Int32x4CalculateResult();
|
||||
|
||||
print("result = $result");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void variadicAt1Struct12BytesHomogeneousInt32Int32x4AfterCallback() {
|
||||
final result =
|
||||
variadicAt1Struct12BytesHomogeneousInt32Int32x4CalculateResult();
|
||||
|
||||
print("after callback result = $result");
|
||||
|
||||
Expect.equals(-4, result);
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ void main() {
|
|||
testVariadicAt1DoubleInt64Int32Struct20BytesHomogeneouLeaf();
|
||||
testVariadicAt5Doublex5Leaf();
|
||||
testVariadicAt1Int64x7Struct12BytesHomogeneousInt32Leaf();
|
||||
testVariadicAt1Struct12BytesHomogeneousInt32Int32x4Leaf();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -804,3 +805,38 @@ void testVariadicAt1Int64x7Struct12BytesHomogeneousInt32Leaf() {
|
|||
|
||||
calloc.free(a7Pointer);
|
||||
}
|
||||
|
||||
final variadicAt1Struct12BytesHomogeneousInt32Int32x4Leaf =
|
||||
ffiTestFunctions.lookupFunction<
|
||||
Int32 Function(Struct12BytesHomogeneousInt32,
|
||||
VarArgs<(Int32, Int32, Int32, Int32)>),
|
||||
int Function(Struct12BytesHomogeneousInt32, int, int, int, int)>(
|
||||
"VariadicAt1Struct12BytesHomogeneousInt32Int32x4",
|
||||
isLeaf: true);
|
||||
|
||||
/// Variadic arguments test on macos_arm64.
|
||||
void testVariadicAt1Struct12BytesHomogeneousInt32Int32x4Leaf() {
|
||||
final a0Pointer = calloc<Struct12BytesHomogeneousInt32>();
|
||||
final Struct12BytesHomogeneousInt32 a0 = a0Pointer.ref;
|
||||
int a1;
|
||||
int a2;
|
||||
int a3;
|
||||
int a4;
|
||||
|
||||
a0.a0 = -1;
|
||||
a0.a1 = 2;
|
||||
a0.a2 = -3;
|
||||
a1 = 4;
|
||||
a2 = -5;
|
||||
a3 = 6;
|
||||
a4 = -7;
|
||||
|
||||
final result =
|
||||
variadicAt1Struct12BytesHomogeneousInt32Int32x4Leaf(a0, a1, a2, a3, a4);
|
||||
|
||||
print("result = $result");
|
||||
|
||||
Expect.equals(-4, result);
|
||||
|
||||
calloc.free(a0Pointer);
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ void main() {
|
|||
testVariadicAt1DoubleInt64Int32Struct20BytesHomogeneouNativeLeaf();
|
||||
testVariadicAt5Doublex5NativeLeaf();
|
||||
testVariadicAt1Int64x7Struct12BytesHomogeneousInt32NativeLeaf();
|
||||
testVariadicAt1Struct12BytesHomogeneousInt32Int32x4NativeLeaf();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -799,3 +800,37 @@ void testVariadicAt1Int64x7Struct12BytesHomogeneousInt32NativeLeaf() {
|
|||
|
||||
calloc.free(a7Pointer);
|
||||
}
|
||||
|
||||
@Native<
|
||||
Int32 Function(Struct12BytesHomogeneousInt32,
|
||||
VarArgs<(Int32, Int32, Int32, Int32)>)>(
|
||||
symbol: 'VariadicAt1Struct12BytesHomogeneousInt32Int32x4', isLeaf: true)
|
||||
external int variadicAt1Struct12BytesHomogeneousInt32Int32x4NativeLeaf(
|
||||
Struct12BytesHomogeneousInt32 a0, int a1, int a2, int a3, int a4);
|
||||
|
||||
/// Variadic arguments test on macos_arm64.
|
||||
void testVariadicAt1Struct12BytesHomogeneousInt32Int32x4NativeLeaf() {
|
||||
final a0Pointer = calloc<Struct12BytesHomogeneousInt32>();
|
||||
final Struct12BytesHomogeneousInt32 a0 = a0Pointer.ref;
|
||||
int a1;
|
||||
int a2;
|
||||
int a3;
|
||||
int a4;
|
||||
|
||||
a0.a0 = -1;
|
||||
a0.a1 = 2;
|
||||
a0.a2 = -3;
|
||||
a1 = 4;
|
||||
a2 = -5;
|
||||
a3 = 6;
|
||||
a4 = -7;
|
||||
|
||||
final result = variadicAt1Struct12BytesHomogeneousInt32Int32x4NativeLeaf(
|
||||
a0, a1, a2, a3, a4);
|
||||
|
||||
print("result = $result");
|
||||
|
||||
Expect.equals(-4, result);
|
||||
|
||||
calloc.free(a0Pointer);
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ void main() {
|
|||
testVariadicAt1DoubleInt64Int32Struct20BytesHomogeneouNative();
|
||||
testVariadicAt5Doublex5Native();
|
||||
testVariadicAt1Int64x7Struct12BytesHomogeneousInt32Native();
|
||||
testVariadicAt1Struct12BytesHomogeneousInt32Int32x4Native();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -794,3 +795,37 @@ void testVariadicAt1Int64x7Struct12BytesHomogeneousInt32Native() {
|
|||
|
||||
calloc.free(a7Pointer);
|
||||
}
|
||||
|
||||
@Native<
|
||||
Int32 Function(Struct12BytesHomogeneousInt32,
|
||||
VarArgs<(Int32, Int32, Int32, Int32)>)>(
|
||||
symbol: 'VariadicAt1Struct12BytesHomogeneousInt32Int32x4')
|
||||
external int variadicAt1Struct12BytesHomogeneousInt32Int32x4Native(
|
||||
Struct12BytesHomogeneousInt32 a0, int a1, int a2, int a3, int a4);
|
||||
|
||||
/// Variadic arguments test on macos_arm64.
|
||||
void testVariadicAt1Struct12BytesHomogeneousInt32Int32x4Native() {
|
||||
final a0Pointer = calloc<Struct12BytesHomogeneousInt32>();
|
||||
final Struct12BytesHomogeneousInt32 a0 = a0Pointer.ref;
|
||||
int a1;
|
||||
int a2;
|
||||
int a3;
|
||||
int a4;
|
||||
|
||||
a0.a0 = -1;
|
||||
a0.a1 = 2;
|
||||
a0.a2 = -3;
|
||||
a1 = 4;
|
||||
a2 = -5;
|
||||
a3 = 6;
|
||||
a4 = -7;
|
||||
|
||||
final result =
|
||||
variadicAt1Struct12BytesHomogeneousInt32Int32x4Native(a0, a1, a2, a3, a4);
|
||||
|
||||
print("result = $result");
|
||||
|
||||
Expect.equals(-4, result);
|
||||
|
||||
calloc.free(a0Pointer);
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ void main() {
|
|||
testVariadicAt1DoubleInt64Int32Struct20BytesHomogeneou();
|
||||
testVariadicAt5Doublex5();
|
||||
testVariadicAt1Int64x7Struct12BytesHomogeneousInt32();
|
||||
testVariadicAt1Struct12BytesHomogeneousInt32Int32x4();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -769,3 +770,37 @@ void testVariadicAt1Int64x7Struct12BytesHomogeneousInt32() {
|
|||
|
||||
calloc.free(a7Pointer);
|
||||
}
|
||||
|
||||
final variadicAt1Struct12BytesHomogeneousInt32Int32x4 =
|
||||
ffiTestFunctions.lookupFunction<
|
||||
Int32 Function(Struct12BytesHomogeneousInt32,
|
||||
VarArgs<(Int32, Int32, Int32, Int32)>),
|
||||
int Function(Struct12BytesHomogeneousInt32, int, int, int,
|
||||
int)>("VariadicAt1Struct12BytesHomogeneousInt32Int32x4");
|
||||
|
||||
/// Variadic arguments test on macos_arm64.
|
||||
void testVariadicAt1Struct12BytesHomogeneousInt32Int32x4() {
|
||||
final a0Pointer = calloc<Struct12BytesHomogeneousInt32>();
|
||||
final Struct12BytesHomogeneousInt32 a0 = a0Pointer.ref;
|
||||
int a1;
|
||||
int a2;
|
||||
int a3;
|
||||
int a4;
|
||||
|
||||
a0.a0 = -1;
|
||||
a0.a1 = 2;
|
||||
a0.a2 = -3;
|
||||
a1 = 4;
|
||||
a2 = -5;
|
||||
a3 = 6;
|
||||
a4 = -7;
|
||||
|
||||
final result =
|
||||
variadicAt1Struct12BytesHomogeneousInt32Int32x4(a0, a1, a2, a3, a4);
|
||||
|
||||
print("result = $result");
|
||||
|
||||
Expect.equals(-4, result);
|
||||
|
||||
calloc.free(a0Pointer);
|
||||
}
|
||||
|
|
|
@ -847,6 +847,18 @@ https://github.com/dart-lang/sdk/issues/49460""",
|
|||
int64,
|
||||
"Struct stradles last argument register, variadic",
|
||||
),
|
||||
FunctionType(
|
||||
varArgsIndex: 1,
|
||||
[
|
||||
struct12bytesInt,
|
||||
int32,
|
||||
int32,
|
||||
int32,
|
||||
int32,
|
||||
],
|
||||
int32,
|
||||
"Variadic arguments test on macos_arm64.",
|
||||
),
|
||||
];
|
||||
|
||||
final struct1byteBool = StructType([bool_]);
|
||||
|
|
Loading…
Reference in a new issue