Affix
view release on metacpan or search on metacpan
infix/include/infix/infix.h view on Meta::CPAN
INFIX_CODE_UNEXPECTED_TOKEN = 200, /**< Encountered an unexpected character or token. */
INFIX_CODE_UNTERMINATED_AGGREGATE, /**< A struct, union, or array was not properly closed. */
INFIX_CODE_INVALID_KEYWORD, /**< An unknown or misspelled type keyword was used. */
INFIX_CODE_MISSING_RETURN_TYPE, /**< A function signature was missing the '->' and return type. */
INFIX_CODE_INTEGER_OVERFLOW, /**< An integer overflow occurred during layout calculation. */
INFIX_CODE_RECURSION_DEPTH_EXCEEDED, /**< A type definition was too deeply nested. */
INFIX_CODE_EMPTY_MEMBER_NAME, /**< A named member was declared with an empty name. */
INFIX_CODE_EMPTY_SIGNATURE, /**< The provided signature string was empty. */
// ABI/Layout Codes (300-399)
INFIX_CODE_UNSUPPORTED_ABI = 300, /**< The current platform's ABI is not supported by `infix`. */
INFIX_CODE_TYPE_TOO_LARGE, /**< A data type exceeded the ABI's size limits. */
INFIX_CODE_UNRESOLVED_NAMED_TYPE, /**< A named type (`@Name`) was not found in the provided registry. */
INFIX_CODE_INVALID_MEMBER_TYPE, /**< An aggregate contained an illegal member type (e.g., `void`). */
INFIX_CODE_LAYOUT_FAILED, /**< The ABI layer failed to calculate a valid memory layout for a type. */
// Library Loading Codes (400-499)
INFIX_CODE_LIBRARY_NOT_FOUND = 400, /**< The requested dynamic library could not be found. */
INFIX_CODE_SYMBOL_NOT_FOUND, /**< The requested symbol was not found in the library. */
INFIX_CODE_LIBRARY_LOAD_FAILED /**< The dynamic library failed to load for other reasons. */
} infix_error_code_t;
/**
* @struct infix_error_details_t
* @brief Provides detailed, thread-local information about the last error that occurred.
*/
typedef struct {
infix_error_category_t category; /**< The general category of the error. */
infix_error_code_t code; /**< The specific error code. */
size_t position; /**< For parser errors, the byte offset into the signature string. */
long system_error_code; /**< The OS-specific error code (e.g., from `GetLastError()` or `errno`). */
char message[256]; /**< A human-readable description of the error. For parser errors, this includes a code snippet.
*/
} infix_error_details_t;
/**
* @brief Retrieves detailed information about the last error that occurred on the current thread.
* @return A copy of the last error details structure. This function is thread-safe.
*/
INFIX_API infix_error_details_t infix_get_last_error(void);
/** @} */ // end of error_api group
/**
* @defgroup direct_marshalling_api Direct Marshalling API
* @brief An advanced, high-performance API for language bindings.
* @ingroup high_level_api
*
* This API provides a way to create highly optimized forward trampolines that
* bypass the standard `void**` argument array. Instead, the JIT-compiled code
* directly calls user-provided "marshaller" functions to convert language-specific
* objects into native C arguments just-in-time. This reduces memory indirection
* and copying, yielding significant performance gains for FFI calls in tight loops.
* @{
*/
/**
* @brief A function pointer for a direct marshalling forward trampoline.
*
* This is the callable code generated by `infix_forward_create_direct`. It takes
* an array of `void*` pointers that point directly to the language-specific
* objects (e.g., `SV*` in Perl, `PyObject*` in Python).
*
* @param return_value_ptr A pointer to a buffer to receive the C function's return value.
* @param lang_objects_array An array of `void*` pointers to the original language objects.
*/
typedef void (*infix_direct_cif_func)(void *, void **);
/**
* @brief A union to hold any primitive value returned by a scalar marshaller.
*
* Since a C function can only have one return type, a marshaller for primitive
* types (`infix_marshaller_fn`) returns this union. The JIT-compiled code will
* know which member of the union to access based on the argument's C type.
*/
typedef union {
uint64_t u64; ///< Used for all unsigned integer types up to 64 bits.
int64_t i64; ///< Used for all signed integer types up to 64 bits.
double f64; ///< Used for `float` and `double`.
void * ptr; ///< Used for all pointer types.
} infix_direct_value_t;
/**
* @brief A function pointer for a custom marshaller for scalar types.
*
* A language binding provides a function of this type to convert a language object
* into a native C primitive value (integer, float, pointer, etc.).
*
* @param source_object A generic `void*` pointer to the language's native object.
* @return An `infix_direct_value_t` union containing the converted C value.
*/
typedef infix_direct_value_t (*infix_marshaller_fn)(void * source_object);
/**
* @brief A function pointer for a custom marshaller for aggregate types (structs/unions).
*
* A language binding provides a function of this type to populate a C struct/union
* from a language object (e.g., a hash or dictionary).
*
* @param source_object A `void*` pointer to the language's native object.
* @param dest_buffer A pointer to a block of memory, allocated by the JIT trampoline,
* that is the exact size of the C aggregate. The function must
* fill this buffer with the native C data.
* @param type A pointer to the `infix_type` object describing the C aggregate. The
* marshaller can introspect this type to determine field names, offsets,
* and member types.
*/
typedef void (*infix_aggregate_marshaller_fn)(void * source_object, void * dest_buffer, const infix_type * type);
/**
* @brief A function pointer for a "write-back" handler for out/in-out parameters.
*
* This function is called by the JIT trampoline *after* the native C function has
* returned. Its purpose is to update the original language object with any changes
* made to the C data by the function.
*
* @param source_object A `void*` pointer to the original language object that was passed in.
* @param c_data_ptr A pointer to the (potentially modified) C data buffer that was passed
* to the C function.
* @param type A pointer to the `infix_type` object describing the C data.
*/
typedef void (*infix_writeback_fn)(void * source_object, void * c_data_ptr, const infix_type * type);
/**
* @brief A struct containing all the necessary handlers for a single function argument.
*
* For each argument, a language binding provides an instance of this struct. Based on
* the argument's type, one or more of the function pointers will be non-NULL.
*/
typedef struct {
/** @brief For "in" parameters of a scalar type (int, float, pointer). */
infix_marshaller_fn scalar_marshaller;
/** @brief For "in" parameters of an aggregate type (struct, union). */
infix_aggregate_marshaller_fn aggregate_marshaller;
/** @brief For "out" or "in-out" parameters. Called after the C function returns. */
infix_writeback_fn writeback_handler;
} infix_direct_arg_handler_t;
/**
* @brief Creates a forward trampoline with direct, JIT-bound marshalling.
*
* This advanced function generates a highly optimized trampoline that calls user-provided
* marshaller functions directly from the JIT-compiled code to convert language-specific
* objects into native C arguments. This avoids intermediate copying and provides the
* highest performance for forward calls.
*
* @param[out] out_trampoline Receives the created trampoline handle upon success.
* @param[in] signature The C signature of the target function (e.g., `"(int, *char)->void"`).
* @param[in] target_function The address of the C function to be called.
* @param[in] handlers An array of `infix_direct_arg_handler_t` structs, one for each
* argument of the C function. The array must have exactly as many
* elements as the function has arguments.
* @param[in] registry An optional type registry for resolving named types (`@Name`)
* used within the signature. Can be `nullptr`.
* @return `INFIX_SUCCESS` on success, or an error code on failure.
*/
INFIX_API INFIX_NODISCARD infix_status infix_forward_create_direct(infix_forward_t ** out_trampoline,
const char * signature,
void * target_function,
infix_direct_arg_handler_t * handlers,
infix_registry_t * registry);
/**
* @brief Gets the callable function pointer from a direct marshalling trampoline.
*
* @param[in] trampoline The `infix_forward_t` handle created with `infix_forward_create_direct`.
* @return A callable `infix_direct_cif_func` pointer on success, or `nullptr` if the
* trampoline is `nullptr` or is not a direct marshalling trampoline.
*/
INFIX_API INFIX_NODISCARD infix_direct_cif_func infix_forward_get_direct_code(infix_forward_t * trampoline);
/** @} */ // end of direct_marshalling_api group
#ifdef __cplusplus
}
#endif
( run in 1.174 second using v1.01-cache-2.11-cpan-437f7b0c052 )