Document limitations in PUSHi et al macros and add new mPUSHi et al macros
Steve Hay [Fri, 30 Apr 2004 10:07:21 +0000 (11:07 +0100)]
Message-ID: <40921749.3050600@uk.radan.com>

p4raw-id: //depot/perl@22756

pod/perlapi.pod
pod/perlguts.pod
pp.h

index 91da7ae..cc7fed8 100644 (file)
@@ -2203,6 +2203,94 @@ Stack marker variable for the XSUB.  See C<dMARK>.
 =for hackers
 Found in file pp.h
 
+=item mPUSHi
+
+Push an integer onto the stack.  The stack must have room for this element.
+Does not handle 'set' magic.  Does not use C<TARG>.  See also C<PUSHi>,
+C<mXPUSHi> and C<XPUSHi>.
+
+       void    mPUSHi(IV iv)
+
+=for hackers
+Found in file pp.h
+
+=item mPUSHn
+
+Push a double onto the stack.  The stack must have room for this element.
+Does not handle 'set' magic.  Does not use C<TARG>.  See also C<PUSHn>,
+C<mXPUSHn> and C<XPUSHn>.
+
+       void    mPUSHn(NV nv)
+
+=for hackers
+Found in file pp.h
+
+=item mPUSHp
+
+Push a string onto the stack.  The stack must have room for this element.
+The C<len> indicates the length of the string.  Does not handle 'set' magic.
+Does not use C<TARG>.  See also C<PUSHp>, C<mXPUSHp> and C<XPUSHp>.
+
+       void    mPUSHp(char* str, STRLEN len)
+
+=for hackers
+Found in file pp.h
+
+=item mPUSHu
+
+Push an unsigned integer onto the stack.  The stack must have room for this
+element.  Does not handle 'set' magic.  Does not use C<TARG>.  See also
+C<PUSHu>, C<mXPUSHu> and C<XPUSHu>.
+
+       void    mPUSHu(UV uv)
+
+=for hackers
+Found in file pp.h
+
+=item mXPUSHi
+
+Push an integer onto the stack, extending the stack if necessary.  Does not
+handle 'set' magic.  Does not use C<TARG>.  See also C<XPUSHi>, C<mPUSHi>
+and C<PUSHi>.
+
+       void    mXPUSHi(IV iv)
+
+=for hackers
+Found in file pp.h
+
+=item mXPUSHn
+
+Push a double onto the stack, extending the stack if necessary.  Does not
+handle 'set' magic.  Does not use C<TARG>.  See also C<XPUSHn>, C<mPUSHn>
+and C<PUSHn>.
+
+       void    mXPUSHn(NV nv)
+
+=for hackers
+Found in file pp.h
+
+=item mXPUSHp
+
+Push a string onto the stack, extending the stack if necessary.  The C<len>
+indicates the length of the string.  Does not handle 'set' magic.  Does not
+use C<TARG>.  See also C<XPUSHp>, C<mPUSHp> and C<PUSHp>.
+
+       void    mXPUSHp(char* str, STRLEN len)
+
+=for hackers
+Found in file pp.h
+
+=item mXPUSHu
+
+Push an unsigned integer onto the stack, extending the stack if necessary.
+Does not handle 'set' magic.  Does not use C<TARG>.  See also C<XPUSHu>,
+C<mPUSHu> and C<PUSHu>.
+
+       void    mXPUSHu(UV uv)
+
+=for hackers
+Found in file pp.h
+
 =item ORIGMARK
 
 The original stack mark for the XSUB.  See C<dORIGMARK>.
@@ -2279,7 +2367,10 @@ Found in file pp.h
 =item PUSHi
 
 Push an integer onto the stack.  The stack must have room for this element.
-Handles 'set' magic.  See C<XPUSHi>.
+Handles 'set' magic.  Uses C<TARG>, so C<dTARGET> or C<dXSTARG> should be
+called to declare it.  Do not call multiple C<TARG>-oriented macros to 
+return lists from XSUB's - see C<mPUSHi> instead.  See also C<XPUSHi> and
+C<mXPUSHi>.
 
        void    PUSHi(IV iv)
 
@@ -2296,10 +2387,24 @@ L<perlcall>.
 =for hackers
 Found in file pp.h
 
+=item PUSHmortal
+
+Push a new mortal SV onto the stack.  The stack must have room for this
+element.  Does not handle 'set' magic.  Does not use C<TARG>.  See also
+C<PUSHs>, C<XPUSHmortal> and C<XPUSHs>.
+
+       void    PUSHmortal()
+
+=for hackers
+Found in file pp.h
+
 =item PUSHn
 
 Push a double onto the stack.  The stack must have room for this element.
