Affix
view release on metacpan or search on metacpan
infix/src/jit/trampoline.c view on Meta::CPAN
* @details This module is the central orchestrator of the `infix` library. It brings
* together the type system, memory management, and ABI-specific logic to generate
* executable machine code at runtime.
*
* It implements both the high-level Signature API (e.g., `infix_forward_create`)
* and the low-level Manual API (e.g., `infix_forward_create_manual`). The high-level
* functions are convenient wrappers that use the signature parser to create the
* necessary `infix_type` objects before calling the core internal implementation.
*
* The core logic is encapsulated in `_infix_forward_create_internal` and
* `_infix_reverse_create_internal`. These functions follow a clear pipeline:
* 1. **Prepare:** Analyze the function signature with the appropriate ABI-specific
* `prepare_*_call_frame` function to create a layout blueprint.
* 2. **Generate:** Use the layout blueprint to call a sequence of ABI-specific
* `generate_*` functions, which emit machine code into a temporary `code_buffer`.
* 3. **Finalize:** Allocate executable memory, copy the generated code into it,
* create the final self-contained trampoline handle (deep-copying all type
* metadata), and make the code executable.
*/
#include "common/infix_internals.h"
#include "common/utility.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined(INFIX_OS_MACOS)
#include <pthread.h>
#endif
#if defined(INFIX_OS_WINDOWS)
#include <windows.h>
#else
#include <sys/mman.h>
#include <unistd.h>
#endif
// Forward Declaration for Internal Creation Function
static infix_status _infix_reverse_create_internal(infix_reverse_t ** out_context,
infix_type * return_type,
infix_type ** arg_types,
size_t num_args,
size_t num_fixed_args,
void * user_callback_fn,
void * user_data,
bool is_callback);
// ABI Specification V-Table Declarations (extern to link to the specific implementations)
#if defined(INFIX_ABI_WINDOWS_X64)
extern const infix_forward_abi_spec g_win_x64_forward_spec;
extern const infix_reverse_abi_spec g_win_x64_reverse_spec;
extern const infix_direct_forward_abi_spec g_win_x64_direct_forward_spec;
#elif defined(INFIX_ABI_SYSV_X64)
extern const infix_forward_abi_spec g_sysv_x64_forward_spec;
extern const infix_reverse_abi_spec g_sysv_x64_reverse_spec;
extern const infix_direct_forward_abi_spec g_sysv_x64_direct_forward_spec;
#elif defined(INFIX_ABI_AAPCS64)
extern const infix_forward_abi_spec g_arm64_forward_spec;
extern const infix_reverse_abi_spec g_arm64_reverse_spec;
extern const infix_direct_forward_abi_spec g_arm64_direct_forward_spec;
#endif
/**
* @internal
* @brief Retrieves a pointer to the ABI specification v-table for forward calls.
* @details This function is the entry point to the ABI abstraction layer. It uses
* compile-time preprocessor macros (defined in `infix_config.h`) to select and
* return the correct v-table for the target platform.
* @return A pointer to the active `infix_forward_abi_spec`, or `nullptr` if the
* platform is unsupported.
*/
const infix_forward_abi_spec * get_current_forward_abi_spec() {
#if defined(INFIX_ABI_WINDOWS_X64)
return &g_win_x64_forward_spec;
#elif defined(INFIX_ABI_SYSV_X64)
return &g_sysv_x64_forward_spec;
#elif defined(INFIX_ABI_AAPCS64)
return &g_arm64_forward_spec;
#else
return nullptr;
#endif
}
/**
* @internal
* @brief Retrieves a pointer to the ABI specification v-table for reverse calls.
* @return A pointer to the active `infix_reverse_abi_spec`, or `nullptr` if the
* platform is unsupported.
*/
const infix_reverse_abi_spec * get_current_reverse_abi_spec() {
#if defined(INFIX_ABI_WINDOWS_X64)
return &g_win_x64_reverse_spec;
#elif defined(INFIX_ABI_SYSV_X64)
return &g_sysv_x64_reverse_spec;
#elif defined(INFIX_ABI_AAPCS64)
return &g_arm64_reverse_spec;
#else
return nullptr;
#endif
}
/**
* @internal
* @brief Retrieves a pointer to the ABI v-table for direct marshalling forward calls.
* @return A pointer to the active `infix_direct_forward_abi_spec`, or `nullptr`.
*/
const infix_direct_forward_abi_spec * get_current_direct_forward_abi_spec() {
#if defined(INFIX_ABI_WINDOWS_X64)
return &g_win_x64_direct_forward_spec;
#elif defined(INFIX_ABI_SYSV_X64)
return &g_sysv_x64_direct_forward_spec;
#elif defined(INFIX_ABI_AAPCS64)
return &g_arm64_direct_forward_spec;
#else
return nullptr;
#endif
}
// Code Buffer Implementation
/**
* @internal
* @brief Initializes a `code_buffer` for JIT code generation.
* @param buf A pointer to the `code_buffer` to initialize.
* @param arena The temporary arena to use for the buffer's memory.
*/
void code_buffer_init(code_buffer * buf, infix_arena_t * arena) {
buf->capacity = 64; // Start with a small initial capacity.
buf->arena = arena;
buf->code = infix_arena_alloc(arena, buf->capacity, 16);
buf->size = 0;
( run in 0.963 second using v1.01-cache-2.11-cpan-39bf76dae61 )