save_re_context(): do "local $n" with no PL_curpm
RT #124109.
2c1f00b9036 localised PL_curpm to NULL when calling swash init code
(i.e. perl-level code that is loaded and executed when something
like "lc $large_codepoint" is executed).
b4fa55d3f1 followed this up by gutting Perl_save_re_context(), since
that function did, basically,
if (PL_curpm) {
for (i = 1; i <= RX_NPARENS(PM_GETRE(PL_curpm))) {
do the C equivalent of the perl code "local ${i}";
}
}
and now that PL_curpm was null, the code wasn't called any more. However,
it turns out that the localisation *was* still needed, it's just that
nothing in the test suite actually tested for it.
In something like the following:
$x = "\x{41c}";
$x =~ /(.*)/;
$s = lc $1;
pp_lc() calls get magic on $1, which sets $1's PV value to a copy of the
substring captured by the current pattern match.
Then pp_lc() calls a function to convert the string to upper case, which
triggers a swash load, which calls perl code that does a pattern match
and, most importantly, uses the value of $1. This triggers get magic on
$1, which overwrites $1's PV value with a new value. When control returns
to pp_lc(), $1 now holds the wrong string value.
Hence $1, $2 etc need localising as well as PL_curpm.
The old way that Perl_save_re_context() used to work (localising
$1..${RX_NPARENS}) won't work directly when PL_curpm is NULL (as in the
swash case), since we don't know how many vars to localise.
In this case, hard-code it as localising $1,$2,$3 and add a porting
test file that checks that the utf8.pm code and dependences don't
use anything outside those 3 vars.