-Handles 'set' magic.  See C<XPUSHn>.
+Handles 'set' magic.  Uses C<TARG>, so C<dTARGET> or C<dXSTARG> should be
+called to declare it.  Do not call multiple C<TARG>-oriented macros to
+return lists from XSUB's - see C<mPUSHn> instead.  See also C<XPUSHn> and
+C<mXPUSHn>.
 
        void    PUSHn(NV nv)
 
@@ -2309,8 +2414,10 @@ Found in file pp.h
 =item PUSHp
 
 Push a string onto the stack.  The stack must have room for this element.
-The C<len> indicates the length of the string.  Handles 'set' magic.  See
-C<XPUSHp>.
+The C<len> indicates the length of the string.  Handles 'set' magic.  Uses
+C<TARG>, so C<dTARGET> or C<dXSTARG> should be called to declare it.  Do not
+call multiple C<TARG>-oriented macros to return lists from XSUB's - see
+C<mPUSHp> instead.  See also C<XPUSHp> and C<mXPUSHp>.
 
        void    PUSHp(char* str, STRLEN len)
 
@@ -2320,7 +2427,8 @@ Found in file pp.h
 =item PUSHs
 
 Push an SV onto the stack.  The stack must have room for this element.
-Does not handle 'set' magic.  See C<XPUSHs>.
+Does not handle 'set' magic.  Does not use C<TARG>.  See also C<PUSHmortal>,
+C<XPUSHs> and C<XPUSHmortal>.
 
        void    PUSHs(SV* sv)
 
@@ -2330,7 +2438,10 @@ Found in file pp.h
 =item PUSHu
 
 Push an unsigned integer onto the stack.  The stack must have room for this
-element.  See C<XPUSHu>.
+element.  Handles 'set' magic.  Uses C<TARG>, so C<dTARGET> or C<dXSTARG>
+should be called to declare it.  Do not call multiple C<TARG>-oriented
+macros to return lists from XSUB's - see C<mPUSHu> instead.  See also
+C<XPUSHu> and C<mXPUSHu>.
 
        void    PUSHu(UV uv)
 
@@ -2367,17 +2478,32 @@ Found in file pp.h
 =item XPUSHi
 
 Push an integer onto the stack, extending the stack if necessary.  Handles
-'set' magic. See C<PUSHi>.
+'set' magic.  Uses C<TARG>, so C<dTARGET> or C<dXSTARG> should be called to
+declare it.  Do not call multiple C<TARG>-oriented macros to return lists
+from XSUB's - see C<mXPUSHi> instead.  See also C<PUSHi> and C<mPUSHi>.
 
        void    XPUSHi(IV iv)
 
 =for hackers
 Found in file pp.h
 
+=item XPUSHmortal
+
+Push a new mortal SV onto the stack, extending the stack if necessary.  Does
+not handle 'set' magic.  Does not use C<TARG>.  See also C<XPUSHs>,
+C<PUSHmortal> and C<PUSHs>.
+
+       void    XPUSHmortal()
+
+=for hackers
+Found in file pp.h
+
 =item XPUSHn
 
 Push a double onto the stack, extending the stack if necessary.  Handles
-'set' magic.  See C<PUSHn>.
+'set' magic.  Uses C<TARG>, so C<dTARGET> or C<dXSTARG> should be called to
+declare it.  Do not call multiple C<TARG>-oriented macros to return lists
+from XSUB's - see C<mXPUSHn> instead.  See also C<PUSHn> and C<mPUSHn>.
 
        void    XPUSHn(NV nv)
 
@@ -2387,8 +2513,10 @@ Found in file pp.h
 =item XPUSHp
 
 Push a string onto the stack, extending the stack if necessary.  The C<len>
-indicates the length of the string.  Handles 'set' magic.  See
-C<PUSHp>.
+indicates the length of the string.  Handles 'set' magic.  Uses C<TARG>, so
+C<dTARGET> or C<dXSTARG> should be called to declare it.  Do not call
+multiple C<TARG>-oriented macros to return lists from XSUB's - see
+C<mXPUSHp> instead.  See also C<PUSHp> and C<mPUSHp>.
 
        void    XPUSHp(char* str, STRLEN len)
 
@@ -2398,7 +2526,8 @@ Found in file pp.h
 =item XPUSHs
 
 Push an SV onto the stack, extending the stack if necessary.  Does not
-handle 'set' magic.  See C<PUSHs>.
+handle 'set' magic.  Does not use C<TARG>.  See also C<XPUSHmortal>,
+C<PUSHs> and C<PUSHmortal>.
 
        void    XPUSHs(SV* sv)
 
