This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
perldelta: This file is for 5.26, not 5.24
[perl5.git] / pp.h
diff --git a/pp.h b/pp.h
index 5712b8e..3b8f36f 100644 (file)
--- a/pp.h
+++ b/pp.h
@@ -55,47 +55,28 @@ Refetch the stack pointer.  Used after a callback.  See L<perlcall>.
 #define MARK mark
 #define TARG targ
 
-#if defined(DEBUGGING) && defined(PERL_USE_GCC_BRACE_GROUPS)
-#define PUSHMARK(p)                                                   \
+#define PUSHMARK(p) \
     STMT_START {                                                      \
         I32 * mark_stack_entry;                                       \
-        if (UNLIKELY((mark_stack_entry = ++PL_markstack_ptr) == PL_markstack_max)) \
+        if (UNLIKELY((mark_stack_entry = ++PL_markstack_ptr)          \
+                                           == PL_markstack_max))      \
            mark_stack_entry = markstack_grow();                      \
         *mark_stack_entry  = (I32)((p) - PL_stack_base);              \
-        DEBUG_s(PerlIO_printf(Perl_debug_log, "MARK push %p %d\n",    \
-                PL_markstack_ptr, *mark_stack_entry));                \
+        DEBUG_s(DEBUG_v(PerlIO_printf(Perl_debug_log,                 \
+                "MARK push %p %" IVdf "\n",                           \
+                PL_markstack_ptr, (IV)*mark_stack_entry)));           \
     } STMT_END
-#define TOPMARK                                                       \
-    ({                                                                \
-        DEBUG_s(PerlIO_printf(Perl_debug_log, "MARK top  %p %d\n",    \
-                PL_markstack_ptr, *PL_markstack_ptr));                \
-        *PL_markstack_ptr;                                            \
-    })
-#define POPMARK                                                       \
-    ({                                                                \
-        DEBUG_s(PerlIO_printf(Perl_debug_log, "MARK pop  %p %d\n",    \
-                (PL_markstack_ptr-1), *(PL_markstack_ptr-1)));        \
-        assert((PL_markstack_ptr > PL_markstack) || !"MARK underflow");\
-        *PL_markstack_ptr--;                                          \
-    })
-#define INCMARK                                                       \
-    ({                                                                \
-        DEBUG_s(PerlIO_printf(Perl_debug_log, "MARK inc  %p %d\n",    \
-                (PL_markstack_ptr+1), *(PL_markstack_ptr+1)));        \
-        *PL_markstack_ptr++;                                          \
-    })
-#else
-#define PUSHMARK(p)                                                   \
-    STMT_START {                                                     \
-        I32 * mark_stack_entry;                                       \
-        if (UNLIKELY((mark_stack_entry = ++PL_markstack_ptr) == PL_markstack_max)) \
-           mark_stack_entry = markstack_grow();                      \
-        *mark_stack_entry  = (I32)((p) - PL_stack_base);              \
+
+#define TOPMARK S_TOPMARK(aTHX)
+#define POPMARK S_POPMARK(aTHX)
+
+#define INCMARK \
+    STMT_START {                                                      \
+        DEBUG_s(DEBUG_v(PerlIO_printf(Perl_debug_log,                 \
+                "MARK inc  %p %" IVdf "\n",                           \
+                (PL_markstack_ptr+1), (IV)*(PL_markstack_ptr+1))));   \
+        PL_markstack_ptr++;                                           \
     } STMT_END
-#define TOPMARK                (*PL_markstack_ptr)
-#define POPMARK                (*PL_markstack_ptr--)
-#define INCMARK                (*PL_markstack_ptr++)
-#endif
 
 #define dSP            SV **sp = PL_stack_sp
 #define djSP           dSP
@@ -371,19 +352,85 @@ Does not use C<TARG>.  See also C<L</XPUSHu>>, C<L</mPUSHu>> and C<L</PUSHu>>.
                          } } 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
+
 #define PUSHs(s)       (*++sp = (s))
 #define PUSHTARG       STMT_START { SvSETMAGIC(TARG); PUSHs(TARG); } STMT_END
 #define PUSHp(p,l)     STMT_START { sv_setpvn(TARG, (p), (l)); PUSHTARG; } STMT_END
