+/* If the next filetest is stacked up with this one
+ (PL_op->op_private & OPpFT_STACKING), we leave
+ the original argument on the stack for success,
+ and skip the stacked operators on failure.
+ The next few macros/functions take care of this.
+*/
+
+static OP *
+S_ft_stacking_return_false(pTHX_ SV *ret) {
+ dSP;
+ OP *next = NORMAL;
+ while (OP_IS_FILETEST(next->op_type)
+ && next->op_private & OPpFT_STACKED)
+ next = next->op_next;
+ if (PL_op->op_flags & OPf_REF) XPUSHs(ret);
+ else SETs(ret);
+ PUTBACK;
+ return next;
+}
+
+#define FT_RETURN_FALSE(X) \
+ STMT_START { \
+ if (PL_op->op_private & OPpFT_STACKING) \
+ return S_ft_stacking_return_false(aTHX_ X); \
+ RETURNX(PL_op->op_flags & OPf_REF ? XPUSHs(X) : SETs(X)); \
+ } STMT_END
+#define FT_RETURN_TRUE(X) \
+ RETURNX((void)( \
+ PL_op->op_flags & OPf_REF \
+ ? (bool)XPUSHs( \
+ PL_op->op_private & OPpFT_STACKING ? (SV *)cGVOP_gv : (X) \
+ ) \
+ : (PL_op->op_private & OPpFT_STACKING || SETs(X)) \
+ ))
+
+#define FT_RETURNNO FT_RETURN_FALSE(&PL_sv_no)
+#define FT_RETURNUNDEF FT_RETURN_FALSE(&PL_sv_undef)
+#define FT_RETURNYES FT_RETURN_TRUE(&PL_sv_yes)
+