/*
    NOTE: mouse_tc_check() handles GETMAGIC
*/
int
mouse_tc_check(pTHX_ SV* const tc_code, SV* const sv) {
    CV* const cv = (CV*)SvRV(tc_code);
    assert(SvTYPE(cv) == SVt_PVCV);

    if(CvXSUB(cv) == XS_Mouse_constraint_check){ /* built-in type constraints */
        MAGIC* const mg = (MAGIC*)CvXSUBANY(cv).any_ptr;

        assert(CvXSUBANY(cv).any_ptr != NULL);
        assert(mg->mg_ptr            != NULL);

        SvGETMAGIC(sv);
        /* call the check function directly, skipping call_sv() */
        return CALL_FPTR((check_fptr_t)mg->mg_ptr)(aTHX_ mg->mg_obj, sv);
    }
    else { /* custom */
        int ok;
        dSP;
        dMY_CXT;

        ENTER;
        SAVETMPS;

        PUSHMARK(SP);
        XPUSHs(sv);
        if( MY_CXT.tc_extra_args ) {
            AV* const av  = MY_CXT.tc_extra_args;
            I32 const len = AvFILLp(av) + 1;
            int i;
            for(i = 0; i < len; i++) {
                XPUSHs( AvARRAY(av)[i] );
            }
        }
        PUTBACK;

        call_sv(tc_code, G_SCALAR);

        SPAGAIN;
        ok = sv_true(POPs);
        PUTBACK;

        FREETMPS;
        LEAVE;

        return ok;
    }
}
Пример #2
0
static void _MopMmV_wrapper (pTHX_ CV *cv) {
    bool has_events;
    I32  j, count;
    SV** args;
    CV*  body;
    SV*  object  = newRV_noinc((SV*) cv);
    AV*  results = newAV();
    
    dXSARGS;

    has_events = MopOV_has_events(object);
    body       = (CV*) CvXSUBANY(cv).any_uv;

    if (has_events) {
        Newx(args, items, SV*);
        for (j = 0; j < items; j++) {
            args[j] = ST(j);
        }
        MopOV_fire_event(object, newSVpv("before:EXECUTE", 14), args, items-1);
    }

    {
        ENTER;
        PUSHMARK(SP);
        for (j = 0; j < items; j++) {
            PUSHs(args[j]);
        }
        PUTBACK;
        count = call_sv((SV*) body, GIMME_V);
        SPAGAIN;

        while (count-- > 0) {
            av_push(results, POPs);
        }

        LEAVE;
    }

    for (j = 0; j < av_len(results) + 1; j++) {
        ST(j) = *av_fetch(results, av_len(results) - j, 0);
    }

    if (has_events) {
        MopOV_fire_event(object, newSVpv("after:EXECUTE", 13), args, items-1);   
    }

    XSRETURN(av_len(results) + 1);
}
Пример #3
0
static void xs_new(pTHX_ SV *cv) {
  dXSARGS;
  if (items < 1) croak("Usage: class, ref");

#ifndef MULTIPLICITY
  AV *slots = CvXSUBANY(cv).any_ptr;
#else
  MAGIC *mg = mg_findext(cv, PERL_MAGIC_ext, &ATTRS_TBL);
  AV *slots = (AV *)mg->mg_obj;
#endif

  SV *class = ST(0);
  HV *hash = newHV();
  SV *obj = sv_2mortal(newRV_noinc((SV *)hash)); // don't move to the end(leaks)

  SV **args;                                               // uniq args
  int args_count = args_to_uniq(&ST(1), items - 1, &args); // skip 1(class)

  int slots_count = av_top_index(slots) + 1;
  for (int i = 0; i < slots_count; i++) { // NEXT_SLOT:
    ECAslot *slot = sv2slot(av_fetch_or_croak(slots, i));

    // iterage args, null if matched
    for (int j = 0; j < args_count; j += 2) {
      SV *tmp = args[j];
      if (!tmp) continue; // already matched

      if (!sv_cmp(tmp, slot->key)) {
        if (slot->check) do_check(slot->check, args[j + 1], slot->key);
        hv_he_store_or_croak(hash, slot->key, args[j + 1]);
        args[j] = NULL;
        goto NEXT_SLOT;
        args[j] = NULL; // mark as consumed
      }
    }

    // slot not found in passed args, decide what to do
    if (slot->type == ECA_REQUIRED) {
      croak("Attribute \"%s\" is required", SvPV_nolen(slot->key));
    } else if (slot->type == ECA_DEFAULT) {
      hv_he_store_or_croak(hash, slot->key, slot->value);
    } else if (slot->type == ECA_DEFAULT_CODE) {
      invoke_and_store(class, slot->value, hash, slot->key);
    }

  NEXT_SLOT:; // simulate continue label
  }
Пример #4
0
SV* THX_newMopMmV(pTHX_ SV* code, U32 flags) {
    SV* method;

    CV* cv = (CV*) newSV(0);
    sv_upgrade((SV*) cv, SVt_PVCV);
    CvISXSUB_on(cv);
    CvXSUB(cv) = _MopMmV_wrapper;
    CvXSUBANY(cv).any_uv = PTR2UV(code);
    CvFILE(cv) = __FILE__;    

    CvANON_off(cv);
    CvMETHOD_on(cv);

    SvREFCNT_inc(code);

    method = newMopOV(newRV_inc((SV*) cv));

    if (flags & MopMmVf_STEAL_STASH) {
        MopMmV_assign_to_stash(method, CvGV(SvRV(code)), CvSTASH(SvRV(code)));
    }

    return method;
}
Пример #5
0
static CV *coroae_closure_sighandler(int sigfd) {

        CV *xsub = newXS(NULL, XS_coroae_sighandler, "uwsgi::coroae");
        CvXSUBANY(xsub).any_ptr = (void *) sigfd;
        return xsub;
}
Пример #6
0
static CV *coroae_closure_acceptor(struct uwsgi_socket *uwsgi_sock) {

	CV *xsub = newXS(NULL, XS_coroae_acceptor, "uwsgi::coroae");
	CvXSUBANY(xsub).any_ptr = uwsgi_sock;
	return xsub;
}
Пример #7
0
SV* THX_MopMmV_get_body(pTHX_ SV* metamethod) {
    return newRV_noinc((SV*) CvXSUBANY((CV*) SvRV(metamethod)).any_uv);
}