This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
perldsc: #109408
[perl5.git] / cop.h
diff --git a/cop.h b/cop.h
index 8690494..041420c 100644 (file)
--- a/cop.h
+++ b/cop.h
@@ -387,9 +387,9 @@ struct cop {
     line_t      cop_line;       /* line # of this command */
     /* label for this construct is now stored in cop_hints_hash */
 #ifdef USE_ITHREADS
-    char *     cop_stashpv;    /* package line was compiled in */
+    PADOFFSET  cop_stashoff;   /* offset into PL_stashpad, for the
+                                  package the line was compiled in */
     char *     cop_file;       /* file name the following line # is from */
-    U32         cop_stashflags; /* currently only SVf_UTF8 */
 #else
     HV *       cop_stash;      /* package line was compiled in */
     GV *       cop_filegv;     /* file the following line # is from */
@@ -426,34 +426,14 @@ struct cop {
 #  else
 #    define CopFILEAVx(c)      (GvAV(gv_fetchfile(CopFILE(c))))
 #  endif
-#  define CopSTASHPV(c)                ((c)->cop_stashpv)
 
+#  define CopSTASH(c)           PL_stashpad[(c)->cop_stashoff]
+#  define CopSTASH_set(c,hv)   ((c)->cop_stashoff = (hv)               \
+                                   ? alloccopstash(hv)                 \
+                                   : 0)
 #  ifdef NETWARE
-#    define CopSTASHPV_set(c,pv)       ((c)->cop_stashpv = ((pv) ? savepv(pv) : NULL))
-#  else
-#    define CopSTASHPV_set(c,pv)       ((c)->cop_stashpv = savesharedpv(pv))
-#  endif
-
-#  define CopSTASH_flags(c)            ((c)->cop_stashflags)
-#  define CopSTASH_flags_set(c,flags)  ((c)->cop_stashflags = flags)
-
-#  define CopSTASH(c)          (CopSTASHPV(c)                                 \
-                                ? gv_stashpv(CopSTASHPV(c),                   \
-                                            GV_ADD|(CopSTASH_flags(c)          \
-                                                    ? CopSTASH_flags(c): 0 )) \
-                                 : NULL)
-#  define CopSTASH_set(c,hv)   (CopSTASHPV_set(c, (hv) ? HvNAME_get(hv) : NULL), \
-                                CopSTASH_flags_set(c,                            \
-                                            ((hv) && HvNAME_HEK(hv) &&              \
-                                                     HvNAMEUTF8(hv))                \
-                                                ? SVf_UTF8                          \
-                                                : 0))
-#  define CopSTASH_eq(c,hv)    ((hv) && stashpv_hvname_match(c,hv))
-#  ifdef NETWARE
-#    define CopSTASH_free(c) SAVECOPSTASH_FREE(c)
 #    define CopFILE_free(c) SAVECOPFILE_FREE(c)
 #  else
-#    define CopSTASH_free(c)   PerlMemShared_free(CopSTASHPV(c))
 #    define CopFILE_free(c)    (PerlMemShared_free(CopFILE(c)),(CopFILE(c) = NULL))
 #  endif
 #else
@@ -472,15 +452,15 @@ struct cop {
                                    ? SvPVX(GvSV(CopFILEGV(c))) : NULL)
 #  define CopSTASH(c)          ((c)->cop_stash)
 #  define CopSTASH_set(c,hv)   ((c)->cop_stash = (hv))
-#  define CopSTASHPV(c)                (CopSTASH(c) ? HvNAME_get(CopSTASH(c)) : NULL)
-   /* cop_stash is not refcounted */
-#  define CopSTASHPV_set(c,pv) CopSTASH_set((c), gv_stashpv(pv,GV_ADD))
-#  define CopSTASH_eq(c,hv)    (CopSTASH(c) == (hv))
-#  define CopSTASH_free(c)     
 #  define CopFILE_free(c)      (SvREFCNT_dec(CopFILEGV(c)),(CopFILEGV(c) = NULL))
 
 #endif /* USE_ITHREADS */
 
