The Perl and Raku Conference 2025: Greenville, South Carolina - June 27-29 Learn more

SV *
name(FieldMeta *self)
ALIAS:
name = 0
sigil = 1
class = 2
CODE:
switch(ix) {
case 0:
RETVAL = SvREFCNT_inc(self->name);
break;
case 1:
RETVAL = newSVpvn(SvPVX(self->name), 1);
break;
case 2:
RETVAL = newSV(0);
sv_setref_uv(RETVAL, "Object::Pad::MOP::Class", PTR2UV(self->class));
break;
default: RETVAL = NULL;
}
OUTPUT:
RETVAL
void
value(FieldMeta *self, obj)
SV *obj
PPCODE:
{
SV *objrv;
if(!SvROK(obj) || !SvOBJECT(objrv = SvRV(obj)))
croak("Cannot fetch field value of a non-instance");
SV *value = get_obj_fieldsv(obj, self);
/* We must prevent caller from assigning to non-scalar fields, in case
* they break the SvTYPE of the value. We can't cancel the CvLVALUE but we
* can yield a READONLY value in this case */
if(SvPV_nolen(self->name)[0] != '$') {
value = sv_mortalcopy(value);
SvREADONLY_on(value);
}
/* stack does not contribute SvREFCNT */
ST(0) = value;
XSRETURN(1);
}
bool
has_attribute(FieldMeta *self, name)
SV *name
CODE:
{
const struct FieldHook *hook = mop_field_get_attribute(self, SvPV_nolen(name));
RETVAL = !!hook;
}
OUTPUT:
RETVAL
SV *
get_attribute_value(FieldMeta *self, name)
SV *name
CODE:
{
const struct FieldHook *hook = mop_field_get_attribute(self, SvPV_nolen(name));
if(!hook)
croak("Field does not have an attribute called %" SVf, SVfARG(name));
RETVAL = newSVsv(hook->attrdata);
}
OUTPUT:
RETVAL
void
get_attribute_values(FieldMeta *self, name)
SV *name
PPCODE:
{
AV *values = mop_field_get_attribute_values(self, SvPV_nolen(name));
if(!values)
croak("Field does not have an attribute called %" SVf, SVfARG(name));
Size_t count = av_count(values);
EXTEND(SP, count);
for(Size_t i = 0; i < count; i++)
PUSHs(SvREFCNT_inc(AvARRAY(values)[i]));
SvREFCNT_dec(values);
XSRETURN(count);
}