create itervar_u union in struct block_loop
authorDavid Mitchell <davem@iabyn.com>
Wed, 8 Sep 2010 13:38:00 +0000 (14:38 +0100)
committerDavid Mitchell <davem@iabyn.com>
Wed, 8 Sep 2010 13:48:30 +0000 (14:48 +0100)
make it clearer what types of pointer to the iterator variable can be
stored, reduce the amount of #ifdef USE_ITHREADS, get rid of some macros,
and generally make the code easier to follow. No change to the size of the
structure.

cop.h
pp_ctl.c
sv.c

diff --git a/cop.h b/cop.h
index 4c269a7..c91e9a4 100644 (file)
--- a/cop.h
+++ b/cop.h
@@ -447,11 +447,11 @@ struct block_eval {
 struct block_loop {
     I32                resetsp;
     LOOP *     my_op;  /* My op, that contains redo, next and last ops.  */
-#ifdef USE_ITHREADS
-    PAD                *oldcomppad; /* Also used for the GV, if my_op->op_targ is 0 */
-#else
-    SV **      itervar;
-#endif
+    union {    /* different ways of locating the iteration variable */
+       SV      **svp;
+       GV      *gv;
+       PAD     *oldcomppad; /* only used in ITHREADS */
+    } itervar_u;
     union {
        struct { /* valid if type is LOOP_FOR or LOOP_PLAIN (but {NULL,0})*/
            AV * ary; /* use the stack if this is NULL */
@@ -470,20 +470,13 @@ struct block_loop {
 
 #ifdef USE_ITHREADS
 #  define CxITERVAR(c)                                                 \
-       ((c)->blk_loop.oldcomppad                                       \
+       ((c)->blk_loop.itervar_u.oldcomppad                             \
         ? (CxPADLOOP(c)                                                \
-           ? &CX_CURPAD_SV( (c)->blk_loop, (c)->blk_loop.my_op->op_targ) \
-           : &GvSV((GV*)(c)->blk_loop.oldcomppad))                     \
+           ? &CX_CURPAD_SV( (c)->blk_loop.itervar_u, (c)->blk_loop.my_op->op_targ) \
+           : &GvSV((c)->blk_loop.itervar_u.gv))                        \
         : (SV**)NULL)
-#  define CX_ITERDATA_SET(cx,idata,o)                                  \
-       if (cx->blk_loop.my_op->op_targ)                                \
-           CX_CURPAD_SAVE(cx->blk_loop);                               \
-       else                                                            \
-           cx->blk_loop.oldcomppad = (idata);
 #else
-#  define CxITERVAR(c)         ((c)->blk_loop.itervar)
-#  define CX_ITERDATA_SET(cx,ivar,o)                                   \
-       cx->blk_loop.itervar = (SV**)(ivar);
+#  define CxITERVAR(c)         ((c)->blk_loop.itervar_u.svp)
 #endif
 #define CxLABEL(c)     (0 + CopLABEL((c)->blk_oldcop))
 #define CxHASARGS(c)   (((c)->cx_type & CXp_HASARGS) == CXp_HASARGS)
@@ -494,14 +487,14 @@ struct block_loop {
        cx->blk_loop.my_op = cLOOP;                                     \
        cx->blk_loop.state_u.ary.ary = NULL;                            \
        cx->blk_loop.state_u.ary.ix = 0;                                \
-       CX_ITERDATA_SET(cx, NULL, 0);
+       cx->blk_loop.itervar_u.svp = NULL;
 
-#define PUSHLOOP_FOR(cx, dat, s, offset)                               \
+#define PUSHLOOP_FOR(cx, ivar, s)                                      \
        cx->blk_loop.resetsp = s - PL_stack_base;                       \
        cx->blk_loop.my_op = cLOOP;                                     \
        cx->blk_loop.state_u.ary.ary = NULL;                            \
        cx->blk_loop.state_u.ary.ix = 0;                                \
-       CX_ITERDATA_SET(cx, dat, offset);
+       cx->blk_loop.itervar_u.svp = (SV**)(ivar);
 
 #define POPLOOP(cx)                                                    \
        if (CxTYPE(cx) == CXt_LOOP_LAZYSV) {                            \
index 93d1675..9673d12 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -1946,11 +1946,8 @@ PP(pp_enteriter)
     dVAR; dSP; dMARK;
     register PERL_CONTEXT *cx;
     const I32 gimme = GIMME_V;
-    SV **svp;
+    void *itervar; /* location of the iteration variable */
     U8 cxtype = CXt_LOOP_FOR;
-#ifdef USE_ITHREADS
-    PAD *iterdata;
-#endif
 
     ENTER_with_name("loop1");
     SAVETMPS;
@@ -1963,18 +1960,20 @@ PP(pp_enteriter)
        }
        SAVEPADSVANDMORTALIZE(PL_op->op_targ);
 #ifndef USE_ITHREADS
-       svp = &PAD_SVl(PL_op->op_targ);         /* "my" variable */
+       itervar = &PAD_SVl(PL_op->op_targ);     /* "my" variable */
 #else
-       iterdata = NULL;
+       itervar = PL_comppad;
 #endif
     }
     else {
        GV * const gv = MUTABLE_GV(POPs);
-       svp = &GvSV(gv);                        /* symbol table variable */
+       SV** svp = &GvSV(gv);                   /* symbol table variable */
        SAVEGENERICSV(*svp);
        *svp = newSV(0);
 #ifdef USE_ITHREADS
-       iterdata = (PAD*)gv;
+       itervar = (void *)gv;
+#else
+       itervar = (void *)svp;
 #endif
     }
 
@@ -1984,11 +1983,7 @@ PP(pp_enteriter)
     ENTER_with_name("loop2");
 
     PUSHBLOCK(cx, cxtype, SP);
-#ifdef USE_ITHREADS
-    PUSHLOOP_FOR(cx, iterdata, MARK, PL_op->op_targ);
-#else
-    PUSHLOOP_FOR(cx, svp, MARK, 0);
-#endif
+    PUSHLOOP_FOR(cx, itervar, MARK);
     if (PL_op->op_flags & OPf_STACKED) {
        SV *maybe_ary = POPs;
        if (SvTYPE(maybe_ary) != SVt_PVAV) {
diff --git a/sv.c b/sv.c
index d6af5ce..8bf7cba 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -11660,13 +11660,13 @@ Perl_cx_dup(pTHX_ PERL_CONTEXT *cxs, I32 ix, I32 max, CLONE_PARAMS* param)
            case CXt_LOOP_LAZYIV:
            case CXt_LOOP_PLAIN:
                if (CxPADLOOP(ncx)) {
-                   ncx->blk_loop.oldcomppad
+                   ncx->blk_loop.itervar_u.oldcomppad
                        = (PAD*)ptr_table_fetch(PL_ptr_table,
-                                               ncx->blk_loop.oldcomppad);
+                                       ncx->blk_loop.itervar_u.oldcomppad);
                } else {
-                   ncx->blk_loop.oldcomppad
-                       = (PAD*)gv_dup((const GV *)ncx->blk_loop.oldcomppad,
-                                      param);
+                   ncx->blk_loop.itervar_u.gv
+                       = gv_dup((const GV *)ncx->blk_loop.itervar_u.gv,
+                                   param);
                }
                break;
            case CXt_FORMAT: