Affix
view release on metacpan or search on metacpan
lib/Affix.h view on Meta::CPAN
OP_PUSH_UINT64,
OP_PUSH_FLOAT,
OP_PUSH_FLOAT16,
OP_PUSH_DOUBLE,
OP_PUSH_LONGDOUBLE,
OP_PUSH_SINT128,
OP_PUSH_UINT128,
OP_PUSH_POINTER, // fallback for pins/refs
OP_PUSH_PTR_CHAR, // char* optimization
OP_PUSH_PTR_WCHAR, // wchar_t* optimization
OP_PUSH_SV, // SV*
OP_PUSH_STRUCT, // aggregates ...
OP_PUSH_UNION,
OP_PUSH_ARRAY,
OP_PUSH_CALLBACK,
OP_PUSH_ENUM,
OP_PUSH_COMPLEX,
OP_PUSH_VECTOR, // optimized vector
OP_DONE, // sentinel to stop the threaded dispatcher
OP_RET_VOID, // retval marshalling opcodes ...
OP_RET_BOOL,
OP_RET_SINT8,
OP_RET_UINT8,
OP_RET_SINT16,
OP_RET_UINT16,
OP_RET_SINT32,
OP_RET_UINT32,
OP_RET_SINT64,
OP_RET_UINT64,
OP_RET_FLOAT,
OP_RET_FLOAT16,
OP_RET_DOUBLE,
OP_RET_LONGDOUBLE,
OP_RET_SINT128,
OP_RET_UINT128,
OP_RET_PTR, // Generic pin return
OP_RET_PTR_CHAR, // Returns Perl String (UTF8)
OP_RET_PTR_WCHAR, // Returns Perl String (from Wide)
OP_RET_SV, // Returns SV* directly
OP_RET_CUSTOM // Complex types (structs, arrays)
} Affix_Opcode;
/// A single step in the pre-compiled execution plan.
struct Affix_Plan_Step {
Affix_Step_Executor executor; // Function pointer to the executor for this step.
Affix_Opcode opcode; // The instruction for the VM
Affix_Step_Data data; // Pre-calculated data needed by the executor.
};
/// Represents a forward FFI call (a Perl sub that calls a C function).
/// This struct holds the pre-compiled execution plan and is attached to the generated XS subroutine.
struct Affix {
infix_forward_t * infix; ///< Handle to the infix trampoline and type info.
infix_arena_t * args_arena; ///< Persistent arena for type data (init-time only).
infix_arena_t * ret_arena; ///< Persistent arena for return type data (init-time only).
infix_arena_t * call_args_arena; ///< Per-call temp arena for arguments (fiber-safe: not restored via SAVEVPTR).
infix_arena_t * call_ret_arena; ///< Per-call temp arena for return value (fiber-safe: not restored via SAVEVPTR).
infix_cif_func cif; ///< A direct function pointer to the JIT-compiled trampoline code.
infix_library_t * lib_handle; ///< If affix() loaded a library itself, stores the handle for cleanup.
SV * return_sv; ///< Pre-allocated, reusable SV to hold the return value.
Affix_Plan_Step * plan; ///< The linear array of operations (the "execution plan").
size_t plan_length; ///< The total number of steps in the plan.
size_t num_args; ///< Cached number of arguments for faster access.
size_t total_args_size; ///< Pre-calculated total size of the C arguments buffer.
// Pre-compiled plan for handling "out" parameters after the C call.
OutParamInfo * out_param_info;
size_t num_out_params;
const infix_type * ret_type;
const infix_type * unwrapped_ret_type; // Pre-unwrapped for OP_RET_PTR
Affix_Pull ret_pull_handler; ///< Cached handler for marshalling the return value.
Affix_Opcode ret_opcode; ///< Optimized return opcode.
bool ret_readonly; ///< Should the returned aggregate prevent perl-side mutations?
void ** c_args;
// Reconstruction info for threading/cloning
char * sig_str;
char * sym_name;
void * target_addr;
char * lib_path;
dTHXfield(owner_perl)
// Variadic demo
HV * variadic_cache;
size_t num_fixed_args;
};
/**
* @struct Affix_Pin_2_Point_Oh
* @brief The internal payload attached to Perl Scalars via Perl Magic (PERL_MAGIC_ext).
* @details This struct holds the raw C pointer, type metadata, and bitfield offsets.
* When Perl attempts to read or write a scalar, the VTable fetches this struct to
* map the scalar value directly to native C memory.
*/
typedef struct {
void * ptr; /**< Pointer to the actual C memory backing this variable. */
const infix_type * type; /**< Pointer to the parsed AST type node. */
infix_arena_t * arena; /**< Local arena for anonymous types. */
uint8_t bit_offset; /**< Bitfield offset (0 for standard types). */
uint8_t bit_width; /**< Bitfield width in bits (0 for standard types). */
bool readonly; /**< True if the pin is marked const/readonly. */
bool absolute; /**< True if ptr is the target address, false if it's the address of a variable */
void (*destructor)(void *);
SV * destructor_lib_sv;
} Affix_Pin_2_Point_Oh;
/// Holds the necessary data for a callback, specifically the Perl subroutine to call.
typedef struct {
SV * coderef_rv; ///< A reference (RV) to the Perl coderef. We hold this to keep it alive.
dTHXfield(perl) ///< The thread context in which the callback was created.
} Affix_Callback_Data;
/// Internal struct holding the C resources that are magically attached
/// to a user's coderef (CV*) when it is first used as a callback.
typedef struct {
infix_reverse_t * reverse_ctx; ///< Handle to the infix reverse-call trampoline.
} Implicit_Callback_Magic;
/// An entry in the thread-local library registry hash.
typedef struct {
infix_library_t * lib; ///< The handle to the opened library.
UV ref_count; ///< Reference count. The library is closed only when this reaches 0.
} LibRegistryEntry;
// Struct for the Direct Marshalling (aka "bundle") backend.
/// Represents a forward FFI call created with the high-performance direct marshalling API.
( run in 1.425 second using v1.01-cache-2.11-cpan-364913b4093 )