=for apidoc ms||djSP
-Declare Just C<SP>. This is actually identical to C<dSP>, and declares
+Declare Just C<SP>. This is actually identical to C<dSP>, and declares
a local copy of perl's stack pointer, available via the C<SP> macro.
See C<SP>. (Available for backward source code compatibility with the
old (Perl 5.005) thread model.)
#define PUSHMARK(p) \
STMT_START { \
- if (++PL_markstack_ptr == PL_markstack_max) \
- markstack_grow(); \
- *PL_markstack_ptr = (I32)((p) - PL_stack_base);\
+ I32 * mark_stack_entry; \
+ if (UNLIKELY((mark_stack_entry = ++PL_markstack_ptr) == PL_markstack_max)) \
+ mark_stack_entry = markstack_grow(); \
+ *mark_stack_entry = (I32)((p) - PL_stack_base); \
} STMT_END
#define TOPMARK (*PL_markstack_ptr)
#define dSP SV **sp = PL_stack_sp
#define djSP dSP
-#define dMARK register SV **mark = PL_stack_base + POPMARK
+#define dMARK SV **mark = PL_stack_base + POPMARK
#define dORIGMARK const I32 origmark = (I32)(mark - PL_stack_base)
#define ORIGMARK (PL_stack_base + origmark)
Pops an SV off the stack.
=for apidoc Amn|char*|POPp
-Pops a string off the stack. Deprecated. New code should use POPpx.
+Pops a string off the stack.
=for apidoc Amn|char*|POPpx
-Pops a string off the stack.
+Pops a string off the stack. Identical to POPp. There are two names for
+historical reasons.
=for apidoc Amn|char*|POPpbytex
Pops a string off the stack which must consist of bytes i.e. characters < 256.
#define RETURNX(x) return (x, PUTBACK, NORMAL)
#define POPs (*sp--)
-#define POPp (SvPVx(POPs, PL_na)) /* deprecated */
+#define POPp POPpx
#define POPpx (SvPVx_nolen(POPs))
#define POPpconstx (SvPVx_nolen_const(POPs))
#define POPpbytex (SvPVbytex_nolen(POPs))
#define POPu ((UV)SvUVx(POPs))
#define POPl ((long)SvIVx(POPs))
#define POPul ((unsigned long)SvIVx(POPs))
-#ifdef HAS_QUAD
-#define POPq ((Quad_t)SvIVx(POPs))
-#define POPuq ((Uquad_t)SvUVx(POPs))
-#endif
#define TOPs (*sp)
#define TOPm1s (*(sp-1))
#define TOPp1s (*(sp+1))
-#define TOPp (SvPV(TOPs, PL_na)) /* deprecated */
+#define TOPp TOPpx
#define TOPpx (SvPV_nolen(TOPs))
#define TOPn (SvNV(TOPs))
#define TOPi ((IV)SvIV(TOPs))
#define TOPu ((UV)SvUV(TOPs))
#define TOPl ((long)SvIV(TOPs))
#define TOPul ((unsigned long)SvUV(TOPs))
-#ifdef HAS_QUAD
-#define TOPq ((Quad_t)SvIV(TOPs))
-#define TOPuq ((Uquad_t)SvUV(TOPs))
-#endif
/* Go to some pains in the rare event that we must extend the stack. */
/*
-=for apidoc Am|void|EXTEND|SP|int nitems
-Used to extend the argument stack for an XSUB's return values. Once
+=for apidoc Am|void|EXTEND|SP|SSize_t nitems
+Used to extend the argument stack for an XSUB's return values. Once
used, guarantees that there is room for at least C<nitems> to be pushed
onto the stack.
=cut
*/
-#define EXTEND(p,n) STMT_START { if (PL_stack_max - p < (int)(n)) { \
- sp = stack_grow(sp,p, (int) (n)); \
- } } STMT_END
-
+#ifdef STRESS_REALLOC
+# define EXTEND(p,n) STMT_START { \
+ sp = stack_grow(sp,p,(SSize_t) (n)); \
+ PERL_UNUSED_VAR(sp); \
+ } STMT_END
+/* Same thing, but update mark register too. */
+# define MEXTEND(p,n) STMT_START { \
+ const int markoff = mark - PL_stack_base; \
+ sp = stack_grow(sp,p,(SSize_t) (n)); \
+ mark = PL_stack_base + markoff; \
+ PERL_UNUSED_VAR(sp); \
+ } STMT_END
+#else
+# define EXTEND(p,n) STMT_START { \
+ if (UNLIKELY(PL_stack_max - p < (int)(n))) { \
+ sp = stack_grow(sp,p,(SSize_t) (n)); \
+ PERL_UNUSED_VAR(sp); \
+ } } STMT_END
/* Same thing, but update mark register too. */
-#define MEXTEND(p,n) STMT_START {if (PL_stack_max - p < (int)(n)) { \
- const int markoff = mark - PL_stack_base; \
- sp = stack_grow(sp,p,(int) (n)); \
- mark = PL_stack_base + markoff; \
- } } STMT_END
+# define MEXTEND(p,n) STMT_START { \
+ if (UNLIKELY(PL_stack_max - p < (int)(n))) { \
+ const int markoff = mark - PL_stack_base; \
+ sp = stack_grow(sp,p,(SSize_t) (n)); \
+ mark = PL_stack_base + markoff; \
+ PERL_UNUSED_VAR(sp); \
+ } } STMT_END
+#endif
#define PUSHs(s) (*++sp = (s))
#define PUSHTARG STMT_START { SvSETMAGIC(TARG); PUSHs(TARG); } 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 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, (NV)(n)); XPUSHTARG; } STMT_END
#define dPOPiv IV value = POPi
#define dTOPuv UV value = TOPu
#define dPOPuv UV value = POPu
-#ifdef HAS_QUAD
-#define dTOPqv Quad_t value = TOPu
-#define dPOPqv Quad_t value = POPu
-#define dTOPuqv Uquad_t value = TOPuq
-#define dPOPuqv Uquad_t value = POPuq
-#endif
#define dPOPXssrl(X) SV *right = POPs; SV *left = CAT2(X,s)
#define dPOPXnnrl(X) NV right = POPn; NV 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) \
- NV right = POPn; \
- SV *leftsv = CAT2(X,s); \
- NV 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
+ (SvOK(sv) || !(PL_op->op_flags & OPf_STACKED))
#define dPOPXiirl_ul_nomg(X) \
- IV right = POPi; \
+ IV right = (sp--, SvIV_nomg(TOPp1s)); \
SV *leftsv = CAT2(X,s); \
IV left = USE_LEFT(leftsv) ? SvIV_nomg(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 dPOPTOPnnrl_nomg \
NV right = SvNV_nomg(TOPs); NV left = (sp--, SvNV_nomg(TOPs))
#define dPOPTOPiirl dPOPXiirl(TOP)
-#define dPOPTOPiirl_ul dPOPXiirl_ul(TOP)
#define dPOPTOPiirl_ul_nomg dPOPXiirl_ul_nomg(TOP)
#define dPOPTOPiirl_nomg \
IV right = SvIV_nomg(TOPs); IV left = (sp--, SvIV_nomg(TOPs))
#define ARGTARG PL_op->op_targ
/* See OPpTARGET_MY: */
-#define MAXARG (PL_op->op_private & 15)
+#define MAXARG (PL_op->op_private & OPpARG4_MASK)
#define SWITCHSTACK(f,t) \
STMT_START { \
#define EXTEND_MORTAL(n) \
STMT_START { \
- if (PL_tmps_ix + (n) >= PL_tmps_max) \
+ if (UNLIKELY(PL_tmps_ix + (n) >= PL_tmps_max)) \
tmps_grow(n); \
} STMT_END
#define AMGf_unary 8
#define AMGf_numeric 0x10 /* for Perl_try_amagic_bin */
#define AMGf_set 0x20 /* for Perl_try_amagic_bin */
+#define AMGf_want_list 0x40
/* do SvGETMAGIC on the stack args before checking for overload */
#define tryAMAGICun_MG(method, flags) STMT_START { \
- if ( (SvFLAGS(TOPs) & (SVf_ROK|SVs_GMG)) \
+ if ( UNLIKELY((SvFLAGS(TOPs) & (SVf_ROK|SVs_GMG))) \
&& Perl_try_amagic_un(aTHX_ method, flags)) \
return NORMAL; \
} STMT_END
#define tryAMAGICbin_MG(method, flags) STMT_START { \
- if ( ((SvFLAGS(TOPm1s)|SvFLAGS(TOPs)) & (SVf_ROK|SVs_GMG)) \
+ if ( UNLIKELY(((SvFLAGS(TOPm1s)|SvFLAGS(TOPs)) & (SVf_ROK|SVs_GMG))) \
&& Perl_try_amagic_bin(aTHX_ method, flags)) \
return NORMAL; \
} STMT_END
/* No longer used in core. Use AMG_CALLunary instead */
#define AMG_CALLun(sv,meth) AMG_CALLunary(sv, CAT2(meth,_amg))
-#define tryAMAGICunTARGET(meth, shift, jump) \
+#define tryAMAGICunTARGETlist(meth, jump) \
STMT_START { \
dSP; \
- sp--; /* get TARGET from below PL_stack_sp */ \
- { \
- dTARGETSTACKED; \
- dSP; \
- SV *tmpsv; \
- SV *arg= sp[shift]; \
- if (SvAMAGIC(arg) && \
- (tmpsv = amagic_call(arg, &PL_sv_undef, meth, \
- AMGf_noright | AMGf_unary))) { \
- SPAGAIN; \
- sp += shift; \
- sv_setsv(TARG, tmpsv); \
- if (opASSIGN) \
- sp--; \
- SETTARG; \
- PUTBACK; \
- if (jump) { \
- PL_markstack_ptr--; \
- return NORMAL->op_next->op_next; \
- } \
- return NORMAL; \
+ SV *tmpsv; \
+ SV *arg= *sp; \
+ int gimme = GIMME_V; \
+ if (UNLIKELY(SvAMAGIC(arg) && \
+ (tmpsv = amagic_call(arg, &PL_sv_undef, meth, \
+ AMGf_want_list | AMGf_noright \
+ |AMGf_unary)))) \
+ { \
+ SPAGAIN; \
+ if (gimme == G_VOID) { \
+ (void)POPs; /* XXX ??? */ \
+ } \
+ else if (gimme == G_ARRAY) { \
+ SSize_t i; \
+ SSize_t len; \
+ assert(SvTYPE(tmpsv) == SVt_PVAV); \
+ len = av_tindex((AV *)tmpsv) + 1; \
+ (void)POPs; /* get rid of the arg */ \
+ EXTEND(sp, len); \
+ for (i = 0; i < len; ++i) \
+ PUSHs(av_shift((AV *)tmpsv)); \
+ } \
+ else { /* AMGf_want_scalar */ \
+ dATARGET; /* just use the arg's location */ \
+ sv_setsv(TARG, tmpsv); \
+ if (opASSIGN) \
+ sp--; \
+ SETTARG; \
+ } \
+ PUTBACK; \
+ if (jump) { \
+ OP *jump_o = NORMAL->op_next; \
+ while (jump_o->op_type == OP_NULL) \
+ jump_o = jump_o->op_next; \
+ assert(jump_o->op_type == OP_ENTERSUB); \
+ PL_markstack_ptr--; \
+ return jump_o->op_next; \
} \
+ return NORMAL; \
} \
} STMT_END
#define SvCANEXISTDELETE(sv) \
(!SvRMAGICAL(sv) \
- || ((mg = mg_find((const SV *) sv, PERL_MAGIC_tied)) \
- && (stash = SvSTASH(SvRV(SvTIED_obj(MUTABLE_SV(sv), mg)))) \
+ || !(mg = mg_find((const SV *) sv, PERL_MAGIC_tied)) \
+ || ( (stash = SvSTASH(SvRV(SvTIED_obj(MUTABLE_SV(sv), mg)))) \
&& gv_fetchmethod_autoload(stash, "EXISTS", TRUE) \
&& gv_fetchmethod_autoload(stash, "DELETE", TRUE) \
) \
)
+#ifdef PERL_CORE
+
+/* These are just for Perl_tied_method(), which is not part of the public API.
+ Use 0x04 rather than the next available bit, to help the compiler if the
+ architecture can generate more efficient instructions. */
+# define TIED_METHOD_MORTALIZE_NOT_NEEDED 0x04
+# define TIED_METHOD_ARGUMENTS_ON_STACK 0x08
+# define TIED_METHOD_SAY 0x10
+
+/* Used in various places that need to dereference a glob or globref */
+# define MAYBE_DEREF_GV_flags(sv,phlags) \
+ ( \
+ (void)(phlags & SV_GMAGIC && (SvGETMAGIC(sv),0)), \
+ isGV_with_GP(sv) \
+ ? (GV *)(sv) \
+ : SvROK(sv) && SvTYPE(SvRV(sv)) <= SVt_PVLV && \
+ (SvGETMAGIC(SvRV(sv)), isGV_with_GP(SvRV(sv))) \
+ ? (GV *)SvRV(sv) \
+ : NULL \
+ )
+# define MAYBE_DEREF_GV(sv) MAYBE_DEREF_GV_flags(sv,SV_GMAGIC)
+# define MAYBE_DEREF_GV_nomg(sv) MAYBE_DEREF_GV_flags(sv,0)
+
+# define FIND_RUNCV_padid_eq 1
+# define FIND_RUNCV_level_eq 2
+
+#endif
+
/*
* Local variables:
* c-indentation-style: bsd
* c-basic-offset: 4
- * indent-tabs-mode: t
+ * indent-tabs-mode: nil
* End:
*
- * ex: set ts=8 sts=4 sw=4 noet:
+ * ex: set ts=8 sts=4 sw=4 et:
*/