Affix
view release on metacpan or search on metacpan
lib/Affix.c view on Meta::CPAN
}
XSRETURN_UNDEF;
}
XS_INTERNAL(Affix_pin_size) {
dXSARGS;
if (items != 1)
croak_xs_usage(cv, "pin");
Affix_Pin * pin = _get_pin_from_sv(aTHX_ ST(0));
if (pin) {
ST(0) = sv_2mortal(newSVuv(pin->size));
XSRETURN(1);
}
XSRETURN_UNDEF;
}
XS_INTERNAL(Affix_pin_get_at) {
dXSARGS;
if (items != 2)
croak_xs_usage(cv, "pin, index");
Affix_Pin * pin = _get_pin_from_sv(aTHX_ ST(0));
IV index = SvIV(ST(1));
if (!pin || !pin->type)
croak("Not a valid pinned pointer");
const infix_type * type = pin->type;
const infix_type * elem_type = type;
if (type->category == INFIX_TYPE_ARRAY)
elem_type = type->meta.array_info.element_type;
else if (type->category == INFIX_TYPE_POINTER && type->meta.pointer_info.pointee_type->category == INFIX_TYPE_VOID)
elem_type = type->meta.pointer_info.pointee_type;
else
croak("Cannot index into non-aggregate type");
size_t elem_size = infix_type_get_size(elem_type);
if (elem_size == 0 && elem_type->category == INFIX_TYPE_VOID) {
elem_size = 1; // Byte-indexed for void*
elem_type = infix_type_create_primitive(INFIX_PRIMITIVE_UINT8);
}
if (elem_size == 0)
croak("Cannot index into zero-sized type");
void * target = (char *)pin->pointer + (index * elem_size);
if (elem_type->category == INFIX_TYPE_STRUCT || elem_type->category == INFIX_TYPE_UNION) {
HV * hv = newHV();
SV * rv = newRV_noinc(MUTABLE_SV(hv));
sv_bless(rv, gv_stashpv("Affix::Live", GV_ADD));
// We might need to pass the owner here too, but let's start with pins
_populate_hv_from_c_struct(aTHX_ nullptr, hv, elem_type, target, true, pin->owner_sv ? pin->owner_sv : ST(0));
ST(0) = sv_2mortal(rv);
}
else if (elem_type->category == INFIX_TYPE_ARRAY) {
// Return a new Affix::Pointer for this sub-array (Live view)
Affix_Pin * new_pin;
Newxz(new_pin, 1, Affix_Pin);
new_pin->pointer = target;
new_pin->managed = false;
new_pin->owner_sv = pin->owner_sv ? pin->owner_sv : ST(0);
SvREFCNT_inc(new_pin->owner_sv);
// We need to keep the type info alive. For now, copy it.
new_pin->type_arena = infix_arena_create(256);
new_pin->type = _copy_type_graph_to_arena(new_pin->type_arena, elem_type);
ST(0) = sv_2mortal(_new_pointer_obj(aTHX_ new_pin));
}
else {
SV * res = sv_newmortal();
ptr2sv(aTHX_ nullptr, target, res, elem_type);
ST(0) = res;
}
XSRETURN(1);
}
XS_INTERNAL(Affix_pin_set_at) {
dXSARGS;
if (items != 3)
croak_xs_usage(cv, "pin, index, value");
Affix_Pin * pin = _get_pin_from_sv(aTHX_ ST(0));
IV index = SvIV(ST(1));
SV * val_sv = ST(2);
if (!pin || !pin->type)
croak("Not a valid pinned pointer");
const infix_type * type = pin->type;
const infix_type * elem_type = type;
if (type->category == INFIX_TYPE_ARRAY)
elem_type = type->meta.array_info.element_type;
else if (type->category == INFIX_TYPE_POINTER && type->meta.pointer_info.pointee_type->category == INFIX_TYPE_VOID)
elem_type = type->meta.pointer_info.pointee_type;
else
croak("Cannot index into non-aggregate type");
size_t elem_size = infix_type_get_size(elem_type);
if (elem_size == 0 && elem_type->category == INFIX_TYPE_VOID) {
elem_size = 1;
elem_type = infix_type_create_primitive(INFIX_PRIMITIVE_UINT8);
}
if (elem_size == 0)
croak("Cannot index into zero-sized type");
void * target = (char *)pin->pointer + (index * elem_size);
sv2ptr(aTHX_ nullptr, val_sv, target, elem_type);
XSRETURN_EMPTY;
}
// Helper to register core internal types
static void _register_core_types(infix_registry_t * registry) {
// Register SV as a named type (dummy struct ensures it keeps the name in the registry).
// This allows signature parsing of "@SV" or "SV" (via hack) to map to a named opaque type.
// Direct usage of this type is blocked in get_opcode_for_type; it must be wrapped in Pointer[].
if (infix_register_types(registry, "@SV = { __sv_opaque: uint8 };") != INFIX_SUCCESS)
croak("Failed to register internal type alias '@SV'");
// We register File and PerlIO as opaque structs.
// This semantically matches C's FILE struct which (for now) will remain opaque to the user.
// We require "Pointer[File]" to mean "FILE*"
if (infix_register_types(registry, "@File = { _opaque: [0:uchar] };") != INFIX_SUCCESS)
croak("Failed to register internal type alias '@File'");
if (infix_register_types(registry, "@PerlIO = { _opaque: [0:uchar] };") != INFIX_SUCCESS)
croak("Failed to register internal type alias '@PerlIO'");
// Other special types are opaque structs too. ...but they don't always mean anything in particular.
( run in 0.541 second using v1.01-cache-2.11-cpan-df04353d9ac )