This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Tidy up context type flags.
[perl5.git] / cop.h
diff --git a/cop.h b/cop.h
index c486907..ccf910b 100644 (file)
--- a/cop.h
+++ b/cop.h
@@ -282,7 +282,6 @@ struct block_sub {
     OP *       retop;  /* op to execute on exit from sub */
     /* Above here is the same for sub, format and eval.  */
     CV *       cv;
-    U8         lval;           /* XXX merge lval and hasargs? */
     /* Above here is the same for sub and format.  */
     AV *       savearray;
     AV *       argarray;
@@ -296,7 +295,6 @@ struct block_format {
     OP *       retop;  /* op to execute on exit from sub */
     /* Above here is the same for sub, format and eval.  */
     CV *       cv;
-    U8         lval;           /* XXX merge lval and hasargs? */
     /* Above here is the same for sub and format.  */
     GV *       gv;
     GV *       dfoutgv;
@@ -324,13 +322,13 @@ struct block_format {
 
 #define PUSHSUB(cx)                                                    \
        PUSHSUB_BASE(cx)                                                \
-       cx->blk_sub.lval = PL_op->op_private &                          \
+       cx->blk_u16 = PL_op->op_private &                               \
                              (OPpLVAL_INTRO|OPpENTERSUB_INARGS);
 
 /* 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->blk_u16 = 0;
 
 
 #define PUSHFORMAT(cx, retop)                                          \
@@ -395,8 +393,6 @@ struct block_format {
 struct block_eval {
     OP *       retop;  /* op to execute on exit from eval */
     /* Above here is the same for sub, format and eval.  */
-    U8         old_in_eval;
-    U16                old_op_type;
     SV *       old_namesv;
     OP *       old_eval_root;
     SV *       cur_text;
@@ -404,10 +400,18 @@ struct block_eval {
     JMPENV *   cur_top_env; /* value of PL_top_env when eval CX created */
 };
 
+/* If we ever need more than 512 op types, change the shift from 7.
+   blku_gimme is actually also only 2 bits, so could be merged with something.
+*/
+
+#define CxOLD_IN_EVAL(cx)      (((cx)->blk_u16) & 0x7F)
+#define CxOLD_OP_TYPE(cx)      (((cx)->blk_u16) >> 7)
+
 #define PUSHEVAL(cx,n,fgv)                                             \
     STMT_START {                                                       \
-       cx->blk_eval.old_in_eval = PL_in_eval;                          \
-       cx->blk_eval.old_op_type = PL_op->op_type;                      \
+       assert(!(PL_in_eval & ~0x7F));                                  \
+       assert(!(PL_op->op_type & ~0x1FF));                             \
+       cx->blk_u16 = (PL_in_eval & 0x7F) | ((U16)PL_op->op_type << 7); \
        cx->blk_eval.old_namesv = (n ? newSVpv(n,0) : NULL);            \
        cx->blk_eval.old_eval_root = PL_eval_root;                      \
        cx->blk_eval.cur_text = PL_parser ? PL_parser->linestr : NULL;  \
@@ -418,8 +422,8 @@ struct block_eval {
 
 #define POPEVAL(cx)                                                    \
     STMT_START {                                                       \
-       PL_in_eval = cx->blk_eval.old_in_eval;                          \
-       optype = cx->blk_eval.old_op_type;                              \
+       PL_in_eval = CxOLD_IN_EVAL(cx);                                 \
+       optype = CxOLD_OP_TYPE(cx);                                     \
        PL_eval_root = cx->blk_eval.old_eval_root;                      \
        if (cx->blk_eval.old_namesv)                                    \
            sv_2mortal(cx->blk_eval.old_namesv);                        \
@@ -486,7 +490,7 @@ struct block_loop {
 #endif
 #define CxLABEL(c)     (0 + (c)->blk_oldcop->cop_label)
 #define CxHASARGS(c)   (((c)->cx_type & CXp_HASARGS) == CXp_HASARGS)
-#define CxLVAL(c)      (0 + (c)->blk_sub.lval)
+#define CxLVAL(c)      (0 + (c)->blk_u16)
 
 #ifdef USE_ITHREADS
 #  define PUSHLOOP_OP_NEXT             /* No need to do anything.  */
@@ -532,9 +536,9 @@ struct block_givwhen {
 
 /* context common to subroutines, evals and loops */
 struct block {
-    U16                blku_type;      /* what kind of context this is */
+    U8         blku_type;      /* what kind of context this is */
     U8         blku_gimme;     /* is this block running in list context? */
-    U8         blku_spare;     /* Padding to match with struct subst */
+    U16                blku_u16;       /* used by block_sub and block_eval (so far) */
     I32                blku_oldsp;     /* stack pointer to copy stuff down to */
     COP *      blku_oldcop;    /* old curcop pointer */
     I32                blku_oldmarksp; /* mark stack index */
@@ -555,6 +559,7 @@ struct block {
 #define blk_oldscopesp cx_u.cx_blk.blku_oldscopesp
 #define blk_oldpm      cx_u.cx_blk.blku_oldpm
 #define blk_gimme      cx_u.cx_blk.blku_gimme
+#define blk_u16                cx_u.cx_blk.blku_u16
 #define blk_sub                cx_u.cx_blk.blk_u.blku_sub
 #define blk_format     cx_u.cx_blk.blk_u.blku_format
 #define blk_eval       cx_u.cx_blk.blk_u.blku_eval
@@ -595,9 +600,9 @@ struct block {
 
 /* substitution context */
 struct subst {
-    U16                sbu_type;       /* what kind of context this is */
-    U8         sbu_once;       /* Actually both booleans, but U8 to matches */
-    U8         sbu_rxtainted;  /* struct block */
+    U8         sbu_type;       /* what kind of context this is */
+    U8         sbu_once;       /* Actually both booleans, but U8/U16 */
+    U16                sbu_rxtainted;  /* matches struct block */
     I32                sbu_iters;
     I32                sbu_maxiters;
     I32                sbu_rflags;
@@ -672,23 +677,22 @@ struct context {
    However, this is checked in many places which do not check the type, so
    this bit needs to be kept clear for most everything else. For reasons I
    haven't investigated, it can coexist with CXp_FOR_DEF */
-#define CXp_MULTICALL  0x0000040       /* part of a multicall (so don't
-                                          tear down context on exit). */ 
+#define CXp_MULTICALL  0x10    /* part of a multicall (so don't
+                                  tear down context on exit). */ 
 
 /* private flags for CXt_SUB and CXt_FORMAT */
-#define CXp_HASARGS    0x00000020
+#define CXp_HASARGS    0x20
 
 /* private flags for CXt_EVAL */
-#define CXp_REAL       0x00000010      /* truly eval'', not a lookalike */
-#define CXp_TRYBLOCK   0x00000020      /* eval{}, not eval'' or similar */
+#define CXp_REAL       0x20    /* truly eval'', not a lookalike */
+#define CXp_TRYBLOCK   0x40    /* eval{}, not eval'' or similar */
 
 /* private flags for CXt_LOOP */
-#define CXp_FOREACH    0x00000020      /* a foreach loop */
-#define CXp_FOR_DEF    0x00000040      /* foreach using $_ */
+#define CXp_FOR_DEF    0x10    /* foreach using $_ */
+#define CXp_FOREACH    0x20    /* a foreach loop */
 #ifdef USE_ITHREADS
-#  define CXp_PADVAR   0x00000010      /* itervar lives on pad, iterdata
-                                          has pad offset; if not set,
-                                          iterdata holds GV* */
+#  define CXp_PADVAR   0x40    /* itervar lives on pad, iterdata has pad
+                                  offset; if not set, iterdata holds GV* */
 #  define CxPADLOOP(c) (((c)->cx_type & (CXt_LOOP|CXp_PADVAR))         \
                         == (CXt_LOOP|CXp_PADVAR))
 #endif