Object-Pad
view release on metacpan or search on metacpan
src/field.c view on Meta::CPAN
if(hook->funcs == reg->funcs)
return hook;
}
return NULL;
}
AV *ObjectPad_mop_field_get_attribute_values(pTHX_ FieldMeta *fieldmeta, const char *name)
{
/* First, work out what hookfuncs the name maps to */
FieldAttributeRegistration *reg = get_active_registration(aTHX_ name);
if(!reg)
return NULL;
/* Now lets see if fieldmeta has one */
if(!fieldmeta->hooks)
return NULL;
AV *ret = NULL;
U32 hooki;
for(hooki = 0; hooki < av_count(fieldmeta->hooks); hooki++) {
struct FieldHook *hook = (struct FieldHook *)AvARRAY(fieldmeta->hooks)[hooki];
if(hook->funcs != reg->funcs)
continue;
if(!ret)
ret = newAV();
av_push(ret, newSVsv(hook->attrdata));
}
return ret;
}
SV *ObjectPad_get_obj_fieldsv(pTHX_ SV *self, FieldMeta *fieldmeta)
{
SV *fieldstore;
FIELDOFFSET fieldix;
ClassMeta *classmeta = fieldmeta->class;
assert(SvROK(self));
assert(SvOBJECT(SvRV(self)));
if(classmeta->type == METATYPE_ROLE) {
HV *objstash = SvSTASH(SvRV(self));
const char *key = HvNAME(objstash);
STRLEN klen = HvNAMELEN(objstash);
if(HvNAMEUTF8(objstash))
klen = -klen;
assert(key);
SV **svp = hv_fetch(classmeta->role.applied_classes, key, klen, 0);
if(!svp)
croak("Cannot fetch role field value from a non-applied instance");
RoleEmbedding *embedding = MUST_ROLEEMBEDDING(*svp);
fieldstore = get_obj_fieldstore(self, embedding->classmeta->repr, true);
fieldix = fieldmeta->fieldix + embedding->offset;
}
else {
const char *stashname = HvNAME(classmeta->stash);
if(!stashname || !sv_derived_from(self, stashname))
croak("Cannot fetch field value from a non-derived instance");
fieldstore = get_obj_fieldstore(self, classmeta->repr, true);
fieldix = fieldmeta->fieldix;
}
if(fieldix > fieldstore_maxfield(fieldstore))
croak("ARGH: instance does not have a field at index %ld", (long int)fieldix);
SV *sv = fieldstore_fields(fieldstore)[fieldix];
return sv;
}
static OP *pp_fieldsv(pTHX)
{
dSP;
FIELDOFFSET fieldix = PL_op->op_targ;
if(PL_op->op_flags & OPf_SPECIAL) {
RoleEmbedding *embedding = get_embedding_from_pad();
if(embedding && embedding != &ObjectPad__embedding_standalone) {
fieldix += embedding->offset;
}
}
SV *fieldstore = PAD_SVl(PADIX_FIELDS);
SV *fieldsv = fieldstore_fields(fieldstore)[fieldix];
EXTEND(SP, 1);
PUSHs(fieldsv);
RETURN;
}
#define newFIELDSVOP(flags, fieldix) S_newFIELDSVOP(aTHX_ flags, fieldix)
static OP *S_newFIELDSVOP(pTHX_ U32 flags, FIELDOFFSET fieldix)
{
OP *o = newOP_CUSTOM(&pp_fieldsv, flags);
o->op_targ = fieldix;
if(flags & OPfMETHSTART_ROLE)
o->op_flags |= OPf_SPECIAL;
return o;
}
#define gen_field_init_op(fieldmeta) S_gen_field_init_op(aTHX_ fieldmeta)
static OP *S_gen_field_init_op(pTHX_ FieldMeta *fieldmeta)
{
ClassMeta *classmeta = fieldmeta->class;
U32 opflags_if_role = (classmeta->type == METATYPE_ROLE) ? OPfMETHSTART_ROLE : 0;
( run in 1.593 second using v1.01-cache-2.11-cpan-71847e10f99 )