+#define CopSTASHPV(c)          (CopSTASH(c) ? HvNAME_get(CopSTASH(c)) : NULL)
+   /* cop_stash is not refcounted */
+#define CopSTASHPV_set(c,pv)   CopSTASH_set((c), gv_stashpv(pv,GV_ADD))
+#define CopSTASH_eq(c,hv)      (CopSTASH(c) == (hv))
+
 #define CopHINTHASH_get(c)     ((COPHH*)((c)->cop_hints_hash))
 #define CopHINTHASH_set(c,h)   ((c)->cop_hints_hash = (h))
 
@@ -1200,6 +1180,12 @@ See L<perlcall/LIGHTWEIGHT CALLBACKS>.
     U8 hasargs = 0             /* used by PUSHSUB */
 
 #define PUSH_MULTICALL(the_cv) \
+    PUSH_MULTICALL_WITHDEPTH(the_cv, 1);
+
+/* Like PUSH_MULTICALL, but allows you to specify the CvDEPTH increment,
+ * rather than the default of 1 (this isn't part of the public API) */
+
+#define PUSH_MULTICALL_WITHDEPTH(the_cv, depth) \
     STMT_START {                                                       \
        CV * const _nOnclAshIngNamE_ = the_cv;                          \
        CV * const cv = _nOnclAshIngNamE_;                              \
@@ -1211,7 +1197,8 @@ See L<perlcall/LIGHTWEIGHT CALLBACKS>.
        PUSHSTACKi(PERLSI_SORT);                                        \
        PUSHBLOCK(cx, CXt_SUB|CXp_MULTICALL, PL_stack_sp);              \
        PUSHSUB(cx);                                                    \
-       if (++CvDEPTH(cv) >= 2) {                                       \
+       CvDEPTH(cv) += depth;                                           \
+       if (CvDEPTH(cv) >= 2) {                                         \
            PERL_STACK_OVERFLOW_CHECK();                                \
            Perl_pad_push(aTHX_ padlist, CvDEPTH(cv));                  \
        }                                                               \
@@ -1229,8 +1216,9 @@ See L<perlcall/LIGHTWEIGHT CALLBACKS>.
 
 #define POP_MULTICALL \
     STMT_START {                                                       \
-       if (! --CvDEPTH(multicall_cv))                                  \
-           LEAVESUB(multicall_cv);                                     \
+       if (! ((CvDEPTH(multicall_cv) = cx->blk_sub.olddepth)) ) {      \
+               LEAVESUB(multicall_cv);                                 \
+       }                                                               \
        POPBLOCK(cx,PL_curpm);                                          \
        POPSTACK;                                                       \
        CATCH_SET(multicall_oldcatch);                                  \
@@ -1238,12 +1226,37 @@ See L<perlcall/LIGHTWEIGHT CALLBACKS>.
        SPAGAIN;                                                        \
     } STMT_END
 
+/* Change the CV of an already-pushed MULTICALL CxSUB block.
+ * (this isn't part of the public API) */
+
+#define CHANGE_MULTICALL_WITHDEPTH(the_cv, depth) \
+    STMT_START {                                                       \
+       CV * const _nOnclAshIngNamE_ = the_cv;                          \
+       CV * const cv = _nOnclAshIngNamE_;                              \
+       AV * const padlist = CvPADLIST(cv);                             \
+       cx = &cxstack[cxstack_ix];                                      \
+       assert(cx->cx_type & CXp_MULTICALL);                            \
+       if (! ((CvDEPTH(multicall_cv) = cx->blk_sub.olddepth)) ) {      \
+               LEAVESUB(multicall_cv);                                 \
+       }                                                               \
+       cx->cx_type &= ~CXp_HASARGS;                                    \
+       PUSHSUB(cx);                                                    \
+       CvDEPTH(cv) += depth;                                           \
+       if (CvDEPTH(cv) >= 2) {                                         \
+           PERL_STACK_OVERFLOW_CHECK();                                \
+           Perl_pad_push(aTHX_ padlist, CvDEPTH(cv));                  \
+       }                                                               \
+       SAVECOMPPAD();                                                  \
+       PAD_SET_CUR_NOSAVE(padlist, CvDEPTH(cv));                       \
+       multicall_cv = cv;                                              \
+       multicall_cop = CvSTART(cv);                                    \
+    } STMT_END
 /*
  * 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:
  */