SV* meta = get_metaclass(klass);
if(!SvOK(meta)){
- dSP;
- PUSHMARK(SP);
-
- EXTEND(SP, 2);
- mPUSHp("Mouse::Meta::Class", sizeof("Mouse::Meta::Class")-1);
- PUSHs(klass);
- PUTBACK;
-
- call_method("initialize", G_SCALAR);
- SPAGAIN;
- meta = POPs;
- PUTBACK;
+ meta = mcall1s(newSVpvs_flags("Mouse::Meta::Class", SVs_TEMP), "initialize", klass);
}
return meta;
PUSHs(args);
PUTBACK;
- call_sv(AvARRAY(buildall)[i], G_VOID);
+ call_sv_safe(AvARRAY(buildall)[i], G_VOID);
/* discard a scalar which G_VOID returns */
SPAGAIN;
SV* table;
SV* storage_ref;
- SvGETMAGIC(name);
- if(!SvOK(name)){
- mouse_throw_error(meta, NULL, "You must define a method name for '%s' modifiers", keys[m]);
- }
+ must_defined(name, "a method name");
table = get_slot(meta, key);
croak("No package name defined");
}
- SvGETMAGIC(name);
- SvGETMAGIC(code);
-
- if(!SvOK(name)){
- mouse_throw_error(self, NULL, "You must define a method name");
- }
- if(!SvROK(code)){
- mouse_throw_error(self, NULL, "You must define a CODE reference");
- }
+ must_defined(name, "a method name");
+ must_ref (code, "a CODE reference", SVt_NULL); /* any reftype is OK */
code_ref = code;
if(SvTYPE(SvRV(code_ref)) != SVt_PVCV){
SV* sv = code_ref; /* used in tryAMAGICunDEREF */
SV** sp = &sv; /* used in tryAMAGICunDEREF */
tryAMAGICunDEREF(to_cv); /* try \&{$code} */
- if(!(SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVCV)){
- mouse_throw_error(self, NULL, "You must pass a CODE reference to add_method");
- }
+ must_ref(code, "a CODE reference", SVt_PVCV);
code_ref = sv;
}
/* *{$package . '::' . $name} -> *gv */
gv = gv_fetchpv(form("%"SVf"::%"SVf, package, name), GV_ADDMULTI, SVt_PVCV);
- if(GvCVu(gv)){ /* delete *slot{gv} to work around "redefine" warning */
- SvREFCNT_dec(GvCV(gv));
- GvCV(gv) = NULL;
- }
- sv_setsv_mg((SV*)gv, code_ref); /* *gv = $code_ref */
-
+ mouse_install_sub(aTHX_ gv, code_ref);
+ //CvMETHOD_on((CV*)SvRV(code_ref));
(void)set_slot(methods, name, code); /* $self->{methods}{$name} = $code */
-
- /* name the CODE ref if it's anonymous */
- {
- CV* const code_entity = (CV*)SvRV(code_ref);
- if(CvANON(code_entity)
- && CvGV(code_entity) /* a cv under construction has no gv */ ){
- HV* dbsub;
-
- /* update %DB::sub to make NYTProf happy */
- if((PL_perldb & (PERLDBf_SUBLINE|PERLDB_NAMEANON))
- && PL_DBsub && (dbsub = GvHV(PL_DBsub))
- ){
- /* see Perl_newATTRSUB() in op.c */
- SV* const subname = sv_newmortal();
- HE* orig;
-
- gv_efullname3(subname, CvGV(code_entity), NULL);
- orig = hv_fetch_ent(dbsub, subname, FALSE, 0U);
- if(orig){
- gv_efullname3(subname, gv, NULL);
- (void)hv_store_ent(dbsub, subname, HeVAL(orig), 0U);
- SvREFCNT_inc_simple_void_NN(HeVAL(orig));
- }
- }
-
- CvGV(code_entity) = gv;
- CvANON_off(code_entity);
- }
- }
}
MODULE = Mouse PACKAGE = Mouse::Meta::Class
for(i = 0; i < items; i++){
PUSHs(ST(i));
}
- //SP += items;
+
PUTBACK;
- call_method("BUILDARGS", G_SCALAR);
+ call_method_safes("BUILDARGS", G_SCALAR);
+
SPAGAIN;
args = POPs;
PUTBACK;
len = AvFILLp(demolishall) + 1;
if(len > 0){
- GV* const statusvalue = gv_fetchpvs("?", 0, SVt_PV);
+ SV* const in_global_destruction = boolSV(PL_dirty);
+ SAVEI32(PL_statusvalue); /* local $? */
+ PL_statusvalue = 0;
- if(statusvalue){ /* it can be NULL */
- SAVESPTR(GvSV(statusvalue)); /* local $? */
- GvSV(statusvalue) = sv_newmortal();
- }
SAVESPTR(ERRSV); /* local $@ */
- ERRSV = newSVpvs_flags("", SVs_TEMP);
+ ERRSV = sv_newmortal();
+
+ EXTEND(SP, 2);
for(i = 0; i < len; i++){
SPAGAIN;
PUSHMARK(SP);
- XPUSHs(object);
- XPUSHs(boolSV(PL_dirty));
+ PUSHs(object);
+ PUSHs(in_global_destruction);
PUTBACK;
call_sv(AvARRAY(demolishall)[i], G_VOID | G_EVAL);
SV* const meta = get_metaclass(self);
AV* const xc = mouse_get_xc(aTHX_ meta);
- if(!IsHashRef(args)){
- croak("You must pass a HASH reference to BUILDALL");
- }
+ must_ref(args, "a HASH reference to BUILDALL", SVt_PVHV);
mouse_buildall(aTHX_ xc, self, args);
}