summaryrefslogtreecommitdiff
path: root/regcomp.c
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2013-01-04 16:10:53 +0000
committerDavid Mitchell <davem@iabyn.com>2013-01-04 16:23:32 +0000
commitd234778b5b6b322797137257f7f372e6c6c60a12 (patch)
treec3318b886cd29d3afbbf2c9902540c7162d8e2b2 /regcomp.c
parent4a30d80398948aef6e63361ec83ff9ec98d0987a (diff)
downloadperl-d234778b5b6b322797137257f7f372e6c6c60a12.tar.gz
make m?$pat? match only once under ithreads
[perl #115080] m?...? is only supposed to match once, until reset. Normally this is done by setting the PMf_USED flag on the PMOP. Under ithreads we can't modify ops, so instead we indicate by setting the regex's SV to readonly. (This is a bit of a hack: the flag should be associated with the PMOP, not the regex). This breaks with run-time regexes when the pattern gets recompiled; for example: for my $c (qw(a b c)) { print "matched $c\n" if $c =~ m?^$c$?; } outputs matched a on unthreaded, but matched a matched b matched c on threaded. The re_eval jumbo fix made this more noticeable by sometimes recompiling even when the pattern text hasn't changed (to make closures work ok). The quick fix is to propagate the readonlyness of the old re to the new re. (The proper fix would be to store the flag state in a pad slot associated with the PMOP). Needless to say, I've gone for the quick fix.
Diffstat (limited to 'regcomp.c')
-rw-r--r--regcomp.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/regcomp.c b/regcomp.c
index d2535f0f0a..2e1ed42053 100644
--- a/regcomp.c
+++ b/regcomp.c
@@ -6350,6 +6350,14 @@ reStudy:
PerlIO_printf(Perl_debug_log, "\n");
});
#endif
+
+#ifdef USE_ITHREADS
+ /* under ithreads the ?pat? PMf_USED flag on the pmop is simulated
+ * by setting the regexp SV to readonly-only instead. If the
+ * pattern's been recompiled, the USEDness should remain. */
+ if (old_re && SvREADONLY(old_re))
+ SvREADONLY_on(rx);
+#endif
return rx;
}