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); }