X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pp.h;h=64020020c8f33be7773c8d1c45f718b1645b4d69;hb=619ffc2be66f166b301c5b0d14a8bbba728675bc;hp=502ced016d2d98f6e0639834f87c1fadf63ed80d;hpb=85e6fe838fb25b257a1b363debf8691c0992ef71;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pp.h b/pp.h index 502ced0..6402002 100644 --- a/pp.h +++ b/pp.h @@ -1,169 +1,250 @@ -/*********************************************************** +/* pp.h * - * $Header: /usr/src/local/lwall/perl5/RCS/pp.h,v 4.1 92/08/07 18:26:20 lwall Exp Locker: lwall $ + * Copyright (c) 1991-1997, Larry Wall * - * Description: - * Push/Pop code defs. + * You may distribute under the terms of either the GNU General Public + * License or the Artistic License, as specified in the README file. * - * Standards: - * - * Created: - * Mon Jun 15 16:47:20 1992 - * - * Author: - * Larry Wall - * - * $Log: pp.h,v $ - * Revision 4.1 92/08/07 18:26:20 lwall - * - * - **********************************************************/ + */ +#ifdef USE_THREADS +#define ARGS thr +#define dARGS struct perl_thread *thr; +#else #define ARGS -#define ARGSproto void #define dARGS -#define PP(s) OP* s(ARGS) dARGS +#endif /* USE_THREADS */ + +#define PP(s) OP * s(ARGSproto) #define SP sp #define MARK mark #define TARG targ -#define POPMARK (*markstack_ptr--) -#define dSP register SV **sp = stack_sp -#define dMARK register SV **mark = stack_base + POPMARK -#define dORIGMARK I32 origmark = mark - stack_base -#define SETORIGMARK origmark = mark - stack_base -#define ORIGMARK stack_base + origmark +#define PUSHMARK(p) if (++PL_markstack_ptr == PL_markstack_max) \ + markstack_grow(); \ + *PL_markstack_ptr = (p) - PL_stack_base + +#define TOPMARK (*PL_markstack_ptr) +#define POPMARK (*PL_markstack_ptr--) -#define SPAGAIN sp = stack_sp -#define MSPAGAIN sp = stack_sp; mark = ORIGMARK +#define djSP register SV **sp = PL_stack_sp +#define dSP dTHR; djSP +#define dMARK register SV **mark = PL_stack_base + POPMARK +#define dORIGMARK I32 origmark = mark - PL_stack_base +#define SETORIGMARK origmark = mark - PL_stack_base +#define ORIGMARK (PL_stack_base + origmark) -#define GETTARGETSTACKED targ = (op->op_flags & OPf_STACKED ? POPs : PAD_SV(op->op_targ)) +#define SPAGAIN sp = PL_stack_sp +#define MSPAGAIN sp = PL_stack_sp; mark = ORIGMARK + +#define GETTARGETSTACKED targ = (PL_op->op_flags & OPf_STACKED ? POPs : PAD_SV(PL_op->op_targ)) #define dTARGETSTACKED SV * GETTARGETSTACKED -#define GETTARGET targ = PAD_SV(op->op_targ) +#define GETTARGET targ = PAD_SV(PL_op->op_targ) #define dTARGET SV * GETTARGET -#define GETATARGET targ = (op->op_flags & OPf_STACKED ? sp[-1] : PAD_SV(op->op_targ)) +#define GETATARGET targ = (PL_op->op_flags & OPf_STACKED ? sp[-1] : PAD_SV(PL_op->op_targ)) #define dATARGET SV * GETATARGET #define dTARG SV *targ -#define GETavn(a,g,st) \ - a = sv_2av(cGVOP->op_gv ? (SV*)cGVOP->op_gv : POPs, &st, &g, 1) -#define GEThvn(h,g,st) \ - h = sv_2hv(cGVOP->op_gv ? (SV*)cGVOP->op_gv : POPs, &st, &g, 1) -#define GETav(a,g,st) \ - a = sv_2av(cGVOP->op_gv ? (SV*)cGVOP->op_gv : POPs, &st, &g, 0) -#define GEThv(h,g,st) \ - h = sv_2hv(cGVOP->op_gv ? (SV*)cGVOP->op_gv : POPs, &st, &g, 0) -#define GETcv(r,g,st) \ - r = sv_2cv(POPs, &st, &g, 0) - -#define NORMAL op->op_next +#define NORMAL PL_op->op_next #define DIE return die -#define PROP if (dying) return die("%s", dying); -#define PUTBACK stack_sp = sp +#define PUTBACK PL_stack_sp = sp #define RETURN return PUTBACK, NORMAL #define RETURNOP(o) return PUTBACK, o #define RETURNX(x) return x, PUTBACK, NORMAL #define POPs (*sp--) -#define POPp (SvPVx(POPs, na)) +#define POPp (SvPVx(POPs, PL_na)) /* deprecated */ +#define POPpx (SvPVx(POPs, n_a)) #define POPn (SvNVx(POPs)) -#define POPi ((int)SvIVx(POPs)) +#define POPi ((IV)SvIVx(POPs)) +#define POPu ((UV)SvUVx(POPs)) #define POPl ((long)SvIVx(POPs)) #define TOPs (*sp) -#define TOPp (SvPV(TOPs, na)) +#define TOPp (SvPV(TOPs, PL_na)) /* deprecated */ +#define TOPpx (SvPV(TOPs, n_a)) #define TOPn (SvNV(TOPs)) -#define TOPi ((int)SvIV(TOPs)) +#define TOPi ((IV)SvIV(TOPs)) +#define TOPu ((UV)SvUV(TOPs)) #define TOPl ((long)SvIV(TOPs)) /* Go to some pains in the rare event that we must extend the stack. */ -#define EXTEND(p,n) do { if (stack_max - p < (n)) { \ - av_fill(stack, (p - stack_base) + (n) + 128); \ - sp = AvARRAY(stack) + (sp - stack_base); \ - stack_base = AvARRAY(stack); \ - stack_max = stack_base + AvMAX(stack) - 1; \ - } } while (0) +#define EXTEND(p,n) STMT_START { if (PL_stack_max - p < (n)) { \ + sp = stack_grow(sp,p, (int) (n)); \ + } } STMT_END + /* Same thing, but update mark register too. */ -#define MEXTEND(p,n) do {if (stack_max - p < (n)) { \ - av_fill(stack, (p - stack_base) + (n) + 128); \ - sp = AvARRAY(stack) + (sp - stack_base); \ - mark = AvARRAY(stack) + (mark - stack_base); \ - stack_base = AvARRAY(stack); \ - stack_max = stack_base + AvMAX(stack) - 1; \ - } } while (0) +#define MEXTEND(p,n) STMT_START {if (PL_stack_max - p < (n)) { \ + int markoff = mark - PL_stack_base; \ + sp = stack_grow(sp,p,(int) (n)); \ + mark = PL_stack_base + markoff; \ + } } STMT_END #define PUSHs(s) (*++sp = (s)) -#define PUSHTARG do { SvSETMAGIC(TARG); PUSHs(TARG); } while (0) -#define PUSHp(p,l) do { sv_setpvn(TARG, (p), (l)); PUSHTARG; } while (0) -#define PUSHn(n) do { sv_setnv(TARG, (n)); PUSHTARG; } while (0) -#define PUSHi(i) do { sv_setiv(TARG, (i)); PUSHTARG; } while (0) - -#define XPUSHs(s) do { EXTEND(sp,1); (*++sp = (s)); } while (0) -#define XPUSHTARG do { SvSETMAGIC(TARG); XPUSHs(TARG); } while (0) -#define XPUSHp(p,l) do { sv_setpvn(TARG, (p), (l)); XPUSHTARG; } while (0) -#define XPUSHn(n) do { sv_setnv(TARG, (n)); XPUSHTARG; } while (0) -#define XPUSHi(i) do { sv_setiv(TARG, (i)); XPUSHTARG; } while (0) - -#define MXPUSHs(s) do { MEXTEND(sp,1); (*++sp = (s)); } while (0) -#define MXPUSHTARG do { SvSETMAGIC(TARG); XPUSHs(TARG); } while (0) -#define MXPUSHp(p,l) do { sv_setpvn(TARG, (p), (l)); XPUSHTARG; } while (0) -#define MXPUSHn(n) do { sv_setnv(TARG, (n)); XPUSHTARG; } while (0) -#define MXPUSHi(i) do { sv_setiv(TARG, (i)); XPUSHTARG; } while (0) +#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, (double)(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 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, (double)(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 SETs(s) (*sp = s) -#define SETTARG do { SvSETMAGIC(TARG); SETs(TARG); } while (0) -#define SETp(p,l) do { sv_setpvn(TARG, (p), (l)); SETTARG; } while (0) -#define SETn(n) do { sv_setnv(TARG, (n)); SETTARG; } while (0) -#define SETi(i) do { sv_setiv(TARG, (i)); SETTARG; } while (0) +#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, (double)(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 dTOPss SV *sv = TOPs #define dPOPss SV *sv = POPs #define dTOPnv double value = TOPn #define dPOPnv double value = POPn -#define dTOPiv I32 value = TOPi -#define dPOPiv I32 value = POPi - -#define dPOPPOPssrl SV *rstr = POPs; SV *lstr = POPs -#define dPOPPOPnnrl double right = POPn; double left = POPn -#define dPOPPOPiirl I32 right = POPi; I32 left = POPi - -#define dPOPTOPssrl SV *rstr = POPs; SV *lstr = TOPs -#define dPOPTOPnnrl double right = POPn; double left = TOPn -#define dPOPTOPiirl I32 right = POPi; I32 left = TOPi - -#define RETPUSHYES RETURNX(PUSHs(&sv_yes)) -#define RETPUSHNO RETURNX(PUSHs(&sv_no)) -#define RETPUSHUNDEF RETURNX(PUSHs(&sv_undef)) - -#define RETSETYES RETURNX(SETs(&sv_yes)) -#define RETSETNO RETURNX(SETs(&sv_no)) -#define RETSETUNDEF RETURNX(SETs(&sv_undef)) - -#define ARGTARG op->op_targ -#define MAXARG op->op_private - -#define SWITCHSTACK(f,t) AvFILL(f) = sp - stack_base; \ - stack_base = AvARRAY(t); \ - stack_max = stack_base + AvMAX(t); \ - sp = stack_base + AvFILL(t); \ - stack = t; - -#define ENTER push_scope() -#define LEAVE pop_scope() - -#define SAVEINT(i) save_int((int*)(&i)); -#define SAVEI32(i) save_I32((I32*)(&i)); -#define SAVELONG(l) save_long((long*)(&l)); -#define SAVESPTR(s) save_sptr((SV**)(&s)) -#define SAVEPPTR(s) save_pptr((char**)(&s)) -#define SAVETMPS save_int(&tmps_floor), tmps_floor = tmps_ix -#define SAVEFREESV(s) save_freesv((SV*)(s)) -#define SAVEFREEOP(o) save_freeop((OP*)(o)) -#define SAVEFREEPV(p) save_freepv((char*)(p)) -#define SAVECLEARSV(sv) save_clearsv((SV**)(&sv)) -#define SAVEDELETE(h,k,l) save_delete((HV*)(h), (char*)(k), (I32)l) +#define dTOPiv IV value = TOPi +#define dPOPiv IV value = POPi +#define dTOPuv UV value = TOPu +#define dPOPuv UV value = POPu + +#define dPOPXssrl(X) SV *right = POPs; SV *left = CAT2(X,s) +#define dPOPXnnrl(X) double right = POPn; double left = CAT2(X,n) +#define dPOPXiirl(X) IV right = POPi; IV left = CAT2(X,i) + +#define USE_LEFT(sv) \ + (SvOK(sv) || SvGMAGICAL(sv) || !(PL_op->op_flags & OPf_STACKED)) +#define dPOPXnnrl_ul(X) \ + double right = POPn; \ + SV *leftsv = CAT2(X,s); \ + double left = USE_LEFT(leftsv) ? SvNV(leftsv) : 0.0 +#define dPOPXiirl_ul(X) \ + IV right = POPi; \ + SV *leftsv = CAT2(X,s); \ + IV left = USE_LEFT(leftsv) ? SvIV(leftsv) : 0 + +#define dPOPPOPssrl dPOPXssrl(POP) +#define dPOPPOPnnrl dPOPXnnrl(POP) +#define dPOPPOPnnrl_ul dPOPXnnrl_ul(POP) +#define dPOPPOPiirl dPOPXiirl(POP) +#define dPOPPOPiirl_ul dPOPXiirl_ul(POP) + +#define dPOPTOPssrl dPOPXssrl(TOP) +#define dPOPTOPnnrl dPOPXnnrl(TOP) +#define dPOPTOPnnrl_ul dPOPXnnrl_ul(TOP) +#define dPOPTOPiirl dPOPXiirl(TOP) +#define dPOPTOPiirl_ul dPOPXiirl_ul(TOP) + +#define RETPUSHYES RETURNX(PUSHs(&PL_sv_yes)) +#define RETPUSHNO RETURNX(PUSHs(&PL_sv_no)) +#define RETPUSHUNDEF RETURNX(PUSHs(&PL_sv_undef)) + +#define RETSETYES RETURNX(SETs(&PL_sv_yes)) +#define RETSETNO RETURNX(SETs(&PL_sv_no)) +#define RETSETUNDEF RETURNX(SETs(&PL_sv_undef)) + +#define ARGTARG PL_op->op_targ +#define MAXARG PL_op->op_private + +#define SWITCHSTACK(f,t) \ + STMT_START { \ + AvFILLp(f) = sp - PL_stack_base; \ + PL_stack_base = AvARRAY(t); \ + PL_stack_max = PL_stack_base + AvMAX(t); \ + sp = PL_stack_sp = PL_stack_base + AvFILLp(t); \ + PL_curstack = t; \ + } STMT_END + +#define EXTEND_MORTAL(n) \ + STMT_START { \ + if (PL_tmps_ix + (n) >= PL_tmps_max) \ + Renew(PL_tmps_stack, PL_tmps_max = PL_tmps_ix + (n) + 1, SV*); \ + } STMT_END + +#ifdef OVERLOAD + +#define AMGf_noright 1 +#define AMGf_noleft 2 +#define AMGf_assign 4 +#define AMGf_unary 8 + +#define tryAMAGICbinW(meth,assign,set) STMT_START { \ + if (PL_amagic_generation) { \ + SV* tmpsv; \ + SV* right= *(sp); SV* left= *(sp-1);\ + if ((SvAMAGIC(left)||SvAMAGIC(right))&&\ + (tmpsv=amagic_call(left, \ + right, \ + CAT2(meth,_amg), \ + (assign)? AMGf_assign: 0))) {\ + SPAGAIN; \ + (void)POPs; set(tmpsv); RETURN; } \ + } \ + } STMT_END + +#define tryAMAGICbin(meth,assign) tryAMAGICbinW(meth,assign,SETsv) +#define tryAMAGICbinSET(meth,assign) tryAMAGICbinW(meth,assign,SETs) + +#define AMG_CALLun(sv,meth) amagic_call(sv,&PL_sv_undef, \ + CAT2(meth,_amg),AMGf_noright | AMGf_unary) +#define AMG_CALLbinL(left,right,meth) \ + amagic_call(left,right,CAT2(meth,_amg),AMGf_noright) + +#define tryAMAGICunW(meth,set,shift,ret) STMT_START { \ + if (PL_amagic_generation) { \ + SV* tmpsv; \ + SV* arg= sp[shift]; \ + am_again: \ + if ((SvAMAGIC(arg))&&\ + (tmpsv=AMG_CALLun(arg,meth))) {\ + SPAGAIN; if (shift) sp += shift; \ + set(tmpsv); ret; } \ + } \ + } STMT_END + +#define FORCE_SETs(sv) STMT_START { sv_setsv(TARG, (sv)); SETTARG; } STMT_END + +#define tryAMAGICun tryAMAGICunSET +#define tryAMAGICunSET(meth) tryAMAGICunW(meth,SETs,0,RETURN) +#define tryAMAGICunTARGET(meth, shift) \ + { dSP; sp--; /* get TARGET from below PL_stack_sp */ \ + { dTARGETSTACKED; \ + { dSP; tryAMAGICunW(meth,FORCE_SETs,shift,RETURN);}}} + +#define setAGAIN(ref) sv = arg = ref; \ + if (!SvROK(ref)) \ + croak("Overloaded dereference did not return a reference"); \ + goto am_again; + +#define tryAMAGICunDEREF(meth) tryAMAGICunW(meth,setAGAIN,0,(void)0) + +#define opASSIGN (PL_op->op_flags & OPf_STACKED) +#define SETsv(sv) STMT_START { \ + if (opASSIGN) { sv_setsv(TARG, (sv)); SETTARG; } \ + else SETs(sv); } STMT_END + +/* newSVsv does not behave as advertised, so we copy missing + * information by hand */ + +/* SV* ref causes confusion with the member variable + changed SV* ref to SV* tmpRef */ +#define RvDEEPCP(rv) STMT_START { SV* tmpRef=SvRV(rv); \ + if (SvREFCNT(tmpRef)>1) { \ + SvREFCNT_dec(tmpRef); \ + SvRV(rv)=AMG_CALLun(rv,copy); \ + } } STMT_END +#else + +#define tryAMAGICbin(a,b) +#define tryAMAGICbinSET(a,b) +#define tryAMAGICun(a) +#define tryAMAGICunSET(a) + +#endif /* OVERLOAD */