Affix
view release on metacpan or search on metacpan
lib/Affix.c view on Meta::CPAN
char buffer[256];
if (infix_type_print(buffer, sizeof(buffer), pin->type, INFIX_DIALECT_SIGNATURE) == INFIX_SUCCESS)
ST(0) = sv_2mortal(newSVpv(buffer, 0));
else
XSRETURN_UNDEF;
XSRETURN(1);
}
XS_INTERNAL(Affix_pin_element_type) {
dXSARGS;
if (items != 1)
croak_xs_usage(cv, "pin");
Affix_Pin_2_Point_Oh * pin = get_pin_v2(aTHX_ ST(0));
if (!pin || !pin->type)
XSRETURN_UNDEF;
const infix_type * elem_type = pin->type;
if (elem_type->category == INFIX_TYPE_ARRAY)
elem_type = elem_type->meta.array_info.element_type;
else if (elem_type->category == INFIX_TYPE_POINTER)
elem_type = elem_type->meta.pointer_info.pointee_type;
char buffer[256];
if (infix_type_print(buffer, sizeof(buffer), elem_type, INFIX_DIALECT_SIGNATURE) == INFIX_SUCCESS)
ST(0) = sv_2mortal(newSVpv(buffer, 0));
else
XSRETURN_UNDEF;
XSRETURN(1);
}
XS_INTERNAL(Affix_pin_count) {
dXSARGS;
if (items != 1)
croak_xs_usage(cv, "pin");
Affix_Pin_2_Point_Oh * pin = get_pin_v2(aTHX_ ST(0));
if (pin && pin->type) {
if (pin->type->category == INFIX_TYPE_ARRAY) {
ST(0) = sv_2mortal(newSVuv(pin->type->meta.array_info.num_elements));
XSRETURN(1);
}
}
XSRETURN_UNDEF;
}
XS_INTERNAL(Affix_pin_size) {
dXSARGS;
if (items != 1)
croak_xs_usage(cv, "pin");
Affix_Pin_2_Point_Oh * pin = get_pin_v2(aTHX_ ST(0));
if (pin && pin->type) {
ST(0) = sv_2mortal(newSVuv(infix_type_get_size(pin->type)));
XSRETURN(1);
}
XSRETURN_UNDEF;
}
// 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.
if (infix_register_types(registry, "@StringList = **char;") != INFIX_SUCCESS)
croak("Failed to register internal type alias '@StringList'");
if (infix_register_types(registry, "@Buffer = *void;") != INFIX_SUCCESS)
croak("Failed to register internal type alias '@Buffer'");
if (infix_register_types(registry, "@SockAddr = *void;") != INFIX_SUCCESS)
croak("Failed to register internal type alias '@SockAddr'");
}
static void _set_readonly_recursive(pTHX_ SV * sv, bool ro) {
if (!sv || !SvOK(sv))
return;
SV * target = SvROK(sv) ? SvRV(sv) : sv;
Affix_Pin_2_Point_Oh * pin = get_pin_v2(aTHX_ target);
if (pin)
pin->readonly = ro;
if (SvTYPE(target) == SVt_PVHV) {
HV * hv = (HV *)target;
HE * entry;
hv_iterinit(hv);
while ((entry = hv_iternext(hv)))
_set_readonly_recursive(aTHX_ hv_iterval(hv, entry), ro);
}
else if (SvTYPE(target) == SVt_PVAV) {
AV * av = (AV *)target;
SSize_t len = av_len(av);
for (SSize_t i = 0; i <= len; i++) {
SV ** val = av_fetch(av, i, 0);
if (val && *val)
_set_readonly_recursive(aTHX_ * val, ro);
}
}
}
XS_INTERNAL(Affix_readonly) {
dXSARGS;
if (items < 1)
croak_xs_usage(cv, "pin, [readonly]");
// Check for V2 Pin first
if (is_pin_v2(aTHX_ ST(0))) {
Affix_Pin_2_Point_Oh * pin_v2 = get_pin_v2(aTHX_ ST(0));
if (items > 1) {
bool ro = SvTRUE(ST(1));
_set_readonly_recursive(aTHX_ ST(0), ro);
}
ST(0) = pin_v2->readonly ? &PL_sv_yes : &PL_sv_no;
( run in 1.172 second using v1.01-cache-2.11-cpan-800906f7e73 )