X-Git-Url: http://git.vpit.fr/?a=blobdiff_plain;f=Magic.xs;h=1349a9cf183144402a08efbe1aef84d548a43efb;hb=c77fbf03cffe6f4a24764ba311a9ac1650c08237;hp=9a07ac57e46d6e0785c665d7ebe5e4bdbd83c047;hpb=a5ab162c9a0aa14e6caccd7104d719912115898f;p=perl%2Fmodules%2FVariable-Magic.git diff --git a/Magic.xs b/Magic.xs index 9a07ac5..1349a9c 100644 --- a/Magic.xs +++ b/Magic.xs @@ -276,6 +276,35 @@ STATIC OP *vmg_trampoline_bump(pTHX_ vmg_trampoline *t, SV *sv, OP *o) { #endif /* VMG_NEEDS_TRAMPOLINE */ +/* --- Cleaner version of sv_magicext() ------------------------------------ */ + +STATIC MAGIC *vmg_sv_magicext(pTHX_ SV *sv, SV *obj, const MGVTBL *vtbl, const void *ptr, I32 len) { +#define vmg_sv_magicext(S, O, V, P, L) vmg_sv_magicext(aTHX_ (S), (O), (V), (P), (L)) + MAGIC *mg; + + mg = sv_magicext(sv, obj, PERL_MAGIC_ext, vtbl, ptr, len); + if (!mg) + return NULL; + + mg->mg_private = 0; + + if (vtbl->svt_copy) + mg->mg_flags |= MGf_COPY; +#if MGf_DUP + if (vtbl->svt_dup) + mg->mg_flags |= MGf_DUP; +#endif /* MGf_DUP */ +#if MGf_LOCAL + if (vtbl->svt_local) + mg->mg_flags |= MGf_LOCAL; +#endif /* MGf_LOCAL */ + + if (mg->mg_flags & MGf_REFCOUNTED) + SvREFCNT_dec(obj); + + return mg; +} + /* --- Safe version of call_sv() ------------------------------------------- */ STATIC I32 vmg_call_sv(pTHX_ SV *sv, I32 flags, int (*cleanup)(pTHX_ void *), void *ud) { @@ -285,8 +314,8 @@ STATIC I32 vmg_call_sv(pTHX_ SV *sv, I32 flags, int (*cleanup)(pTHX_ void *), vo SV *old_err = NULL; if (SvTRUE(ERRSV)) { - old_err = ERRSV; - ERRSV = newSV(0); + old_err = newSVsv(ERRSV); + sv_setsv(ERRSV, &PL_sv_undef); } cxix = (cxstack_ix < cxstack_max) ? (cxstack_ix + 1) : Perl_cxinc(aTHX); @@ -299,11 +328,8 @@ STATIC I32 vmg_call_sv(pTHX_ SV *sv, I32 flags, int (*cleanup)(pTHX_ void *), vo cxstack[cxix] = saved_cx; if (SvTRUE(ERRSV)) { - if (old_err) { - sv_setsv(old_err, ERRSV); - SvREFCNT_dec(ERRSV); - ERRSV = old_err; - } + SvREFCNT_dec(old_err); + if (IN_PERL_COMPILETIME) { if (!PL_in_eval) { if (PL_errors) @@ -326,8 +352,8 @@ STATIC I32 vmg_call_sv(pTHX_ SV *sv, I32 flags, int (*cleanup)(pTHX_ void *), vo } } else { if (old_err) { - SvREFCNT_dec(ERRSV); - ERRSV = old_err; + sv_setsv(ERRSV, old_err); + SvREFCNT_dec(old_err); } } @@ -707,14 +733,8 @@ STATIC SV *vmg_wizard_sv_new(pTHX_ const vmg_wizard *w) { wiz = newSViv(PTR2IV(w)); #endif - if (w) { - MAGIC *mg = sv_magicext(wiz, NULL, PERL_MAGIC_ext, &vmg_wizard_sv_vtbl, - (const char *) w, 0); - mg->mg_private = 0; -#if VMG_THREADSAFE - mg->mg_flags |= MGf_DUP; -#endif - } + vmg_sv_magicext(wiz, NULL, &vmg_wizard_sv_vtbl, w, 0); + SvREADONLY_on(wiz); return wiz; @@ -903,22 +923,7 @@ STATIC UV vmg_cast(pTHX_ SV *sv, const vmg_wizard *w, const SV *wiz, SV **args, data = (w->cb_data) ? vmg_data_new(w->cb_data, sv, args, items) : NULL; t = vmg_vtable_vtbl(w->vtable); - mg = sv_magicext(sv, data, PERL_MAGIC_ext, t, (const char *) wiz, HEf_SVKEY); - mg->mg_private = 0; - - /* sv_magicext() calls mg_magical and increments data's refcount */ - SvREFCNT_dec(data); - - if (t->svt_copy) - mg->mg_flags |= MGf_COPY; -#if 0 - if (t->svt_dup) - mg->mg_flags |= MGf_DUP; -#endif -#if MGf_LOCAL - if (t->svt_local) - mg->mg_flags |= MGf_LOCAL; -#endif /* MGf_LOCAL */ + mg = vmg_sv_magicext(sv, data, t, wiz, HEf_SVKEY); if (SvTYPE(sv) < SVt_PVHV) goto done; @@ -1184,8 +1189,7 @@ STATIC SV *vmg_dispell_guard_new(pTHX_ MAGIC *root) { SV *guard; guard = sv_newmortal(); - sv_magicext(guard, NULL, PERL_MAGIC_ext, &vmg_dispell_guard_vtbl, - (char *) root, 0); + vmg_sv_magicext(guard, NULL, &vmg_dispell_guard_vtbl, root, 0); return guard; } @@ -1378,8 +1382,8 @@ STATIC OP *vmg_pp_propagate_errsv(pTHX) { SVOP *o = cSVOPx(PL_op); if (o->op_sv) { - SvREFCNT_dec(ERRSV); - ERRSV = o->op_sv; + sv_setsv(ERRSV, o->op_sv); + SvREFCNT_dec(o->op_sv); o->op_sv = NULL; } @@ -1389,11 +1393,8 @@ STATIC OP *vmg_pp_propagate_errsv(pTHX) { #endif /* VMG_PROPAGATE_ERRSV_NEEDS_TRAMPOLINE */ STATIC int vmg_propagate_errsv_free(pTHX_ SV *sv, MAGIC *mg) { - if (mg->mg_obj) { - ERRSV = mg->mg_obj; - mg->mg_obj = NULL; - mg->mg_flags &= ~MGf_REFCOUNTED; - } + if (mg->mg_obj) + sv_setsv(ERRSV, mg->mg_obj); return 0; } @@ -1438,20 +1439,16 @@ STATIC int vmg_svt_free_cleanup(pTHX_ void *ud_) { PL_op = vmg_trampoline_bump(&MY_CXT.propagate_errsv, errsv, PL_op); } else if (optype == OP_LEAVEEVAL) { SV *guard = sv_newmortal(); - sv_magicext(guard, errsv, PERL_MAGIC_ext, &vmg_propagate_errsv_vtbl, - NULL, 0); + vmg_sv_magicext(guard, errsv, &vmg_propagate_errsv_vtbl, NULL, 0); } #else /* !VMG_PROPAGATE_ERRSV_NEEDS_TRAMPOLINE */ # if !VMG_HAS_PERL(5, 8, 9) { SV *guard = sv_newmortal(); - sv_magicext(guard, errsv, PERL_MAGIC_ext, &vmg_propagate_errsv_vtbl, - NULL, 0); + vmg_sv_magicext(guard, errsv, &vmg_propagate_errsv_vtbl, NULL, 0); } # else - sv_magicext(ERRSV, errsv, PERL_MAGIC_ext, &vmg_propagate_errsv_vtbl, - NULL, 0); - SvREFCNT_dec(errsv); + vmg_sv_magicext(ERRSV, errsv, &vmg_propagate_errsv_vtbl, NULL, 0); # endif #endif /* VMG_PROPAGATE_ERRSV_NEEDS_TRAMPOLINE */