@@ -2408,7 +2537,10 @@ Found in file pp.h
 =item XPUSHu
 
 Push an unsigned integer onto the stack, extending the stack if necessary.
-See C<PUSHu>.
+Handles 'set' magic.  Uses C<TARG>, so C<dTARGET> or C<dXSTARG> should be
+called to declare it.  Do not call multiple C<TARG>-oriented macros to
+return lists from XSUB's - see C<mXPUSHu> instead.  See also C<PUSHu> and
+C<mPUSHu>.
 
        void    XPUSHu(UV uv)
 
index 78a1dfc..9932b37 100644 (file)
@@ -1381,11 +1381,12 @@ and C<num> is the number of elements the stack should be extended by.
 
 Now that there is room on the stack, values can be pushed on it using C<PUSHs>
 macro. The pushed values will often need to be "mortal" (See
-L</Reference Counts and Mortality>).
+L</Reference Counts and Mortality>):
 
     PUSHs(sv_2mortal(newSViv(an_integer)))
+    PUSHs(sv_2mortal(newSVuv(an_unsigned_integer)))
+    PUSHs(sv_2mortal(newSVnv(a_double)))
     PUSHs(sv_2mortal(newSVpv("Some String",0)))
-    PUSHs(sv_2mortal(newSVnv(3.141592)))
 
 And now the Perl program calling C<tzname>, the two values will be assigned
 as in:
@@ -1401,8 +1402,9 @@ This macro automatically adjust the stack for you, if needed.  Thus, you
 do not need to call C<EXTEND> to extend the stack.
 
 Despite their suggestions in earlier versions of this document the macros
-C<PUSHi>, C<PUSHn> and C<PUSHp> are I<not> suited to XSUBs which return
-multiple results, see L</Putting a C value on Perl stack>.
+C<(X)PUSH[iunp]> are I<not> suited to XSUBs which return multiple results.
+For that, either stick to the C<(X)PUSHs> macros shown above, or use the new
+C<m(X)PUSH[iunp]> macros instead; see L</Putting a C value on Perl stack>.
 
 For more information, consult L<perlxs> and L<perlxstut>.
 
@@ -1536,7 +1538,7 @@ corresponding parts of its I<target> and puts the I<target> on stack.
 
 The macro to put this target on stack is C<PUSHTARG>, and it is
 directly used in some opcodes, as well as indirectly in zillions of
-others, which use it via C<(X)PUSH[pni]>.
+others, which use it via C<(X)PUSH[iunp]>.
 
 Because the target is reused, you must be careful when pushing multiple
 values on the stack. The following code will not do what you think:
@@ -1548,12 +1550,30 @@ This translates as "set C<TARG> to 10, push a pointer to C<TARG> onto
 the stack; set C<TARG> to 20, push a pointer to C<TARG> onto the stack".
 At the end of the operation, the stack does not contain the values 10
 and 20, but actually contains two pointers to C<TARG>, which we have set
-to 20. If you need to push multiple different values, use C<XPUSHs>,
-which bypasses C<TARG>.
+to 20.
 
-On a related note, if you do use C<(X)PUSH[npi]>, then you're going to
+If you need to push multiple different values then you should either use
+the C<(X)PUSHs> macros, or else use the new C<m(X)PUSH[iunp]> macros,
+none of which make use of C<TARG>.  The C<(X)PUSHs> macros simply push an
+SV* on the stack, which, as noted under L</XSUBs and the Argument Stack>,
+will often need to be "mortal".  The new C<m(X)PUSH[iunp]> macros make
+this a little easier to achieve by creating a new mortal for you (via
+C<(X)PUSHmortal>), pushing that onto the stack (extending it if necessary
+in the case of the C<mXPUSH[iunp]> macros), and then setting its value.
+Thus, instead of writing this to "fix" the example above:
+
+    XPUSHs(sv_2mortal(newSViv(10)))
+    XPUSHs(sv_2mortal(newSViv(20)))
+
+you can simply write:
+
+    mXPUSHi(10)
+    mXPUSHi(20)
+
+On a related note, if you do use C<(X)PUSH[iunp]>, then you're going to
 need a C<dTARG> in your variable declarations so that the C<*PUSH*>
-macros can make use of the local variable C<TARG>.
+macros can make use of the local variable C<TARG>.  See also C<dTARGET>
+and C<dXSTARG>.
 
 =head2 Scratchpads
 
diff --git a/pp.h b/pp.h
index 3893c10..7178ae7 100644 (file)
--- a/pp.h
+++ b/pp.h
@@ -162,45 +162,117 @@ onto the stack.
 
 =for apidoc Am|void|PUSHs|SV* sv
 Push an SV onto the stack.  The stack must have room for this element.
