AV * savearray;
AV * argarray;
I32 olddepth;
- U8 hasargs;
- U8 lval; /* XXX merge lval and hasargs? */
+ /* These are merged to to get struct context down to 64 bytes on ILP32. */
+ U8 hasargs_lval;
PAD *oldcomppad;
OP * retop; /* op to execute on exit from sub */
};
+#define CX_SUB_HASARGS_SET(cx, v) ((cx)->blk_sub.hasargs_lval = \
+ ((cx)->blk_sub.hasargs_lval & 0xFE) | ((v) ? 1 : 0))
+#define CX_SUB_HASARGS_GET(cx) ((cx)->blk_sub.hasargs_lval & 0x01)
+
+#define CX_SUB_LVAL_SET(cx, v) ((cx)->blk_sub.hasargs_lval = \
+ (((cx)->blk_sub.hasargs_lval & 0x01) | ((v) & (OPpLVAL_INTRO|OPpENTERSUB_INARGS))))
+#define CX_SUB_LVAL(cx) ((cx)->blk_sub.hasargs_lval & 0xFE)
+#define CX_SUB_LVAL_INARGS(cx) ((cx)->blk_sub.hasargs_lval & \
+ OPpENTERSUB_INARGS)
+
/* base for the next two macros. Don't use directly.
* Note that the refcnt of the cv is incremented twice; The CX one is
* decremented by LEAVESUB, the other by LEAVE. */
#define PUSHSUB_BASE(cx) \
cx->blk_sub.cv = cv; \
cx->blk_sub.olddepth = CvDEPTH(cv); \
- cx->blk_sub.hasargs = hasargs; \
+ CX_SUB_HASARGS_SET(cx, hasargs); \
cx->blk_sub.retop = NULL; \
if (!CvDEPTH(cv)) { \
SvREFCNT_inc_simple_void_NN(cv); \
#define PUSHSUB(cx) \
PUSHSUB_BASE(cx) \
- cx->blk_sub.lval = PL_op->op_private & \
- (OPpLVAL_INTRO|OPpENTERSUB_INARGS);
+ CX_SUB_LVAL_SET(cx, PL_op->op_private)
/* variant for use by OP_DBSTATE, where op_private holds hint bits */
#define PUSHSUB_DB(cx) \
PUSHSUB_BASE(cx) \
- cx->blk_sub.lval = 0;
+ CX_SUB_LVAL_SET(cx, 0)
#define PUSHFORMAT(cx) \
cx->blk_sub.cv = cv; \
cx->blk_sub.gv = gv; \
cx->blk_sub.retop = NULL; \
- cx->blk_sub.hasargs = 0; \
+ CX_SUB_HASARGS_SET(cx, 0); \
cx->blk_sub.dfoutgv = PL_defoutgv; \
SvREFCNT_inc_void(cx->blk_sub.dfoutgv)
#define POPSUB(cx,sv) \
STMT_START { \
- if (cx->blk_sub.hasargs) { \
+ if (CX_SUB_HASARGS_GET(cx)) { \
POP_SAVEARRAY(); \
/* abandon @_ if it got reified */ \
if (AvREAL(cx->blk_sub.argarray)) { \
- SSize_t fill = AvFILLp(cx->blk_sub.argarray); \
+ const SSize_t fill = AvFILLp(cx->blk_sub.argarray); \
SvREFCNT_dec(cx->blk_sub.argarray); \
cx->blk_sub.argarray = newAV(); \
av_extend(cx->blk_sub.argarray, fill); \
/* context common to subroutines, evals and loops */
struct block {
+ U16 blku_type; /* what kind of context this is */
+ U8 blku_gimme; /* is this block running in list context? */
I32 blku_oldsp; /* stack pointer to copy stuff down to */
COP * blku_oldcop; /* old curcop pointer */
I32 blku_oldmarksp; /* mark stack index */
I32 blku_oldscopesp; /* scope stack index */
PMOP * blku_oldpm; /* values of pattern match vars */
- U8 blku_gimme; /* is this block running in list context? */
union {
struct block_sub blku_sub;
/* substitution context */
struct subst {
+ U16 sbu_type; /* what kind of context this is */
+ bool sbu_once;
+ bool sbu_rxtainted;
I32 sbu_iters;
I32 sbu_maxiters;
I32 sbu_rflags;
I32 sbu_oldsave;
- bool sbu_once;
- bool sbu_rxtainted;
char * sbu_orig;
SV * sbu_dstr;
SV * sbu_targ;
cx->sb_rx = rx, \
cx->cx_type = CXt_SUBST; \
rxres_save(&cx->sb_rxres, rx); \
- ReREFCNT_inc(rx)
+ (void)ReREFCNT_inc(rx)
#define POPSUBST(cx) cx = &cxstack[cxstack_ix--]; \
rxres_free(&cx->sb_rxres); \
ReREFCNT_dec(cx->sb_rx)
struct context {
- U32 cx_type; /* what kind of context this is */
union {
struct block cx_blk;
struct subst cx_subst;
} cx_u;
};
+#define cx_type cx_u.cx_subst.sbu_type
#define CXTYPEMASK 0xff
#define CXt_NULL 0