From: Vincent Pit Date: Wed, 7 Dec 2016 00:55:57 +0000 (-0200) Subject: Only enable careful self destruction on perl 5.25.3 and higher X-Git-Tag: v0.61~3 X-Git-Url: http://git.vpit.fr/?p=perl%2Fmodules%2FVariable-Magic.git;a=commitdiff_plain;h=7ffa818799831666a3a166baa292421f7c03809b Only enable careful self destruction on perl 5.25.3 and higher --- diff --git a/Magic.xs b/Magic.xs index ba59f54..001f608 100644 --- a/Magic.xs +++ b/Magic.xs @@ -187,6 +187,8 @@ static OP *vmg_trampoline_bump(pTHX_ vmg_trampoline *t, SV *sv, OP *o) { # define OP_CLASS(O) (PL_opargs[(O)->op_type] & OA_CLASS_MASK) #endif +#define VMG_CAREFUL_SELF_DESTRUCTION XSH_HAS_PERL(5, 25, 3) + /* ... Bug-free mg_magical ................................................. */ /* See the discussion at http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2008-01/msg00036.html */ @@ -1420,7 +1422,9 @@ static MGVTBL vmg_propagate_errsv_vtbl = { typedef struct { SV *sv; +#if VMG_CAREFUL_SELF_DESTRUCTION SV *rsv; /* The ref to the sv currently being freed, pushed on the stack */ +#endif int in_eval; I32 base; } vmg_svt_free_cleanup_ud; @@ -1465,6 +1469,7 @@ static int vmg_svt_free_cleanup(pTHX_ void *ud_) { SV *sv = ud->sv; MAGIC *mg; +#if VMG_CAREFUL_SELF_DESTRUCTION /* Silently undo the ref - don't trigger destruction in the referent * for a second time */ if (SvROK(ud->rsv) && SvRV(ud->rsv) == sv) { @@ -1473,6 +1478,7 @@ static int vmg_svt_free_cleanup(pTHX_ void *ud_) { SvROK_off(ud->rsv); } SvREFCNT_dec_NN(ud->rsv); +#endif /* We are about to croak() while sv is being destroyed. Try to clean up * things a bit. */ @@ -1532,8 +1538,12 @@ static int vmg_svt_free(pTHX_ SV *sv, MAGIC *mg) { PUSHMARK(SP); EXTEND(SP, 2); /* This will bump the refcount of sv from 0 to 1 */ +#if VMG_CAREFUL_SELF_DESTRUCTION ud.rsv = newRV_inc(sv); PUSHs(ud.rsv); +#else + PUSHs(sv_2mortal(newRV_inc(sv))); +#endif PUSHs(mg->mg_obj ? mg->mg_obj : &PL_sv_undef); if (w->opinfo) XPUSHs(vmg_op_info(w->opinfo)); @@ -1560,6 +1570,7 @@ static int vmg_svt_free(pTHX_ SV *sv, MAGIC *mg) { POPSTACK; +#if VMG_CAREFUL_SELF_DESTRUCTION /* Silently undo the ref - don't trigger destruction in the referent * for a second time */ if (SvROK(ud.rsv) && SvRV(ud.rsv) == sv) { @@ -1568,6 +1579,7 @@ static int vmg_svt_free(pTHX_ SV *sv, MAGIC *mg) { --SvREFCNT(sv); /* silent */ } SvREFCNT_dec_NN(ud.rsv); +#endif FREETMPS; LEAVE;