-Does not handle 'set' magic.  See C<XPUSHs>.
+Does not handle 'set' magic.  Does not use C<TARG>.  See also C<PUSHmortal>,
+C<XPUSHs> and C<XPUSHmortal>.
 
 =for apidoc Am|void|PUSHp|char* str|STRLEN len
 Push a string onto the stack.  The stack must have room for this element.
-The C<len> indicates the length of the string.  Handles 'set' magic.  See
-C<XPUSHp>.
+The C<len> indicates the length of the string.  Handles 'set' magic.  Uses
+C<TARG>, so C<dTARGET> or C<dXSTARG> should be called to declare it.  Do not
+call multiple C<TARG>-oriented macros to return lists from XSUB's - see
+C<mPUSHp> instead.  See also C<XPUSHp> and C<mXPUSHp>.
 
 =for apidoc Am|void|PUSHn|NV nv
 Push a double onto the stack.  The stack must have room for this element.
-Handles 'set' magic.  See C<XPUSHn>.
+Handles 'set' magic.  Uses C<TARG>, so C<dTARGET> or C<dXSTARG> should be
+called to declare it.  Do not call multiple C<TARG>-oriented macros to
+return lists from XSUB's - see C<mPUSHn> instead.  See also C<XPUSHn> and
+C<mXPUSHn>.
 
 =for apidoc Am|void|PUSHi|IV iv
 Push an integer onto the stack.  The stack must have room for this element.
-Handles 'set' magic.  See C<XPUSHi>.
+Handles 'set' magic.  Uses C<TARG>, so C<dTARGET> or C<dXSTARG> should be
+called to declare it.  Do not call multiple C<TARG>-oriented macros to 
+return lists from XSUB's - see C<mPUSHi> instead.  See also C<XPUSHi> and
+C<mXPUSHi>.
 
 =for apidoc Am|void|PUSHu|UV uv
 Push an unsigned integer onto the stack.  The stack must have room for this
-element.  See C<XPUSHu>.
+element.  Handles 'set' magic.  Uses C<TARG>, so C<dTARGET> or C<dXSTARG>
+should be called to declare it.  Do not call multiple C<TARG>-oriented
+macros to return lists from XSUB's - see C<mPUSHu> instead.  See also
+C<XPUSHu> and C<mXPUSHu>.
 
 =for apidoc Am|void|XPUSHs|SV* sv
 Push an SV onto the stack, extending the stack if necessary.  Does not
-handle 'set' magic.  See C<PUSHs>.
+handle 'set' magic.  Does not use C<TARG>.  See also C<XPUSHmortal>,
+C<PUSHs> and C<PUSHmortal>.
 
 =for apidoc Am|void|XPUSHp|char* str|STRLEN len
 Push a string onto the stack, extending the stack if necessary.  The C<len>
-indicates the length of the string.  Handles 'set' magic.  See
-C<PUSHp>.
+indicates the length of the string.  Handles 'set' magic.  Uses C<TARG>, so
+C<dTARGET> or C<dXSTARG> should be called to declare it.  Do not call
+multiple C<TARG>-oriented macros to return lists from XSUB's - see
+C<mXPUSHp> instead.  See also C<PUSHp> and C<mPUSHp>.
 
 =for apidoc Am|void|XPUSHn|NV nv
 Push a double onto the stack, extending the stack if necessary.  Handles
-'set' magic.  See C<PUSHn>.
+'set' magic.  Uses C<TARG>, so C<dTARGET> or C<dXSTARG> should be called to
+declare it.  Do not call multiple C<TARG>-oriented macros to return lists
+from XSUB's - see C<mXPUSHn> instead.  See also C<PUSHn> and C<mPUSHn>.
 
 =for apidoc Am|void|XPUSHi|IV iv
 Push an integer onto the stack, extending the stack if necessary.  Handles
-'set' magic. See C<PUSHi>.
+'set' magic.  Uses C<TARG>, so C<dTARGET> or C<dXSTARG> should be called to
+declare it.  Do not call multiple C<TARG>-oriented macros to return lists
+from XSUB's - see C<mXPUSHi> instead.  See also C<PUSHi> and C<mPUSHi>.
 
 =for apidoc Am|void|XPUSHu|UV uv
 Push an unsigned integer onto the stack, extending the stack if necessary.
