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 **);
192typedef struct {
193 uint8_t * code;
194 size_t capacity;
195 size_t size;
196 bool error;
208 void * handle;
209#if defined(INFIX_OS_WINDOWS)
210 bool is_pseudo_handle;
211#endif
212};
213// ABI Abstraction Layer
219#define INFIX_MAX_STACK_ALLOC (1024 * 1024 * 4)
224#define INFIX_MAX_ARG_SIZE (1024 * 64)
233typedef enum {
236#if defined(INFIX_ABI_AAPCS64)
238 ARG_LOCATION_VPR,
242 ARG_LOCATION_GPR_REFERENCE,
244 ARG_LOCATION_VPR_HFA,
245#else // x64 ABIs
247 ARG_LOCATION_XMM,
256#endif
281typedef struct {
283 uint8_t num_gpr_args;
284#if defined(INFIX_ABI_AAPCS64)
285 uint8_t num_vpr_args;
286#else
287 uint8_t num_xmm_args;
288#endif
293 size_t num_args;
294 void * target_fn;
325typedef struct {
341 infix_status (*prepare_forward_call_frame)(infix_arena_t * arena,
342 infix_call_frame_layout ** out_layout,
345 size_t num_args,
346 size_t num_fixed_args,
347 void * target_fn);
354 infix_status (*generate_forward_prologue)(code_buffer * buf, infix_call_frame_layout * layout);
364 infix_status (*generate_forward_argument_moves)(code_buffer * buf,
367 size_t num_args,
368 size_t num_fixed_args);
375 infix_status (*generate_forward_call_instruction)(code_buffer * buf, infix_call_frame_layout * layout);
383 infix_status (*generate_forward_epilogue)(code_buffer * buf,
394typedef struct {
402 infix_status (*prepare_reverse_call_frame)(infix_arena_t * arena,
404 infix_reverse_t * context);
411 infix_status (*generate_reverse_prologue)(code_buffer * buf, infix_reverse_call_frame_layout * layout);
419 infix_status (*generate_reverse_argument_marshalling)(code_buffer * buf,
421 infix_reverse_t * context);
429 infix_status (*generate_reverse_dispatcher_call)(code_buffer * buf,
431 infix_reverse_t * context);
439 infix_status (*generate_reverse_epilogue)(code_buffer * buf,
441 infix_reverse_t * context);
443
456
471
478typedef struct {
480 infix_status (*prepare_direct_forward_call_frame)(infix_arena_t * arena,
481 infix_direct_call_frame_layout ** out_layout,
484 size_t num_args,
486 void * target_fn);
488 infix_status (*generate_direct_forward_prologue)(code_buffer * buf, infix_direct_call_frame_layout * layout);
490 infix_status (*generate_direct_forward_argument_moves)(code_buffer * buf, infix_direct_call_frame_layout * layout);
492 infix_status (*generate_direct_forward_call_instruction)(code_buffer * buf,
495 infix_status (*generate_direct_forward_epilogue)(code_buffer * buf,
498
500
501// Internal Function Prototypes (Shared across modules)
512void _infix_set_error(infix_error_category_t category, infix_error_code_t code, size_t position);
524 long system_code,
525 const char * msg);
531void _infix_clear_error(void);
593size_t _infix_estimate_graph_size(infix_arena_t * temp_arena, const infix_type * type);
630void code_buffer_append(code_buffer * buf, const void * data, size_t len);
636void emit_byte(code_buffer * buf, uint8_t byte);
642void emit_int32(code_buffer * buf, int32_t value);
648void emit_int64(code_buffer * buf, int64_t value);
713void infix_internal_dispatch_callback_fn_impl(infix_reverse_t * context, void * return_value_ptr, void ** args_array);
714// Utility Macros & Inlines
716#define EMIT_BYTES(buf, ...) \
717 do { \
718 const uint8_t bytes[] = {__VA_ARGS__}; \
719 code_buffer_append((buf), bytes, sizeof(bytes)); \
720 } while (0)
727static inline size_t _infix_align_up(size_t value, size_t alignment) {
728 return (value + alignment - 1) & ~(alignment - 1);
729}
735static inline bool is_float(const infix_type * type) {
737}
743static inline bool is_double(const infix_type * type) {
745}
751static inline bool is_long_double(const infix_type * type) {
753}
754// Include architecture-specific emitter prototypes for internal use by the JIT engine.
755#if defined(INFIX_ABI_SYSV_X64) || defined(INFIX_ABI_WINDOWS_X64)
757#elif defined(INFIX_ABI_AAPCS64)
759#endif
infix_arena_t * arena
Definition 005_layouts.c:60
infix_registry_t * registry
Definition 008_registry_introspection.c:32
infix_type * arg_types[]
Definition 901_call_overhead.c:61
infix_type * ret_type
Definition 901_call_overhead.c:60
infix_direct_arg_handler_t handlers[2]
Definition 901_call_overhead.c:103
Declares internal helper functions for emitting AArch64 machine code.
Declares internal helper functions for emitting x86-64 machine code.
#define c23_nodiscard
A compatibility macro for the C23 [[nodiscard]] attribute.
Definition compat_c23.h:106
infix_error_code_t
Enumerates specific error codes.
Definition infix.h:1223
infix_error_category_t
Enumerates the high-level categories of errors that can occur.
Definition infix.h:1213
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:352
infix_type_category category
Definition infix.h:196
infix_primitive_type_id primitive_id
Metadata for INFIX_TYPE_PRIMITIVE.
Definition infix.h:204
infix_print_dialect_t
Specifies the output format for printing types and function signatures.
Definition infix.h:1038
@ INFIX_PRIMITIVE_LONG_DOUBLE
Definition infix.h:178
@ INFIX_PRIMITIVE_FLOAT
Definition infix.h:176
@ INFIX_PRIMITIVE_DOUBLE
Definition infix.h:177
@ INFIX_TYPE_PRIMITIVE
Definition infix.h:149
The public interface for the infix FFI library.
Platform, architecture, and ABI detection macros.
void emit_byte(code_buffer *buf, uint8_t byte)
A convenience wrapper to append a single byte to a code buffer.
Definition trampoline.c:183
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
void infix_protected_free(infix_protected_t prot)
Frees a block of protected memory.
Definition executor.c:437
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:751
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:350
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:292
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:165
void _infix_type_recalculate_layout(infix_type *type)
Recalculates the layout of a fully resolved type graph.
Definition types.c:938
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:963
void code_buffer_init(code_buffer *buf, infix_arena_t *arena)
Initializes a code buffer for JIT code generation.
Definition trampoline.c:135
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:1125
infix_arg_location_type
Describes the physical location where a function argument is passed according to the ABI.
Definition infix_internals.h:233
@ ARG_LOCATION_GPR_PAIR
(SysV x64) A struct passed in two GPRs (e.g., RDI, RSI).
Definition infix_internals.h:249
@ ARG_LOCATION_STACK
Argument is passed on the stack.
Definition infix_internals.h:258
@ ARG_LOCATION_INTEGER_SSE_PAIR
(SysV x64) A struct split between a GPR and an SSE register.
Definition infix_internals.h:253
@ ARG_LOCATION_GPR
Argument is passed in a general-purpose integer register (e.g., RCX, RDI, X0).
Definition infix_internals.h:235
@ ARG_LOCATION_SSE_SSE_PAIR
(SysV x64) A struct passed in two SSE registers (e.g., XMM0, XMM1).
Definition infix_internals.h:251
@ ARG_LOCATION_SSE_INTEGER_PAIR
(SysV x64) A struct split between an SSE and a GPR register.
Definition infix_internals.h:255
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:727
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:1230
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:335
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:743
c23_nodiscard infix_protected_t infix_protected_alloc(size_t size)
Allocates a block of standard memory for later protection.
Definition executor.c:407
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:234
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:205
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
c23_nodiscard infix_status _infix_forward_create_internal(infix_forward_t **, infix_type *, infix_type **, size_t, size_t, void *)
The core implementation for creating all forward trampolines.
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:187
void _infix_clear_error(void)
Clears the thread-local error state.
Definition error.c:258
c23_nodiscard bool infix_protected_make_readonly(infix_protected_t prot)
Makes a block of memory read-only for security hardening.
Definition executor.c:457
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
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:735
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:492
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:185
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
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:1508
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
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:192
uint8_t * code
Definition infix_internals.h:193
bool error
Definition infix_internals.h:196
size_t size
Definition infix_internals.h:195
size_t capacity
Definition infix_internals.h:194
infix_arena_t * arena
Definition infix_internals.h:197
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:267
uint32_t stack_offset
Definition infix_internals.h:272
uint8_t reg_index
Definition infix_internals.h:269
infix_arg_location_type type
Definition infix_internals.h:268
uint32_t num_regs
Definition infix_internals.h:271
uint8_t reg_index2
Definition infix_internals.h:270
A complete layout blueprint for a forward call frame.
Definition infix_internals.h:281
bool is_variadic
Definition infix_internals.h:291
size_t num_stack_args
Definition infix_internals.h:292
void * target_fn
Definition infix_internals.h:294
infix_arg_location * arg_locations
Definition infix_internals.h:289
size_t total_stack_alloc
Definition infix_internals.h:282
uint8_t num_gpr_args
Definition infix_internals.h:283
bool return_value_in_memory
Definition infix_internals.h:290
size_t num_args
Definition infix_internals.h:293
uint8_t num_xmm_args
Definition infix_internals.h:287
A struct containing all the necessary handlers for a single function argument.
Definition infix.h:1354
Internal layout information for a single argument in a direct marshalling trampoline.
Definition infix_internals.h:451
const infix_direct_arg_handler_t * handler
Pointer to the user-provided handler struct for this argument.
Definition infix_internals.h:454
infix_arg_location location
The physical location (register/stack) of the argument.
Definition infix_internals.h:452
const infix_type * type
The infix_type of this argument.
Definition infix_internals.h:453
A complete layout blueprint for a direct marshalling forward call frame.
Definition infix_internals.h:464
infix_direct_arg_layout * args
An array of layout info for each argument.
Definition infix_internals.h:469
bool return_value_in_memory
true if the return value uses a hidden pointer argument.
Definition infix_internals.h:468
size_t total_stack_alloc
Total bytes to allocate on the stack for arguments and ABI-required space.
Definition infix_internals.h:465
void * target_fn
The target C function address.
Definition infix_internals.h:467
size_t num_args
The total number of arguments.
Definition infix_internals.h:466
Defines the ABI-specific implementation interface for direct marshalling forward trampolines.
Definition infix_internals.h:478
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:325
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:207
void * handle
Definition infix_internals.h:208
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 registry iterator.
Definition infix_internals.h:179
const _infix_registry_entry_t * current_entry
Definition infix_internals.h:182
const infix_registry_t * registry
Definition infix_internals.h:180
size_t current_bucket
Definition infix_internals.h:181
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:394
A complete layout blueprint for a reverse call frame.
Definition infix_internals.h:303
int32_t args_array_offset
Definition infix_internals.h:306
int32_t xmm_save_area_offset
Definition infix_internals.h:309
int32_t saved_args_offset
Definition infix_internals.h:307
int32_t gpr_save_area_offset
Definition infix_internals.h:308
size_t total_stack_alloc
Definition infix_internals.h:304
int32_t return_buffer_offset
Definition infix_internals.h:305
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:194