X-Git-Url: http://git.vpit.fr/?a=blobdiff_plain;f=Magic.xs;h=5dc98a6d3a9038579ade44e4eefa02856bf13bbb;hb=12570a1f39c0588d6ae68281b45ef1b7e6083958;hp=1e6a77c823a99a7ddcdf3e3ffeece4b86dd630f4;hpb=10f8553bdaa6203542526b85e154d27aa48dc832;p=perl%2Fmodules%2FVariable-Magic.git diff --git a/Magic.xs b/Magic.xs index 1e6a77c..5dc98a6 100644 --- a/Magic.xs +++ b/Magic.xs @@ -1257,9 +1257,9 @@ STATIC I32 vmg_svt_val(pTHX_ IV action, SV *sv) { if (uf[1].uf_set) uf[1].uf_set(aTHX_ action, sv); - action &= HV_FETCH_ISSTORE | HV_FETCH_ISEXISTS | HV_FETCH_LVALUE | HV_DELETE; for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) { const vmg_wizard *w; + switch (mg->mg_type) { case PERL_MAGIC_ext: break; @@ -1269,8 +1269,11 @@ STATIC I32 vmg_svt_val(pTHX_ IV action, SV *sv) { default: continue; } + w = vmg_wizard_from_mg(mg); - if (!w) continue; + if (!w) + continue; + switch (w->uvar) { case 0: continue; @@ -1278,7 +1281,9 @@ STATIC I32 vmg_svt_val(pTHX_ IV action, SV *sv) { if (!newkey) newkey = key = umg->mg_obj = sv_mortalcopy(umg->mg_obj); } - switch (action) { + + switch (action + & (HV_FETCH_ISSTORE|HV_FETCH_ISEXISTS|HV_FETCH_LVALUE|HV_DELETE)) { case 0: if (w->cb_fetch) vmg_cb_call2(w->cb_fetch, w->opinfo, sv, mg->mg_obj, key); @@ -1300,21 +1305,21 @@ STATIC I32 vmg_svt_val(pTHX_ IV action, SV *sv) { } } - if (SvRMAGICAL(sv) && !tied) { + if (SvRMAGICAL(sv) && !tied && !(action & (HV_FETCH_ISSTORE|HV_DELETE))) { /* Temporarily hide the RMAGICAL flag of the hash so it isn't wrongly * mistaken for a tied hash by the rest of hv_common. It will be reset by * the op_ppaddr of a new fake op injected between the current and the next * one. */ - OP *o = PL_op; - if (!o->op_next || o->op_next->op_ppaddr != vmg_pp_resetuvar) { + OP *nop = PL_op->op_next; + if (!nop || nop->op_ppaddr != vmg_pp_resetuvar) { SVOP *svop; NewOp(1101, svop, 1, SVOP); svop->op_type = OP_STUB; svop->op_ppaddr = vmg_pp_resetuvar; - svop->op_next = o->op_next; + svop->op_next = nop; svop->op_flags = 0; svop->op_sv = sv; - o->op_next = (OP *) svop; + PL_op->op_next = (OP *) svop; } SvRMAGICAL_off(sv); }