HV * cop_stash; /* package line was compiled in */
GV * cop_filegv; /* file the following line # is from */
#endif
+ U32 cop_hints; /* hints bits from pragmata */
U32 cop_seq; /* parse sequence number */
- I32 cop_arybase; /* array base this line was compiled with */
line_t cop_line; /* line # of this command */
/* Beware. mg.c and warnings.pl assume the type of this is STRLEN *: */
STRLEN * cop_warnings; /* lexical warnings bitmask */
- SV * cop_io; /* lexical IO defaults */
/* compile time state of %^H. See the comment in op.c for how this is
used to recreate a hash to return from caller. */
- struct refcounted_he * cop_hints;
+ struct refcounted_he * cop_hints_hash;
};
#ifdef USE_ITHREADS
# define OutCopFILE(c) CopFILE(c)
#endif
-/* CopARYBASE is likely to be removed soon. */
-#define CopARYBASE(c) ((c)->cop_arybase)
-#define CopARYBASE_get(c) ((c)->cop_arybase + 0)
-#define CopARYBASE_set(c, b) STMT_START { (c)->cop_arybase = (b); } STMT_END
+/* If $[ is non-zero, it's stored in cop_hints under the key "$[", and
+ HINT_ARYBASE is set to indicate this.
+ Setting it is ineficient due to the need to create 2 mortal SVs, but as
+ using $[ is highly discouraged, no sane Perl code will be using it. */
+#define CopARYBASE_get(c) \
+ ((CopHINTS_get(c) & HINT_ARYBASE) \
+ ? SvIV(Perl_refcounted_he_fetch(aTHX_ (c)->cop_hints_hash, 0, \
+ "$[", 2, 0, 0)) \
+ : 0)
+#define CopARYBASE_set(c, b) STMT_START { \
+ if (b || ((c)->cop_hints & HINT_ARYBASE)) { \
+ (c)->cop_hints |= HINT_ARYBASE; \
+ if ((c) == &PL_compiling) \
+ PL_hints |= HINT_LOCALIZE_HH | HINT_ARYBASE; \
+ (c)->cop_hints_hash \
+ = Perl_refcounted_he_new(aTHX_ (c)->cop_hints_hash, \
+ sv_2mortal(newSVpvs("$[")), \
+ sv_2mortal(newSViv(b))); \
+ } \
+ } STMT_END
/* FIXME NATIVE_HINTS if this is changed from op_private (see perl.h) */
-#define CopHINTS_get(c) ((c)->op_private + 0)
+#define CopHINTS_get(c) ((c)->cop_hints + 0)
#define CopHINTS_set(c, h) STMT_START { \
- (c)->op_private \
- = (U8)((h) & HINT_PRIVATE_MASK); \
+ (c)->cop_hints = (h); \
} STMT_END
/*
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); \
cx->sb_rxres = NULL, \
cx->sb_rx = rx, \
cx->cx_type = CXt_SUBST; \
- rxres_save(&cx->sb_rxres, rx)
+ rxres_save(&cx->sb_rxres, rx); \
+ (void)ReREFCNT_inc(rx)
#define POPSUBST(cx) cx = &cxstack[cxstack_ix--]; \
- rxres_free(&cx->sb_rxres)
+ rxres_free(&cx->sb_rxres); \
+ ReREFCNT_dec(cx->sb_rx)
struct context {
U32 cx_type; /* what kind of context this is */