Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

implementation of C< use re 'eval' >

0 views
Skip to first unread message

h...@crypt.org

unread,
Mar 9, 2004, 10:43:32 PM3/9/04
to perl5-...@perl.org, h...@crypt.org
Damian has reported this:

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

Yitzchak Scott-Thoennes

unread,
Mar 9, 2004, 11:43:11 PM3/9/04
to h...@crypt.org, perl5-...@perl.org
On Wed, Mar 10, 2004 at 03:43:32AM +0000, h...@crypt.org wrote:
> Damian has reported this:
>
> 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.

> 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 (??{}).

h...@crypt.org

unread,
Mar 11, 2004, 11:45:00 AM3/11/04
to stho...@efn.org, perl5-...@perl.org
Yitzchak Scott-Thoennes <stho...@efn.org> wrote:

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

0 new messages