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 )