-See C<PUSHu>.
+Handles 'set' magic.  Uses C<TARG>, so C<dTARGET> or C<dXSTARG> should be
+called to declare it.  Do not call multiple C<TARG>-oriented macros to
+return lists from XSUB's - see C<mXPUSHu> instead.  See also C<PUSHu> and
+C<mPUSHu>.
+
+=for apidoc Am|void|PUSHmortal
+Push a new mortal SV onto the stack.  The stack must have room for this
+element.  Does not handle 'set' magic.  Does not use C<TARG>.  See also
+C<PUSHs>, C<XPUSHmortal> and C<XPUSHs>.
+
+=for apidoc Am|void|mPUSHp|char* str|STRLEN len
+Push a string onto the stack.  The stack must have room for this element.
+The C<len> indicates the length of the string.  Does not handle 'set' magic.
+Does not use C<TARG>.  See also C<PUSHp>, C<mXPUSHp> and C<XPUSHp>.
+
+=for apidoc Am|void|mPUSHn|NV nv
+Push a double onto the stack.  The stack must have room for this element.
+Does not handle 'set' magic.  Does not use C<TARG>.  See also C<PUSHn>,
+C<mXPUSHn> and C<XPUSHn>.
+
+=for apidoc Am|void|mPUSHi|IV iv
+Push an integer onto the stack.  The stack must have room for this element.
+Does not handle 'set' magic.  Does not use C<TARG>.  See also C<PUSHi>,
+C<mXPUSHi> and C<XPUSHi>.
+
+=for apidoc Am|void|mPUSHu|UV uv
+Push an unsigned integer onto the stack.  The stack must have room for this
+element.  Does not handle 'set' magic.  Does not use C<TARG>.  See also
+C<PUSHu>, C<mXPUSHu> and C<XPUSHu>.
+
+=for apidoc Am|void|XPUSHmortal
+Push a new mortal SV onto the stack, extending the stack if necessary.  Does
+not handle 'set' magic.  Does not use C<TARG>.  See also C<XPUSHs>,
+C<PUSHmortal> and C<PUSHs>.
+
+=for apidoc Am|void|mXPUSHp|char* str|STRLEN len
+Push a string onto the stack, extending the stack if necessary.  The C<len>
+indicates the length of the string.  Does not handle 'set' magic.  Does not
+use C<TARG>.  See also C<XPUSHp>, C<mPUSHp> and C<PUSHp>.
+
+=for apidoc Am|void|mXPUSHn|NV nv
+Push a double onto the stack, extending the stack if necessary.  Does not
+handle 'set' magic.  Does not use C<TARG>.  See also C<XPUSHn>, C<mPUSHn>
+and C<PUSHn>.
+
+=for apidoc Am|void|mXPUSHi|IV iv
+Push an integer onto the stack, extending the stack if necessary.  Does not
+handle 'set' magic.  Does not use C<TARG>.  See also C<XPUSHi>, C<mPUSHi>
+and C<PUSHi>.
+
+=for apidoc Am|void|mXPUSHu|UV uv
+Push an unsigned integer onto the stack, extending the stack if necessary.
+Does not handle 'set' magic.  Does not use C<TARG>.  See also C<XPUSHu>,
+C<mPUSHu> and C<PUSHu>.
 
 =cut
 */
@@ -231,6 +303,18 @@ See C<PUSHu>.
 #define XPUSHu(u)      STMT_START { sv_setuv(TARG, (UV)(u)); XPUSHTARG; } STMT_END
 #define XPUSHundef     STMT_START { SvOK_off(TARG); XPUSHs(TARG); } STMT_END
 
+#define PUSHmortal(s)  PUSHs(sv_newmortal())
+#define mPUSHp(p,l)    STMT_START { sv_setpvn(PUSHmortal, (p), (l)); } STMT_END
+#define mPUSHn(n)      STMT_START { sv_setnv(PUSHmortal, (NV)(n)); } STMT_END
+#define mPUSHi(i)      STMT_START { sv_setiv(PUSHmortal, (IV)(i)); } STMT_END
+#define mPUSHu(u)      STMT_START { sv_setuv(PUSHmortal, (UV)(u)); } STMT_END
+
+#define XPUSHmortal(s) STMT_START { EXTEND(sp,1); PUSHmortal; } STMT_END
+#define mXPUSHp(p,l)   STMT_START { sv_setpvn(XPUSHmortal, (p), (l)); } STMT_END
+#define mXPUSHn(n)     STMT_START { sv_setnv(XPUSHmortal, (NV)(n)); } STMT_END
+#define mXPUSHi(i)     STMT_START { sv_setiv(XPUSHmortal, (IV)(i)); } STMT_END
+#define mXPUSHu(u)     STMT_START { sv_setuv(XPUSHmortal, (UV)(u)); } STMT_END
+
 #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