#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);
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;
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;
}
/* ... 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;
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");
}
}
} 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;
}
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)) {