XPUSHs(opsv);
switch (o->op_type) {
case OP_SUBST:
+#if PERL_VERSION >= 9
+ SP = oplist(aTHX_ cPMOPo->op_pmstashstartu.op_pmreplstart, SP);
+#else
SP = oplist(aTHX_ cPMOPo->op_pmreplstart, SP);
+#endif
continue;
case OP_SORT:
if (o->op_flags & OPf_STACKED && o->op_flags & OPf_SPECIAL) {
RETVAL
#define PMOP_pmreplroot(o) o->op_pmreplroot
-#define PMOP_pmreplstart(o) o->op_pmreplstart
+#if PERL_VERSION >= 9
+# define PMOP_pmreplstart(o) o->op_pmstashstartu.op_pmreplstart
+#else
+# define PMOP_pmreplstart(o) o->op_pmreplstart
+#endif
#define PMOP_pmnext(o) o->op_pmnext
#define PMOP_pmregexp(o) PM_GETRE(o)
#ifdef USE_ITHREADS
#define PMOP_pmoffset(o) o->op_pmoffset
-#define PMOP_pmstashpv(o) o->op_pmstashpv
+#define PMOP_pmstashpv(o) PmopSTASHPV(o);
#else
-#define PMOP_pmstash(o) o->op_pmstash
+#define PMOP_pmstash(o) PmopSTASH(o);
#endif
#define PMOP_pmflags(o) o->op_pmflags
repl->op_next = (OP*)rcop;
pm->op_pmreplroot = scalar((OP*)rcop);
- pm->op_pmreplstart = LINKLIST(rcop);
+ assert(!(pm->op_pmflags & PMf_ONCE));
+ pm->op_pmstashstartu.op_pmreplstart = LINKLIST(rcop);
rcop->op_next = 0;
}
}
case OP_SUBST:
o->op_opt = 1;
- while (cPMOP->op_pmreplstart &&
- cPMOP->op_pmreplstart->op_type == OP_NULL)
- cPMOP->op_pmreplstart = cPMOP->op_pmreplstart->op_next;
- peep(cPMOP->op_pmreplstart);
+ assert(!(cPMOP->op_pmflags & PMf_ONCE));
+ while (cPMOP->op_pmstashstartu.op_pmreplstart &&
+ cPMOP->op_pmstashstartu.op_pmreplstart->op_type == OP_NULL)
+ cPMOP->op_pmstashstartu.op_pmreplstart
+ = cPMOP->op_pmstashstartu.op_pmreplstart->op_next;
+ peep(cPMOP->op_pmstashstartu.op_pmreplstart);
break;
case OP_EXEC:
case OP_QR:
case OP_MATCH:
- assert (!cPMOP->op_pmreplstart);
+ if (!(cPMOP->op_pmflags & PMf_ONCE)) {
+ assert (!cPMOP->op_pmstashstartu.op_pmreplstart);
+ }
/* FALL THROUGH */
default:
o->op_opt = 1;
OP * op_first;
OP * op_last;
OP * op_pmreplroot; /* (type is really union {OP*,GV*,PADOFFSET}) */
- OP * op_pmreplstart;
#ifdef USE_ITHREADS
IV op_pmoffset;
#else
REGEXP * op_pmregexp; /* compiled expression */
#endif
U32 op_pmflags;
- /* This field is only needed so that PMOPs can delete themselves from the
- list held by the stash. In turn, that list is only needed for reset
- to work correctly, and is now only a list of ops used by ?? matches,
- which are rare. Hence it would be useful if we could find a way to
- shave it. */
+ union {
+ OP * op_pmreplstart; /* Only used in OP_SUBST */
#ifdef USE_ITHREADS
- char * op_pmstashpv;
+ char * op_pmstashpv; /* Only used in OP_MATCH, with PMf_ONCE set */
#else
- HV * op_pmstash;
+ HV * op_pmstash;
#endif
+ } op_pmstashstartu;
};
#ifdef USE_ITHREADS
#define PMf_RETAINT 0x0001 /* taint $1 etc. if target tainted */
#define PMf_ONCE 0x0002 /* match successfully only once per
reset, with related flag RXf_USED
- in re->extflags holding state */
+ in re->extflags holding state.
+ This is used only for ?? matches,
+ and only on OP_MATCH and OP_QR */
#define PMf_UNUSED 0x0004 /* free for use */
#define PMf_MAYBE_CONST 0x0008 /* replacement contains variables */
#ifdef USE_ITHREADS
-# define PmopSTASHPV(o) ((o)->op_pmstashpv)
-# define PmopSTASHPV_set(o,pv) (PmopSTASHPV(o) = savesharedpv(pv))
+# define PmopSTASHPV(o) \
+ (((o)->op_pmflags & PMf_ONCE) ? (o)->op_pmstashstartu.op_pmstashpv : NULL)
+# if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
+# define PmopSTASHPV_set(o,pv) ({ \
+ assert((o)->op_pmflags & PMf_ONCE); \
+ ((o)->op_pmstashstartu.op_pmstashpv = savesharedpv(pv)); \
+ })
+# else
+# define PmopSTASHPV_set(o,pv) \
+ ((o)->op_pmstashstartu.op_pmstashpv = savesharedpv(pv))
+# endif
# define PmopSTASH(o) (PmopSTASHPV(o) \
- ? gv_stashpv(PmopSTASHPV(o),GV_ADD) : NULL)
+ ? gv_stashpv((o)->op_pmstashstartu.op_pmstashpv,GV_ADD) : NULL)
# define PmopSTASH_set(o,hv) PmopSTASHPV_set(o, ((hv) ? HvNAME_get(hv) : NULL))
# define PmopSTASH_free(o) PerlMemShared_free(PmopSTASHPV(o))
#else
-# define PmopSTASH(o) ((o)->op_pmstash)
-# define PmopSTASH_set(o,hv) ((o)->op_pmstash = (hv))
+# define PmopSTASH(o) \
+ (((o)->op_pmflags & PMf_ONCE) ? (o)->op_pmstashstartu.op_pmstash : NULL)
+# if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
+# define PmopSTASH_set(o,hv) ({ \
+ assert((o)->op_pmflags & PMf_ONCE); \
+ ((o)->op_pmstashstartu.op_pmstash = (hv)); \
+ })
+# else
+# define PmopSTASH_set(o,hv) ((o)->op_pmstashstartu.op_pmstash = (hv))
+# endif
# define PmopSTASHPV(o) (PmopSTASH(o) ? HvNAME_get(PmopSTASH(o)) : NULL)
- /* op_pmstash is not refcounted */
+ /* op_pmstashstartu.op_pmstash is not refcounted */
# define PmopSTASHPV_set(o,pv) PmopSTASH_set((o), gv_stashpv(pv,GV_ADD))
# define PmopSTASH_free(o)
#endif