From: Steve Hay Date: Fri, 30 Apr 2004 10:07:21 +0000 (+0100) Subject: Document limitations in PUSHi et al macros and add new mPUSHi et al macros X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=d82b684cd82be03d9cc38309478c329f914280b5;p=p5sagit%2Fp5-mst-13.2.git Document limitations in PUSHi et al macros and add new mPUSHi et al macros Message-ID: <40921749.3050600@uk.radan.com> p4raw-id: //depot/perl@22756 --- diff --git a/pod/perlapi.pod b/pod/perlapi.pod index 91da7ae..cc7fed8 100644 --- a/pod/perlapi.pod +++ b/pod/perlapi.pod @@ -2203,6 +2203,94 @@ Stack marker variable for the XSUB. See C. =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. See also C, +C and C. + + 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. See also C, +C and C. + + 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 indicates the length of the string. Does not handle 'set' magic. +Does not use C. See also C, C and C. + + 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. See also +C, C and C. + + 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. See also C, C +and C. + + 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. See also C, C +and C. + + 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 +indicates the length of the string. Does not handle 'set' magic. Does not +use C. See also C, C and C. + + 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. See also C, +C and C. + + void mXPUSHu(UV uv) + +=for hackers +Found in file pp.h + =item ORIGMARK The original stack mark for the XSUB. See C. @@ -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. +Handles 'set' magic. Uses C, so C or C should be +called to declare it. Do not call multiple C-oriented macros to +return lists from XSUB's - see C instead. See also C and +C. void PUSHi(IV iv) @@ -2296,10 +2387,24 @@ L. =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. See also +C, C and C. + + 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. +Handles 'set' magic. Uses C, so C or C should be +called to declare it. Do not call multiple C-oriented macros to +return lists from XSUB's - see C instead. See also C and +C. 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 indicates the length of the string. Handles 'set' magic. See -C. +The C indicates the length of the string. Handles 'set' magic. Uses +C, so C or C should be called to declare it. Do not +call multiple C-oriented macros to return lists from XSUB's - see +C instead. See also C and C. 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. +Does not handle 'set' magic. Does not use C. See also C, +C and C. 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. +element. Handles 'set' magic. Uses C, so C or C +should be called to declare it. Do not call multiple C-oriented +macros to return lists from XSUB's - see C instead. See also +C and C. 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. +'set' magic. Uses C, so C or C should be called to +declare it. Do not call multiple C-oriented macros to return lists +from XSUB's - see C instead. See also C and C. 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. See also C, +C and C. + + 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. +'set' magic. Uses C, so C or C should be called to +declare it. Do not call multiple C-oriented macros to return lists +from XSUB's - see C instead. See also C and C. 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 -indicates the length of the string. Handles 'set' magic. See -C. +indicates the length of the string. Handles 'set' magic. Uses C, so +C or C should be called to declare it. Do not call +multiple C-oriented macros to return lists from XSUB's - see +C instead. See also C and C. 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. +handle 'set' magic. Does not use C. See also C, +C and C. 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. +Handles 'set' magic. Uses C, so C or C should be +called to declare it. Do not call multiple C-oriented macros to +return lists from XSUB's - see C instead. See also C and +C. void XPUSHu(UV uv) diff --git a/pod/perlguts.pod b/pod/perlguts.pod index 78a1dfc..9932b37 100644 --- a/pod/perlguts.pod +++ b/pod/perlguts.pod @@ -1381,11 +1381,12 @@ and C 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 macro. The pushed values will often need to be "mortal" (See -L). +L): 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, 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 to extend the stack. Despite their suggestions in earlier versions of this document the macros -C, C and C are I suited to XSUBs which return -multiple results, see L. +C<(X)PUSH[iunp]> are I suited to XSUBs which return multiple results. +For that, either stick to the C<(X)PUSHs> macros shown above, or use the new +C macros instead; see L. For more information, consult L and L. @@ -1536,7 +1538,7 @@ corresponding parts of its I and puts the I on stack. The macro to put this target on stack is C, 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 to 10, push a pointer to C onto the stack; set C to 20, push a pointer to C 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, which we have set -to 20. If you need to push multiple different values, use C, -which bypasses C. +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 macros, +none of which make use of C. The C<(X)PUSHs> macros simply push an +SV* on the stack, which, as noted under L, +will often need to be "mortal". The new C 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 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 in your variable declarations so that the C<*PUSH*> -macros can make use of the local variable C. +macros can make use of the local variable C. See also C +and C. =head2 Scratchpads diff --git a/pp.h b/pp.h index 3893c10..7178ae7 100644 --- 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. +Does not handle 'set' magic. Does not use C. See also C, +C and C. =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 indicates the length of the string. Handles 'set' magic. See -C. +The C indicates the length of the string. Handles 'set' magic. Uses +C, so C or C should be called to declare it. Do not +call multiple C-oriented macros to return lists from XSUB's - see +C instead. See also C and C. =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. +Handles 'set' magic. Uses C, so C or C should be +called to declare it. Do not call multiple C-oriented macros to +return lists from XSUB's - see C instead. See also C and +C. =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. +Handles 'set' magic. Uses C, so C or C should be +called to declare it. Do not call multiple C-oriented macros to +return lists from XSUB's - see C instead. See also C and +C. =for apidoc Am|void|PUSHu|UV uv Push an unsigned integer onto the stack. The stack must have room for this -element. See C. +element. Handles 'set' magic. Uses C, so C or C +should be called to declare it. Do not call multiple C-oriented +macros to return lists from XSUB's - see C instead. See also +C and C. =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. +handle 'set' magic. Does not use C. See also C, +C and C. =for apidoc Am|void|XPUSHp|char* str|STRLEN len Push a string onto the stack, extending the stack if necessary. The C -indicates the length of the string. Handles 'set' magic. See -C. +indicates the length of the string. Handles 'set' magic. Uses C, so +C or C should be called to declare it. Do not call +multiple C-oriented macros to return lists from XSUB's - see +C instead. See also C and C. =for apidoc Am|void|XPUSHn|NV nv Push a double onto the stack, extending the stack if necessary. Handles -'set' magic. See C. +'set' magic. Uses C, so C or C should be called to +declare it. Do not call multiple C-oriented macros to return lists +from XSUB's - see C instead. See also C and C. =for apidoc Am|void|XPUSHi|IV iv Push an integer onto the stack, extending the stack if necessary. Handles -'set' magic. See C. +'set' magic. Uses C, so C or C should be called to +declare it. Do not call multiple C-oriented macros to return lists +from XSUB's - see C instead. See also C and C. =for apidoc Am|void|XPUSHu|UV uv Push an unsigned integer onto the stack, extending the stack if necessary. -See C. +Handles 'set' magic. Uses C, so C or C should be +called to declare it. Do not call multiple C-oriented macros to +return lists from XSUB's - see C instead. See also C and +C. + +=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. See also +C, C and C. + +=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 indicates the length of the string. Does not handle 'set' magic. +Does not use C. See also C, C and C. + +=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. See also C, +C and C. + +=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. See also C, +C and C. + +=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. See also +C, C and C. + +=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. See also C, +C and C. + +=for apidoc Am|void|mXPUSHp|char* str|STRLEN len +Push a string onto the stack, extending the stack if necessary. The C +indicates the length of the string. Does not handle 'set' magic. Does not +use C. See also C, C and C. + +=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. See also C, C +and C. + +=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. See also C, C +and C. + +=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. See also C, +C and C. =cut */ @@ -231,6 +303,18 @@ See C. #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