diff options
author | Yves Orton <demerphq@gmail.com> | 2006-09-29 14:41:26 +0200 |
---|---|---|
committer | H.Merijn Brand <h.m.brand@xs4all.nl> | 2006-09-29 12:29:24 +0000 |
commit | f9f4320a413e57e41ac9bf0d94d8c4e8dbe71ec8 (patch) | |
tree | 28f2158bf3db85ad65e1be291366af1df07fb5b6 | |
parent | dfeee9b153e7ebbeaa1e263dad19a3e5a819bacd (diff) | |
download | perl-f9f4320a413e57e41ac9bf0d94d8c4e8dbe71ec8.tar.gz |
Re: [PATCH] Add hook for re_dup() into regex engine as reg_dupe (make re pluggable under threads)
Message-ID: <9b18b3110609290341p11767110sec20a6fee2038a00@mail.gmail.com>
p4raw-id: //depot/perl@28900
-rw-r--r-- | MANIFEST | 2 | ||||
-rw-r--r-- | embed.fnc | 2 | ||||
-rw-r--r-- | embed.h | 12 | ||||
-rw-r--r-- | embedvar.h | 12 | ||||
-rw-r--r-- | ext/re/re.pm | 35 | ||||
-rw-r--r-- | ext/re/re.xs | 106 | ||||
-rw-r--r-- | ext/re/t/lexical_debug.pl | 25 | ||||
-rw-r--r-- | ext/re/t/lexical_debug.t | 30 | ||||
-rw-r--r-- | ext/re/t/re.t | 7 | ||||
-rw-r--r-- | op.c | 2 | ||||
-rw-r--r-- | perl.h | 28 | ||||
-rw-r--r-- | perlapi.h | 12 | ||||
-rw-r--r-- | pp.c | 4 | ||||
-rw-r--r-- | pp_ctl.c | 4 | ||||
-rw-r--r-- | pp_hot.c | 14 | ||||
-rw-r--r-- | proto.h | 2 | ||||
-rw-r--r-- | regcomp.c | 49 | ||||
-rw-r--r-- | regcomp.h | 23 | ||||
-rw-r--r-- | regcomp.pl | 8 | ||||
-rw-r--r-- | regexec.c | 33 | ||||
-rw-r--r-- | regexp.h | 29 | ||||
-rw-r--r-- | regnodes.h | 186 | ||||
-rw-r--r-- | sv.c | 12 | ||||
-rw-r--r-- | thrdvar.h | 16 |
24 files changed, 355 insertions, 298 deletions
@@ -985,6 +985,8 @@ ext/re/re_top.h re extension symbol hiding header ext/re/re.xs re extension external subroutines ext/re/t/regop.pl generate debug output for various patterns ext/re/t/regop.t test RE optimizations by scraping debug output +ext/re/t/lexical_debug.pl generate debug output for lexical re 'debug' +ext/re/t/lexical_debug.t test that lexical re 'debug' works ext/re/t/re.t see if re pragma works ext/Safe/t/safe1.t See if Safe works ext/Safe/t/safe2.t See if Safe works @@ -1362,7 +1362,9 @@ ERs |bool |reginclass |NULLOK const regexp *prog|NN const regnode *n|NN const U8 Es |CHECKPOINT|regcppush |I32 parenfloor Es |char* |regcppop |NN const regexp *rex ERsn |U8* |reghop3 |NN U8 *pos|I32 off|NN const U8 *lim +#ifdef XXX_dmq ERsn |U8* |reghop4 |NN U8 *pos|I32 off|NN const U8 *llim|NN const U8 *rlim +#endif ERsn |U8* |reghopmaybe3 |NN U8 *pos|I32 off|NN const U8 *lim ERs |char* |find_byclass |NN regexp * prog|NN const regnode *c|NN char *s|NN const char *strend|NULLOK const regmatch_info *reginfo Es |void |to_utf8_substr |NN regexp * prog @@ -1360,7 +1360,13 @@ #define regcppush S_regcppush #define regcppop S_regcppop #define reghop3 S_reghop3 +#endif +#ifdef XXX_dmq +#if defined(PERL_CORE) || defined(PERL_EXT) #define reghop4 S_reghop4 +#endif +#endif +#if defined(PERL_CORE) || defined(PERL_EXT) #define reghopmaybe3 S_reghopmaybe3 #define find_byclass S_find_byclass #define to_utf8_substr S_to_utf8_substr @@ -3551,7 +3557,13 @@ #define regcppush(a) S_regcppush(aTHX_ a) #define regcppop(a) S_regcppop(aTHX_ a) #define reghop3 S_reghop3 +#endif +#ifdef XXX_dmq +#if defined(PERL_CORE) || defined(PERL_EXT) #define reghop4 S_reghop4 +#endif +#endif +#if defined(PERL_CORE) || defined(PERL_EXT) #define reghopmaybe3 S_reghopmaybe3 #define find_byclass(a,b,c,d,e) S_find_byclass(aTHX_ a,b,c,d,e) #define to_utf8_substr(a) S_to_utf8_substr(aTHX_ a) diff --git a/embedvar.h b/embedvar.h index b38723863d..2aec5f091f 100644 --- a/embedvar.h +++ b/embedvar.h @@ -82,13 +82,7 @@ #define PL_opsave (vTHX->Topsave) #define PL_peepp (vTHX->Tpeepp) #define PL_reg_state (vTHX->Treg_state) -#define PL_regcompp (vTHX->Tregcompp) #define PL_regdummy (vTHX->Tregdummy) -#define PL_regdupe (vTHX->Tregdupe) -#define PL_regexecp (vTHX->Tregexecp) -#define PL_regfree (vTHX->Tregfree) -#define PL_regint_start (vTHX->Tregint_start) -#define PL_regint_string (vTHX->Tregint_string) #define PL_reginterp_cnt (vTHX->Treginterp_cnt) #define PL_regmatch_slab (vTHX->Tregmatch_slab) #define PL_regmatch_state (vTHX->Tregmatch_state) @@ -756,13 +750,7 @@ #define PL_Topsave PL_opsave #define PL_Tpeepp PL_peepp #define PL_Treg_state PL_reg_state -#define PL_Tregcompp PL_regcompp #define PL_Tregdummy PL_regdummy -#define PL_Tregdupe PL_regdupe -#define PL_Tregexecp PL_regexecp -#define PL_Tregfree PL_regfree -#define PL_Tregint_start PL_regint_start -#define PL_Tregint_string PL_regint_string #define PL_Treginterp_cnt PL_reginterp_cnt #define PL_Tregmatch_slab PL_regmatch_slab #define PL_Tregmatch_state PL_regmatch_state diff --git a/ext/re/re.pm b/ext/re/re.pm index ee262c6141..9fab039c04 100644 --- a/ext/re/re.pm +++ b/ext/re/re.pm @@ -215,6 +215,10 @@ sub setcolor { $colors =~ s/\0//g; $ENV{PERL_RE_COLORS} = $colors; }; + if ($@) { + $ENV{PERL_RE_COLORS}||=qq'\t\t> <\t> <\t\t' + } + } my %flags = ( @@ -241,31 +245,34 @@ $flags{More} = $flags{MORE} = $flags{All} | $flags{TRIE_MORE} | $flags{STATE}; $flags{State} = $flags{DUMP} | $flags{EXECUTE} | $flags{STATE}; $flags{TRIE} = $flags{DUMP} | $flags{EXECUTE} | $flags{TRIE_COMPILE}; -my $installed = 0; - -sub _load_unload { - my $on = shift; +my $installed =eval { require XSLoader; XSLoader::load('re'); - install($on); + install(); +}; + +sub _load_unload { + my ($on)= @_; + if ($on) { + die "'re' not installed!?" unless $installed; + #warn "installed: $installed\n"; + install(); # allow for changes in colors + $^H{regcomp}= $installed; + } else { + delete $^H{regcomp}; + } } sub bits { my $on = shift; my $bits = 0; unless (@_) { - require Carp; - Carp::carp("Useless use of \"re\" pragma"); + return; } foreach my $idx (0..$#_){ my $s=$_[$idx]; if ($s eq 'Debug' or $s eq 'Debugcolor') { - if ($s eq 'Debugcolor') { - setcolor(); - } else { - # $ENV{PERL_RE_COLORS}||=qq'\t\t> <\t> <\t\t' - } - + setcolor() if $s =~/color/i; ${^RE_DEBUG_FLAGS} = 0 unless defined ${^RE_DEBUG_FLAGS}; for my $idx ($idx+1..$#_) { if ($flags{$_[$idx]}) { @@ -283,7 +290,7 @@ sub bits { _load_unload($on ? 1 : ${^RE_DEBUG_FLAGS}); last; } elsif ($s eq 'debug' or $s eq 'debugcolor') { - setcolor() if $s eq 'debugcolor'; + setcolor() if $s =~/color/i; _load_unload($on); } elsif (exists $bitmask{$s}) { $bits |= $bitmask{$s}; diff --git a/ext/re/re.xs b/ext/re/re.xs index 3433a0fd7e..933296b10d 100644 --- a/ext/re/re.xs +++ b/ext/re/re.xs @@ -7,6 +7,7 @@ #include "perl.h" #include "XSUB.h" + START_EXTERN_C extern regexp* my_regcomp (pTHX_ char* exp, char* xend, PMOP* pm); @@ -19,104 +20,29 @@ extern char* my_re_intuit_start (pTHX_ regexp *prog, SV *sv, char *strpos, struct re_scream_pos_data_s *data); extern SV* my_re_intuit_string (pTHX_ regexp *prog); -extern regexp* my_regdupe (pTHX_ regexp *r, CLONE_PARAMS *param); - - -END_EXTERN_C - -/* engine details need to be paired - non debugging, debuggin */ -#define NEEDS_DEBUGGING 0x01 -struct regexp_engine { - regexp* (*regcomp) (pTHX_ char* exp, char* xend, PMOP* pm); - I32 (*regexec) (pTHX_ regexp* prog, char* stringarg, char* strend, - char* strbeg, I32 minend, SV* screamer, - void* data, U32 flags); - char* (*re_intuit_start) (pTHX_ regexp *prog, SV *sv, char *strpos, - char *strend, U32 flags, - struct re_scream_pos_data_s *data); - SV* (*re_intuit_string) (pTHX_ regexp *prog); - void (*regfree) (pTHX_ struct regexp* r); #if defined(USE_ITHREADS) - regexp* (*regdupe) (pTHX_ regexp *r, CLONE_PARAMS *param); +extern regexp* my_regdupe (pTHX_ const regexp *r, CLONE_PARAMS *param); #endif -}; -struct regexp_engine engines[] = { - { Perl_pregcomp, Perl_regexec_flags, Perl_re_intuit_start, - Perl_re_intuit_string, Perl_pregfree +const struct regexp_engine my_reg_engine = { + my_regcomp, + my_regexec, + my_re_intuit_start, + my_re_intuit_string, + my_regfree, #if defined(USE_ITHREADS) - , Perl_regdupe + my_regdupe #endif - }, - { my_regcomp, my_regexec, my_re_intuit_start, my_re_intuit_string, - my_regfree -#if defined(USE_ITHREADS) - , my_regdupe -#endif - } }; -#define MY_CXT_KEY "re::_guts" XS_VERSION - -typedef struct { - int x_oldflag; /* debug flag */ - unsigned int x_state; -} my_cxt_t; - -START_MY_CXT - -#define oldflag (MY_CXT.x_oldflag) - -static void -install(pTHX_ unsigned int new_state) -{ - dMY_CXT; - const unsigned int states - = sizeof(engines) / sizeof(struct regexp_engine) -1; - if(new_state == MY_CXT.x_state) - return; - - if (new_state > states) { - Perl_croak(aTHX_ "panic: re::install state %u is illegal - max is %u", - new_state, states); - } - - PL_regexecp = engines[new_state].regexec; - PL_regcompp = engines[new_state].regcomp; - PL_regint_start = engines[new_state].re_intuit_start; - PL_regint_string = engines[new_state].re_intuit_string; - PL_regfree = engines[new_state].regfree; -#if defined(USE_ITHREADS) - PL_regdupe = engines[new_state].regdupe; -#endif - - if (new_state & NEEDS_DEBUGGING) { - PL_colorset = 0; /* Allow reinspection of ENV. */ - if (!(MY_CXT.x_state & NEEDS_DEBUGGING)) { - /* Debugging is turned on for the first time. */ - oldflag = PL_debug & DEBUG_r_FLAG; - PL_debug |= DEBUG_r_FLAG; - } - } else { - if (!(MY_CXT.x_state & NEEDS_DEBUGGING)) { - if (!oldflag) - PL_debug &= ~DEBUG_r_FLAG; - } - } - - MY_CXT.x_state = new_state; -} +END_EXTERN_C MODULE = re PACKAGE = re -BOOT: -{ - MY_CXT_INIT; -} - - void -install(new_state) - unsigned int new_state; - CODE: - install(aTHX_ new_state); +install() + PPCODE: + PL_colorset = 0; /* Allow reinspection of ENV. */ + /* PL_debug |= DEBUG_r_FLAG; */ + XPUSHs(sv_2mortal(newSViv(PTR2IV(&my_reg_engine)))); + diff --git a/ext/re/t/lexical_debug.pl b/ext/re/t/lexical_debug.pl new file mode 100644 index 0000000000..c8b7c5bc67 --- /dev/null +++ b/ext/re/t/lexical_debug.pl @@ -0,0 +1,25 @@ +use re 'debug'; + +$_ = 'foo bar baz bop fip fop'; + +/foo/ and $count++; + +{ + no re 'debug'; + /bar/ and $count++; + { + use re 'debug'; + /baz/ and $count++; + } + /bop/ and $count++; +} + +/fip/ and $count++; + +no re 'debug'; + +/fop/ and $count++; + +print "Count=$count\n"; + + diff --git a/ext/re/t/lexical_debug.t b/ext/re/t/lexical_debug.t new file mode 100644 index 0000000000..affa7c50fc --- /dev/null +++ b/ext/re/t/lexical_debug.t @@ -0,0 +1,30 @@ +#!./perl + +BEGIN { + chdir 't' if -d 't'; + @INC = '../lib'; + require Config; + if (($Config::Config{'extensions'} !~ /\bre\b/) ){ + print "1..0 # Skip -- Perl configured without re module\n"; + exit 0; + } +} + +use strict; +require "./test.pl"; +my $out = runperl(progfile => "../ext/re/t/lexical_debug.pl", stderr => 1 ); + +print "1..7\n"; + +# Each pattern will produce an EXACT node with a specific string in +# it, so we will look for that. We can't just look for the string +# alone as the string being matched against contains all of them. + +ok( $out =~ /EXACT <foo>/, "Expect 'foo'"); +ok( $out !~ /EXACT <bar>/, "No 'bar'"); +ok( $out =~ /EXACT <baz>/, "Expect 'baz'"); +ok( $out !~ /EXACT <bop>/, "No 'bop'"); +ok( $out =~ /EXACT <fip>/, "Expect 'fip'"); +ok( $out !~ /EXACT <fop>/, "No 'baz'"); +ok( $out =~ /Count=6\n/,"Count is 6"); + diff --git a/ext/re/t/re.t b/ext/re/t/re.t index 5f09966d81..204092f028 100644 --- a/ext/re/t/re.t +++ b/ext/re/t/re.t @@ -12,7 +12,7 @@ BEGIN { use strict; -use Test::More tests => 14; +use Test::More tests => 13; require_ok( 're' ); # setcolor @@ -31,8 +31,8 @@ my $warn; local $SIG{__WARN__} = sub { $warn = shift; }; -eval { re::bits(1) }; -like( $warn, qr/Useless use/, 'bits() should warn with no args' ); +#eval { re::bits(1) }; +#like( $warn, qr/Useless use/, 'bits() should warn with no args' ); delete $ENV{PERL_RE_COLORS}; re::bits(0, 'debug'); @@ -65,7 +65,6 @@ my $ok='foo'=~/$reg/; eval"no re Debug=>'ALL'"; ok( $ok, 'No segv!' ); - package Term::Cap; sub Tgetent { @@ -3225,7 +3225,7 @@ Perl_pmruntime(pTHX_ OP *o, OP *expr, bool isreg) if (DO_UTF8(pat)) pm->op_pmdynflags |= PMdf_UTF8; /* FIXME - can we make this function take const char * args? */ - PM_SETRE(pm, CALLREGCOMP(aTHX_ (char*)p, (char*)p + plen, pm)); + PM_SETRE(pm, CALLREGCOMP((char*)p, (char*)p + plen, pm)); if (strEQ("\\s+", PM_GETRE(pm)->precomp)) pm->op_pmflags |= PMf_WHITE; #ifdef PERL_MAD @@ -195,12 +195,24 @@ #define CALL_FPTR(fptr) (*fptr) #define CALLRUNOPS CALL_FPTR(PL_runops) -#define CALLREGCOMP CALL_FPTR(PL_regcompp) -#define CALLREGEXEC CALL_FPTR(PL_regexecp) -#define CALLREG_INTUIT_START CALL_FPTR(PL_regint_start) -#define CALLREG_INTUIT_STRING CALL_FPTR(PL_regint_string) -#define CALLREGFREE CALL_FPTR(PL_regfree) -#define CALLREGDUPE CALL_FPTR(PL_regdupe) + +#define CALLREGCOMP(exp, xend, pm) Perl_pregcomp(aTHX_ exp,xend,pm) + +#define CALLREGEXEC(prog,stringarg,strend,strbeg,minend,screamer,data,flags) \ + CALL_FPTR((prog)->engine->regexec)(aTHX_ (prog),(stringarg),(strend), \ + (strbeg),(minend),(screamer),(data),(flags)) +#define CALLREG_INTUIT_START(prog,sv,strpos,strend,flags,data) \ + CALL_FPTR((prog)->engine->re_intuit_start)(aTHX_ (prog), (sv), (strpos), \ + (strend),(flags),(data)) +#define CALLREG_INTUIT_STRING(prog) \ + CALL_FPTR((prog)->engine->re_intuit_string)(aTHX_ (prog)) +#define CALLREGFREE(prog) \ + if(prog) CALL_FPTR((prog)->engine->regfree)(aTHX_ (prog)) +#if defined(USE_ITHREADS) +#define CALLREGDUPE(prog,param) \ + (prog ? CALL_FPTR((prog)->engine->regdupe)(aTHX_ (prog),(param)) \ + : (REGEXP *)NULL) +#endif /* * Because of backward compatibility reasons the PERL_UNUSED_DECL @@ -3499,7 +3511,11 @@ Gid_t getegid (void); } STMT_END # define DEBUG_f(a) DEBUG__(DEBUG_f_TEST, a) +#ifndef PERL_EXT_RE_BUILD # define DEBUG_r(a) DEBUG__(DEBUG_r_TEST, a) +#else +# define DEBUG_r(a) STMT_START {a;} STMT_END +#endif /* PERL_EXT_RE_BUILD */ # define DEBUG_x(a) DEBUG__(DEBUG_x_TEST, a) # define DEBUG_u(a) DEBUG__(DEBUG_u_TEST, a) # define DEBUG_H(a) DEBUG__(DEBUG_H_TEST, a) @@ -784,20 +784,8 @@ END_EXTERN_C #define PL_peepp (*Perl_Tpeepp_ptr(aTHX)) #undef PL_reg_state #define PL_reg_state (*Perl_Treg_state_ptr(aTHX)) -#undef PL_regcompp -#define PL_regcompp (*Perl_Tregcompp_ptr(aTHX)) #undef PL_regdummy #define PL_regdummy (*Perl_Tregdummy_ptr(aTHX)) -#undef PL_regdupe -#define PL_regdupe (*Perl_Tregdupe_ptr(aTHX)) -#undef PL_regexecp -#define PL_regexecp (*Perl_Tregexecp_ptr(aTHX)) -#undef PL_regfree -#define PL_regfree (*Perl_Tregfree_ptr(aTHX)) -#undef PL_regint_start -#define PL_regint_start (*Perl_Tregint_start_ptr(aTHX)) -#undef PL_regint_string -#define PL_regint_string (*Perl_Tregint_string_ptr(aTHX)) #undef PL_reginterp_cnt #define PL_reginterp_cnt (*Perl_Treginterp_cnt_ptr(aTHX)) #undef PL_regmatch_slab @@ -4638,7 +4638,7 @@ PP(pp_split) && (rx->reganch & ROPT_CHECK_ALL) && !(rx->reganch & ROPT_ANCH)) { const int tail = (rx->reganch & RE_INTUIT_TAIL); - SV * const csv = CALLREG_INTUIT_STRING(aTHX_ rx); + SV * const csv = CALLREG_INTUIT_STRING(rx); len = rx->minlen; if (len == 1 && !(rx->reganch & ROPT_UTF8) && !tail) { @@ -4688,7 +4688,7 @@ PP(pp_split) { I32 rex_return; PUTBACK; - rex_return = CALLREGEXEC(aTHX_ rx, (char*)s, (char*)strend, (char*)orig, 1 , + rex_return = CALLREGEXEC(rx, (char*)s, (char*)strend, (char*)orig, 1 , sv, NULL, 0); SPAGAIN; if (rex_return == 0) @@ -146,7 +146,7 @@ PP(pp_regcomp) if (pm->op_pmdynflags & PMdf_UTF8) t = (char*)bytes_to_utf8((U8*)t, &len); } - PM_SETRE(pm, CALLREGCOMP(aTHX_ (char *)t, (char *)t + len, pm)); + PM_SETRE(pm, CALLREGCOMP((char *)t, (char *)t + len, pm)); if (!DO_UTF8(tmpstr) && (pm->op_pmdynflags & PMdf_UTF8)) Safefree(t); PL_reginterp_cnt = 0; /* XXXX Be extra paranoid - needed @@ -214,7 +214,7 @@ PP(pp_substcont) FREETMPS; /* Prevent excess tmp stack */ /* Are we done */ - if (cx->sb_once || !CALLREGEXEC(aTHX_ rx, s, cx->sb_strend, orig, + if (cx->sb_once || !CALLREGEXEC(rx, s, cx->sb_strend, orig, s == m, cx->sb_targ, NULL, ((cx->sb_rflags & REXEC_COPY_STR) ? (REXEC_IGNOREPOS|REXEC_NOT_FIRST) @@ -1371,7 +1371,7 @@ play_it_again: DO_UTF8(TARG) == ((rx->reganch & ROPT_UTF8) != 0)) { /* FIXME - can PL_bostr be made const char *? */ PL_bostr = (char *)truebase; - s = CALLREG_INTUIT_START(aTHX_ rx, TARG, (char *)s, (char *)strend, r_flags, NULL); + s = CALLREG_INTUIT_START(rx, TARG, (char *)s, (char *)strend, r_flags, NULL); if (!s) goto nope; @@ -1383,7 +1383,7 @@ play_it_again: && !SvROK(TARG)) /* Cannot trust since INTUIT cannot guess ^ */ goto yup; } - if (CALLREGEXEC(aTHX_ rx, (char*)s, (char *)strend, (char*)truebase, minmatch, TARG, NULL, r_flags)) + if (CALLREGEXEC(rx, (char*)s, (char *)strend, (char*)truebase, minmatch, TARG, NULL, r_flags)) { PL_curpm = pm; if (dynpm->op_pmflags & PMf_ONCE) @@ -2139,7 +2139,7 @@ PP(pp_subst) orig = m = s; if (rx->reganch & RE_USE_INTUIT) { PL_bostr = orig; - s = CALLREG_INTUIT_START(aTHX_ rx, TARG, s, strend, r_flags, NULL); + s = CALLREG_INTUIT_START(rx, TARG, s, strend, r_flags, NULL); if (!s) goto nope; @@ -2187,7 +2187,7 @@ PP(pp_subst) && (I32)clen <= rx->minlen && (once || !(r_flags & REXEC_COPY_STR)) && !(rx->reganch & ROPT_LOOKBEHIND_SEEN) && (!doutf8 || SvUTF8(TARG))) { - if (!CALLREGEXEC(aTHX_ rx, s, strend, orig, 0, TARG, NULL, + if (!CALLREGEXEC(rx, s, strend, orig, 0, TARG, NULL, r_flags | REXEC_CHECKED)) { SPAGAIN; @@ -2265,7 +2265,7 @@ PP(pp_subst) d += clen; } s = rx->endp[0] + orig; - } while (CALLREGEXEC(aTHX_ rx, s, strend, orig, s == m, + } while (CALLREGEXEC(rx, s, strend, orig, s == m, TARG, NULL, /* don't match same null twice */ REXEC_NOT_FIRST|REXEC_IGNOREPOS)); @@ -2292,7 +2292,7 @@ PP(pp_subst) RETURN; } - if (CALLREGEXEC(aTHX_ rx, s, strend, orig, 0, TARG, NULL, + if (CALLREGEXEC(rx, s, strend, orig, 0, TARG, NULL, r_flags | REXEC_CHECKED)) { if (force_on_match) { @@ -2337,7 +2337,7 @@ PP(pp_subst) sv_catpvn(dstr, c, clen); if (once) break; - } while (CALLREGEXEC(aTHX_ rx, s, strend, orig, s == m, + } while (CALLREGEXEC(rx, s, strend, orig, s == m, TARG, NULL, r_flags)); if (doutf8 && !DO_UTF8(TARG)) sv_catpvn_utf8_upgrade(dstr, s, strend - s, nsv); @@ -3718,12 +3718,14 @@ STATIC U8* S_reghop3(U8 *pos, I32 off, const U8 *lim) __attribute__nonnull__(1) __attribute__nonnull__(3); +#ifdef XXX_dmq STATIC U8* S_reghop4(U8 *pos, I32 off, const U8 *llim, const U8 *rlim) __attribute__warn_unused_result__ __attribute__nonnull__(1) __attribute__nonnull__(3) __attribute__nonnull__(4); +#endif STATIC U8* S_reghopmaybe3(U8 *pos, I32 off, const U8 *lim) __attribute__warn_unused_result__ __attribute__nonnull__(1) @@ -3669,6 +3669,7 @@ Perl_reginitcolors(pTHX) #else #define CHECK_RESTUDY_GOTO #endif + /* - pregcomp - compile a regular expression into internal code * @@ -3684,10 +3685,37 @@ Perl_reginitcolors(pTHX) * Beware that the optimization-preparation code in here knows about some * of the structure of the compiled regexp. [I'll say.] */ +#ifndef PERL_IN_XSUB_RE +#define CORE_ONLY_BLOCK(c) {c}{ +#define RE_ENGINE_PTR &PL_core_reg_engine +#else +#define CORE_ONLY_BLOCK(c) { +extern const struct regexp_engine my_reg_engine; +#define RE_ENGINE_PTR &my_reg_engine +#endif +#define END_BLOCK } + regexp * Perl_pregcomp(pTHX_ char *exp, char *xend, PMOP *pm) { dVAR; + GET_RE_DEBUG_FLAGS_DECL; + DEBUG_r(if (!PL_colorset) reginitcolors()); + CORE_ONLY_BLOCK( + /* Dispatch a request to compile a regexp to correct + regexp engine. */ + HV * const table = GvHV(PL_hintgv); + if (table) { + SV **ptr= hv_fetchs(table, "regcomp", FALSE); + if (ptr && SvIOK(*ptr)) { + const regexp_engine *eng=INT2PTR(regexp_engine*,SvIV(*ptr)); + DEBUG_COMPILE_r({ + PerlIO_printf(Perl_debug_log, "Using engine %"IVxf"\n", + SvIV(*ptr)); + }); + return CALL_FPTR((eng->regcomp))(aTHX_ exp, xend, pm); + } + }) register regexp *r; regnode *scan; regnode *first; @@ -3702,16 +3730,12 @@ Perl_pregcomp(pTHX_ char *exp, char *xend, PMOP *pm) int restudied= 0; RExC_state_t copyRExC_state; #endif - - GET_RE_DEBUG_FLAGS_DECL; - if (exp == NULL) FAIL("NULL regexp argument"); RExC_utf8 = pm->op_pmdynflags & PMdf_CMP_UTF8; RExC_precomp = exp; - DEBUG_r(if (!PL_colorset) reginitcolors()); DEBUG_COMPILE_r({ SV *dsv= sv_newmortal(); RE_PV_QUOTED_DECL(s, RExC_utf8, @@ -3765,16 +3789,19 @@ Perl_pregcomp(pTHX_ char *exp, char *xend, PMOP *pm) if (RExC_whilem_seen > 15) RExC_whilem_seen = 15; - /* Allocate space and initialize. */ + /* Allocate space and zero-initialize. Note, the two step process + of zeroing when in debug mode, thus anything assigned has to + happen after that */ Newxc(r, sizeof(regexp) + (unsigned)RExC_size * sizeof(regnode), char, regexp); if (r == NULL) FAIL("Regexp out of space"); - #ifdef DEBUGGING /* avoid reading uninitialized memory in DEBUGGING code in study_chunk() */ Zero(r, sizeof(regexp) + (unsigned)RExC_size * sizeof(regnode), char); #endif + /* initialization begins here */ + r->engine= RE_ENGINE_PTR; r->refcnt = 1; r->prelen = xend - exp; r->precomp = savepvn(RExC_precomp, r->prelen); @@ -4209,6 +4236,8 @@ reStudy: r->reganch |= ROPT_CANY_SEEN; Newxz(r->startp, RExC_npar, I32); Newxz(r->endp, RExC_npar, I32); + + if (RExC_charnames) SvREFCNT_dec((SV*)(RExC_charnames)); @@ -4230,8 +4259,12 @@ reStudy: PerlIO_printf(Perl_debug_log, "\n"); }); return(r); + END_BLOCK } +#undef CORE_ONLY_BLOCK +#undef END_BLOCK +#undef RE_ENGINE_PTR #define DEBUG_PARSE_MSG(funcname) DEBUG_PARSE_r({ \ int rem=(int)(RExC_end - RExC_parse); \ @@ -7676,7 +7709,6 @@ Perl_pregfree(pTHX_ struct regexp *r) See pregfree() above if you change anything here. */ - #if defined(USE_ITHREADS) regexp * Perl_regdupe(pTHX_ const regexp *r, CLONE_PARAMS *param) @@ -7792,6 +7824,8 @@ Perl_regdupe(pTHX_ const regexp *r, CLONE_PARAMS *param) ret->sublen = r->sublen; + ret->engine = r->engine; + if (RX_MATCH_COPIED(ret)) ret->subbeg = SAVEPVN(r->subbeg, r->sublen); else @@ -7802,7 +7836,6 @@ Perl_regdupe(pTHX_ const regexp *r, CLONE_PARAMS *param) ptr_table_store(PL_ptr_table, r, ret); return ret; - return NULL; } #endif @@ -364,13 +364,26 @@ EXTCONST U8 PL_simple[] = { }; #endif +#ifndef PLUGGABLE_RE_EXTENSION +#ifndef DOINIT +EXTCONST regexp_engine PL_core_reg_engine; +#else /* DOINIT */ +EXTCONST regexp_engine PL_core_reg_engine = { + Perl_pregcomp, + Perl_regexec_flags, + Perl_re_intuit_start, + Perl_re_intuit_string, + Perl_pregfree, +#if defined(USE_ITHREADS) + Perl_regdupe +#endif +}; +#endif /* DOINIT */ +#endif /* PLUGGABLE_RE_EXTENSION */ + + END_EXTERN_C -typedef struct re_scream_pos_data_s -{ - char **scream_olds; /* match pos */ - I32 *scream_pos; /* Internal iterator of scream. */ -} re_scream_pos_data; /* .what is a character array with one character for each member of .data * The character describes the function of the corresponding .data item: diff --git a/regcomp.pl b/regcomp.pl index bfea6e25cd..2884971115 100644 --- a/regcomp.pl +++ b/regcomp.pl @@ -86,12 +86,14 @@ printf OUT <<EOP, #define %*s\t%d EOP --$width,REGNODE_MAX=>$lastregop-1,-$width,REGMATCH_STATE_MAX=>$tot-1; + -$width, REGNODE_MAX => $lastregop - 1, + -$width, REGMATCH_STATE_MAX => $tot - 1 +; $ind = 0; while (++$ind <= $tot) { my $oind = $ind - 1; - printf OUT "#define\t%*s\t%d\t/*%#04x %s*/\n", + printf OUT "#define\t%*s\t%d\t/* %#04x %s */\n", -$width, $name[$ind], $ind-1, $ind-1, $rest[$ind]; print OUT "\n\t/* ------------ States ------------- */\n\n" if $ind == $lastregop and $lastregop != $tot; @@ -150,7 +152,7 @@ print OUT <<EOP; }; #ifdef DEBUGGING -extern const char * const reg_name[] = { +const char * const reg_name[] = { EOP $ind = 0; @@ -1637,7 +1637,7 @@ Perl_regexec_flags(pTHX_ register regexp *prog, char *stringarg, register char * I32 scream_pos = -1; /* Internal iterator of scream. */ char *scream_olds = NULL; SV* const oreplsv = GvSV(PL_replgv); - const bool do_utf8 = DO_UTF8(sv); + const bool do_utf8 = (bool)DO_UTF8(sv); I32 multiline; regmatch_info reginfo; /* create some info to pass to regtry etc */ @@ -1773,7 +1773,11 @@ Perl_regexec_flags(pTHX_ register regexp *prog, char *stringarg, register char * } } goto phooey; - } else if (prog->reganch & ROPT_ANCH_GPOS) { + } else if (ROPT_GPOS_CHECK == (prog->reganch & ROPT_GPOS_CHECK)) + { + /* the warning about reginfo.ganch being used without intialization + is bogus -- we set it above, when prog->reganch & ROPT_GPOS_SEEN + and we only enter this block when the same bit is set. */ if (regtry(®info, reginfo.ganch)) goto got_it; goto phooey; @@ -2203,13 +2207,13 @@ S_regtry(pTHX_ const regmatch_info *reginfo, char *startpos) #define sayNO_SILENT goto do_no #define saySAME(x) if (x) goto yes; else goto no -#define CACHEsayNO STMT_START { \ +/* we dont use STMT_START/END here because it leads to + "unreachable code" warnings, which are bogus, but distracting. */ +#define CACHEsayNO \ if (st->u.whilem.cache_offset | st->u.whilem.cache_bit) \ PL_reg_poscache[st->u.whilem.cache_offset] |= \ (1<<st->u.whilem.cache_bit); \ - sayNO; \ -} STMT_END - + sayNO /* this is used to determine how far from the left messages like 'failed...' are printed. It should be set such that messages @@ -2472,7 +2476,7 @@ S_dump_exec_pos(pTHX_ const char *locinput, len1, s1, (docolor ? "" : "> <"), len2, s2, - tlen > 19 ? 0 : 19 - tlen, + (int)(tlen > 19 ? 0 : 19 - tlen), ""); } } @@ -2715,7 +2719,7 @@ S_regmatch(pTHX_ const regmatch_info *reginfo, regnode *prog) while ( state && uc <= (U8*)PL_regeol ) { U32 base = trie->states[ state ].trans.base; - UV uvc; + UV uvc = 0; U16 charid; /* We use charid to hold the wordnum as we don't use it for charid until after we have done the wordnum logic. @@ -3389,7 +3393,7 @@ S_regmatch(pTHX_ const regmatch_info *reginfo, regnode *prog) Zero(&pm, 1, PMOP); if (DO_UTF8(ret)) pm.op_pmdynflags |= PMdf_DYN_UTF8; - re = CALLREGCOMP(aTHX_ (char*)t, (char*)t + len, &pm); + re = CALLREGCOMP((char*)t, (char*)t + len, &pm); if (!(SvFLAGS(ret) & (SVs_TEMP | SVs_PADTMP | SVf_READONLY | SVs_GMG))) @@ -3434,7 +3438,7 @@ S_regmatch(pTHX_ const regmatch_info *reginfo, regnode *prog) /* NOTREACHED */ } /* /(?(?{...})X|Y)/ */ - st->sw = SvTRUE(ret); + st->sw = (bool)SvTRUE(ret); st->logical = 0; break; } @@ -3484,7 +3488,7 @@ S_regmatch(pTHX_ const regmatch_info *reginfo, regnode *prog) break; case GROUPP: n = ARG(scan); /* which paren pair */ - st->sw = ((I32)*PL_reglastparen >= n && PL_regendp[n] != -1); + st->sw = (bool)((I32)*PL_reglastparen >= n && PL_regendp[n] != -1); break; case IFTHEN: PL_reg_leftiter = PL_reg_maxiter; /* Void cache */ @@ -5178,6 +5182,11 @@ S_reghop3(U8 *s, I32 off, const U8* lim) return s; } +#ifdef XXX_dmq +/* there are a bunch of places where we use two reghop3's that should + be replaced with this routine. but since thats not done yet + we ifdef it out - dmq +*/ STATIC U8 * S_reghop4(U8 *s, I32 off, const U8* llim, const U8* rlim) { @@ -5200,7 +5209,7 @@ S_reghop4(U8 *s, I32 off, const U8* llim, const U8* rlim) } return s; } - +#endif STATIC U8 * S_reghopmaybe3(U8* s, I32 off, const U8* lim) @@ -30,6 +30,8 @@ struct reg_substr_data; struct reg_data; +struct regexp_engine; + typedef struct regexp { I32 *startp; I32 *endp; @@ -52,9 +54,32 @@ typedef struct regexp { U32 lastcloseparen; /* last paren matched */ U32 reganch; /* Internal use only + Tainted information used by regexec? */ + const struct regexp_engine* engine; regnode program[1]; /* Unwarranted chumminess with compiler. */ } regexp; + +typedef struct re_scream_pos_data_s +{ + char **scream_olds; /* match pos */ + I32 *scream_pos; /* Internal iterator of scream. */ +} re_scream_pos_data; + +typedef struct regexp_engine { + regexp* (*regcomp) (pTHX_ char* exp, char* xend, PMOP* pm); + I32 (*regexec) (pTHX_ regexp* prog, char* stringarg, char* strend, + char* strbeg, I32 minend, SV* screamer, + void* data, U32 flags); + char* (*re_intuit_start) (pTHX_ regexp *prog, SV *sv, char *strpos, + char *strend, U32 flags, + struct re_scream_pos_data_s *data); + SV* (*re_intuit_string) (pTHX_ regexp *prog); + void (*regfree) (pTHX_ struct regexp* r); +#if defined(USE_ITHREADS) + regexp* (*regdupe) (pTHX_ const regexp *r, CLONE_PARAMS *param); +#endif +} regexp_engine; + #define ROPT_ANCH (ROPT_ANCH_BOL|ROPT_ANCH_MBOL|ROPT_ANCH_GPOS|ROPT_ANCH_SBOL) #define ROPT_ANCH_SINGLE (ROPT_ANCH_SBOL|ROPT_ANCH_GPOS) #define ROPT_ANCH_BOL 0x00000001 @@ -70,6 +95,7 @@ typedef struct regexp { #define ROPT_EVAL_SEEN 0x00000400 #define ROPT_CANY_SEEN 0x00000800 #define ROPT_SANY_SEEN ROPT_CANY_SEEN /* src bckwrd cmpt */ +#define ROPT_GPOS_CHECK (ROPT_GPOS_SEEN|ROPT_ANCH_GPOS) /* 0xf800 of reganch is used by PMf_COMPILETIME */ @@ -106,6 +132,7 @@ typedef struct regexp { #define RX_MATCH_COPIED_set(prog,t) ((t) \ ? RX_MATCH_COPIED_on(prog) \ : RX_MATCH_COPIED_off(prog)) + #endif /* PLUGGABLE_RE_EXTENSION */ /* Stuff that needs to be included in the plugable extension goes below here */ @@ -145,7 +172,7 @@ typedef struct regexp { #define REXEC_NOT_FIRST 0x10 /* This is another iteration of //g. */ #define ReREFCNT_inc(re) ((void)(re && re->refcnt++), re) -#define ReREFCNT_dec(re) CALLREGFREE(aTHX_ re) +#define ReREFCNT_dec(re) CALLREGFREE(re) #define FBMcf_TAIL_DOLLAR 1 #define FBMcf_TAIL_DOLLARM 2 diff --git a/regnodes.h b/regnodes.h index b967287a95..31286f9c84 100644 --- a/regnodes.h +++ b/regnodes.h @@ -7,101 +7,101 @@ #define REGNODE_MAX 66 #define REGMATCH_STATE_MAX 91 -#define END 0 /*0000 End of program.*/ -#define SUCCEED 1 /*0x01 Return from a subroutine, basically.*/ -#define BOL 2 /*0x02 Match "" at beginning of line.*/ -#define MBOL 3 /*0x03 Same, assuming multiline.*/ -#define SBOL 4 /*0x04 Same, assuming singleline.*/ -#define EOS 5 /*0x05 Match "" at end of string.*/ -#define EOL 6 /*0x06 Match "" at end of line.*/ -#define MEOL 7 /*0x07 Same, assuming multiline.*/ -#define SEOL 8 /*0x08 Same, assuming singleline.*/ -#define BOUND 9 /*0x09 Match "" at any word boundary*/ -#define BOUNDL 10 /*0x0a Match "" at any word boundary*/ -#define NBOUND 11 /*0x0b Match "" at any word non-boundary*/ -#define NBOUNDL 12 /*0x0c Match "" at any word non-boundary*/ -#define GPOS 13 /*0x0d Matches where last m//g left off.*/ -#define REG_ANY 14 /*0x0e Match any one character (except newline).*/ -#define SANY 15 /*0x0f Match any one character.*/ -#define CANY 16 /*0x10 Match any one byte.*/ -#define ANYOF 17 /*0x11 Match character in (or not in) this class.*/ -#define ALNUM 18 /*0x12 Match any alphanumeric character*/ -#define ALNUML 19 /*0x13 Match any alphanumeric char in locale*/ -#define NALNUM 20 /*0x14 Match any non-alphanumeric character*/ -#define NALNUML 21 /*0x15 Match any non-alphanumeric char in locale*/ -#define SPACE 22 /*0x16 Match any whitespace character*/ -#define SPACEL 23 /*0x17 Match any whitespace char in locale*/ -#define NSPACE 24 /*0x18 Match any non-whitespace character*/ -#define NSPACEL 25 /*0x19 Match any non-whitespace char in locale*/ -#define DIGIT 26 /*0x1a Match any numeric character*/ -#define DIGITL 27 /*0x1b Match any numeric character in locale*/ -#define NDIGIT 28 /*0x1c Match any non-numeric character*/ -#define NDIGITL 29 /*0x1d Match any non-numeric character in locale*/ -#define CLUMP 30 /*0x1e Match any combining character sequence*/ -#define BRANCH 31 /*0x1f Match this alternative, or the next...*/ -#define BACK 32 /*0x20 Match "", "next" ptr points backward.*/ -#define EXACT 33 /*0x21 Match this string (preceded by length).*/ -#define EXACTF 34 /*0x22 Match this string, folded (prec. by length).*/ -#define EXACTFL 35 /*0x23 Match this string, folded in locale (w/len).*/ -#define NOTHING 36 /*0x24 Match empty string.*/ -#define TAIL 37 /*0x25 Match empty string. Can jump here from outside.*/ -#define STAR 38 /*0x26 Match this (simple) thing 0 or more times.*/ -#define PLUS 39 /*0x27 Match this (simple) thing 1 or more times.*/ -#define CURLY 40 /*0x28 Match this simple thing {n,m} times.*/ -#define CURLYN 41 /*0x29 Match next-after-this simple thing*/ -#define CURLYM 42 /*0x2a Match this medium-complex thing {n,m} times.*/ -#define CURLYX 43 /*0x2b Match this complex thing {n,m} times.*/ -#define WHILEM 44 /*0x2c Do curly processing and see if rest matches.*/ -#define OPEN 45 /*0x2d Mark this point in input as start of*/ -#define CLOSE 46 /*0x2e Analogous to OPEN.*/ -#define REF 47 /*0x2f Match some already matched string*/ -#define REFF 48 /*0x30 Match already matched string, folded*/ -#define REFFL 49 /*0x31 Match already matched string, folded in loc.*/ -#define IFMATCH 50 /*0x32 Succeeds if the following matches.*/ -#define UNLESSM 51 /*0x33 Fails if the following matches.*/ -#define SUSPEND 52 /*0x34 "Independent" sub-RE.*/ -#define IFTHEN 53 /*0x35 Switch, should be preceeded by switcher .*/ -#define GROUPP 54 /*0x36 Whether the group matched.*/ -#define LONGJMP 55 /*0x37 Jump far away.*/ -#define BRANCHJ 56 /*0x38 BRANCH with long offset.*/ -#define EVAL 57 /*0x39 Execute some Perl code.*/ -#define MINMOD 58 /*0x3a Next operator is not greedy.*/ -#define LOGICAL 59 /*0x3b Next opcode should set the flag only.*/ -#define RENUM 60 /*0x3c Group with independently numbered parens.*/ -#define TRIE 61 /*0x3d Match many EXACT(FL?)? at once. flags==type*/ -#define TRIEC 62 /*0x3e Same as TRIE, but with embedded charclass data*/ -#define AHOCORASICK 63 /*0x3f Aho Corasick stclass. flags==type*/ -#define AHOCORASICKC 64 /*0x40 Same as AHOCORASICK, but with embedded charclass data*/ -#define OPTIMIZED 65 /*0x41 Placeholder for dump.*/ -#define PSEUDO 66 /*0x42 Pseudo opcode for internal use.*/ +#define END 0 /* 0000 End of program. */ +#define SUCCEED 1 /* 0x01 Return from a subroutine, basically. */ +#define BOL 2 /* 0x02 Match "" at beginning of line. */ +#define MBOL 3 /* 0x03 Same, assuming multiline. */ +#define SBOL 4 /* 0x04 Same, assuming singleline. */ +#define EOS 5 /* 0x05 Match "" at end of string. */ +#define EOL 6 /* 0x06 Match "" at end of line. */ +#define MEOL 7 /* 0x07 Same, assuming multiline. */ +#define SEOL 8 /* 0x08 Same, assuming singleline. */ +#define BOUND 9 /* 0x09 Match "" at any word boundary */ +#define BOUNDL 10 /* 0x0a Match "" at any word boundary */ +#define NBOUND 11 /* 0x0b Match "" at any word non-boundary */ +#define NBOUNDL 12 /* 0x0c Match "" at any word non-boundary */ +#define GPOS 13 /* 0x0d Matches where last m//g left off. */ +#define REG_ANY 14 /* 0x0e Match any one character (except newline). */ +#define SANY 15 /* 0x0f Match any one character. */ +#define CANY 16 /* 0x10 Match any one byte. */ +#define ANYOF 17 /* 0x11 Match character in (or not in) this class. */ +#define ALNUM 18 /* 0x12 Match any alphanumeric character */ +#define ALNUML 19 /* 0x13 Match any alphanumeric char in locale */ +#define NALNUM 20 /* 0x14 Match any non-alphanumeric character */ +#define NALNUML 21 /* 0x15 Match any non-alphanumeric char in locale */ +#define SPACE 22 /* 0x16 Match any whitespace character */ +#define SPACEL 23 /* 0x17 Match any whitespace char in locale */ +#define NSPACE 24 /* 0x18 Match any non-whitespace character */ +#define NSPACEL 25 /* 0x19 Match any non-whitespace char in locale */ +#define DIGIT 26 /* 0x1a Match any numeric character */ +#define DIGITL 27 /* 0x1b Match any numeric character in locale */ +#define NDIGIT 28 /* 0x1c Match any non-numeric character */ +#define NDIGITL 29 /* 0x1d Match any non-numeric character in locale */ +#define CLUMP 30 /* 0x1e Match any combining character sequence */ +#define BRANCH 31 /* 0x1f Match this alternative, or the next... */ +#define BACK 32 /* 0x20 Match "", "next" ptr points backward. */ +#define EXACT 33 /* 0x21 Match this string (preceded by length). */ +#define EXACTF 34 /* 0x22 Match this string, folded (prec. by length). */ +#define EXACTFL 35 /* 0x23 Match this string, folded in locale (w/len). */ +#define NOTHING 36 /* 0x24 Match empty string. */ +#define TAIL 37 /* 0x25 Match empty string. Can jump here from outside. */ +#define STAR 38 /* 0x26 Match this (simple) thing 0 or more times. */ +#define PLUS 39 /* 0x27 Match this (simple) thing 1 or more times. */ +#define CURLY 40 /* 0x28 Match this simple thing {n,m} times. */ +#define CURLYN 41 /* 0x29 Match next-after-this simple thing */ +#define CURLYM 42 /* 0x2a Match this medium-complex thing {n,m} times. */ +#define CURLYX 43 /* 0x2b Match this complex thing {n,m} times. */ +#define WHILEM 44 /* 0x2c Do curly processing and see if rest matches. */ +#define OPEN 45 /* 0x2d Mark this point in input as start of */ +#define CLOSE 46 /* 0x2e Analogous to OPEN. */ +#define REF 47 /* 0x2f Match some already matched string */ +#define REFF 48 /* 0x30 Match already matched string, folded */ +#define REFFL 49 /* 0x31 Match already matched string, folded in loc. */ +#define IFMATCH 50 /* 0x32 Succeeds if the following matches. */ +#define UNLESSM 51 /* 0x33 Fails if the following matches. */ +#define SUSPEND 52 /* 0x34 "Independent" sub-RE. */ +#define IFTHEN 53 /* 0x35 Switch, should be preceeded by switcher . */ +#define GROUPP 54 /* 0x36 Whether the group matched. */ +#define LONGJMP 55 /* 0x37 Jump far away. */ +#define BRANCHJ 56 /* 0x38 BRANCH with long offset. */ +#define EVAL 57 /* 0x39 Execute some Perl code. */ +#define MINMOD 58 /* 0x3a Next operator is not greedy. */ +#define LOGICAL 59 /* 0x3b Next opcode should set the flag only. */ +#define RENUM 60 /* 0x3c Group with independently numbered parens. */ +#define TRIE 61 /* 0x3d Match many EXACT(FL?)? at once. flags==type */ +#define TRIEC 62 /* 0x3e Same as TRIE, but with embedded charclass data */ +#define AHOCORASICK 63 /* 0x3f Aho Corasick stclass. flags==type */ +#define AHOCORASICKC 64 /* 0x40 Same as AHOCORASICK, but with embedded charclass data */ +#define OPTIMIZED 65 /* 0x41 Placeholder for dump. */ +#define PSEUDO 66 /* 0x42 Pseudo opcode for internal use. */ /* ------------ States ------------- */ -#define TRIE_next 67 /*0x43 Regmatch state for TRIE*/ -#define TRIE_next_fail 68 /*0x44 Regmatch state for TRIE*/ -#define EVAL_AB 69 /*0x45 Regmatch state for EVAL*/ -#define EVAL_AB_fail 70 /*0x46 Regmatch state for EVAL*/ -#define resume_CURLYX 71 /*0x47 Regmatch state for CURLYX*/ -#define resume_WHILEM1 72 /*0x48 Regmatch state for WHILEM*/ -#define resume_WHILEM2 73 /*0x49 Regmatch state for WHILEM*/ -#define resume_WHILEM3 74 /*0x4a Regmatch state for WHILEM*/ -#define resume_WHILEM4 75 /*0x4b Regmatch state for WHILEM*/ -#define resume_WHILEM5 76 /*0x4c Regmatch state for WHILEM*/ -#define resume_WHILEM6 77 /*0x4d Regmatch state for WHILEM*/ -#define BRANCH_next 78 /*0x4e Regmatch state for BRANCH*/ -#define BRANCH_next_fail 79 /*0x4f Regmatch state for BRANCH*/ -#define CURLYM_A 80 /*0x50 Regmatch state for CURLYM*/ -#define CURLYM_A_fail 81 /*0x51 Regmatch state for CURLYM*/ -#define CURLYM_B 82 /*0x52 Regmatch state for CURLYM*/ -#define CURLYM_B_fail 83 /*0x53 Regmatch state for CURLYM*/ -#define IFMATCH_A 84 /*0x54 Regmatch state for IFMATCH*/ -#define IFMATCH_A_fail 85 /*0x55 Regmatch state for IFMATCH*/ -#define CURLY_B_min_known 86 /*0x56 Regmatch state for CURLY*/ -#define CURLY_B_min_known_fail 87 /*0x57 Regmatch state for CURLY*/ -#define CURLY_B_min 88 /*0x58 Regmatch state for CURLY*/ -#define CURLY_B_min_fail 89 /*0x59 Regmatch state for CURLY*/ -#define CURLY_B_max 90 /*0x5a Regmatch state for CURLY*/ -#define CURLY_B_max_fail 91 /*0x5b Regmatch state for CURLY*/ +#define TRIE_next 67 /* 0x43 Regmatch state for TRIE */ +#define TRIE_next_fail 68 /* 0x44 Regmatch state for TRIE */ +#define EVAL_AB 69 /* 0x45 Regmatch state for EVAL */ +#define EVAL_AB_fail 70 /* 0x46 Regmatch state for EVAL */ +#define resume_CURLYX 71 /* 0x47 Regmatch state for CURLYX */ +#define resume_WHILEM1 72 /* 0x48 Regmatch state for WHILEM */ +#define resume_WHILEM2 73 /* 0x49 Regmatch state for WHILEM */ +#define resume_WHILEM3 74 /* 0x4a Regmatch state for WHILEM */ +#define resume_WHILEM4 75 /* 0x4b Regmatch state for WHILEM */ +#define resume_WHILEM5 76 /* 0x4c Regmatch state for WHILEM */ +#define resume_WHILEM6 77 /* 0x4d Regmatch state for WHILEM */ +#define BRANCH_next 78 /* 0x4e Regmatch state for BRANCH */ +#define BRANCH_next_fail 79 /* 0x4f Regmatch state for BRANCH */ +#define CURLYM_A 80 /* 0x50 Regmatch state for CURLYM */ +#define CURLYM_A_fail 81 /* 0x51 Regmatch state for CURLYM */ +#define CURLYM_B 82 /* 0x52 Regmatch state for CURLYM */ +#define CURLYM_B_fail 83 /* 0x53 Regmatch state for CURLYM */ +#define IFMATCH_A 84 /* 0x54 Regmatch state for IFMATCH */ +#define IFMATCH_A_fail 85 /* 0x55 Regmatch state for IFMATCH */ +#define CURLY_B_min_known 86 /* 0x56 Regmatch state for CURLY */ +#define CURLY_B_min_known_fail 87 /* 0x57 Regmatch state for CURLY */ +#define CURLY_B_min 88 /* 0x58 Regmatch state for CURLY */ +#define CURLY_B_min_fail 89 /* 0x59 Regmatch state for CURLY */ +#define CURLY_B_max 90 /* 0x5a Regmatch state for CURLY */ +#define CURLY_B_max_fail 91 /* 0x5b Regmatch state for CURLY */ #ifndef DOINIT @@ -347,7 +347,7 @@ static const char reg_off_by_arg[] = { }; #ifdef DEBUGGING -extern const char * const reg_name[] = { +const char * const reg_name[] = { "END", /* 0000 */ "SUCCEED", /* 0x01 */ "BOL", /* 0x02 */ @@ -9483,7 +9483,7 @@ ptr_table_* functions. REGEXP * Perl_re_dup(pTHX_ const REGEXP *r, CLONE_PARAMS *param) { - return CALLREGDUPE(aTHX_ r,param); + return CALLREGDUPE(r,param); } /* duplicate a file handle */ @@ -10941,15 +10941,7 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, sv_setpvn(PERL_DEBUG_PAD(2), "", 0); /* even without DEBUGGING. */ - /* RE engine - function pointers -- must initilize these before - re_dup() is called. dmq. */ - PL_regcompp = proto_perl->Tregcompp; - PL_regexecp = proto_perl->Tregexecp; - PL_regint_start = proto_perl->Tregint_start; - PL_regint_string = proto_perl->Tregint_string; - PL_regfree = proto_perl->Tregfree; - PL_regdupe = proto_perl->Tregdupe; - + /* RE engine related */ Zero(&PL_reg_state, 1, struct re_save_state); PL_reginterp_cnt = 0; PL_regmatch_slab = NULL; @@ -165,22 +165,6 @@ PERLVARA(Tcolors,6, char *) /* from regcomp.c */ PERLVARI(Tpeepp, peep_t, MEMBER_TO_FPTR(Perl_peep)) /* Pointer to peephole optimizer */ -PERLVARI(Tregcompp, regcomp_t, MEMBER_TO_FPTR(Perl_pregcomp)) - /* Pointer to REx compiler */ -PERLVARI(Tregexecp, regexec_t, MEMBER_TO_FPTR(Perl_regexec_flags)) - /* Pointer to REx executer */ -PERLVARI(Tregint_start, re_intuit_start_t, MEMBER_TO_FPTR(Perl_re_intuit_start)) - /* Pointer to optimized REx executer */ -PERLVARI(Tregint_string,re_intuit_string_t, MEMBER_TO_FPTR(Perl_re_intuit_string)) - /* Pointer to optimized REx string */ -PERLVARI(Tregfree, regfree_t, MEMBER_TO_FPTR(Perl_pregfree)) - /* Pointer to REx free()er */ - -#if defined(USE_ITHREADS) -PERLVARI(Tregdupe, regdupe_t, MEMBER_TO_FPTR(Perl_regdupe)) - /* Pointer to REx dupe()er */ -#endif - PERLVARI(Treginterp_cnt,int, 0) /* Whether "Regexp" was interpolated. */ PERLVARI(Twatchaddr, char **, 0) |