Change 33855 by [EMAIL PROTECTED] on 2008/05/18 14:30:48 Integrate: [ 32933] seen_eval regex field wasn't getting cloned [ 32938] The correct solution is to reference count the regexp in PL_reg_curpm, rather than put in lots of hacks to work round not reference counting it. [ 32939] It seems that you don't need to reference count PL_reg_curpm without ithreads, so don't waste time doing it there.
Affected files ... ... //depot/maint-5.10/perl/perl.c#10 integrate ... //depot/maint-5.10/perl/regcomp.c#11 integrate ... //depot/maint-5.10/perl/regexec.c#8 edit ... //depot/maint-5.10/perl/t/op/threads.t#2 integrate Differences ... ==== //depot/maint-5.10/perl/perl.c#10 (text) ==== Index: perl/perl.c --- perl/perl.c#9~33745~ 2008-04-24 20:30:37.000000000 -0700 +++ perl/perl.c 2008-05-18 07:30:48.000000000 -0700 @@ -881,13 +881,7 @@ while (i) { SV * const resv = ary[--i]; - if (SvFLAGS(resv) & SVf_BREAK) { - /* this is PL_reg_curpm, already freed - * flag is set in regexec.c:S_regtry - */ - SvFLAGS(resv) &= ~SVf_BREAK; - } - else if(SvREPADTMP(resv)) { + if(SvREPADTMP(resv)) { SvREPADTMP_off(resv); } else if(SvIOKp(resv)) { ==== //depot/maint-5.10/perl/regcomp.c#11 (text) ==== Index: perl/regcomp.c --- perl/regcomp.c#10~33742~ 2008-04-24 19:21:31.000000000 -0700 +++ perl/regcomp.c 2008-05-18 07:30:48.000000000 -0700 @@ -9440,7 +9440,6 @@ ret->mother_re = NULL; ret->gofs = 0; - ret->seen_evals = 0; ptr_table_store(PL_ptr_table, r, ret); return ret; ==== //depot/maint-5.10/perl/regexec.c#8 (text) ==== Index: perl/regexec.c --- perl/regexec.c#7~33150~ 2008-01-31 04:04:14.000000000 -0800 +++ perl/regexec.c 2008-05-18 07:30:48.000000000 -0700 @@ -2253,15 +2253,23 @@ #ifdef USE_ITHREADS { SV* const repointer = newSViv(0); - /* so we know which PL_regex_padav element is PL_reg_curpm - when clearing up in perl_destruct() */ - SvFLAGS(repointer) |= SVf_BREAK; + /* this regexp is also owned by the new PL_reg_curpm, which + will try to free it. */ av_push(PL_regex_padav,repointer); PL_reg_curpm->op_pmoffset = av_len(PL_regex_padav); PL_regex_pad = AvARRAY(PL_regex_padav); } #endif } +#ifdef USE_ITHREADS + /* It seems that non-ithreads works both with and without this code. + So for efficiency reasons it seems best not to have the code + compiled when it is not needed. */ + /* This is safe against NULLs: */ + ReREFCNT_dec(PM_GETRE(PL_reg_curpm)); + /* PM_reg_curpm owns a reference to this regexp. */ + ReREFCNT_inc(prog); +#endif PM_SETRE(PL_reg_curpm, prog); PL_reg_oldcurpm = PL_curpm; PL_curpm = PL_reg_curpm; ==== //depot/maint-5.10/perl/t/op/threads.t#2 (text) ==== Index: perl/t/op/threads.t --- perl/t/op/threads.t#1~32694~ 2007-12-22 01:23:09.000000000 -0800 +++ perl/t/op/threads.t 2008-05-18 07:30:48.000000000 -0700 @@ -16,7 +16,7 @@ exit 0; } - plan(10); + plan(11); } use strict; @@ -159,4 +159,21 @@ ok(1, '[perl #45053]'); } + +# the seen_evals field of a regexp was getting zeroed on clone, so +# within a thread it didn't know that a regex object contrained a 'safe' +# re_eval expression, so it later died with 'Eval-group not allowed' when +# you tried to interpolate the object + +sub safe_re { + my $re = qr/(?{1})/; # this is literal, so safe + eval { "a" =~ /$re$re/ }; # interpolating safe values, so safe + ok($@ eq "", 'clone seen-evals'); +} +threads->new(\&safe_re)->join(); + +# tests in threads don't get counted, so +curr_test(curr_test() + 1); + + # EOF End of Patch.