}
}
+static I32
+S_dopoptosub(pTHX_ I32 const startingblock)
+{
+ const PERL_CONTEXT* const cxstk = cxstack;
+ I32 i;
+ for (i = startingblock; i >= 0; i--) {
+ const PERL_CONTEXT* const cx = &cxstk[i];
+
+ switch (CxTYPE(cx)) {
+ case CXt_EVAL:
+ case CXt_SUB:
+ case CXt_FORMAT:
+ return i;
+ }
+ }
+ return i;
+}
+
+/* workaround RT #69939 */
+I32
+mouse_call_sv_safe(pTHX_ SV* const sv, I32 const flags) {
+ const PERL_CONTEXT* const cx = &cxstack[S_dopoptosub(aTHX_ cxstack_ix)];
+ assert( (flags & G_EVAL) == 0 );
+
+ //warn("cx_type=0x%02x PL_eval=0x%02x (%"SVf")", (unsigned)cx->cx_type, (unsigned)PL_in_eval, sv);
+ if(!(cx->cx_type & CXp_TRYBLOCK)) {
+ I32 count;
+ //SAVESPTR(ERRSV);
+ //ERRSV = sv_newmortal();
+
+ count = Perl_call_sv(aTHX_ sv, flags | G_EVAL);
+
+ if(sv_true(ERRSV)){
+ croak(NULL); /* rethrow */
+ }
+ return count;
+ }
+ else {
+ return Perl_call_sv(aTHX_ sv, flags);
+ }
+}
+
void
mouse_must_defined(pTHX_ SV* const value, const char* const name) {
assert(value);
GV* const gv = (GV*)HeVAL(he);
if(isGV(gv)){
- if(GvCVu(gv)){
+ if(GvCVu(gv)){ /* is GV and has CV */
+ hv_iterinit(stash); /* reset */
return TRUE;
}
}
- else if(SvOK(gv)){
+ else if(SvOK(gv)){ /* is a stub or constant */
+ hv_iterinit(stash); /* reset */
return TRUE;
}
}
XPUSHs(self);
PUTBACK;
- call_sv(method, G_SCALAR | G_METHOD);
+ call_sv_safe(method, G_SCALAR | G_METHOD);
SPAGAIN;
ret = POPs;
PUSHs(arg1);
PUTBACK;
- call_sv(method, G_SCALAR | G_METHOD);
+ call_sv_safe(method, G_SCALAR | G_METHOD);
SPAGAIN;
ret = POPs;
}
{
dMY_CXT;
- if(MY_CXT.metas) croak("Cannot set metaclass storage more than once");
+ if(MY_CXT.metas && ckWARN(WARN_REDEFINE)){
+ Perl_warner(aTHX_ packWARN(WARN_REDEFINE), "Metaclass storage more than once");
+ }
MY_CXT.metas = metas;
SvREFCNT_inc_simple_void_NN(metas);
}