]> git.vpit.fr Git - perl/modules/Variable-Magic.git/blobdiff - Magic.xs
'store' and 'delete' uvar magics don't need the uvar/clear hack
[perl/modules/Variable-Magic.git] / Magic.xs
index bf413ff0329b69ed1af14bced53f689fdd31d211..5dc98a6d3a9038579ade44e4eefa02856bf13bbb 100644 (file)
--- a/Magic.xs
+++ b/Magic.xs
@@ -1195,13 +1195,13 @@ STATIC int vmg_svt_free(pTHX_ SV *sv, MAGIC *mg) {
  return ret;
 }
 
-STATIC int vmg_svt_copy(pTHX_ SV *sv, MAGIC *mg, SV *nsv, const char *key,
-# if VMG_HAS_PERL_MAINT(5, 11, 0, 33256) || VMG_HAS_PERL(5, 12, 0)
-  I32 keylen
-# else
-  int keylen
-# endif
- ) {
+#if VMG_HAS_PERL_MAINT(5, 11, 0, 33256) || VMG_HAS_PERL(5, 12, 0)
+# define VMG_SVT_COPY_KEYLEN_TYPE I32
+#else
+# define VMG_SVT_COPY_KEYLEN_TYPE int
+#endif
+
+STATIC int vmg_svt_copy(pTHX_ SV *sv, MAGIC *mg, SV *nsv, const char *key, VMG_SVT_COPY_KEYLEN_TYPE keylen) {
  const vmg_wizard *w = vmg_wizard_from_mg_nocheck(mg);
  SV *keysv;
  int ret;
@@ -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);
  }