Affix

 view release on metacpan or  search on metacpan

infix/src/common/infix_internals.h  view on Meta::CPAN

 * memory corruption. The context is allocated in a standard read-write memory
 * region, fully populated, and then its permissions are changed to read-only
 * using this handle.
 */
typedef struct {
    void * rw_ptr; /**< The read-write pointer before being made read-only. */
    size_t size;   /**< The size of the allocated memory region in bytes. */
} infix_protected_t;
/**
 * @struct infix_forward_t
 * @brief Internal definition of a forward trampoline handle.
 * @details This is the concrete implementation of the opaque `infix_forward_t` pointer
 * returned to the user. It is a self-contained object that owns all memory and
 * metadata required for its operation. The type information (`return_type`,
 * `arg_types`) is a deep copy stored in the trampoline's private `arena`,
 * ensuring its lifetime is independent of the types used to create it.
 */
struct infix_forward_t {
    infix_arena_t * arena;   /**< Private or shared arena holding all type metadata for this trampoline. */
    bool is_external_arena;  /**< True if the arena is user-provided and should not be freed by `infix_forward_destroy`.
                              */
    infix_executable_t exec; /**< The executable memory containing the JIT-compiled code. */
    infix_type * return_type;  /**< A deep copy of the function's return type. */
    infix_type ** arg_types;   /**< A deep copy of the function's argument types. */
    size_t num_args;           /**< The total number of arguments. */
    size_t num_fixed_args;     /**< The number of non-variadic arguments. */
    void * target_fn;          /**< The target C function pointer (for bound trampolines), or `nullptr` for unbound. */
    bool is_direct_trampoline; /**< If true, this is a high-performance direct marshalling trampoline. */
    bool is_safe;              /**< If true, the trampoline wraps the call in an exception handler. */
    size_t ref_count;          /**< Reference count for deduplication and shared ownership. */
    char * signature;          /**< The normalized signature string used to create this trampoline. */
};
/**
 * @brief A function pointer to the universal C dispatcher for reverse calls.
 * @details This is the C function that the JIT-compiled reverse trampoline stub calls
 * after marshalling all arguments into a standard C format.
 */
typedef void (*infix_internal_dispatch_callback_fn)(infix_reverse_t *, void *, void **);
/**
 * @struct infix_reverse_t
 * @brief Internal definition of a reverse trampoline (callback/closure) handle.
 * @details This is the concrete implementation of the opaque `infix_reverse_t` pointer.
 * The entire struct is allocated in a page-aligned memory region that is made read-only
 * after initialization to prevent memory corruption vulnerabilities. Like the forward
 * trampoline, it is self-contained and owns deep copies of all its type metadata.
 */
struct infix_reverse_t {
    infix_arena_t * arena;           /**< Private arena for type metadata. */
    infix_executable_t exec;         /**< Executable memory for the JIT stub. */
    infix_protected_t protected_ctx; /**< The read-only memory region holding this struct. */
    infix_type * return_type;        /**< Deep copy of the function's return type. */
    infix_type ** arg_types;         /**< Deep copy of the function's argument types. */
    size_t num_args;                 /**< Total number of arguments. */
    size_t num_fixed_args;           /**< Number of non-variadic arguments. */
    bool is_variadic;                /**< `true` if the signature contains variadic arguments. */
    void * user_callback_fn;         /**< The user-provided handler function pointer (type-safe or generic). */
    void * user_data;                /**< The user-provided context pointer for closures. */
    infix_internal_dispatch_callback_fn
        internal_dispatcher; /**< Pointer to the universal C dispatcher implementation. */
    infix_forward_t *
        cached_forward_trampoline; /**< For type-safe callbacks, a pre-generated trampoline to call the C handler. */
};
/**
 * @struct infix_arena_t
 * @brief Internal definition of a memory arena.
 * @details An arena is a fast, region-based allocator. It pre-allocates a single
 * block of memory and serves subsequent small allocation requests by simply
 * "bumping" a pointer. All memory allocated from an arena is freed at once by
 * destroying the arena itself, eliminating the need to track individual allocations.
 */
struct infix_arena_t {
    char * buffer;                     /**< The backing memory buffer for the arena. */
    size_t capacity;                   /**< The total size of the buffer. */
    size_t current_offset;             /**< The current high-water mark of allocation. */
    bool error;                        /**< A flag set if any allocation fails, preventing subsequent allocations. */
    struct infix_arena_t * next_block; /**< A pointer to the next block in the chain, if this one is full. */
    size_t block_size;                 /**< The size of this specific block's buffer, for chained arenas. */
};
// Mutex Abstraction for Internal Synchronization
#if defined(INFIX_OS_WINDOWS)
#include <windows.h>
typedef SRWLOCK infix_mutex_t;
#define INFIX_MUTEX_INITIALIZER SRWLOCK_INIT
#define INFIX_MUTEX_LOCK(m) AcquireSRWLockExclusive(m)
#define INFIX_MUTEX_UNLOCK(m) ReleaseSRWLockExclusive(m)
#define INFIX_MUTEX_DESTROY(m) ((void)0)
#else
#include <pthread.h>
typedef pthread_mutex_t infix_mutex_t;
#define INFIX_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
#define INFIX_MUTEX_LOCK(m) pthread_mutex_lock(m)
#define INFIX_MUTEX_UNLOCK(m) pthread_mutex_unlock(m)
#define INFIX_MUTEX_DESTROY(m) pthread_mutex_destroy(m)
#endif

/**
 * @struct _infix_registry_entry_t
 * @brief A single entry in the registry's hash table.
 * @details This is a node in a singly-linked list used for chaining in the
 * event of a hash collision.
 */
typedef struct _infix_registry_entry_t {
    const char * name;                     /**< The registered name of the type. */
    uint64_t hash;                         /**< The pre-calculated djb2 hash of the name. */
    infix_type * type;                     /**< A pointer to the canonical `infix_type` object. */
    bool is_forward_declaration;           /**< `true` if this is just a forward declaration (`@Name;`). */
    struct _infix_registry_entry_t * next; /**< The next entry in the hash bucket chain. */
} _infix_registry_entry_t;
/**
 * @struct infix_registry_t
 * @brief Internal definition of a named type registry.
 * @details Implemented as a hash table with separate chaining for collision resolution.
 * The canonical `infix_type` objects and entry metadata are owned by a single arena,
 * while the internal bucket array is heap-allocated to allow for efficient resizing.
 */
struct infix_registry_t {
    infix_arena_t * arena;              /**< The arena that owns all type metadata and entry structs. */
    bool is_external_arena;             /**< True if the arena is user-provided and should not be freed. */
    size_t num_buckets;                 /**< The number of buckets in the hash table. */
    size_t num_items;                   /**< The total number of items in the registry. */
    _infix_registry_entry_t ** buckets; /**< The array of hash table buckets (heap-allocated). */



( run in 0.945 second using v1.01-cache-2.11-cpan-39bf76dae61 )