/* ... pp_multideref ....................................................... */
static UV a_do_multideref(const OP *o, UV flags) {
- UV isexdel;
+ UV isexdel, other_flags;
assert(o->op_type == OP_MULTIDEREF);
- isexdel = o->op_private & (OPpMULTIDEREF_EXISTS|OPpMULTIDEREF_DELETE);
+ other_flags = flags & ~A_HINT_DO;
+ isexdel = o->op_private & (OPpMULTIDEREF_EXISTS|OPpMULTIDEREF_DELETE);
if (isexdel) {
if (isexdel & OPpMULTIDEREF_EXISTS) {
- if (flags & A_HINT_EXISTS)
- return A_HINT_EXISTS;
+ flags &= A_HINT_EXISTS;
} else {
- if (flags & A_HINT_DELETE)
- return A_HINT_DELETE;
+ flags &= A_HINT_DELETE;
}
} else {
if (o->op_flags & OPf_MOD) {
- if (flags & A_HINT_STORE)
- return A_HINT_STORE;
+ flags &= A_HINT_STORE;
} else {
- if (flags & A_HINT_FETCH)
- return A_HINT_FETCH;
+ flags &= A_HINT_FETCH;
}
}
- return 0;
+ return flags ? (flags | other_flags) : 0;
}
static SV *a_do_fake_pp(pTHX_ OP *op) {
UNOP_AUX_item *items;
UV actions;
UV flags = 0;
- UV deref = 0;
SV *sv = NULL;
dSP;
dA_MAP_THX;
const a_op_info *oi = a_map_fetch(PL_op);
assert(oi);
- flags = oi->flags;
- deref = a_do_multideref(PL_op, flags);
- if (!deref)
+ flags = a_do_multideref(PL_op, oi->flags);
+ if (!flags)
return oi->old_pp(aTHX);
}
}
PL_multideref_pc = items;
if (actions & MDEREF_FLAG_last) {
- switch (deref) {
+ switch (flags & A_HINT_DO) {
case A_HINT_FETCH:
sv = a_do_pp_afetch(sv, esv);
break;
}
PL_multideref_pc = items;
if (actions & MDEREF_FLAG_last) {
- switch (deref) {
+ switch (flags & A_HINT_DO) {
case A_HINT_FETCH:
sv = a_do_pp_hfetch(sv, key);
break;
}
ret_undef:
- if ((flags & A_HINT_NOTIFY) || (deref == A_HINT_STORE))
+ if (flags & (A_HINT_NOTIFY|A_HINT_STORE))
a_cannot_vivify(flags);
- if (deref == A_HINT_EXISTS)
+ if (flags & A_HINT_EXISTS)
sv = &PL_sv_no;
else
sv = &PL_sv_undef;