X-Git-Url: http://git.vpit.fr/?a=blobdiff_plain;f=Magic.xs;h=d87c651834fb44073924f65f940f042e31e50414;hb=4591803a480417f70ed1f166ea4433facfddefd4;hp=ccb4685953e2f119e6a1c32566c42d19762f3863;hpb=02e503ed53ca6660ac886020f3aaa12776cb60f5;p=perl%2Fmodules%2FVariable-Magic.git diff --git a/Magic.xs b/Magic.xs index ccb4685..d87c651 100644 --- a/Magic.xs +++ b/Magic.xs @@ -222,14 +222,10 @@ STATIC void vmg_mg_magical(SV *sv) { /* ... Safe version of call_sv() ........................................... */ -#define VMG_SAVE_LAST_CX (!VMG_HAS_PERL(5, 8, 4) || VMG_HAS_PERL(5, 9, 5)) - STATIC I32 vmg_call_sv(pTHX_ SV *sv, I32 flags, SV *dsv) { #define vmg_call_sv(S, F, D) vmg_call_sv(aTHX_ (S), (F), (D)) - I32 ret, cxix = 0, in_eval = 0; -#if VMG_SAVE_LAST_CX + I32 ret, cxix, in_eval = 0; PERL_CONTEXT saved_cx; -#endif SV *old_err = NULL; if (SvTRUE(ERRSV)) { @@ -238,22 +234,18 @@ STATIC I32 vmg_call_sv(pTHX_ SV *sv, I32 flags, SV *dsv) { } if (cxstack_ix < cxstack_max) { - cxix = cxstack_ix + 1; - if (dsv && CxTYPE(cxstack + cxix) == CXt_EVAL) - in_eval = 1; + cxix = cxstack_ix + 1; + in_eval = CxTYPE(cxstack + cxix) == CXt_EVAL; + } else { + cxix = Perl_cxinc(aTHX); } - -#if VMG_SAVE_LAST_CX /* The last popped context will be reused by call_sv(), but our callers may * still need its previous value. Back it up so that it isn't clobbered. */ saved_cx = cxstack[cxix]; -#endif ret = call_sv(sv, flags | G_EVAL); -#if VMG_SAVE_LAST_CX cxstack[cxix] = saved_cx; -#endif if (SvTRUE(ERRSV)) { if (old_err) { @@ -778,6 +770,11 @@ STATIC SV *vmg_data_get(pTHX_ SV *sv, const vmg_wizard *w) { #if VMG_UVAR STATIC I32 vmg_svt_val(pTHX_ IV, SV *); +typedef struct { + struct ufuncs new_uf; + struct ufuncs old_uf; +} vmg_uvar_ud; + STATIC void vmg_uvar_del(SV *sv, MAGIC *prevmagic, MAGIC *mg, MAGIC *moremagic) { if (prevmagic) { prevmagic->mg_moremagic = moremagic; @@ -837,14 +834,14 @@ STATIC UV vmg_cast(pTHX_ SV *sv, const vmg_wizard *w, const SV *wiz, SV **args, #if VMG_UVAR if (w->uvar) { MAGIC *prevmagic, *moremagic = NULL; - struct ufuncs uf[2]; + vmg_uvar_ud ud; - uf[0].uf_val = vmg_svt_val; - uf[0].uf_set = NULL; - uf[0].uf_index = 0; - uf[1].uf_val = NULL; - uf[1].uf_set = NULL; - uf[1].uf_index = 0; + ud.new_uf.uf_val = vmg_svt_val; + ud.new_uf.uf_set = NULL; + ud.new_uf.uf_index = 0; + ud.old_uf.uf_val = NULL; + ud.old_uf.uf_set = NULL; + ud.old_uf.uf_index = 0; /* One uvar magic in the chain is enough. */ for (prevmagic = NULL, mg = SvMAGIC(sv); mg; prevmagic = mg, mg = moremagic) { @@ -854,18 +851,18 @@ STATIC UV vmg_cast(pTHX_ SV *sv, const vmg_wizard *w, const SV *wiz, SV **args, } if (mg) { /* Found another uvar magic. */ - struct ufuncs *olduf = (struct ufuncs *) mg->mg_ptr; - if (olduf->uf_val == vmg_svt_val) { + struct ufuncs *uf = (struct ufuncs *) mg->mg_ptr; + if (uf->uf_val == vmg_svt_val) { /* It's our uvar magic, nothing to do. oldgmg was true. */ goto done; } else { /* It's another uvar magic, backup it and replace it by ours. */ - uf[1] = *olduf; + ud.old_uf = *uf; vmg_uvar_del(sv, prevmagic, mg, moremagic); } } - sv_magic(sv, NULL, PERL_MAGIC_uvar, (const char *) &uf, sizeof(uf)); + sv_magic(sv, NULL, PERL_MAGIC_uvar, (const char *) &ud, sizeof(ud)); vmg_mg_magical(sv); /* Our hash now carries uvar magic. The uvar/clear shortcoming has to be * handled by our uvar callback. */ @@ -942,19 +939,23 @@ STATIC UV vmg_dispell(pTHX_ SV *sv, const vmg_wizard *w) { } if (uvars == 1) { - struct ufuncs *uf; + vmg_uvar_ud *ud; + for (prevmagic = NULL, mg = SvMAGIC(sv); mg; prevmagic = mg, mg = moremagic){ moremagic = mg->mg_moremagic; if (mg->mg_type == PERL_MAGIC_uvar) break; } - uf = (struct ufuncs *) mg->mg_ptr; - if (uf[1].uf_val || uf[1].uf_set) { + + ud = (vmg_uvar_ud *) mg->mg_ptr; + if (ud->old_uf.uf_val || ud->old_uf.uf_set) { /* Revert the original uvar magic. */ - uf[0] = uf[1]; - Renew(uf, 1, struct ufuncs); + struct ufuncs *uf; + Newx(uf, 1, struct ufuncs); + *uf = ud->old_uf; + Safefree(ud); mg->mg_ptr = (char *) uf; - mg->mg_len = sizeof(struct ufuncs); + mg->mg_len = sizeof(*uf); } else { /* Remove the uvar magic. */ vmg_uvar_del(sv, prevmagic, mg, moremagic); @@ -1317,7 +1318,7 @@ STATIC OP *vmg_pp_resetuvar(pTHX) { } STATIC I32 vmg_svt_val(pTHX_ IV action, SV *sv) { - struct ufuncs *uf; + vmg_uvar_ud *ud; MAGIC *mg, *umg; SV *key = NULL, *newkey = NULL; int tied = 0; @@ -1325,12 +1326,12 @@ STATIC I32 vmg_svt_val(pTHX_ IV action, SV *sv) { umg = mg_find(sv, PERL_MAGIC_uvar); /* umg can't be NULL or we wouldn't be there. */ key = umg->mg_obj; - uf = (struct ufuncs *) umg->mg_ptr; + ud = (vmg_uvar_ud *) umg->mg_ptr; - if (uf[1].uf_val) - uf[1].uf_val(aTHX_ action, sv); - if (uf[1].uf_set) - uf[1].uf_set(aTHX_ action, sv); + if (ud->old_uf.uf_val) + ud->old_uf.uf_val(aTHX_ action, sv); + if (ud->old_uf.uf_set) + ud->old_uf.uf_set(aTHX_ action, sv); for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) { const vmg_wizard *w;