infix
A JIT-Powered FFI Library for C
Loading...
Searching...
No Matches
infix_internals.h
Go to the documentation of this file.
1
33#pragma once
34#include "common/infix_config.h"
35#include "common/platform.h"
36#include <infix/infix.h>
56typedef struct {
57#if defined(INFIX_OS_WINDOWS)
58 HANDLE handle;
59#else
60 int shm_fd;
61#endif
62 void * rx_ptr;
63 void * rw_ptr;
64 size_t size;
75typedef struct {
76 void * rw_ptr;
77 size_t size;
105typedef void (*infix_internal_dispatch_callback_fn)(infix_reverse_t *, void *, void **);
180typedef struct {
181 uint8_t * code;
182 size_t capacity;
183 size_t size;
184 bool error;
196 void * handle;
197#if defined(INFIX_OS_WINDOWS)
198 bool is_pseudo_handle;
199#endif
200};
201// ABI Abstraction Layer
207#define INFIX_MAX_STACK_ALLOC (1024 * 1024 * 4)
212#define INFIX_MAX_ARG_SIZE (1024 * 64)
221typedef enum {
224#if defined(INFIX_ABI_AAPCS64)
226 ARG_LOCATION_VPR,
230 ARG_LOCATION_GPR_REFERENCE,
232 ARG_LOCATION_VPR_HFA,
233#else // x64 ABIs
235 ARG_LOCATION_XMM,
244#endif
269typedef struct {
271 uint8_t num_gpr_args;
272#if defined(INFIX_ABI_AAPCS64)
273 uint8_t num_vpr_args;
274#else
275 uint8_t num_xmm_args;
276#endif
281 size_t num_args;
282 void * target_fn;
313typedef struct {
329 infix_status (*prepare_forward_call_frame)(infix_arena_t * arena,
330 infix_call_frame_layout ** out_layout,
333 size_t num_args,
334 size_t num_fixed_args,
335 void * target_fn);
342 infix_status (*generate_forward_prologue)(code_buffer * buf, infix_call_frame_layout * layout);
352 infix_status (*generate_forward_argument_moves)(code_buffer * buf,
355 size_t num_args,
356 size_t num_fixed_args);
363 infix_status (*generate_forward_call_instruction)(code_buffer * buf, infix_call_frame_layout * layout);
371 infix_status (*generate_forward_epilogue)(code_buffer * buf,
382typedef struct {
390 infix_status (*prepare_reverse_call_frame)(infix_arena_t * arena,
392 infix_reverse_t * context);
399 infix_status (*generate_reverse_prologue)(code_buffer * buf, infix_reverse_call_frame_layout * layout);
407 infix_status (*generate_reverse_argument_marshalling)(code_buffer * buf,
409 infix_reverse_t * context);
417 infix_status (*generate_reverse_dispatcher_call)(code_buffer * buf,
419 infix_reverse_t * context);
427 infix_status (*generate_reverse_epilogue)(code_buffer * buf,
429 infix_reverse_t * context);
431
444
459
466typedef struct {
468 infix_status (*prepare_direct_forward_call_frame)(infix_arena_t * arena,
469 infix_direct_call_frame_layout ** out_layout,
472 size_t num_args,
474 void * target_fn);
476 infix_status (*generate_direct_forward_prologue)(code_buffer * buf, infix_direct_call_frame_layout * layout);
478 infix_status (*generate_direct_forward_argument_moves)(code_buffer * buf, infix_direct_call_frame_layout * layout);
480 infix_status (*generate_direct_forward_call_instruction)(code_buffer * buf,
483 infix_status (*generate_direct_forward_epilogue)(code_buffer * buf,
486
488
489// Internal Function Prototypes (Shared across modules)
512 long system_code,
513 const char * msg);
563 size_t,
564 const infix_type *,
585INFIX_INTERNAL size_t _infix_estimate_graph_size(infix_arena_t * temp_arena, const infix_type * type);
622INFIX_INTERNAL void code_buffer_append(code_buffer * buf, const void * data, size_t len);
628INFIX_INTERNAL void emit_byte(code_buffer * buf, uint8_t byte);
634INFIX_INTERNAL void emit_int32(code_buffer * buf, int32_t value);
640INFIX_INTERNAL void emit_int64(code_buffer * buf, int64_t value);
697 void * return_value_ptr,
698 void ** args_array);
699// Utility Macros & Inlines
701#define EMIT_BYTES(buf, ...) \
702 do { \
703 const uint8_t bytes[] = {__VA_ARGS__}; \
704 code_buffer_append((buf), bytes, sizeof(bytes)); \
705 } while (0)
712static inline size_t _infix_align_up(size_t value, size_t alignment) {
713 return (value + alignment - 1) & ~(alignment - 1);
714}
720static inline bool is_float(const infix_type * type) {
722}
728static inline bool is_double(const infix_type * type) {
730}
736static inline bool is_long_double(const infix_type * type) {
738}
739// Include architecture-specific emitter prototypes for internal use by the JIT engine.
740#if defined(INFIX_ABI_SYSV_X64) || defined(INFIX_ABI_WINDOWS_X64)
742#elif defined(INFIX_ABI_AAPCS64)
744#endif
infix_arena_t * arena
Definition 005_layouts.c:62
infix_registry_t * registry
Definition 008_registry_introspection.c:33
infix_type * arg_types[]
Definition 901_call_overhead.c:62
infix_type * ret_type
Definition 901_call_overhead.c:61
infix_direct_arg_handler_t handlers[2]
Definition 901_call_overhead.c:104
Declares internal helper functions for emitting AArch64 machine code.
Declares internal helper functions for emitting x86-64 machine code.
#define c23_nodiscard
Internal alias for the public INFIX_NODISCARD macro.
Definition compat_c23.h:91
infix_error_code_t
Enumerates specific error codes.
Definition infix.h:1342
infix_error_category_t
Enumerates the high-level categories of errors that can occur.
Definition infix.h:1332
union infix_type_t::@0 meta
A union containing metadata specific to the type's category.
infix_status
Enumerates the possible status codes returned by infix API functions.
Definition infix.h:433
infix_type_category category
Definition infix.h:275
infix_primitive_type_id primitive_id
Metadata for INFIX_TYPE_PRIMITIVE.
Definition infix.h:285
infix_print_dialect_t
Specifies the output format for printing types and function signatures.
Definition infix.h:1157
@ INFIX_PRIMITIVE_LONG_DOUBLE
Definition infix.h:257
@ INFIX_PRIMITIVE_FLOAT
Definition infix.h:255
@ INFIX_PRIMITIVE_DOUBLE
Definition infix.h:256
@ INFIX_TYPE_PRIMITIVE
Definition infix.h:228
The public interface for the infix FFI library.
Platform, architecture, and ABI detection macros.
#define INFIX_INTERNAL
When compiling with -fvisibility=hidden, we use this to explicitly mark internal-but-shared functions...
Definition infix_config.h:211
INFIX_INTERNAL c23_nodiscard infix_status _infix_parse_type_internal(infix_type **, infix_arena_t **, const char *)
The internal core of the signature parser.
Definition signature.c:978
static bool is_long_double(const infix_type *type)
A fast inline check to determine if an infix_type is a long double.
Definition infix_internals.h:736
INFIX_INTERNAL void infix_executable_free(infix_executable_t exec)
Frees a block of executable memory and applies guard pages to prevent use-after-free.
Definition executor.c:347
INFIX_INTERNAL c23_nodiscard infix_status _infix_resolve_type_graph_inplace(infix_type **type_ptr, infix_registry_t *registry)
Resolves all named type references in a type graph in-place.
Definition type_registry.c:429
INFIX_INTERNAL c23_nodiscard infix_protected_t infix_protected_alloc(size_t size)
Allocates a block of standard memory for later protection.
Definition executor.c:480
INFIX_INTERNAL void emit_int32(code_buffer *buf, int32_t value)
A convenience wrapper to append a 32-bit integer (little-endian) to a code buffer.
Definition trampoline.c:188
INFIX_INTERNAL void emit_int64(code_buffer *buf, int64_t value)
A convenience wrapper to append a 64-bit integer (little-endian) to a code buffer.
Definition trampoline.c:190
INFIX_INTERNAL void infix_protected_free(infix_protected_t prot)
Frees a block of protected memory.
Definition executor.c:514
infix_arg_location_type
Describes the physical location where a function argument is passed according to the ABI.
Definition infix_internals.h:221
@ ARG_LOCATION_GPR_PAIR
(SysV x64) A struct passed in two GPRs (e.g., RDI, RSI).
Definition infix_internals.h:237
@ ARG_LOCATION_STACK
Argument is passed on the stack.
Definition infix_internals.h:246
@ ARG_LOCATION_INTEGER_SSE_PAIR
(SysV x64) A struct split between a GPR and an SSE register.
Definition infix_internals.h:241
@ ARG_LOCATION_GPR
Argument is passed in a general-purpose integer register (e.g., RCX, RDI, X0).
Definition infix_internals.h:223
@ ARG_LOCATION_SSE_SSE_PAIR
(SysV x64) A struct passed in two SSE registers (e.g., XMM0, XMM1).
Definition infix_internals.h:239
@ ARG_LOCATION_SSE_INTEGER_PAIR
(SysV x64) A struct split between an SSE and a GPR register.
Definition infix_internals.h:243
static size_t _infix_align_up(size_t value, size_t alignment)
Aligns a value up to the next multiple of a power-of-two alignment.
Definition infix_internals.h:712
INFIX_INTERNAL void _infix_set_system_error(infix_error_category_t category, infix_error_code_t code, long system_code, const char *msg)
Sets the thread-local error state for a system-level error.
Definition error.c:242
INFIX_INTERNAL c23_nodiscard infix_executable_t infix_executable_alloc(size_t size)
Allocates a block of executable memory using the platform's W^X strategy.
Definition executor.c:235
static bool is_double(const infix_type *type)
A fast inline check to determine if an infix_type is a double.
Definition infix_internals.h:728
INFIX_INTERNAL const infix_forward_abi_spec * get_current_forward_abi_spec(void)
Gets the ABI v-table for forward calls for the current platform.
Definition trampoline.c:84
INFIX_INTERNAL infix_type * _copy_type_graph_to_arena(infix_arena_t *, const infix_type *)
Performs a deep copy of a type graph into a destination arena.
Definition types.c:1141
INFIX_INTERNAL void code_buffer_append(code_buffer *buf, const void *data, size_t len)
Appends raw bytes to a code buffer, reallocating within its arena if necessary.
Definition trampoline.c:154
INFIX_INTERNAL size_t _infix_estimate_graph_size(infix_arena_t *temp_arena, const infix_type *type)
Estimates the total memory required to deep-copy a complete type graph.
Definition types.c:1246
INFIX_INTERNAL c23_nodiscard bool infix_protected_make_readonly(infix_protected_t prot)
Makes a block of memory read-only for security hardening.
Definition executor.c:534
INFIX_INTERNAL void _infix_type_recalculate_layout(infix_type *type)
Recalculates the layout of a fully resolved type graph.
Definition types.c:953
INFIX_INTERNAL c23_nodiscard bool infix_executable_make_executable(infix_executable_t *exec)
Makes a block of JIT memory executable, completing the W^X process.
Definition executor.c:399
INFIX_INTERNAL const infix_direct_forward_abi_spec * get_current_direct_forward_abi_spec(void)
Gets the ABI v-table for direct marshalling forward calls for the current platform.
Definition trampoline.c:117
INFIX_INTERNAL void _infix_clear_error(void)
Clears the thread-local error state.
Definition error.c:266
INFIX_INTERNAL void code_buffer_init(code_buffer *buf, infix_arena_t *arena)
Initializes a code buffer for JIT code generation.
Definition trampoline.c:135
static bool is_float(const infix_type *type)
A fast inline check to determine if an infix_type is a float.
Definition infix_internals.h:720
INFIX_INTERNAL void emit_byte(code_buffer *buf, uint8_t byte)
A convenience wrapper to append a single byte to a code buffer.
Definition trampoline.c:186
INFIX_INTERNAL void _infix_set_error(infix_error_category_t category, infix_error_code_t code, size_t position)
Sets the thread-local error state with detailed information.
Definition error.c:173
INFIX_INTERNAL const infix_reverse_abi_spec * get_current_reverse_abi_spec(void)
Gets the ABI v-table for reverse calls for the current platform.
Definition trampoline.c:101
void(* infix_internal_dispatch_callback_fn)(infix_reverse_t *, void *, void **)
A function pointer to the universal C dispatcher for reverse calls.
Definition infix_internals.h:105
INFIX_INTERNAL void infix_internal_dispatch_callback_fn_impl(infix_reverse_t *context, void *return_value_ptr, void **args_array)
The universal C entry point for all reverse call trampolines.
Definition executor.c:573
INFIX_INTERNAL c23_nodiscard infix_status _infix_type_print_body_only(char *, size_t, const infix_type *, infix_print_dialect_t)
An internal-only function to serialize a type's body without its registered name.
Definition signature.c:1822
Declares internal, runtime CPU/OS feature detection functions.
A single entry in the registry's hash table.
Definition infix_internals.h:152
bool is_forward_declaration
Definition infix_internals.h:155
const char * name
Definition infix_internals.h:153
infix_type * type
Definition infix_internals.h:154
struct _infix_registry_entry_t * next
Definition infix_internals.h:156
A dynamic buffer for staged machine code generation.
Definition infix_internals.h:180
uint8_t * code
Definition infix_internals.h:181
bool error
Definition infix_internals.h:184
size_t size
Definition infix_internals.h:183
size_t capacity
Definition infix_internals.h:182
infix_arena_t * arena
Definition infix_internals.h:185
Internal definition of a memory arena.
Definition infix_internals.h:138
char * buffer
Definition infix_internals.h:139
bool error
Definition infix_internals.h:142
size_t capacity
Definition infix_internals.h:140
size_t block_size
Definition infix_internals.h:144
size_t current_offset
Definition infix_internals.h:141
struct infix_arena_t * next_block
Definition infix_internals.h:143
Detailed location information for a single function argument.
Definition infix_internals.h:255
uint32_t stack_offset
Definition infix_internals.h:260
uint8_t reg_index
Definition infix_internals.h:257
infix_arg_location_type type
Definition infix_internals.h:256
uint32_t num_regs
Definition infix_internals.h:259
uint8_t reg_index2
Definition infix_internals.h:258
A complete layout blueprint for a forward call frame.
Definition infix_internals.h:269
bool is_variadic
Definition infix_internals.h:279
size_t num_stack_args
Definition infix_internals.h:280
void * target_fn
Definition infix_internals.h:282
infix_arg_location * arg_locations
Definition infix_internals.h:277
size_t total_stack_alloc
Definition infix_internals.h:270
uint8_t num_gpr_args
Definition infix_internals.h:271
bool return_value_in_memory
Definition infix_internals.h:278
size_t num_args
Definition infix_internals.h:281
uint8_t num_xmm_args
Definition infix_internals.h:275
A struct containing all the necessary handlers for a single function argument.
Definition infix.h:1481
Internal layout information for a single argument in a direct marshalling trampoline.
Definition infix_internals.h:439
const infix_direct_arg_handler_t * handler
Pointer to the user-provided handler struct for this argument.
Definition infix_internals.h:442
infix_arg_location location
The physical location (register/stack) of the argument.
Definition infix_internals.h:440
const infix_type * type
The infix_type of this argument.
Definition infix_internals.h:441
A complete layout blueprint for a direct marshalling forward call frame.
Definition infix_internals.h:452
infix_direct_arg_layout * args
An array of layout info for each argument.
Definition infix_internals.h:457
bool return_value_in_memory
true if the return value uses a hidden pointer argument.
Definition infix_internals.h:456
size_t total_stack_alloc
Total bytes to allocate on the stack for arguments and ABI-required space.
Definition infix_internals.h:453
void * target_fn
The target C function address.
Definition infix_internals.h:455
size_t num_args
The total number of arguments.
Definition infix_internals.h:454
Defines the ABI-specific implementation interface for direct marshalling forward trampolines.
Definition infix_internals.h:466
Internal representation of an executable memory block for JIT code.
Definition infix_internals.h:56
size_t size
Definition infix_internals.h:64
void * rw_ptr
Definition infix_internals.h:63
void * rx_ptr
Definition infix_internals.h:62
int shm_fd
Definition infix_internals.h:60
Defines the ABI-specific implementation interface for forward trampolines.
Definition infix_internals.h:313
Internal definition of a forward trampoline handle.
Definition infix_internals.h:88
infix_executable_t exec
Definition infix_internals.h:92
void * target_fn
Definition infix_internals.h:97
size_t num_args
Definition infix_internals.h:95
bool is_external_arena
Definition infix_internals.h:90
size_t num_fixed_args
Definition infix_internals.h:96
infix_type ** arg_types
Definition infix_internals.h:94
infix_type * return_type
Definition infix_internals.h:93
infix_arena_t * arena
Definition infix_internals.h:89
bool is_direct_trampoline
Definition infix_internals.h:98
Internal definition of a dynamic library handle.
Definition infix_internals.h:195
void * handle
Definition infix_internals.h:196
Internal representation of a memory block that will be made read-only.
Definition infix_internals.h:75
size_t size
Definition infix_internals.h:77
void * rw_ptr
Definition infix_internals.h:76
Internal definition of a named type registry.
Definition infix_internals.h:165
size_t num_items
Definition infix_internals.h:169
bool is_external_arena
Definition infix_internals.h:167
infix_arena_t * arena
Definition infix_internals.h:166
_infix_registry_entry_t ** buckets
Definition infix_internals.h:170
size_t num_buckets
Definition infix_internals.h:168
Defines the ABI-specific implementation interface for reverse trampolines.
Definition infix_internals.h:382
A complete layout blueprint for a reverse call frame.
Definition infix_internals.h:291
int32_t args_array_offset
Definition infix_internals.h:294
int32_t xmm_save_area_offset
Definition infix_internals.h:297
int32_t saved_args_offset
Definition infix_internals.h:295
int32_t gpr_save_area_offset
Definition infix_internals.h:296
size_t total_stack_alloc
Definition infix_internals.h:292
int32_t return_buffer_offset
Definition infix_internals.h:293
Internal definition of a reverse trampoline (callback/closure) handle.
Definition infix_internals.h:114
infix_type * return_type
Definition infix_internals.h:118
void * user_data
Definition infix_internals.h:124
void * user_callback_fn
Definition infix_internals.h:123
infix_executable_t exec
Definition infix_internals.h:116
infix_internal_dispatch_callback_fn internal_dispatcher
Definition infix_internals.h:126
size_t num_args
Definition infix_internals.h:120
size_t num_fixed_args
Definition infix_internals.h:121
infix_protected_t protected_ctx
Definition infix_internals.h:117
bool is_variadic
Definition infix_internals.h:122
infix_forward_t * cached_forward_trampoline
Definition infix_internals.h:128
infix_arena_t * arena
Definition infix_internals.h:115
infix_type ** arg_types
Definition infix_internals.h:119
A semi-opaque structure that describes a C type.
Definition infix.h:273