Affix

 view release on metacpan or  search on metacpan

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

void tap_note(const char * fmt, ...) DBLTAP_PRINTF_FORMAT(1, 2);
void test_body(void);

#ifdef __cplusplus
}
#endif

// Public Test Harness Macros
/** @brief Declares the total number of tests to be run in the current scope. Must be called before any tests. */
#define plan(count) tap_plan(count)
/** @brief Concludes testing, validates the plan, and returns an exit code based on success or failure. */
#define done() tap_done()
/** @brief Immediately terminates the entire test suite with a failure message. Useful for fatal setup errors. */
#define bail_out(...) tap_bail_out(__VA_ARGS__)
/** @brief The core assertion macro. Checks a condition and prints an "ok" or "not ok" TAP line with diagnostics on
 * failure. */
#define ok(cond, ...) tap_ok(!!(cond), __FILE__, __LINE__, __func__, #cond, __VA_ARGS__)
/** @brief A convenience macro that always passes. Equivalent to `ok(true, ...)`. */
#define pass(...) ok(true, __VA_ARGS__)
/** @brief A convenience macro that always fails. Equivalent to `ok(false, ...)`. */
#define fail(...) ok(false, __VA_ARGS__)

infix/src/core/signature.c  view on Meta::CPAN

 *     human-readable signature string (e.g., `"({int, *char}) -> void"`) into an
 *     unresolved `infix_type` object graph. This is the **"Parse"** stage of the core
 *     data pipeline. The internal entry point for the "Parse" stage is `_infix_parse_type_internal`.
 *
 * 2.  **Printing:** It provides functions to serialize a fully resolved `infix_type`
 *     graph back into a canonical signature string. This is crucial for introspection,
 *     debugging, and verifying the library's understanding of a type.
 *
 * The public functions `infix_type_from_signature` and `infix_signature_parse`
 * are high-level orchestrators. They manage the entire **"Parse -> Copy -> Resolve -> Layout"**
 * pipeline, providing the user with a fully validated, self-contained, and ready-to-use
 * type object that is safe to use for the lifetime of its returned arena.
 */
#include "common/infix_internals.h"
#include <ctype.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/** @internal A thread-local pointer to the full signature string being parsed, used by `error.c` for rich error

infix/src/jit/executor.c  view on Meta::CPAN

#define kCFStringEncodingUTF8 0x08000100
// A struct to hold dynamically loaded function pointers from macOS frameworks.
static struct {
    void (*CFRelease)(CFTypeRef);
    bool (*CFBooleanGetValue)(CFTypeRef boolean);
    CFStringRef (*CFStringCreateWithCString)(CFTypeRef allocator, const char * cStr, uint32_t encoding);
    CFTypeRef kCFAllocatorDefault;
    SecTaskRef (*SecTaskCreateFromSelf)(CFTypeRef allocator);
    CFTypeRef (*SecTaskCopyValueForEntitlement)(SecTaskRef task, CFStringRef entitlement, CFErrorRef * error);
    void (*pthread_jit_write_protect_np)(int enabled);
    void (*sys_icache_invalidate)(void * start, size_t len);
} g_macos_apis;
/**
 * @internal
 * @brief One-time initialization to dynamically load macOS framework functions.
 * @details Uses `dlopen` and `dlsym` to find the necessary CoreFoundation and Security
 * framework functions at runtime. This avoids a hard link-time dependency,
 * making the library more portable and resilient if these frameworks change.
 */
static void initialize_macos_apis(void) {
    // We don't need to link against these frameworks, which makes building simpler.
    void * cf = dlopen("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation", RTLD_LAZY);
    void * sec = dlopen("/System/Library/Frameworks/Security.framework/Security", RTLD_LAZY);

    // Hardened Runtime helpers found in libSystem/libpthread
    g_macos_apis.pthread_jit_write_protect_np = dlsym(RTLD_DEFAULT, "pthread_jit_write_protect_np");
    g_macos_apis.sys_icache_invalidate = dlsym(RTLD_DEFAULT, "sys_icache_invalidate");

    if (!cf || !sec) {
        INFIX_DEBUG_PRINTF("Warning: Could not dlopen macOS frameworks. JIT security features will be degraded.");
        if (cf)
            dlclose(cf);
        if (sec)
            dlclose(sec);
        return;
    }
    g_macos_apis.CFRelease = dlsym(cf, "CFRelease");

infix/src/jit/executor.c  view on Meta::CPAN

 */
c23_nodiscard bool infix_executable_make_executable(infix_executable_t * exec,
                                                    c23_maybe_unused infix_executable_category_t category,
                                                    c23_maybe_unused uint32_t prologue_size,
                                                    c23_maybe_unused uint32_t epilogue_offset) {
    if (exec->rw_ptr == nullptr || exec->size == 0)
        return false;

    // On AArch64 (and other RISC architectures), the instruction and data caches can be
    // separate. We must explicitly flush the D-cache (where the JIT wrote the code)
    // and invalidate the I-cache so the CPU fetches the new instructions.
    // We might as well do it on x64 too.
#if defined(INFIX_COMPILER_MSVC)
    // Use the Windows-specific API.
    FlushInstructionCache(GetCurrentProcess(), exec->rw_ptr, exec->size);
#elif defined(INFIX_OS_MACOS)
    // Use the Apple-specific API if available (required for Apple Silicon correctness)
    if (g_macos_apis.sys_icache_invalidate)
        g_macos_apis.sys_icache_invalidate(exec->rw_ptr, exec->size);
    else
        __builtin___clear_cache((char *)exec->rw_ptr, (char *)exec->rw_ptr + exec->size);
#elif defined(INFIX_ARCH_AARCH64)
    // Robust manual cache clearing for AArch64 Linux/BSD.
    // We clean the D-cache to point of unification and invalidate the I-cache.
    uintptr_t start = (uintptr_t)exec->rw_ptr;
    uintptr_t end = start + exec->size;
    uintptr_t ctr_el0;
    __asm__ __volatile__("mrs %0, ctr_el0" : "=r"(ctr_el0));

    // D-cache line size is in bits [19:16] as log2 of number of words.
    uintptr_t d_line_size = 4 << ((ctr_el0 >> 16) & 0xf);
    for (uintptr_t addr = start & ~(d_line_size - 1); addr < end; addr += d_line_size)
        __asm__ __volatile__("dc cvau, %0" ::"r"(addr) : "memory");
    __asm__ __volatile__("dsb ish" ::: "memory");

infix/src/jit/trampoline.c  view on Meta::CPAN

 * @param type The type to check.
 * @param visited_head A list to track visited nodes and prevent infinite recursion on cycles.
 * @return `true` if the graph is fully resolved, `false` otherwise.
 */
static bool _is_type_graph_resolved_recursive(const infix_type * type, visited_node_t * visited_head) {
    if (!type)
        return true;
    if (type->is_incomplete)
        return false;
    // Cycle detection: if we've seen this node before, we can assume it's resolved
    // for the purpose of this check, as we'll validate it on the first visit.
    for (visited_node_t * v = visited_head; v != NULL; v = v->next)
        if (v->type == type)
            return true;
    visited_node_t current_visited_node = {.type = type, .next = visited_head};
    switch (type->category) {
    case INFIX_TYPE_NAMED_REFERENCE:
        return false;  // Base case: an unresolved reference.
    case INFIX_TYPE_POINTER:
        return _is_type_graph_resolved_recursive(type->meta.pointer_info.pointee_type, &current_visited_node);
    case INFIX_TYPE_ARRAY:



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