-#define PUSHn(n)       STMT_START { sv_setnv(TARG, (NV)(n)); PUSHTARG; } STMT_END
-#define PUSHi(i)       STMT_START { sv_setiv(TARG, (IV)(i)); PUSHTARG; } STMT_END
-#define PUSHu(u)       STMT_START { sv_setuv(TARG, (UV)(u)); PUSHTARG; } STMT_END
+#define PUSHn(n)       STMT_START { TARGn(n,1); PUSHs(TARG); } STMT_END
+#define PUSHi(i)       STMT_START { TARGi(i,1); PUSHs(TARG); } STMT_END
+#define PUSHu(u)       STMT_START { TARGu(u,1); PUSHs(TARG); } STMT_END
 
 #define XPUSHs(s)      STMT_START { EXTEND(sp,1); *++sp = (s); } STMT_END
 #define XPUSHTARG      STMT_START { SvSETMAGIC(TARG); XPUSHs(TARG); } STMT_END
 #define XPUSHp(p,l)    STMT_START { sv_setpvn(TARG, (p), (l)); XPUSHTARG; } STMT_END
-#define XPUSHn(n)      STMT_START { sv_setnv(TARG, (NV)(n)); XPUSHTARG; } STMT_END
-#define XPUSHi(i)      STMT_START { sv_setiv(TARG, (IV)(i)); XPUSHTARG; } STMT_END
-#define XPUSHu(u)      STMT_START { sv_setuv(TARG, (UV)(u)); XPUSHTARG; } STMT_END
+#define XPUSHn(n)      STMT_START { TARGn(n,1); XPUSHs(TARG); } STMT_END
+#define XPUSHi(i)      STMT_START { TARGi(i,1); XPUSHs(TARG); } STMT_END
+#define XPUSHu(u)      STMT_START { TARGu(u,1); XPUSHs(TARG); } STMT_END
 #define XPUSHundef     STMT_START { SvOK_off(TARG); XPUSHs(TARG); } STMT_END
 
 #define mPUSHs(s)      PUSHs(sv_2mortal(s))
@@ -403,9 +450,9 @@ Does not use C<TARG>.  See also C<L</XPUSHu>>, C<L</mPUSHu>> and C<L</PUSHu>>.
 #define SETs(s)                (*sp = s)
 #define SETTARG                STMT_START { SvSETMAGIC(TARG); SETs(TARG); } STMT_END
 #define SETp(p,l)      STMT_START { sv_setpvn(TARG, (p), (l)); SETTARG; } STMT_END
-#define SETn(n)                STMT_START { sv_setnv(TARG, (NV)(n)); SETTARG; } STMT_END
-#define SETi(i)                STMT_START { sv_setiv(TARG, (IV)(i)); SETTARG; } STMT_END
-#define SETu(u)                STMT_START { sv_setuv(TARG, (UV)(u)); SETTARG; } STMT_END
+#define SETn(n)                STMT_START { TARGn(n,1); SETs(TARG); } STMT_END
+#define SETi(i)                STMT_START { TARGi(i,1); SETs(TARG); } STMT_END
+#define SETu(u)                STMT_START { TARGu(u,1); SETs(TARG); } STMT_END
 
 #define dTOPss         SV *sv = TOPs
 #define dPOPss         SV *sv = POPs
@@ -504,7 +551,7 @@ Does not use C<TARG>.  See also C<L</XPUSHu>>, C<L</mPUSHu>> and C<L</PUSHu>>.
        dSP;                                                    \
        SV *tmpsv;                                              \
        SV *arg= *sp;                                           \
-        int gimme = GIMME_V;                                    \
+        U8 gimme = GIMME_V;                                    \
        if (UNLIKELY(SvAMAGIC(arg) &&                           \
            (tmpsv = amagic_call(arg, &PL_sv_undef, meth,       \
                                 AMGf_want_list | AMGf_noright  \
@@ -537,7 +584,7 @@ Does not use C<TARG>.  See also C<L</XPUSHu>>, C<L</mPUSHu>> and C<L</PUSHu>>.
                while (jump_o->op_type == OP_NULL)              \
                    jump_o = jump_o->op_next;                   \
                assert(jump_o->op_type == OP_ENTERSUB);         \
-               POPMARK;                                        \
+               (void)POPMARK;                                        \
                return jump_o->op_next;                         \
            }                                                   \
            return NORMAL;                                      \