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