static void
-mouse_class_initialize_object(pTHX_ SV* const meta, SV* const object, HV* const args, bool const ignore_triggers) {
+mouse_class_initialize_object(pTHX_ SV* const meta, SV* const object, HV* const args, bool const is_cloning) {
AV* const xc = mouse_get_xc(aTHX_ meta);
AV* const attrs = MOUSE_xc_attrall(xc);
- I32 len = AvFILLp(attrs) + 1;
+ I32 const len = AvFILLp(attrs) + 1;
I32 i;
AV* triggers_queue = NULL;
I32 used = 0;
croak("You cannot use tied HASH reference as initializing arguments");
}
- if(!ignore_triggers){
- triggers_queue = newAV_mortal();
- }
-
/* for each attribute */
for(i = 0; i < len; i++){
SV* const attr = MOUSE_av_at(attrs, i);
if(SvROK(value) && flags & MOUSEf_ATTR_IS_WEAK_REF){
weaken_slot(object, slot);
}
- if(flags & MOUSEf_ATTR_HAS_TRIGGER && triggers_queue){
+ if(flags & MOUSEf_ATTR_HAS_TRIGGER){
AV* const pair = newAV();
av_push(pair, newSVsv( mcall0s(attr, "trigger") ));
av_push(pair, newSVsv(value));
+ if(!triggers_queue) {
+ triggers_queue = newAV_mortal();
+ }
av_push(triggers_queue, (SV*)pair);
}
used++;
}
- else { /* no init arg */
+ else if(!is_cloning){ /* no init arg, noop while cloning */
if(flags & (MOUSEf_ATTR_HAS_DEFAULT | MOUSEf_ATTR_HAS_BUILDER)){
if(!(flags & MOUSEf_ATTR_IS_LAZY)){
mouse_xa_set_default(aTHX_ xa, object);
}
if(triggers_queue){
- len = AvFILLp(triggers_queue) + 1;
+ I32 const len = AvFILLp(triggers_queue) + 1;
for(i = 0; i < len; i++){
AV* const pair = (AV*)AvARRAY(triggers_queue)[i];
SV* const trigger = AvARRAY(pair)[0];
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);
mouse_install_sub(aTHX_ gv, code_ref);
+ //CvMETHOD_on((CV*)SvRV(code_ref));
(void)set_slot(methods, name, code); /* $self->{methods}{$name} = $code */
}
RETVAL
void
-_initialize_object(SV* meta, SV* object, HV* args, bool ignore_triggers = FALSE)
+_initialize_object(SV* meta, SV* object, HV* args, bool is_cloning = FALSE)
CODE:
{
- mouse_class_initialize_object(aTHX_ meta, object, args, ignore_triggers);
+ mouse_class_initialize_object(aTHX_ meta, object, args, is_cloning);
}
MODULE = Mouse PACKAGE = Mouse::Meta::Role
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);
}