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

Tests FFI calls with a large number of arguments, forcing stack usage. More...

#include "common/double_tap.h"
#include "types.h"
#include <infix/infix.h>
#include <math.h>
#include <string.h>
Include dependency graph for 401_large_stack.c:

Macros

#define DBLTAP_IMPLEMENTATION
 
#define MAX_REG_DOUBLES   8
 
#define ONE_STACK_DOUBLE   (MAX_REG_DOUBLES + 1)
 
#define ARG(N)   c23_maybe_unused double arg##N
 
#define LIST10(M, p)   M(p##0), M(p##1), M(p##2), M(p##3), M(p##4), M(p##5), M(p##6), M(p##7), M(p##8), M(p##9)
 
#define LIST100(M, p)
 
#define ARGS_0_TO_99
 
#define ARGS_100_TO_499   LIST100(ARG, 1), LIST100(ARG, 2), LIST100(ARG, 3), LIST100(ARG, 4)
 
#define ARGS_500_TO_519   LIST10(ARG, 50), LIST10(ARG, 51)
 
#define NUM_LARGE_ARGS   520
 

Functions

double sum_max_reg_doubles (double a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8)
 Sums the maximum number of doubles that can fit in registers for the target ABI.
 
double sum_one_stack_double (double a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
 Sums one more double than can fit in registers, forcing one onto the stack.
 
double large_stack_callee (ARGS_0_TO_99, ARGS_100_TO_499, ARGS_500_TO_519)
 A function with 520 arguments to test massive stack frames.
 
int many_args_callback_handler (int a, double b, int c, const char *d, Point e, float f)
 A callback handler that takes a mix of register and stack arguments.
 
void execute_many_args_callback (int(*func_ptr)(int, double, int, const char *, Point, float))
 A harness to call the generated callback with many arguments.
 
 subtest ("Forward calls with register and stack arguments")
 
 subtest ("Reverse call (callback) with stack arguments")
 

Variables

 TEST
 

Detailed Description

Tests FFI calls with a large number of arguments, forcing stack usage.

Copyright (c) 2025 Sanko Robinson

This source code is dual-licensed under the Artistic License 2.0 or the MIT License. You may choose to use this code under the terms of either license.

SPDX-License-Identifier: (Artistic-2.0 OR MIT)

The documentation blocks within this file are licensed under the Creative Commons Attribution 4.0 International License (CC BY 4.0).

SPDX-License-Identifier: CC-BY-4.0

This test suite is designed to stress-test the ABI implementation when the number of arguments exceeds the number of available parameter registers. It verifies correct stack layout, alignment, and argument marshalling for both forward and reverse FFI calls.

It covers several key scenarios:

  1. Forward Call (Register Limit): A function is called with the exact number of arguments to fill all available parameter registers, testing this important boundary condition.
  2. Forward Call (One on Stack): A function is called with one more argument than fits in registers, testing the transition to stack-based passing.
  3. Forward Call (Massive Stack): A function with over 500 arguments is called, verifying the library's ability to handle stack frames larger than a single memory page and exercising the bulk-copy optimization for homogeneous stack arguments.
  4. Reverse Call (Callback): A callback is created for a handler with a mixed set of arguments that will spill onto the stack, ensuring the JIT stub can correctly retrieve arguments from both registers and the caller's stack frame.

Macro Definition Documentation

◆ ARG

#define ARG (   N)    c23_maybe_unused double arg##N

◆ ARGS_0_TO_99

#define ARGS_0_TO_99
Value:
LIST10(ARG, ), LIST10(ARG, 1), LIST10(ARG, 2), LIST10(ARG, 3), LIST10(ARG, 4), LIST10(ARG, 5), LIST10(ARG, 6), \
LIST10(ARG, 7), LIST10(ARG, 8), LIST10(ARG, 9)
#define ARG(N)
Definition 401_large_stack.c:101
#define LIST10(M, p)
Definition 401_large_stack.c:102

◆ ARGS_100_TO_499

#define ARGS_100_TO_499   LIST100(ARG, 1), LIST100(ARG, 2), LIST100(ARG, 3), LIST100(ARG, 4)

◆ ARGS_500_TO_519

#define ARGS_500_TO_519   LIST10(ARG, 50), LIST10(ARG, 51)

◆ DBLTAP_IMPLEMENTATION

#define DBLTAP_IMPLEMENTATION

◆ LIST10

#define LIST10 (   M,
 
)    M(p##0), M(p##1), M(p##2), M(p##3), M(p##4), M(p##5), M(p##6), M(p##7), M(p##8), M(p##9)

◆ LIST100

#define LIST100 (   M,
 
)
Value:
LIST10(M, p##0), LIST10(M, p##1), LIST10(M, p##2), LIST10(M, p##3), LIST10(M, p##4), LIST10(M, p##5), \
LIST10(M, p##6), LIST10(M, p##7), LIST10(M, p##8), LIST10(M, p##9)

◆ MAX_REG_DOUBLES

#define MAX_REG_DOUBLES   8

◆ NUM_LARGE_ARGS

#define NUM_LARGE_ARGS   520

◆ ONE_STACK_DOUBLE

#define ONE_STACK_DOUBLE   (MAX_REG_DOUBLES + 1)

Function Documentation

◆ execute_many_args_callback()

void execute_many_args_callback ( int(*)(int, double, int, const char *, Point, float)  func_ptr)

A harness to call the generated callback with many arguments.

◆ large_stack_callee()

double large_stack_callee ( ARGS_0_TO_99  ,
ARGS_100_TO_499  ,
ARGS_500_TO_519   
)

A function with 520 arguments to test massive stack frames.

◆ many_args_callback_handler()

int many_args_callback_handler ( int  a,
double  b,
int  c,
const char *  d,
Point  e,
float  f 
)

A callback handler that takes a mix of register and stack arguments.

◆ subtest() [1/2]

subtest ( "Forward calls with register and stack arguments"  )

◆ subtest() [2/2]

subtest ( "Reverse call (callback) with stack arguments"  )

◆ sum_max_reg_doubles()

double sum_max_reg_doubles ( double  a1,
double  a2,
double  a3,
double  a4,
double  a5,
double  a6,
double  a7,
double  a8 
)

Sums the maximum number of doubles that can fit in registers for the target ABI.

◆ sum_one_stack_double()

double sum_one_stack_double ( double  a1,
double  a2,
double  a3,
double  a4,
double  a5,
double  a6,
double  a7,
double  a8,
double  a9 
)

Sums one more double than can fit in registers, forcing one onto the stack.

Variable Documentation

◆ TEST

TEST
Initial value:
{
plan(2)
#define plan(count)
Definition double_tap.h:132