+# define MEXTEND(p,n) STMT_START { \
+ const SSize_t markoff = mark - PL_stack_base; \
+ sp = stack_grow(sp,p,_EXTEND_SAFE_N(n)); \
+ mark = PL_stack_base + markoff; \
+ PERL_UNUSED_VAR(sp); \
+ } STMT_END
+#else
+
+/* _EXTEND_NEEDS_GROW(p,n): private helper macro for EXTEND().
+ * Tests to see whether n is too big and we need to grow the stack. Be
+ * very careful if modifying this. There are many ways to get things wrong
+ * (wrapping, truncating etc) that could cause a false negative and cause
+ * the call to stack_grow() to be skipped. On the other hand, false
+ * positives are safe.
+ * Bear in mind that sizeof(p) may be less than, equal to, or greater
+ * than sizeof(n), and while n is documented to be signed, someone might
+ * pass an unsigned value or expression. In general don't use casts to
+ * avoid warnings; instead expect the caller to fix their code.
+ * It is legal for p to be greater than PL_stack_max.
+ * If the allocated stack is already very large but current usage is
+ * small, then PL_stack_max - p might wrap round to a negative value, but
+ * this just gives a safe false positive
+ */
+
+# define _EXTEND_NEEDS_GROW(p,n) ((n) < 0 || PL_stack_max - (p) < (n))
+
+
+/* EXTEND_SKIP(): used for where you would normally call EXTEND(), but
+ * you know for sure that a previous op will have already extended the
+ * stack sufficiently. For example pp_enteriter ensures that that there
+ * is always at least 1 free slot, so pp_iter can return &PL_sv_yes/no
+ * without checking each time. Calling EXTEND_SKIP() defeats the HWM
+ * debugging mechanism which would otherwise whine
+ */
+
+# define EXTEND_SKIP(p, n) STMT_START { \
+ EXTEND_HWM_SET(p, n); \
+ assert(!_EXTEND_NEEDS_GROW(p,n)); \
+ } STMT_END
+
+
+# define EXTEND(p,n) STMT_START { \
+ EXTEND_HWM_SET(p, n); \
+ if (UNLIKELY(_EXTEND_NEEDS_GROW(p,n))) { \
+ sp = stack_grow(sp,p,_EXTEND_SAFE_N(n)); \
+ PERL_UNUSED_VAR(sp); \
+ } } STMT_END
+/* Same thing, but update mark register too. */
+# define MEXTEND(p,n) STMT_START { \
+ EXTEND_HWM_SET(p, n); \
+ if (UNLIKELY(_EXTEND_NEEDS_GROW(p,n))) { \
+ const SSize_t markoff = mark - PL_stack_base;\
+ sp = stack_grow(sp,p,_EXTEND_SAFE_N(n)); \
+ mark = PL_stack_base + markoff; \
+ PERL_UNUSED_VAR(sp); \
+ } } STMT_END
+#endif
+
+
+/* set TARG to the IV value i. If do_taint is false,
+ * assume that PL_tainted can never be true */
+#define TARGi(i, do_taint) \
+ STMT_START { \
+ IV TARGi_iv = i; \
+ if (LIKELY( \
+ ((SvFLAGS(TARG) & (SVTYPEMASK|SVf_THINKFIRST|SVf_IVisUV)) == SVt_IV) \
+ & (do_taint ? !TAINT_get : 1))) \
+ { \
+ /* Cheap SvIOK_only(). \
+ * Assert that flags which SvIOK_only() would test or \
+ * clear can't be set, because we're SVt_IV */ \
+ assert(!(SvFLAGS(TARG) & \
+ (SVf_OOK|SVf_UTF8|(SVf_OK & ~(SVf_IOK|SVp_IOK))))); \
+ SvFLAGS(TARG) |= (SVf_IOK|SVp_IOK); \
+ /* SvIV_set() where sv_any points to head */ \
+ TARG->sv_u.svu_iv = TARGi_iv; \
+ } \
+ else \
+ sv_setiv_mg(targ, TARGi_iv); \
+ } STMT_END
+
+/* set TARG to the UV value u. If do_taint is false,
+ * assume that PL_tainted can never be true */
+#define TARGu(u, do_taint) \
+ STMT_START { \
+ UV TARGu_uv = u; \
+ if (LIKELY( \
+ ((SvFLAGS(TARG) & (SVTYPEMASK|SVf_THINKFIRST|SVf_IVisUV)) == SVt_IV) \
+ & (do_taint ? !TAINT_get : 1) \
+ & (TARGu_uv <= (UV)IV_MAX))) \
+ { \
+ /* Cheap SvIOK_only(). \
+ * Assert that flags which SvIOK_only() would test or \
+ * clear can't be set, because we're SVt_IV */ \
+ assert(!(SvFLAGS(TARG) & \
+ (SVf_OOK|SVf_UTF8|(SVf_OK & ~(SVf_IOK|SVp_IOK))))); \
+ SvFLAGS(TARG) |= (SVf_IOK|SVp_IOK); \
+ /* SvIV_set() where sv_any points to head */ \
+ TARG->sv_u.svu_iv = TARGu_uv; \
+ } \
+ else \
+ sv_setuv_mg(targ, TARGu_uv); \
+ } STMT_END
+
+/* set TARG to the NV value n. If do_taint is false,
+ * assume that PL_tainted can never be true */
+#define TARGn(n, do_taint) \
+ STMT_START { \
+ NV TARGn_nv = n; \
+ if (LIKELY( \
+ ((SvFLAGS(TARG) & (SVTYPEMASK|SVf_THINKFIRST)) == SVt_NV) \
+ & (do_taint ? !TAINT_get : 1))) \
+ { \
+ /* Cheap SvNOK_only(). \
+ * Assert that flags which SvNOK_only() would test or \
+ * clear can't be set, because we're SVt_NV */ \
+ assert(!(SvFLAGS(TARG) & \
+ (SVf_OOK|SVf_UTF8|(SVf_OK & ~(SVf_NOK|SVp_NOK))))); \
+ SvFLAGS(TARG) |= (SVf_NOK|SVp_NOK); \
+ SvNV_set(TARG, TARGn_nv); \
+ } \
+ else \
+ sv_setnv_mg(targ, TARGn_nv); \
+ } STMT_END