From: Vincent Pit Date: Thu, 2 Aug 2012 21:52:18 +0000 (+0200) Subject: Make the uvar user data into a proper struct X-Git-Tag: v0.51~14 X-Git-Url: http://git.vpit.fr/?p=perl%2Fmodules%2FVariable-Magic.git;a=commitdiff_plain;h=4b913bc8188ef7f2fc57062123c8b537db8c0796 Make the uvar user data into a proper struct --- diff --git a/Magic.xs b/Magic.xs index ccb4685..d3d17bf 100644 --- a/Magic.xs +++ b/Magic.xs @@ -778,6 +778,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 +842,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 +859,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 +947,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 +1326,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 +1334,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;