Affix

 view release on metacpan or  search on metacpan

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

 * the memory's protection to be inaccessible, causing an immediate crash on a UAF.
 * @param exec The handle to the memory block to free.
 */
INFIX_INTERNAL void infix_executable_free(infix_executable_t exec);
typedef enum {
    INFIX_EXECUTABLE_FORWARD,
    INFIX_EXECUTABLE_SAFE_FORWARD,
    INFIX_EXECUTABLE_REVERSE,
    INFIX_EXECUTABLE_DIRECT
} infix_executable_category_t;

/**
 * @brief Makes a block of JIT memory executable, completing the W^X process.
 * @details Located in `src/jit/executor.c`. For single-map platforms, this calls
 * `VirtualProtect` or `mprotect`. For dual-map platforms, this is a no-op. It
 * also handles instruction cache flushing on relevant architectures like AArch64.
 * @param exec The handle to the memory block to make executable.
 * @param prologue_size The size of the generated prologue in bytes.
 * @param category The type of trampoline being finalized.
 * @return `true` on success, `false` on failure.
 */
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);
/**
 * @brief Allocates a block of standard memory for later protection.
 * @details Located in `src/jit/executor.c`. This is used to allocate the memory
 * for an `infix_reverse_t` context before it is made read-only.
 * @param size The number of bytes to allocate.
 * @return An `infix_protected_t` handle.
 */
INFIX_INTERNAL c23_nodiscard infix_protected_t infix_protected_alloc(size_t size);
/**
 * @brief Frees a block of protected memory.
 * @details Located in `src/jit/executor.c`.
 * @param prot The memory block to free.
 */
INFIX_INTERNAL void infix_protected_free(infix_protected_t prot);
/**
 * @brief Makes a block of memory read-only for security hardening.
 * @details Located in `src/jit/executor.c`. This is called on the `infix_reverse_t`
 * context after it has been fully initialized.
 * @param prot The memory block to make read-only.
 * @return `true` on success, `false` on failure.
 */
INFIX_INTERNAL c23_nodiscard bool infix_protected_make_readonly(infix_protected_t prot);
/**
 * @brief The universal C entry point for all reverse call trampolines.
 * @details Located in `src/jit/executor.c`, this function is called by the JIT-compiled
 * stub. It receives the marshalled arguments and dispatches the call to either
 * the type-safe callback (via a cached forward trampoline) or the generic closure handler.
 * @param[in] context The `infix_reverse_t` context for this call.
 * @param[out] return_value_ptr A pointer to the stack buffer for the return value.
 * @param[in] args_array A pointer to the `void**` array of argument pointers.
 */
INFIX_INTERNAL void infix_internal_dispatch_callback_fn_impl(infix_reverse_t * context,
                                                             void * return_value_ptr,
                                                             void ** args_array);

// Utility Macros & Inlines
/** @brief Appends a sequence of bytes (e.g., an instruction opcode) to a code buffer. */
#define EMIT_BYTES(buf, ...)                             \
    do {                                                 \
        const uint8_t bytes[] = {__VA_ARGS__};           \
        code_buffer_append((buf), bytes, sizeof(bytes)); \
    } while (0)
/**
 * @brief Aligns a value up to the next multiple of a power-of-two alignment.
 * @param value The value to align.
 * @param alignment The alignment boundary (must be a power of two).
 * @return The aligned value.
 */
static inline size_t _infix_align_up(size_t value, size_t alignment) {
    return (value + alignment - 1) & ~(alignment - 1);
}
/**
 * @brief A fast inline check to determine if an `infix_type` is a half-precision float (`float16`).
 * @param type The type to check.
 * @return `true` if the type is a float16 primitive.
 */
static inline bool is_float16(const infix_type * type) {
    return type->category == INFIX_TYPE_PRIMITIVE && type->meta.primitive_id == INFIX_PRIMITIVE_FLOAT16;
}
/**
 * @brief A fast inline check to determine if an `infix_type` is a `float` (32-bit).
 * @param type The type to check.
 * @return `true` if the type is a float primitive.
 */
static inline bool is_float(const infix_type * type) {
    return type->category == INFIX_TYPE_PRIMITIVE && type->meta.primitive_id == INFIX_PRIMITIVE_FLOAT;
}
/**
 * @brief A fast inline check to determine if an `infix_type` is a `double`.
 * @param type The type to check.
 * @return `true` if the type is a double primitive.
 */
static inline bool is_double(const infix_type * type) {
    return type->category == INFIX_TYPE_PRIMITIVE && type->meta.primitive_id == INFIX_PRIMITIVE_DOUBLE;
}
/**
 * @brief A fast inline check to determine if an `infix_type` is a `long double`.
 * @param type The type to check.
 * @return `true` if the type is a long double primitive.
 */
static inline bool is_long_double(const infix_type * type) {
    return type->category == INFIX_TYPE_PRIMITIVE && type->meta.primitive_id == INFIX_PRIMITIVE_LONG_DOUBLE;
}
// Include architecture-specific emitter prototypes for internal use by the JIT engine.
#if defined(INFIX_ABI_SYSV_X64) || defined(INFIX_ABI_WINDOWS_X64)
#include "arch/x64/abi_x64_emitters.h"
#elif defined(INFIX_ABI_AAPCS64)
#include "arch/aarch64/abi_arm64_emitters.h"
#endif

// Trampoline Caching
INFIX_INTERNAL infix_forward_t * _infix_cache_lookup(const char * signature, void * target_fn, bool is_safe);
INFIX_INTERNAL void _infix_cache_insert(infix_forward_t * trampoline);
INFIX_INTERNAL bool _infix_cache_remove(infix_forward_t * trampoline);
INFIX_INTERNAL void _infix_cache_release(infix_forward_t * trampoline);
INFIX_INTERNAL void _infix_cache_clear(void);



( run in 0.514 second using v1.01-cache-2.11-cpan-99c4e6809bf )