]> git.vpit.fr Git - perl/modules/autovivification.git/blobdiff - autovivification.xs
Classify aliasing constructs in the "store" category
[perl/modules/autovivification.git] / autovivification.xs
index 4b05d289cf6513713f45ad97567fe8fea1a6c185..91ba46a8cddfd1f8c439ba63158c517970d995b5 100644 (file)
@@ -176,11 +176,7 @@ STATIC const a_op_info *a_map_fetch(const OP *o, a_op_info *oi) {
 #endif
 
  val = ptable_fetch(a_op_map, o);
- if (val) {
-  *oi = *val;
-  val = oi;
- } else
-  oi->old_pp = 0;
+ *oi = *val;
 
 #ifdef USE_ITHREADS
  MUTEX_UNLOCK(&a_op_map_mutex);
@@ -276,7 +272,9 @@ STATIC OP *a_pp_rv2av(pTHX) {
 
  a_map_fetch(PL_op, &oi);
 
- if (PL_op != oi.root && !SvOK(TOPs)) {
+ if (PL_op == oi.root) { /* This means "@$arrayref" */
+  PL_op->op_ppaddr = oi.old_pp;
+ } else if (!SvOK(TOPs)) {
   /* We always need to push an empty array to fool the pp_aelem() that comes
    * later. */
   SV *av;
@@ -298,13 +296,9 @@ STATIC OP *a_pp_rv2hv(pTHX) {
 
  a_map_fetch(PL_op, &oi);
 
- if (PL_op != oi.root && !SvOK(TOPs)) {
-  if (oi.root->op_flags & OPf_MOD) {
-   SV *hv;
-   POPs;
-   hv = sv_2mortal((SV *) newHV());
-   PUSHs(hv);
-  }
+ if (PL_op == oi.root) { /* This means "%$hashref" */
+  PL_op->op_ppaddr = oi.old_pp;
+ } else if (!SvOK(TOPs)) {
   RETURN;
  }
 
@@ -313,9 +307,6 @@ STATIC OP *a_pp_rv2hv(pTHX) {
 
 /* ... pp_deref (aelem,helem,rv2sv,padsv) .................................. */
 
-STATIC const char a_msg_forbidden[]  = "Reference vivification forbidden";
-STATIC const char a_msg_impossible[] = "Can't vivify reference";
-
 STATIC OP *a_pp_deref(pTHX) {
  a_op_info oi;
  UV flags;
@@ -338,11 +329,11 @@ deref:
    SPAGAIN;
    if (!SvOK(TOPs)) {
     if (flags & A_HINT_STRICT)
-     croak(a_msg_forbidden);
+     croak("Reference vivification forbidden");
     else if (flags & A_HINT_WARN)
-      warn(a_msg_forbidden);
+      warn("Reference was vivified");
     else /* A_HINT_STORE */
-     croak(a_msg_impossible);
+     croak("Can't vivify reference");
    }
   }
 
@@ -350,11 +341,11 @@ deref:
  } else if (flags && (PL_op->op_private & OPpDEREF || PL_op == oi.root)) {
   oi.flags = flags & A_HINT_NOTIFY;
 
-  if ((oi.root->op_flags & (OPf_MOD|OPf_REF)) != (OPf_MOD|OPf_REF)) {
-   if (flags & A_HINT_FETCH)
-    oi.flags |= (A_HINT_FETCH|A_HINT_DEREF);
-  } else if (flags & A_HINT_STORE)
+  if (oi.root->op_flags & OPf_MOD) {
+   if (flags & A_HINT_STORE)
     oi.flags |= (A_HINT_STORE|A_HINT_DEREF);
+  } else if (flags & A_HINT_FETCH)
+    oi.flags |= (A_HINT_FETCH|A_HINT_DEREF);
 
   if (PL_op == oi.root)
    oi.flags &= ~A_HINT_DEREF;
@@ -532,6 +523,9 @@ STATIC OP *a_ck_rv2xv(pTHX_ OP *o) {
  }
  o = CALL_FPTR(old_ck)(aTHX_ o);
 
+ if (cUNOPo->op_first->op_type == OP_GV)
+  return o;
+
  hint = a_hint();
  if (hint & A_HINT_DO) {
   if (!(hint & A_HINT_STRICT)) {