zen% perl -Mre=eval -we 'sub a {"x"} sub b {"(??{a()})"} "x" =~ /(??{b()})/'
Eval-group not allowed at runtime, use re 'eval' in regex m/(??{a()})/ at -e line 1.
zen%
Looking at the code to see how C< use re qw/eval/ > is supposed to propagate
its effects, I find I don't really understand it.
In regcomp.c:S_reg(), we have:
case '{': /* (?{...}) */
{
[...]
if (PL_reginterp_cnt < ++RExC_seen_evals
&& IN_PERL_RUNTIME)
/* No compiled RE interpolated, has runtime
components ===> unsafe. */
FAIL("Eval-group not allowed at runtime, use re 'eval'")
.. so we rely on PL_reginterp_cnt to be set to some number greater than
the number of evals we have seen.
References to PL_reginterp_cnt are sparse; it is set to a non-zero value
in only two places; in sv.c:Perl_sv_2pv_flags() we have:
PL_reginterp_cnt += re->program[0].next_off;
in the case where the source is a qr{} compiled regexp, which isn't the
case here; and in pp_ctl.c:Perl_pp_regcomp() we have:
if (PL_op->op_flags & OPf_SPECIAL)
PL_reginterp_cnt = I32_MAX; /* Mark as safe. */
Going from the other end, we find that re.pm implements import('eval')
by setting HINT_RE_EVAL, and references to this are also rare, all in
op.c:Perl_pmruntime(), where we find that OPf_SPECIAL is set. But I
have no idea what Perl_pmruntime is supposed to do, or who is supposed
to call it - C< $var =~ /pattern/ > results (from perly.y) in a call
to op.c:Perl_bind_match(), which may call Perl_pmruntime(), but
doesn't in the test case above.
Since the code in op.c that checks HINT_RE_EVAL is never reached I'm
supposing that's where the problem lies - could someone with a clue
about who does what in op.c provide a hint?
hugo
> Going from the other end, we find that re.pm implements import('eval')
> by setting HINT_RE_EVAL, and references to this are also rare, all in
> op.c:Perl_pmruntime(), where we find that OPf_SPECIAL is set. But I
> have no idea what Perl_pmruntime is supposed to do, or who is supposed
> to call it - C< $var =~ /pattern/ > results (from perly.y) in a call
> to op.c:Perl_bind_match(), which may call Perl_pmruntime(), but
> doesn't in the test case above.
>
> Since the code in op.c that checks HINT_RE_EVAL is never reached I'm
> supposing that's where the problem lies - could someone with a clue
> about who does what in op.c provide a hint?
It looks to me like pmruntime called at compile time to set things up
for a regex to be compiled at runtime, e.g. "x" =~ $y.
I think fixing this may require mjd's lexical pragmas fix, since as is
the hint is only available at compile time and Damian's case needs it
at run time. Or find a way to *always* store the hint in the
match/subst/split op at compile time. Or store the hint if a regex
contains (??{}).
Thanks for the enlightenment.
The information is sort of available at runtime in PL_reginterp_cnt,
but choosing to propagate the hint state for the parent regexp rather
than that for the lexical scope seems like the wrong thing to do,
so I think this should probably wait until mjd's work makes it possible
to do it right.
Hugo