source: trunk/third/perl/pp.h @ 10724

Revision 10724, 7.0 KB checked in by ghudson, 27 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r10723, which included commits to RCS files with non-trunk default branches.
Line 
1/*    pp.h
2 *
3 *    Copyright (c) 1991-1997, Larry Wall
4 *
5 *    You may distribute under the terms of either the GNU General Public
6 *    License or the Artistic License, as specified in the README file.
7 *
8 */
9
10#define ARGS
11#define ARGSproto void
12#define dARGS
13#define PP(s) OP* s(ARGS) dARGS
14
15#define SP sp
16#define MARK mark
17#define TARG targ
18
19#define PUSHMARK(p) if (++markstack_ptr == markstack_max)       \
20                        markstack_grow();                       \
21                    *markstack_ptr = (p) - stack_base
22
23#define TOPMARK         (*markstack_ptr)
24#define POPMARK         (*markstack_ptr--)
25
26#define dSP             register SV **sp = stack_sp
27#define dMARK           register SV **mark = stack_base + POPMARK
28#define dORIGMARK       I32 origmark = mark - stack_base
29#define SETORIGMARK     origmark = mark - stack_base
30#define ORIGMARK        (stack_base + origmark)
31
32#define SPAGAIN         sp = stack_sp
33#define MSPAGAIN        sp = stack_sp; mark = ORIGMARK
34
35#define GETTARGETSTACKED targ = (op->op_flags & OPf_STACKED ? POPs : PAD_SV(op->op_targ))
36#define dTARGETSTACKED SV * GETTARGETSTACKED
37
38#define GETTARGET targ = PAD_SV(op->op_targ)
39#define dTARGET SV * GETTARGET
40
41#define GETATARGET targ = (op->op_flags & OPf_STACKED ? sp[-1] : PAD_SV(op->op_targ))
42#define dATARGET SV * GETATARGET
43
44#define dTARG SV *targ
45
46#define NORMAL op->op_next
47#define DIE return die
48
49#define PUTBACK         stack_sp = sp
50#define RETURN          return PUTBACK, NORMAL
51#define RETURNOP(o)     return PUTBACK, o
52#define RETURNX(x)      return x, PUTBACK, NORMAL
53
54#define POPs            (*sp--)
55#define POPp            (SvPVx(POPs, na))
56#define POPn            (SvNVx(POPs))
57#define POPi            ((IV)SvIVx(POPs))
58#define POPu            ((UV)SvUVx(POPs))
59#define POPl            ((long)SvIVx(POPs))
60
61#define TOPs            (*sp)
62#define TOPp            (SvPV(TOPs, na))
63#define TOPn            (SvNV(TOPs))
64#define TOPi            ((IV)SvIV(TOPs))
65#define TOPu            ((UV)SvUV(TOPs))
66#define TOPl            ((long)SvIV(TOPs))
67
68/* Go to some pains in the rare event that we must extend the stack. */
69#define EXTEND(p,n)     STMT_START { if (stack_max - p < (n)) {         \
70                            sp = stack_grow(sp,p, (int) (n));           \
71                        } } STMT_END
72
73/* Same thing, but update mark register too. */
74#define MEXTEND(p,n)    STMT_START {if (stack_max - p < (n)) {          \
75                            int markoff = mark - stack_base;            \
76                            sp = stack_grow(sp,p,(int) (n));            \
77                            mark = stack_base + markoff;                \
78                        } } STMT_END
79
80#define PUSHs(s)        (*++sp = (s))
81#define PUSHTARG        STMT_START { SvSETMAGIC(TARG); PUSHs(TARG); } STMT_END
82#define PUSHp(p,l)      STMT_START { sv_setpvn(TARG, (p), (l)); PUSHTARG; } STMT_END
83#define PUSHn(n)        STMT_START { sv_setnv(TARG, (double)(n)); PUSHTARG; } STMT_END
84#define PUSHi(i)        STMT_START { sv_setiv(TARG, (IV)(i)); PUSHTARG; } STMT_END
85#define PUSHu(u)        STMT_START { sv_setuv(TARG, (UV)(u)); PUSHTARG; } STMT_END
86
87#define XPUSHs(s)       STMT_START { EXTEND(sp,1); (*++sp = (s)); } STMT_END
88#define XPUSHTARG       STMT_START { SvSETMAGIC(TARG); XPUSHs(TARG); } STMT_END
89#define XPUSHp(p,l)     STMT_START { sv_setpvn(TARG, (p), (l)); XPUSHTARG; } STMT_END
90#define XPUSHn(n)       STMT_START { sv_setnv(TARG, (double)(n)); XPUSHTARG; } STMT_END
91#define XPUSHi(i)       STMT_START { sv_setiv(TARG, (IV)(i)); XPUSHTARG; } STMT_END
92#define XPUSHu(u)       STMT_START { sv_setuv(TARG, (UV)(u)); XPUSHTARG; } STMT_END
93
94#define SETs(s)         (*sp = s)
95#define SETTARG         STMT_START { SvSETMAGIC(TARG); SETs(TARG); } STMT_END
96#define SETp(p,l)       STMT_START { sv_setpvn(TARG, (p), (l)); SETTARG; } STMT_END
97#define SETn(n)         STMT_START { sv_setnv(TARG, (double)(n)); SETTARG; } STMT_END
98#define SETi(i)         STMT_START { sv_setiv(TARG, (IV)(i)); SETTARG; } STMT_END
99#define SETu(u)         STMT_START { sv_setuv(TARG, (UV)(u)); SETTARG; } STMT_END
100
101#define dTOPss          SV *sv = TOPs
102#define dPOPss          SV *sv = POPs
103#define dTOPnv          double value = TOPn
104#define dPOPnv          double value = POPn
105#define dTOPiv          IV value = TOPi
106#define dPOPiv          IV value = POPi
107#define dTOPuv          UV value = TOPu
108#define dPOPuv          UV value = POPu
109
110#define dPOPXssrl(X)    SV *right = POPs; SV *left = CAT2(X,s)
111#define dPOPXnnrl(X)    double right = POPn; double left = CAT2(X,n)
112#define dPOPXiirl(X)    IV right = POPi; IV left = CAT2(X,i)
113
114#define USE_LEFT(sv) \
115        (SvOK(sv) || SvGMAGICAL(sv) || !(op->op_flags & OPf_STACKED))
116#define dPOPXnnrl_ul(X) \
117    double right = POPn;                                \
118    SV *leftsv = CAT2(X,s);                             \
119    double left = USE_LEFT(leftsv) ? SvNV(leftsv) : 0.0
120#define dPOPXiirl_ul(X) \
121    IV right = POPi;                                    \
122    SV *leftsv = CAT2(X,s);                             \
123    IV left = USE_LEFT(leftsv) ? SvIV(leftsv) : 0
124
125#define dPOPPOPssrl     dPOPXssrl(POP)
126#define dPOPPOPnnrl     dPOPXnnrl(POP)
127#define dPOPPOPnnrl_ul  dPOPXnnrl_ul(POP)
128#define dPOPPOPiirl     dPOPXiirl(POP)
129#define dPOPPOPiirl_ul  dPOPXiirl_ul(POP)
130
131#define dPOPTOPssrl     dPOPXssrl(TOP)
132#define dPOPTOPnnrl     dPOPXnnrl(TOP)
133#define dPOPTOPnnrl_ul  dPOPXnnrl_ul(TOP)
134#define dPOPTOPiirl     dPOPXiirl(TOP)
135#define dPOPTOPiirl_ul  dPOPXiirl_ul(TOP)
136
137#define RETPUSHYES      RETURNX(PUSHs(&sv_yes))
138#define RETPUSHNO       RETURNX(PUSHs(&sv_no))
139#define RETPUSHUNDEF    RETURNX(PUSHs(&sv_undef))
140
141#define RETSETYES       RETURNX(SETs(&sv_yes))
142#define RETSETNO        RETURNX(SETs(&sv_no))
143#define RETSETUNDEF     RETURNX(SETs(&sv_undef))
144
145#define ARGTARG         op->op_targ
146#define MAXARG          op->op_private
147
148#define SWITCHSTACK(f,t)        AvFILL(f) = sp - stack_base;            \
149                                stack_base = AvARRAY(t);                \
150                                stack_max = stack_base + AvMAX(t);      \
151                                sp = stack_sp = stack_base + AvFILL(t); \
152                                curstack = t;
153
154#define EXTEND_MORTAL(n) \
155        STMT_START { \
156            if (tmps_ix + (n) >= tmps_max) \
157                Renew(tmps_stack, tmps_max = tmps_ix + (n) + 1, SV*); \
158        } STMT_END
159
160#ifdef OVERLOAD
161
162#define AMGf_noright    1
163#define AMGf_noleft     2
164#define AMGf_assign     4
165#define AMGf_unary      8
166
167#define tryAMAGICbinW(meth,assign,set) STMT_START { \
168          if (amagic_generation) { \
169            SV* tmpsv; \
170            SV* right= *(sp); SV* left= *(sp-1);\
171            if ((SvAMAGIC(left)||SvAMAGIC(right))&&\
172                (tmpsv=amagic_call(left, \
173                                   right, \
174                                   CAT2(meth,_amg), \
175                                   (assign)? AMGf_assign: 0))) {\
176               SPAGAIN; \
177               (void)POPs; set(tmpsv); RETURN; } \
178          } \
179        } STMT_END
180
181#define tryAMAGICbin(meth,assign) tryAMAGICbinW(meth,assign,SETsv)
182#define tryAMAGICbinSET(meth,assign) tryAMAGICbinW(meth,assign,SETs)
183
184#define AMG_CALLun(sv,meth) amagic_call(sv,&sv_undef,  \
185                                        CAT2(meth,_amg),AMGf_noright | AMGf_unary)
186#define AMG_CALLbinL(left,right,meth) \
187            amagic_call(left,right,CAT2(meth,_amg),AMGf_noright)
188
189#define tryAMAGICunW(meth,set) STMT_START { \
190          if (amagic_generation) { \
191            SV* tmpsv; \
192            SV* arg= *(sp); \
193            if ((SvAMAGIC(arg))&&\
194                (tmpsv=AMG_CALLun(arg,meth))) {\
195               SPAGAIN; \
196               set(tmpsv); RETURN; } \
197          } \
198        } STMT_END
199
200#define tryAMAGICun     tryAMAGICunSET
201#define tryAMAGICunSET(meth) tryAMAGICunW(meth,SETs)
202
203#define opASSIGN (op->op_flags & OPf_STACKED)
204#define SETsv(sv)       STMT_START {                                    \
205                if (opASSIGN) { sv_setsv(TARG, (sv)); SETTARG; }        \
206                else SETs(sv); } STMT_END
207
208/* newSVsv does not behave as advertised, so we copy missing
209 * information by hand */
210
211
212#define RvDEEPCP(rv) STMT_START { SV* ref=SvRV(rv);      \
213  if (SvREFCNT(ref)>1) {                 \
214    SvREFCNT_dec(ref);                   \
215    SvRV(rv)=AMG_CALLun(rv,copy);        \
216  } } STMT_END
217#else
218
219#define tryAMAGICbin(a,b)
220#define tryAMAGICbinSET(a,b)
221#define tryAMAGICun(a)
222#define tryAMAGICunSET(a)
223
224#endif /* OVERLOAD */
Note: See TracBrowser for help on using the repository browser.