infix
A JIT-Powered FFI Library for C
Loading...
Searching...
No Matches
402_variadic_functions.c File Reference

Unit test for FFI calls to and from variadic C functions. More...

#include "common/double_tap.h"
#include "common/infix_config.h"
#include "types.h"
#include <infix/infix.h>
#include <math.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
Include dependency graph for 402_variadic_functions.c:

Macros

#define DBLTAP_IMPLEMENTATION
 

Functions

int forward_variadic_checker (char *buffer, size_t size, const char *format,...)
 
int forward_variadic_aggregate_checker (int fixed_arg,...)
 
int variadic_reverse_handler (const char *topic,...)
 
 subtest ("Forward variadic call")
 
 subtest ("Forward variadic call (aggregates)")
 
 subtest ("Reverse variadic callback")
 
 subtest ("Platform ABI: macOS AArch64 variadic struct passing")
 
 subtest ("Platform ABI: Windows x64 variadic float/double passing")
 

Variables

 TEST
 

Detailed Description

Unit test for FFI calls to and from variadic C functions.

This test file is extremely important for verifying ABI-compliance, as the rules for passing variadic arguments differ significantly between platforms, even on the same architecture.

The test covers:

  • Forward Variadic Call (Primitives): A call is made to a printf-like function with a mix of fixed and variadic arguments (*char, int, double). This tests the core variadic calling mechanism.
  • Forward Variadic Call (Aggregates): A call is made passing a struct as a variadic argument. This is highly platform-dependent:
    • On System V, the struct is passed on the stack.
    • On Windows x64, a pointer to the struct is passed in a GPR.
    • On AArch64, the struct is passed on the stack.
  • Reverse Variadic Callback: A reverse trampoline is created for a variadic function. The test verifies that when the JIT-compiled function pointer is called with variadic arguments, the C handler receives them correctly via va_list/va_arg.
  • Platform-Specific ABI Deviations: Includes dedicated subtests for known tricky variadic cases, such as passing floats/doubles on Windows x64 (which requires them to be passed in both GPRs and XMM registers) and passing structs on macOS on ARM (which has its own unique stack-passing rules).

Macro Definition Documentation

◆ DBLTAP_IMPLEMENTATION

#define DBLTAP_IMPLEMENTATION

Function Documentation

◆ forward_variadic_aggregate_checker()

int forward_variadic_aggregate_checker ( int  fixed_arg,
  ... 
)

◆ forward_variadic_checker()

int forward_variadic_checker ( char *  buffer,
size_t  size,
const char *  format,
  ... 
)

◆ subtest() [1/5]

subtest ( "Forward variadic call (aggregates)"  )

◆ subtest() [2/5]

subtest ( "Forward variadic call"  )

◆ subtest() [3/5]

subtest ( "Platform ABI: macOS AArch64 variadic struct passing"  )

◆ subtest() [4/5]

subtest ( "Platform ABI: Windows x64 variadic float/double passing"  )

◆ subtest() [5/5]

subtest ( "Reverse variadic callback"  )

◆ variadic_reverse_handler()

int variadic_reverse_handler ( const char *  topic,
  ... 
)

Variable Documentation

◆ TEST

TEST
Initial value:
{
plan(5)
#define plan(count)
Definition double_tap.h:163