Merge branch 'master' into metadata
Lukas Mai [Wed, 14 Nov 2012 14:27:34 +0000 (15:27 +0100)]
1  2 
Parameters.xs

diff --combined Parameters.xs
@@@ -147,39 -147,6 +147,6 @@@ static SV *sentinel_mortalize(Sentinel 
        return sv;
  }
  
- static void my_safefree(void *p) {
-       Safefree(p);
- }
- #define SENTINEL_ALLOC(SEN, P, N, T) STMT_START { \
-       Newx(P, N, T); \
-       sentinel_register(SEN, P, my_safefree); \
- } STMT_END
- #define SENTINEL_MDUP(SEN, P, O, N, T) STMT_START { \
-       void *const _sentinel_mdup_tmp_ = (P); \
-       SENTINEL_ALLOC(SEN, P, N, T); \
-       memcpy(P, _sentinel_mdup_tmp_, O * sizeof (T)); \
- } STMT_END
- #define SENTINEL_REALLOC(SEN, P, N, T) STMT_START { \
-       assert((N) > 0); \
-       if (!(P)) { \
-               SENTINEL_ALLOC(SEN, P, N, T); \
-       } else { \
-               Resource **_sentinel_realloc_tmp_ = (SEN); \
-               for (;;) { \
-                       assert(*_sentinel_realloc_tmp_ != NULL); \
-                       if ((*_sentinel_realloc_tmp_)->data == (P)) { \
-                               Renew((*_sentinel_realloc_tmp_)->data, N, T); \
-                               (P) = (*_sentinel_realloc_tmp_)->data; \
-                               break; \
-                       } \
-                       _sentinel_realloc_tmp_ = &(*_sentinel_realloc_tmp_)->next; \
-               } \
-       } \
- } STMT_END
  static int kw_flags(pTHX_ Sentinel sen, const char *kw_ptr, STRLEN kw_len, KWSpec *spec) {
        HV *hints;
        SV *sv, **psv;
@@@ -786,123 -753,6 +753,123 @@@ static OP *mkconstpv(pTHX_ const char *
  
  #define mkconstpvs(S) mkconstpv(aTHX_ "" S "", sizeof S - 1)
  
 +static void register_info(pTHX_ UV key, SV *declarator, const KWSpec *kws, const ParamSpec *ps) {
 +      dSP;
 +
 +      ENTER;
 +      SAVETMPS;
 +
 +      PUSHMARK(SP);
 +      EXTEND(SP, 8);
 +
 +      /* 0 */ {
 +              mPUSHu(key);
 +      }
 +      /* 1 */ {
 +              size_t n;
 +              char *p = SvPV(declarator, n);
 +              char *q = memchr(p, ' ', n);
 +              mPUSHp(p, q ? (size_t)(q - p) : n);
 +      }
 +      if (!ps) {
 +              if (SvTRUE(kws->shift)) {
 +                      PUSHs(kws->shift);
 +              } else {
 +                      PUSHmortal;
 +              }
 +              mPUSHs(newRV_noinc((SV *)newAV()));
 +              mPUSHs(newRV_noinc((SV *)newAV()));
 +              mPUSHs(newRV_noinc((SV *)newAV()));
 +              mPUSHs(newRV_noinc((SV *)newAV()));
 +              mPUSHp("@_", 2);
 +      } else {
 +              /* 2 */ {
 +                      if (ps->invocant.name) {
 +                              PUSHs(ps->invocant.name);
 +                      } else {
 +                              PUSHmortal;
 +                      }
 +              }
 +              /* 3 */ {
 +                      size_t i, lim;
 +                      AV *av;
 +
 +                      lim = ps->positional_required.used;
 +
 +                      av = newAV();
 +                      if (lim) {
 +                              av_extend(av, lim - 1);
 +                              for (i = 0; i < lim; i++) {
 +                                      av_push(av, SvREFCNT_inc_simple_NN(ps->positional_required.data[i].name));
 +                              }
 +                      }
 +
 +                      mPUSHs(newRV_noinc((SV *)av));
 +              }
 +              /* 4 */ {
 +                      size_t i, lim;
 +                      AV *av;
 +
 +                      lim = ps->positional_optional.used;
 +
 +                      av = newAV();
 +                      if (lim) {
 +                              av_extend(av, lim - 1);
 +                              for (i = 0; i < lim; i++) {
 +                                      av_push(av, SvREFCNT_inc_simple_NN(ps->positional_optional.data[i].param.name));
 +                              }
 +                      }
 +
 +                      mPUSHs(newRV_noinc((SV *)av));
 +              }
 +              /* 5 */ {
 +                      size_t i, lim;
 +                      AV *av;
 +
 +                      lim = ps->named_required.used;
 +
 +                      av = newAV();
 +                      if (lim) {
 +                              av_extend(av, lim - 1);
 +                              for (i = 0; i < lim; i++) {
 +                                      av_push(av, SvREFCNT_inc_simple_NN(ps->named_required.data[i].name));
 +                              }
 +                      }
 +
 +                      mPUSHs(newRV_noinc((SV *)av));
 +              }
 +              /* 6 */ {
 +                      size_t i, lim;
 +                      AV *av;
 +
 +                      lim = ps->named_optional.used;
 +
 +                      av = newAV();
 +                      if (lim) {
 +                              av_extend(av, lim - 1);
 +                              for (i = 0; i < lim; i++) {
 +                                      av_push(av, SvREFCNT_inc_simple_NN(ps->named_optional.data[i].param.name));
 +                              }
 +                      }
 +
 +                      mPUSHs(newRV_noinc((SV *)av));
 +              }
 +              /* 7 */ {
 +                      if (ps->slurpy.name) {
 +                              PUSHs(ps->slurpy.name);
 +                      } else {
 +                              PUSHmortal;
 +                      }
 +              }
 +      }
 +      PUTBACK;
 +
 +      call_pv(MY_PKG "::_register_info", G_VOID);
 +
 +      FREETMPS;
 +      LEAVE;
 +}
 +
  static int parse_fun(pTHX_ Sentinel sen, OP **pop, const char *keyword_ptr, STRLEN keyword_len, const KWSpec *spec) {
        ParamSpec *param_spec;
        SV *declarator;
  
        /* it's go time. */
        {
 +              CV *cv;
                OP *const attrs = *attrs_sentinel;
                *attrs_sentinel = NULL;
 +
                SvREFCNT_inc_simple_void(PL_compcv);
  
                /* close outer block: '}' */
                S_block_end(aTHX_ save_ix, body);
  
 -              if (!saw_name) {
 -                      *pop = newANONATTRSUB(
 -                              floor_ix,
 -                              proto ? newSVOP(OP_CONST, 0, SvREFCNT_inc_simple_NN(proto)) : NULL,
 -                              attrs,
 -                              body
 -                      );
 -                      return KEYWORD_PLUGIN_EXPR;
 -              }
 -
 -              newATTRSUB(
 +              cv = newATTRSUB(
                        floor_ix,
 -                      newSVOP(OP_CONST, 0, SvREFCNT_inc_simple_NN(saw_name)),
 +                      saw_name ? newSVOP(OP_CONST, 0, SvREFCNT_inc_simple_NN(saw_name)) : NULL,
                        proto ? newSVOP(OP_CONST, 0, SvREFCNT_inc_simple_NN(proto)) : NULL,
                        attrs,
                        body
                );
 -              *pop = newOP(OP_NULL, 0);
 -              return KEYWORD_PLUGIN_STMT;
 +
 +              register_info(aTHX_ PTR2UV(CvROOT(cv)), declarator, spec, param_spec);
 +
 +              if (saw_name) {
 +                      *pop = newOP(OP_NULL, 0);
 +                      return KEYWORD_PLUGIN_STMT;
 +              }
 +
 +              *pop = newUNOP(
 +                      OP_REFGEN, 0,
 +                      newSVOP(
 +                              OP_ANONCODE, 0,
 +                              (SV *)cv
 +                      )
 +              );
 +              return KEYWORD_PLUGIN_EXPR;
        }
  }
  
@@@ -1702,22 -1546,9 +1669,22 @@@ static int my_keyword_plugin(pTHX_ cha
  
  WARNINGS_RESET
  
 -MODULE = Function::Parameters   PACKAGE = Function::Parameters
 +MODULE = Function::Parameters   PACKAGE = Function::Parameters   PREFIX = fp_
  PROTOTYPES: ENABLE
  
 +UV
 +fp__cv_root(sv)
 +      SV * sv
 +      PREINIT:
 +              CV *xcv;
 +              HV *hv;
 +              GV *gv;
 +      CODE:
 +              xcv = sv_2cv(sv, &hv, &gv, 0);
 +              RETVAL = PTR2UV(xcv ? CvROOT(xcv) : NULL);
 +      OUTPUT:
 +              RETVAL
 +
  BOOT:
  WARNINGS_ENABLE {
        HV *const stash = gv_stashpvs(MY_PKG, GV_ADD);