This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Handle literal code blocks in runtime regexes
authorDavid Mitchell <davem@iabyn.com>
Sat, 12 Nov 2011 20:51:27 +0000 (20:51 +0000)
committerDavid Mitchell <davem@iabyn.com>
Wed, 13 Jun 2012 12:25:52 +0000 (13:25 +0100)
commit346d3070ad0aa2f924e07bfdde6bb8809da64e45
tree30b7f0ab2b93b7eaaa34beb85ce8588872584fd8
parentb1603ef883c1cc16a978ec3c12aa376876ceb8d6
Handle literal code blocks in runtime regexes

In the following types of regex:

      /$runtime(?{...})/
    qr/$runtime(?{...})/

make it so that the code block is compiled at the same time that the
surrounding code is compiled, then is incorporated, rather than
re-compiled, when the regex source is assembled and compiled at runtime.

This fixes a bunch of closure-related TODO tests.

Note that this still doesn't yet handle the cases where $runtime contains:
    $runtime = qr/...(?{...})/; # block will be stringified and recompiled
    $runtime = '(?{...})';      # block compiled the old way, with
                                  matching nesting of {} required

It also doesn't yet handle the case where the pattern getting compiled is
upgraded to utf8 and so is restarted.

Note that this is rather complex, because in something like

    $str =~ qr/$a(?{...})$b[1]/

there are four separate phases

* perl compile time; we also compile the code block at the same time,
  but within a separate anon CV (with a separate pad)

* at run time, we execute the code that generates the list of SVs
  (i.e. $a, $b[1] etc), but have to execute them within the context of the
  anon sub, since that's what they were compiled in; we then have to
  concat the arguments, while remembering which were literal code blocks;

* then qr// clones the compiled regex, and clones the anon CV at the same
  time;

* finally, the pattern is executed.

Through all this we have to ensure that the code blocks and associated
anon CV and pad get preserved and incorporated into the right places
for eventual use.

The changes in this commit build upon the work in the previous few
commits, and work by:

* at (perl) compile time, in pmruntime(), the anon CV (if any) associated
  with a qr//, as well as being referred to by the op_targ of the
  anoncode op, is also made the targ of the regcomp op;

* at pattern assembly and compile time,
    * Perl_re_op_compile() takes the list of SVs gathered by pp_regcomp(),
      along with the op tree (from op_code_list) that was used to generate
      those SVs (as well as containing the individual DO blocks), and
      concatenates them to get a final pattern source string, while
      noting the start and end positions of any literal (?{..})'s,
      and which block they must correspond to.

    * after compilation, pp_regcomp() then uses op_targ to locate
      the anon CV and store a pointer to it in the regex.

qr// instantiation and execution work unchanged.
op.c
pp_ctl.c
regcomp.c
t/re/pat_re_eval.t