Affix
view release on metacpan or search on metacpan
infix/include/infix/infix.h view on Meta::CPAN
* @brief Advances the iterator to the next defined type in the registry.
*
* @param[in,out] iterator The iterator to advance.
* @return `true` if the iterator was advanced to a valid type, or `false` if there are no more types.
*/
INFIX_API INFIX_NODISCARD bool infix_registry_iterator_next(infix_registry_iterator_t *);
/**
* @brief Gets the name of the type at the iterator's current position.
*
* @param[in] iterator The iterator.
* @return The name of the type (e.g., "MyStruct"), or `nullptr` if the iterator is invalid or at the end.
*/
INFIX_API INFIX_NODISCARD const char * infix_registry_iterator_get_name(const infix_registry_iterator_t *);
/**
* @brief Gets the `infix_type` object of the type at the iterator's current position.
*
* @param[in] iterator The iterator.
* @return A pointer to the canonical `infix_type` object, or `nullptr` if the iterator is invalid or at the end.
*/
INFIX_API INFIX_NODISCARD const infix_type * infix_registry_iterator_get_type(const infix_registry_iterator_t *);
/**
* @brief Checks if a type with the given name is fully defined in the registry.
*
* This function will return `false` for names that are only forward-declared but
* have not been given a definition.
*
* @param[in] registry The registry to search.
* @param[in] name The name of the type to check (e.g., "MyStruct").
* @return `true` if a complete definition for the name exists, `false` otherwise.
*/
INFIX_API INFIX_NODISCARD bool infix_registry_is_defined(const infix_registry_t *, const char *);
/**
* @brief Retrieves the canonical `infix_type` object for a given name from the registry.
*
* @param[in] registry The registry to search.
* @param[in] name The name of the type to retrieve.
* @return A pointer to the canonical `infix_type` object if found and fully defined.
* Returns `nullptr` if the name is not found or is only a forward declaration.
* The returned pointer is owned by the registry and is valid for its lifetime.
*/
INFIX_API INFIX_NODISCARD const infix_type * infix_registry_lookup_type(const infix_registry_t *, const char *);
/**
* @brief Creates a new named type registry that allocates from a user-provided arena.
*
* This advanced function allows multiple registries and trampolines to share a single
* memory arena, enabling pointer sharing and reducing memory overhead. The user
* is responsible for managing the lifetime of the provided arena.
*
* @param[in] arena The user-managed arena to use for all internal allocations.
* @return A pointer to the new registry, or `nullptr` on allocation failure.
* @note The registry should still be destroyed with `infix_registry_destroy`, but
* this will not free the user-provided arena itself.
*/
INFIX_API INFIX_NODISCARD infix_registry_t * infix_registry_create_in_arena(infix_arena_t * arena);
/** @} */ // end of registry_introspection_api group
/**
* @brief Creates a "bound" forward trampoline from a signature string.
*
* @details A bound trampoline is a highly optimized JIT-compiled function where the
* target C function's address is compiled directly into the executable code. This
* provides the best performance for forward calls, as it involves a direct `call`
* instruction to a known address. It is ideal for situations where you will call
* the same C function repeatedly.
*
* The returned handle contains a callable function pointer of type `infix_cif_func`,
* which you can retrieve with `infix_forward_get_code`.
*
* @param[out] out_trampoline A pointer to an `infix_forward_t*` that will receive the
* created trampoline handle upon success.
* @param[in] signature The signature string of the target function (e.g., `"(int, int)->int"`).
* @param[in] target_function The address of the C function to be called.
* @param[in] registry An optional type registry for resolving named types (`@Name`)
* used within the signature. Can be `nullptr` if no named types are used.
* @return `INFIX_SUCCESS` on success, or an `INFIX_ERROR_...` code on failure.
* @note The caller is responsible for destroying the handle with `infix_forward_destroy`.
*
* @code
* // C function to call
* int add(int a, int b) { return a + b; }
*
* infix_forward_t* trampoline = NULL;
* const char* signature = "(int, int) -> int";
*
* // Create a trampoline bound to the `add` function.
* infix_status status = infix_forward_create(&trampoline, signature, (void*)add, NULL);
* if (status != INFIX_SUCCESS) {
* // Handle error...
* }
*
* // Get the callable JIT-compiled function pointer.
* infix_cif_func cif = infix_forward_get_code(trampoline);
*
* // Prepare arguments and return buffer.
* int a = 10, b = 32;
* void* args[] = { &a, &b };
* int result;
*
* // Call the C function through the FFI.
* cif(&result, args); // result is now 42
*
* infix_forward_destroy(trampoline);
* @endcode
*/
INFIX_API INFIX_NODISCARD infix_status infix_forward_create(infix_forward_t **,
const char *,
void *,
infix_registry_t *);
/**
* @brief Creates a "safe" bound forward trampoline that catches native exceptions.
* @details This is identical to `infix_forward_create`, but the generated trampoline
* is wrapped in a platform-specific exception handler (e.g., SEH on Windows).
* If the target function throws an exception, the trampoline will catch it
* and set the thread-local error to `INFIX_CODE_NATIVE_EXCEPTION`.
*
* @param[out] out_trampoline Receives the created handle.
* @param[in] signature The function signature.
* @param[in] target_function The address of the C function.
* @param[in] registry An optional type registry.
* @return `INFIX_SUCCESS` on success.
*/
INFIX_API INFIX_NODISCARD infix_status infix_forward_create_safe(infix_forward_t **,
( run in 0.764 second using v1.01-cache-2.11-cpan-364913b4093 )