# endif
#endif
-/* uvar magic and Hash::Util::FieldHash were commited with 28419 */
-#if VMG_HAS_PERL_MAINT(5, 9, 4, 28419) || VMG_HAS_PERL(5, 10, 0)
+/* uvar magic and Hash::Util::FieldHash were commited with 28419, but only
+ * enable it on 5.10 */
+#if VMG_HAS_PERL(5, 10, 0)
# define VMG_UVAR 1
#else
# define VMG_UVAR 0
STATIC int vmg_svt_free(pTHX_ SV *sv, MAGIC *mg) {
const MGWIZ *w;
+#if VMG_HAS_PERL(5, 9, 5)
+ PERL_CONTEXT saved_cx;
+ I32 cxix;
+#endif
unsigned int had_err, has_err, flags = G_SCALAR | G_EVAL;
int ret = 0;
if (had_err)
flags |= G_KEEPERR;
+#if VMG_HAS_PERL(5, 9, 5)
+ /* This context should not be used anymore, but since we croak in places the
+ * core doesn't even dare to, some pointers to it may remain in the upper call
+ * stack. Make sure call_sv() doesn't clobber it. */
+ if (cxstack_ix < cxstack_max)
+ cxix = cxstack_ix + 1;
+ else
+ cxix = Perl_cxinc(aTHX);
+ saved_cx = cxstack[cxix];
+#endif
+
call_sv(w->cb_free, flags);
+#if VMG_HAS_PERL(5, 9, 5)
+ cxstack[cxix] = saved_cx;
+#endif
+
has_err = SvTRUE(ERRSV);
if (IN_PERL_COMPILETIME && !had_err && has_err)
++PL_error_count;
FREETMPS;
LEAVE;
- if (has_err) {
- /* Get the eval context that was pushed by call_sv, and fake an entry for the
- * namesv, as die_where will need it to be non NULL later */
- PERL_CONTEXT *cx = cxstack + cxstack_ix + 1;
- if (!cx->blk_eval.old_namesv)
- cx->blk_eval.old_namesv
- = sv_2mortal(newSVpvn_share("Variable/Magic/DUMMY.pm", 23, 0));
- }
-
/* Calling SvREFCNT_dec() will trigger destructors in an infinite loop, so
* we have to rely on SvREFCNT() being a lvalue. Heck, even the core does it */
--SvREFCNT(sv);
if (hv_delete(MY_CXT.wizards, buf, sprintf(buf, "%u", w->sig), 0) != wiz)
return 0;
}
- SvFLAGS(wiz) |= SVf_BREAK;
- FREETMPS;
+
+ /* Unmortalize the wizard to avoid it being freed in weird places. */
+ if (SvTEMP(wiz) && !SvREFCNT(wiz)) {
+ const I32 myfloor = PL_tmps_floor;
+ I32 i;
+ for (i = PL_tmps_ix; i > myfloor; --i) {
+ if (PL_tmps_stack[i] == wiz)
+ PL_tmps_stack[i] = NULL;
+ }
+ }
if (w->cb_data) SvREFCNT_dec(SvRV(w->cb_data));
if (w->cb_get) SvREFCNT_dec(SvRV(w->cb_get));
SV *getsig(SV *wiz)
PROTOTYPE: $
+PREINIT:
+ U16 sig;
CODE:
- if (!SvROK(wiz))
- croak(vmg_invalid_wiz);
- RETVAL = newSVuv(SV2MGWIZ(SvRV(wiz))->sig);
+ sig = vmg_wizard_sig(wiz);
+ RETVAL = newSVuv(sig);
OUTPUT:
RETVAL