X-Git-Url: http://git.vpit.fr/?p=perl%2Fmodules%2FVariable-Magic.git;a=blobdiff_plain;f=Magic.xs;h=aa4af3518fc3c50dc6d35484ab3160cee3929a12;hp=ba59f548791c51eb6c6778eb28fcadfeec60cb19;hb=HEAD;hpb=92d785f98afb5bd5707e622ba9cc68818b8f0b33 diff --git a/Magic.xs b/Magic.xs index ba59f54..aa4af35 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,14 +1469,16 @@ 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) { - --SvREFCNT(sv); SvRV_set(ud->rsv, NULL); SvROK_off(ud->rsv); + --SvREFCNT(sv); /* Silent */ } 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,14 +1570,16 @@ 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) { SvRV_set(ud.rsv, NULL); SvROK_off(ud.rsv); - --SvREFCNT(sv); /* silent */ + --SvREFCNT(sv); /* Silent */ } SvREFCNT_dec_NN(ud.rsv); +#endif FREETMPS; LEAVE;