#define ARGS
#define dARGS
#endif /* USE_THREADS */
-#ifdef PERL_OBJECT
-#define PP(s) OP * CPerlObj::s(ARGSproto)
-#else
+
#define PP(s) OP * s(ARGSproto)
-#endif
#define SP sp
#define MARK mark
#define RETURNX(x) return x, PUTBACK, NORMAL
#define POPs (*sp--)
-#define POPp (SvPVx(POPs, PL_na))
+#define POPp (SvPVx(POPs, PL_na)) /* deprecated */
+#define POPpx (SvPVx(POPs, n_a))
#define POPn (SvNVx(POPs))
#define POPi ((IV)SvIVx(POPs))
#define POPu ((UV)SvUVx(POPs))
#define POPl ((long)SvIVx(POPs))
#define TOPs (*sp)
-#define TOPp (SvPV(TOPs, PL_na))
+#define TOPp (SvPV(TOPs, PL_na)) /* deprecated */
+#define TOPpx (SvPV(TOPs, n_a))
#define TOPn (SvNV(TOPs))
#define TOPi ((IV)SvIV(TOPs))
#define TOPu ((UV)SvUV(TOPs))
#define AMG_CALLbinL(left,right,meth) \
amagic_call(left,right,CAT2(meth,_amg),AMGf_noright)
-#define tryAMAGICunW(meth,set) STMT_START { \
+#define tryAMAGICunW(meth,set,shift,ret) STMT_START { \
if (PL_amagic_generation) { \
SV* tmpsv; \
- SV* arg= *(sp); \
+ SV* arg= sp[shift]; \
+ am_again: \
if ((SvAMAGIC(arg))&&\
(tmpsv=AMG_CALLun(arg,meth))) {\
- SPAGAIN; \
- set(tmpsv); RETURN; } \
+ SPAGAIN; if (shift) sp += shift; \
+ set(tmpsv); ret; } \
} \
} STMT_END
+#define FORCE_SETs(sv) STMT_START { sv_setsv(TARG, (sv)); SETTARG; } STMT_END
+
#define tryAMAGICun tryAMAGICunSET
-#define tryAMAGICunSET(meth) tryAMAGICunW(meth,SETs)
+#define tryAMAGICunSET(meth) tryAMAGICunW(meth,SETs,0,RETURN)
+#define tryAMAGICunTARGET(meth, shift) \
+ { dSP; sp--; /* get TARGET from below PL_stack_sp */ \
+ { dTARGETSTACKED; \
+ { dSP; tryAMAGICunW(meth,FORCE_SETs,shift,RETURN);}}}
+
+#define setAGAIN(ref) sv = arg = ref; \
+ if (!SvROK(ref)) \
+ croak("Overloaded dereference did not return a reference"); \
+ goto am_again;
+
+#define tryAMAGICunDEREF(meth) tryAMAGICunW(meth,setAGAIN,0,(void)0)
#define opASSIGN (PL_op->op_flags & OPf_STACKED)
#define SETsv(sv) STMT_START { \