Object-Pad

 view release on metacpan or  search on metacpan

include/class.h  view on Meta::CPAN


  FIELDOFFSET start_fieldix; /* first field index of this partial within its instance */
  FIELDOFFSET next_fieldix;  /* 1 + final field index of this partial within its instance; includes fields in roles */

  /* In the following, "MERGED" means the item includes elements merged from a
   * superclass if present, and any applied roles
   * "direct" means only the things added directly to this exact class/role
   */

  SV *name;
  HV *stash;
  CV *constructor;     /* CV that implements &new constructor */
  AV *isa;             /* cached pointer to the @ISA array for the stash */
  AV *pending_submeta; /* NULL, or AV containing raw ClassMeta pointers to subclasses pending seal */
  AV *hooks;           /* NULL, or AV of raw pointers directly to ClassHook structs */
  AV *fields;          /* each elem is a raw pointer directly to a FieldMeta */
  AV *direct_methods;  /* each elem is a raw pointer directly to a MethodMeta */
  HV *parammap;        /* NULL, or each elem is a raw pointer directly at a ParamMeta (MERGED) */
  AV *requiremethods;  /* each elem is an SVt_PV giving a name */
  CV *initfields;      /* the INITFIELDS method body */
  AV *buildcvs;        /* the BUILD {} phaser blocks; each elem is a CV* directly (MERGED) */
  AV *adjustcvs;       /* the ADJUST {} phaser blocks; each elem is a CV* directly (MERGED) */

  AV *fieldhooks_makefield; /* NULL, or AV of struct FieldHook, all of whose ->funcs->post_makefield exist (MERGED) */
  AV *fieldhooks_construct; /* NULL, or AV of struct FieldHook, all of whose ->funcs->post_construct exist (MERGED) */

  COP *tmpcop;         /* a COP to use during generated constructor */
  CV *methodscope;     /* a temporary CV used just during compilation of a `method` */
  U32 methodscope_seq; /* PL_cop_seqmax at the time methodscope was created */

  SuspendedCompCVBuffer initfields_compcv; /* temporary PL_compcv + associated state during initfields */
  OP *initfields_lines;                    /* temporary OP_LINESEQ to contain the initfield ops */
  U32 next_field_for_initfields;           /* how many fields have we seen so far? (offset into direct_fields, !NOT! fieldix) */

  SuspendedCompCVBuffer adjust_compcv; /* temporary PL_compcv + associated state during true-block ADJUSTs */
  CV *adjust_methodscope;              /* temporary CV used during compilation of ADJUST blocks */
  AV *adjust_params;                   /* temporary AV of the params used by true-block ADJUST :params */
  OP *adjust_lines;                    /* temporary OP_LINESEQ to contain true-block ADJUSTs */
  U32 next_field_for_adjust;           /* how many fields have we seen so far? (offset into direct_fields; !NOT! fieldix) */

  union {
    /* Things that only true classes have */
    struct {
      ClassMeta *supermeta; /* superclass */
      CV *foreign_new;      /* superclass is not Object::Pad, here is the constructor */
      CV *foreign_does;     /* superclass is not Object::Pad, here is SUPER::DOES (which could be UNIVERSAL::DOES) */
      AV *direct_roles;     /* each elem is a raw pointer directly to a RoleEmbedding for roles directly applied to this class */
      AV *embedded_roles;   /* each elem is a raw pointer directly to a RoleEmbedding for all roles embedded (MERGED) */
    } cls; /* not 'class' or C++ compilers get upset */

    /* Things that only roles have */
    struct {
      AV *superroles;      /* each elem is a raw pointer directly to a ClassMeta whose type == METATYPE_ROLE */
      HV *applied_classes; /* keyed by class name each elem is a raw pointer directly to a RoleEmbedding */
      AV *applycvs;        /* the APPLY {} phaser blocks; each elem is a CV* directly */
    } role;
  };
};

/* Metadata about the embedding of a role into a class */
#define LINNET_VAL_ROLEEMBEDDING  0x4F505245  /* "OPRE" */
#define MUST_ROLEEMBEDDING(ptr)   LINNET_CHECK_CAST(ptr, RoleEmbedding *, LINNET_VAL_ROLEEMBEDDING)
typedef struct RoleEmbedding {
  LINNET_FIELD
  SV *embeddingsv;
  struct ClassMeta *rolemeta;
  struct ClassMeta *classmeta;
  PADOFFSET offset;
} RoleEmbedding;

#define LINNET_VAL_METHODMETA  0x4F504D4D  /* "OPMM" */
#define MUST_METHODMETA(ptr)   LINNET_CHECK_CAST(ptr, MethodMeta *, LINNET_VAL_METHODMETA)
struct MethodMeta {
  LINNET_FIELD
  SV *name;
  ClassMeta *class;
  ClassMeta *role;   /* set if inherited from a role */
  /* We don't store the method body CV; leave that in the class stash */
  unsigned int is_common : 1;
};

#define LINNET_VAL_PARAMMETA  0x4F50504D  /* "OPPM" */
#define MUST_PARAMMETA(ptr)   LINNET_CHECK_CAST(ptr, ParamMeta *, LINNET_VAL_PARAMMETA)
typedef struct ParamMeta {
  LINNET_FIELD
  SV *name;
  ClassMeta *class;
  enum {
    PARAM_FIELD,
    PARAM_ADJUST,
  } type;
  union {
    struct {
      FieldMeta *fieldmeta;
      FIELDOFFSET fieldix;
    } field;
    struct {
      /* TODO: store the block itself sometime?? */
      PADOFFSET padix;
      OP *defexpr;
      unsigned int def_if_undef : 1;
      unsigned int def_if_false : 1;
    } adjust;
  };
} ParamMeta;

#define MOP_CLASS_RUN_HOOKS_NOARGS(classmeta, func)                                       \
  {                                                                                       \
    U32 hooki;                                                                            \
    for(hooki = 0; classmeta->hooks && hooki < av_count(classmeta->hooks); hooki++) {     \
      struct ClassHook *h = (struct ClassHook *)AvARRAY(classmeta->hooks)[hooki];         \
      if(*h->funcs->func)                                                                 \
        (*h->funcs->func)(aTHX_ classmeta, h->attrdata, h->funcdata);                     \
    }                                                                                     \
  }

#define MOP_CLASS_RUN_HOOKS(classmeta, func, ...)                                         \
  {                                                                                       \
    U32 hooki;                                                                            \
    for(hooki = 0; classmeta->hooks && hooki < av_count(classmeta->hooks); hooki++) {     \
      struct ClassHook *h = (struct ClassHook *)AvARRAY(classmeta->hooks)[hooki];         \
      if(*h->funcs->func)                                                                 \



( run in 2.291 seconds using v1.01-cache-2.11-cpan-71847e10f99 )