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 void * seh_registration;
60#else
61 int shm_fd;
62 void * eh_frame_ptr;
63#endif
64 void * rx_ptr;
65 void * rw_ptr;
66 size_t size;
77typedef struct {
78 void * rw_ptr;
79 size_t size;
110typedef void (*infix_internal_dispatch_callback_fn)(infix_reverse_t *, void *, void **);
151// Mutex Abstraction for Internal Synchronization
152#if defined(INFIX_OS_WINDOWS)
153#include <windows.h>
154typedef SRWLOCK infix_mutex_t;
155#define INFIX_MUTEX_INITIALIZER SRWLOCK_INIT
156#define INFIX_MUTEX_LOCK(m) AcquireSRWLockExclusive(m)
157#define INFIX_MUTEX_UNLOCK(m) ReleaseSRWLockExclusive(m)
158#define INFIX_MUTEX_DESTROY(m) ((void)0)
159#else
160#include <pthread.h>
161typedef pthread_mutex_t infix_mutex_t;
162#define INFIX_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
163#define INFIX_MUTEX_LOCK(m) pthread_mutex_lock(m)
164#define INFIX_MUTEX_UNLOCK(m) pthread_mutex_unlock(m)
165#define INFIX_MUTEX_DESTROY(m) pthread_mutex_destroy(m)
166#endif
167
199typedef struct {
200 const char * p;
201 const char * start;
203 int depth;
205
210typedef struct {
211 uint8_t * code;
212 size_t capacity;
213 size_t size;
214 bool error;
226 void * handle;
227#if defined(INFIX_OS_WINDOWS)
228 bool is_pseudo_handle;
229#endif
230};
231// ABI Abstraction Layer
237#define INFIX_MAX_STACK_ALLOC (1024 * 1024 * 4)
242#define INFIX_MAX_ARG_SIZE (1024 * 64)
251typedef enum {
254#if defined(INFIX_ABI_AAPCS64) || defined(INFIX_ABI_RISCV64)
256 ARG_LOCATION_VPR,
262 ARG_LOCATION_VPR_HFA,
265 ARG_LOCATION_MIXED,
268 ARG_LOCATION_GPR_STACK_SPLIT,
269#else // x64 ABIs
271 ARG_LOCATION_XMM,
282#endif
307typedef struct {
309 uint8_t num_gpr_args;
310#if defined(INFIX_ABI_AAPCS64) || defined(INFIX_ABI_RISCV64)
311 uint8_t num_vpr_args;
312#else
313 uint8_t num_xmm_args;
314#endif
319 size_t num_args;
320 void * target_fn;
321 uint32_t max_align;
322 uint32_t prologue_size;
356typedef struct {
372 infix_status (*prepare_forward_call_frame)(infix_arena_t * arena,
373 infix_call_frame_layout ** out_layout,
376 size_t num_args,
377 size_t num_fixed_args,
378 void * target_fn);
385 infix_status (*generate_forward_prologue)(code_buffer * buf, infix_call_frame_layout * layout);
395 infix_status (*generate_forward_argument_moves)(code_buffer * buf,
398 size_t num_args,
399 size_t num_fixed_args);
406 infix_status (*generate_forward_call_instruction)(code_buffer * buf, infix_call_frame_layout * layout);
414 infix_status (*generate_forward_epilogue)(code_buffer * buf,
425typedef struct {
433 infix_status (*prepare_reverse_call_frame)(infix_arena_t * arena,
435 infix_reverse_t * context);
442 infix_status (*generate_reverse_prologue)(code_buffer * buf, infix_reverse_call_frame_layout * layout);
450 infix_status (*generate_reverse_argument_marshalling)(code_buffer * buf,
452 infix_reverse_t * context);
460 infix_status (*generate_reverse_dispatcher_call)(code_buffer * buf,
462 infix_reverse_t * context);
470 infix_status (*generate_reverse_epilogue)(code_buffer * buf,
472 infix_reverse_t * context);
474
487
504
511typedef struct {
513 infix_status (*prepare_direct_forward_call_frame)(infix_arena_t * arena,
514 infix_direct_call_frame_layout ** out_layout,
517 size_t num_args,
519 void * target_fn);
521 infix_status (*generate_direct_forward_prologue)(code_buffer * buf, infix_direct_call_frame_layout * layout);
523 infix_status (*generate_direct_forward_argument_moves)(code_buffer * buf, infix_direct_call_frame_layout * layout);
525 infix_status (*generate_direct_forward_call_instruction)(code_buffer * buf,
528 infix_status (*generate_direct_forward_epilogue)(code_buffer * buf,
531
533
534// Internal Function Prototypes (Shared across modules)
557 long system_code,
558 const char * msg);
569
613 size_t,
614 const infix_type *,
635INFIX_INTERNAL size_t _infix_estimate_graph_size(infix_arena_t * temp_arena, const infix_type * type);
672INFIX_INTERNAL void code_buffer_append(code_buffer * buf, const void * data, size_t len);
678INFIX_INTERNAL void emit_byte(code_buffer * buf, uint8_t byte);
684INFIX_INTERNAL void emit_int32(code_buffer * buf, int32_t value);
690INFIX_INTERNAL void emit_int64(code_buffer * buf, int64_t value);
712
725 uint32_t prologue_size,
726 uint32_t epilogue_offset);
759 void * return_value_ptr,
760 void ** args_array);
761
762// Utility Macros & Inlines
764#define EMIT_BYTES(buf, ...) \
765 do { \
766 const uint8_t bytes[] = {__VA_ARGS__}; \
767 code_buffer_append((buf), bytes, sizeof(bytes)); \
768 } while (0)
775static inline size_t _infix_align_up(size_t value, size_t alignment) {
776 return (value + alignment - 1) & ~(alignment - 1);
777}
783static inline bool is_float16(const infix_type * type) {
785}
791static inline bool is_float(const infix_type * type) {
793}
799static inline bool is_double(const infix_type * type) {
801}
807static inline bool is_long_double(const infix_type * type) {
809}
810// Include architecture-specific emitter prototypes for internal use by the JIT engine.
811#if defined(INFIX_ABI_SYSV_X64) || defined(INFIX_ABI_WINDOWS_X64)
813#elif defined(INFIX_ABI_AAPCS64)
815#elif defined(INFIX_ABI_RISCV64)
817#endif
818
819// Trampoline Caching
823#define INFIX_CACHE_MAX_ENTRIES 1024
824INFIX_INTERNAL infix_forward_t * _infix_cache_lookup(const char * signature, void * target_fn, bool is_safe);
830
831// Internal Cleanup
833
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.
Public interface for emitting RISC-V (RV64GC) instructions.
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:92
infix_error_code_t
Enumerates specific error codes.
Definition infix.h:1412
infix_error_category_t
Enumerates the high-level categories of errors that can occur.
Definition infix.h:1402
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:486
infix_type_category category
Definition infix.h:278
infix_primitive_type_id primitive_id
Metadata for INFIX_TYPE_PRIMITIVE.
Definition infix.h:288
infix_print_dialect_t
Specifies the output format for printing types and function signatures.
Definition infix.h:1227
@ INFIX_PRIMITIVE_LONG_DOUBLE
Definition infix.h:260
@ INFIX_PRIMITIVE_FLOAT
Definition infix.h:258
@ INFIX_PRIMITIVE_DOUBLE
Definition infix.h:259
@ INFIX_PRIMITIVE_FLOAT16
Definition infix.h:257
@ INFIX_TYPE_PRIMITIVE
Definition infix.h:230
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:232
infix_executable_category_t
Definition infix_internals.h:706
@ INFIX_EXECUTABLE_REVERSE
Definition infix_internals.h:709
@ INFIX_EXECUTABLE_SAFE_FORWARD
Definition infix_internals.h:708
@ INFIX_EXECUTABLE_DIRECT
Definition infix_internals.h:710
@ INFIX_EXECUTABLE_FORWARD
Definition infix_internals.h:707
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:1018
INFIX_INTERNAL void _infix_cache_insert(infix_forward_t *trampoline)
Definition cache.c:136
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:807
INFIX_INTERNAL c23_nodiscard bool infix_executable_make_executable(infix_executable_t *exec, infix_executable_category_t category, uint32_t prologue_size, uint32_t epilogue_offset)
Makes a block of JIT memory executable, completing the W^X process.
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:863
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:428
INFIX_INTERNAL infix_type * parse_primitive(parser_state *state)
Definition signature.c:502
pthread_mutex_t infix_mutex_t
Definition infix_internals.h:161
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:1055
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:198
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:200
INFIX_INTERNAL void infix_protected_free(infix_protected_t prot)
Frees a block of protected memory.
Definition executor.c:1089
infix_arg_location_type
Describes the physical location where a function argument is passed according to the ABI.
Definition infix_internals.h:251
@ ARG_LOCATION_GPR_PAIR
(SysV x64) A struct passed in two GPRs (e.g., RDI, RSI).
Definition infix_internals.h:273
@ ARG_LOCATION_STACK
Argument is passed on the stack.
Definition infix_internals.h:284
@ ARG_LOCATION_INTEGER_SSE_PAIR
(SysV x64) A struct split between a GPR and an SSE register.
Definition infix_internals.h:277
@ ARG_LOCATION_GPR
Argument is passed in a general-purpose integer register (e.g., RCX, RDI, X0, a0).
Definition infix_internals.h:253
@ ARG_LOCATION_SSE_SSE_PAIR
(SysV x64) A struct passed in two SSE registers (e.g., XMM0, XMM1).
Definition infix_internals.h:275
@ ARG_LOCATION_SSE_INTEGER_PAIR
(SysV x64) A struct split between an SSE and a GPR register.
Definition infix_internals.h:279
@ ARG_LOCATION_GPR_REFERENCE
(x64) A large aggregate (> 16 bytes) passed by reference; the pointer is in a GPR.
Definition infix_internals.h:281
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:775
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:244
INFIX_INTERNAL void skip_whitespace(parser_state *state)
Definition signature.c:72
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:280
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:799
INFIX_INTERNAL void _infix_cache_clear(void)
Definition cache.c:183
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:88
static bool is_float16(const infix_type *type)
A fast inline check to determine if an infix_type is a half-precision float (float16).
Definition infix_internals.h:783
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:1128
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:164
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:1233
INFIX_INTERNAL void _infix_forward_destroy_internal(infix_forward_t *trampoline)
Definition trampoline.c:712
INFIX_INTERNAL void _infix_set_parser_error(parser_state *state, infix_error_code_t code)
Definition signature.c:62
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:1109
INFIX_INTERNAL void _infix_type_recalculate_layout(infix_type *type)
Recalculates the layout of a fully resolved type graph.
Definition types.c:940
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:125
INFIX_INTERNAL void _infix_clear_error(void)
Clears the thread-local error state.
Definition error.c:268
INFIX_INTERNAL void code_buffer_init(code_buffer *buf, infix_arena_t *arena)
Initializes a code buffer for JIT code generation.
Definition trampoline.c:145
static bool is_float(const infix_type *type)
A fast inline check to determine if an infix_type is a float (32-bit).
Definition infix_internals.h:791
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:196
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:175
INFIX_INTERNAL void _infix_cache_release(infix_forward_t *trampoline)
Definition cache.c:258
INFIX_INTERNAL infix_forward_t * _infix_cache_lookup(const char *signature, void *target_fn, bool is_safe)
Definition cache.c:103
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:107
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:110
INFIX_INTERNAL infix_type * parse_type(parser_state *state)
Definition signature.c:634
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:1148
INFIX_INTERNAL bool _infix_cache_remove(infix_forward_t *trampoline)
Definition cache.c:247
INFIX_INTERNAL size_t _infix_cache_count(void)
Definition cache.c:206
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:2014
Declares internal, runtime CPU/OS feature detection functions.
A single entry in the registry's hash table.
Definition infix_internals.h:174
bool is_forward_declaration
Definition infix_internals.h:178
const char * name
Definition infix_internals.h:175
uint64_t hash
Definition infix_internals.h:176
infix_type * type
Definition infix_internals.h:177
struct _infix_registry_entry_t * next
Definition infix_internals.h:179
A dynamic buffer for staged machine code generation.
Definition infix_internals.h:210
uint8_t * code
Definition infix_internals.h:211
bool error
Definition infix_internals.h:214
size_t size
Definition infix_internals.h:213
size_t capacity
Definition infix_internals.h:212
infix_arena_t * arena
Definition infix_internals.h:215
Internal definition of a memory arena.
Definition infix_internals.h:143
char * buffer
Definition infix_internals.h:144
bool error
Definition infix_internals.h:147
size_t capacity
Definition infix_internals.h:145
size_t block_size
Definition infix_internals.h:149
size_t current_offset
Definition infix_internals.h:146
struct infix_arena_t * next_block
Definition infix_internals.h:148
Detailed location information for a single function argument.
Definition infix_internals.h:293
uint32_t stack_offset
Definition infix_internals.h:298
uint8_t reg_index
Definition infix_internals.h:295
infix_arg_location_type type
Definition infix_internals.h:294
uint32_t num_regs
Definition infix_internals.h:297
uint8_t reg_index2
Definition infix_internals.h:296
A complete layout blueprint for a forward call frame.
Definition infix_internals.h:307
bool is_variadic
Definition infix_internals.h:317
size_t num_stack_args
Definition infix_internals.h:318
void * target_fn
Definition infix_internals.h:320
uint32_t epilogue_offset
Definition infix_internals.h:323
infix_arg_location * arg_locations
Definition infix_internals.h:315
size_t total_stack_alloc
Definition infix_internals.h:308
uint8_t num_gpr_args
Definition infix_internals.h:309
bool return_value_in_memory
Definition infix_internals.h:316
uint32_t prologue_size
Definition infix_internals.h:322
size_t num_args
Definition infix_internals.h:319
uint8_t num_xmm_args
Definition infix_internals.h:313
uint32_t max_align
Definition infix_internals.h:321
A struct containing all the necessary handlers for a single function argument.
Definition infix.h:1552
Internal layout information for a single argument in a direct marshalling trampoline.
Definition infix_internals.h:482
const infix_direct_arg_handler_t * handler
Pointer to the user-provided handler struct for this argument.
Definition infix_internals.h:485
infix_arg_location location
The physical location (register/stack) of the argument.
Definition infix_internals.h:483
const infix_type * type
The infix_type of this argument.
Definition infix_internals.h:484
A complete layout blueprint for a direct marshalling forward call frame.
Definition infix_internals.h:495
uint32_t epilogue_offset
Offset from the start of the JIT block to the epilogue.
Definition infix_internals.h:502
uint32_t prologue_size
Size of the generated prologue in bytes.
Definition infix_internals.h:501
infix_direct_arg_layout * args
An array of layout info for each argument.
Definition infix_internals.h:500
bool return_value_in_memory
true if the return value uses a hidden pointer argument.
Definition infix_internals.h:499
size_t total_stack_alloc
Total bytes to allocate on the stack for arguments and ABI-required space.
Definition infix_internals.h:496
void * target_fn
The target C function address.
Definition infix_internals.h:498
size_t num_args
The total number of arguments.
Definition infix_internals.h:497
Defines the ABI-specific implementation interface for direct marshalling forward trampolines.
Definition infix_internals.h:511
Internal representation of an executable memory block for JIT code.
Definition infix_internals.h:56
size_t size
Definition infix_internals.h:66
void * rw_ptr
Definition infix_internals.h:65
void * rx_ptr
Definition infix_internals.h:64
void * eh_frame_ptr
Definition infix_internals.h:62
int shm_fd
Definition infix_internals.h:61
Defines the ABI-specific implementation interface for forward trampolines.
Definition infix_internals.h:356
Internal definition of a forward trampoline handle.
Definition infix_internals.h:90
infix_executable_t exec
Definition infix_internals.h:94
void * target_fn
Definition infix_internals.h:99
size_t num_args
Definition infix_internals.h:97
bool is_external_arena
Definition infix_internals.h:92
size_t num_fixed_args
Definition infix_internals.h:98
infix_type ** arg_types
Definition infix_internals.h:96
infix_type * return_type
Definition infix_internals.h:95
size_t ref_count
Definition infix_internals.h:102
bool is_safe
Definition infix_internals.h:101
infix_arena_t * arena
Definition infix_internals.h:91
char * signature
Definition infix_internals.h:103
bool is_direct_trampoline
Definition infix_internals.h:100
Internal definition of a dynamic library handle.
Definition infix_internals.h:225
void * handle
Definition infix_internals.h:226
Internal representation of a memory block that will be made read-only.
Definition infix_internals.h:77
size_t size
Definition infix_internals.h:79
void * rw_ptr
Definition infix_internals.h:78
Internal definition of a named type registry.
Definition infix_internals.h:188
size_t num_items
Definition infix_internals.h:192
bool is_external_arena
Definition infix_internals.h:190
infix_arena_t * arena
Definition infix_internals.h:189
_infix_registry_entry_t ** buckets
Definition infix_internals.h:193
size_t num_buckets
Definition infix_internals.h:191
Defines the ABI-specific implementation interface for reverse trampolines.
Definition infix_internals.h:425
A complete layout blueprint for a reverse call frame.
Definition infix_internals.h:332
int32_t args_array_offset
Definition infix_internals.h:335
uint32_t prologue_size
Definition infix_internals.h:340
int32_t xmm_save_area_offset
Definition infix_internals.h:338
uint32_t max_align
Definition infix_internals.h:339
int32_t saved_args_offset
Definition infix_internals.h:336
int32_t gpr_save_area_offset
Definition infix_internals.h:337
size_t total_stack_alloc
Definition infix_internals.h:333
int32_t return_buffer_offset
Definition infix_internals.h:334
Internal definition of a reverse trampoline (callback/closure) handle.
Definition infix_internals.h:119
infix_type * return_type
Definition infix_internals.h:123
void * user_data
Definition infix_internals.h:129
void * user_callback_fn
Definition infix_internals.h:128
infix_executable_t exec
Definition infix_internals.h:121
infix_internal_dispatch_callback_fn internal_dispatcher
Definition infix_internals.h:131
size_t num_args
Definition infix_internals.h:125
size_t num_fixed_args
Definition infix_internals.h:126
infix_protected_t protected_ctx
Definition infix_internals.h:122
bool is_variadic
Definition infix_internals.h:127
infix_forward_t * cached_forward_trampoline
Definition infix_internals.h:133
infix_arena_t * arena
Definition infix_internals.h:120
infix_type ** arg_types
Definition infix_internals.h:124
A semi-opaque structure that describes a C type.
Definition infix.h:276
Holds the complete state of the recursive descent parser during a single parse operation.
Definition infix_internals.h:199
const char * start
Definition infix_internals.h:201
infix_arena_t * arena
Definition infix_internals.h:202
int depth
Definition infix_internals.h:203
const char * p
Definition infix_internals.h:200