Change 33135 by [EMAIL PROTECTED] on 2008/01/30 19:50:56

        Integrate:
        [ 32761]
        Fix Perl #49190, tests from Abigail, codefix from me.
        
        [ 32857]
        Fix regexec.c so $^N and $+ are correctly updated so that they work 
properly inside of (?{...}) blocks as reported by Moritz Lenz in
        
        Subject: Bugs in extended regexp features
        From: Moritz Lenz <[EMAIL PROTECTED]>
        Date: Sat, 05 Jan 2008 17:14:37 +0100
        Message-ID: <[EMAIL PROTECTED]>
        
        [ 32873]
        Subject: Re: [perl #49264] say behaves as just print on tied filehandle
        From: Michael G Schwern <[EMAIL PROTECTED]>
        Date: Wed, 02 Jan 2008 17:08:36 -0800
        Message-ID: <[EMAIL PROTECTED]>
        
        [ 32915]
        Fix leak introduced by change #32873, thanks to Nicholas
        
        [ 32948]
        Subject: Re: [perl #49564] Re: MRO and av_clear
        From: Rick Delaney <[EMAIL PROTECTED]>
        Date: Wed, 9 Jan 2008 13:36:55 -0500
        Message-ID: <[EMAIL PROTECTED]>
        
        [ 33009]
        [perl #49522] state variable not available
        Svf_PADSTALE means something different for state vars. Make sure
        we always handle it correctly
        
        [ 33050]
        Comment change from 33009 that was actually in POD, so needs to be
        propagated to perlintern.pod

Affected files ...

... //depot/maint-5.10/perl/embed.fnc#4 integrate
... //depot/maint-5.10/perl/embed.h#2 integrate
... //depot/maint-5.10/perl/mg.c#4 integrate
... //depot/maint-5.10/perl/pad.c#3 integrate
... //depot/maint-5.10/perl/perl.h#5 integrate
... //depot/maint-5.10/perl/pod/perlintern.pod#3 integrate
... //depot/maint-5.10/perl/pod/perltie.pod#2 integrate
... //depot/maint-5.10/perl/pp_hot.c#5 integrate
... //depot/maint-5.10/perl/proto.h#2 integrate
... //depot/maint-5.10/perl/regexec.c#4 integrate
... //depot/maint-5.10/perl/t/mro/basic.t#2 integrate
... //depot/maint-5.10/perl/t/op/pat.t#4 integrate
... //depot/maint-5.10/perl/t/op/state.t#2 integrate
... //depot/maint-5.10/perl/t/op/tiehandle.t#2 integrate

Differences ...

==== //depot/maint-5.10/perl/embed.fnc#4 (text) ====
Index: perl/embed.fnc
--- perl/embed.fnc#3~33133~     2008-01-30 10:46:51.000000000 -0800
+++ perl/embed.fnc      2008-01-30 11:50:56.000000000 -0800
@@ -429,6 +429,7 @@
 p      |int    |magic_clearenv |NN SV* sv|NN MAGIC* mg
 p      |int    |magic_clear_all_env|NN SV* sv|NN MAGIC* mg
 dp     |int    |magic_clearhint|NN SV* sv|NN MAGIC* mg
+p      |int    |magic_clearisa |NN SV* sv|NN MAGIC* mg
 p      |int    |magic_clearpack|NN SV* sv|NN MAGIC* mg
 p      |int    |magic_clearsig |NN SV* sv|NN MAGIC* mg
 p      |int    |magic_existspack|NN SV* sv|NN const MAGIC* mg

==== //depot/maint-5.10/perl/embed.h#2 (text+w) ====
Index: perl/embed.h
--- perl/embed.h#1~32694~       2007-12-22 01:23:09.000000000 -0800
+++ perl/embed.h        2008-01-30 11:50:56.000000000 -0800
@@ -401,6 +401,7 @@
 #define magic_clearenv         Perl_magic_clearenv
 #define magic_clear_all_env    Perl_magic_clear_all_env
 #define magic_clearhint                Perl_magic_clearhint
+#define magic_clearisa         Perl_magic_clearisa
 #define magic_clearpack                Perl_magic_clearpack
 #define magic_clearsig         Perl_magic_clearsig
 #define magic_existspack       Perl_magic_existspack
@@ -2690,6 +2691,7 @@
 #define magic_clearenv(a,b)    Perl_magic_clearenv(aTHX_ a,b)
 #define magic_clear_all_env(a,b)       Perl_magic_clear_all_env(aTHX_ a,b)
 #define magic_clearhint(a,b)   Perl_magic_clearhint(aTHX_ a,b)
+#define magic_clearisa(a,b)    Perl_magic_clearisa(aTHX_ a,b)
 #define magic_clearpack(a,b)   Perl_magic_clearpack(aTHX_ a,b)
 #define magic_clearsig(a,b)    Perl_magic_clearsig(aTHX_ a,b)
 #define magic_existspack(a,b)  Perl_magic_existspack(aTHX_ a,b)

==== //depot/maint-5.10/perl/mg.c#4 (text) ====
Index: perl/mg.c
--- perl/mg.c#3~33132~  2008-01-30 10:18:00.000000000 -0800
+++ perl/mg.c   2008-01-30 11:50:56.000000000 -0800
@@ -1556,6 +1556,29 @@
 }
 
 int
+Perl_magic_clearisa(pTHX_ SV *sv, MAGIC *mg)
+{
+    dVAR;
+    HV* stash;
+
+    /* Bail out if destruction is going on */
+    if(PL_dirty) return 0;
+
+    av_clear((AV*)sv);
+
+    /* XXX see comments in magic_setisa */
+    stash = GvSTASH(
+        SvTYPE(mg->mg_obj) == SVt_PVGV
+            ? (GV*)mg->mg_obj
+            : (GV*)SvMAGIC(mg->mg_obj)->mg_obj
+    );
+
+    mro_isa_changed_in(stash);
+
+    return 0;
+}
+
+int
 Perl_magic_setamagic(pTHX_ SV *sv, MAGIC *mg)
 {
     dVAR;

==== //depot/maint-5.10/perl/pad.c#3 (text) ====
Index: perl/pad.c
--- perl/pad.c#2~33132~ 2008-01-30 10:18:00.000000000 -0800
+++ perl/pad.c  2008-01-30 11:50:56.000000000 -0800
@@ -102,6 +102,8 @@
 
     { my $x = 1; sub f { eval '$x'} } f();
 
+For state vars, SVf_PADSTALE is overloaded to mean 'not yet initialised'
+
 =cut
 */
 
@@ -768,6 +770,7 @@
                else {
                    int newwarn = warn;
                    if (!CvCOMPILED(cv) && (*out_flags & PAD_FAKELEX_MULTI)
+                        && !SvPAD_STATE(name_svp[offset])
                         && warn && ckWARN(WARN_CLOSURE)) {
                        newwarn = 0;
                        Perl_warner(aTHX_ packWARN(WARN_CLOSURE),
@@ -796,7 +799,9 @@
                        "Pad findlex cv=0x%"UVxf" found lex=0x%"UVxf"\n",
                        PTR2UV(cv), PTR2UV(*out_capture)));
 
-                   if (SvPADSTALE(*out_capture)) {
+                   if (SvPADSTALE(*out_capture)
+                       && !SvPAD_STATE(name_svp[offset]))
+                   {
                        if (ckWARN(WARN_CLOSURE))
                            Perl_warner(aTHX_ packWARN(WARN_CLOSURE),
                                "Variable \"%s\" is not available", name);
@@ -853,7 +858,7 @@
                    ? SvSTASH(*out_name_sv) : NULL,
            SvOURSTASH(*out_name_sv),
            1,  /* fake */
-           0   /* not a state variable */
+           SvPAD_STATE(*out_name_sv) ? 1 : 0 /* state variable ? */
        );
 
        new_namesv = AvARRAY(PL_comppad_name)[new_offset];
@@ -1496,8 +1501,8 @@
                assert(sv);
                /* formats may have an inactive parent,
                   while my $x if $false can leave an active var marked as
-                  stale */
-               if (SvPADSTALE(sv)) {
+                  stale. And state vars are always available */
+               if (SvPADSTALE(sv) && !SvPAD_STATE(namesv)) {
                    if (ckWARN(WARN_CLOSURE))
                        Perl_warner(aTHX_ packWARN(WARN_CLOSURE),
                            "Variable \"%s\" is not available", 
SvPVX_const(namesv));

==== //depot/maint-5.10/perl/perl.h#5 (text) ====
Index: perl/perl.h
--- perl/perl.h#4~33130~        2008-01-30 09:34:11.000000000 -0800
+++ perl/perl.h 2008-01-30 11:50:56.000000000 -0800
@@ -4888,7 +4888,7 @@
     0,
     MEMBER_TO_FPTR(Perl_magic_setisa),
     0,
-    MEMBER_TO_FPTR(Perl_magic_setisa),
+    MEMBER_TO_FPTR(Perl_magic_clearisa),
     0,
     0,
     0,

==== //depot/maint-5.10/perl/pod/perlintern.pod#3 (text+w) ====
Index: perl/pod/perlintern.pod
--- perl/pod/perlintern.pod#2~33123~    2008-01-30 03:45:08.000000000 -0800
+++ perl/pod/perlintern.pod     2008-01-30 11:50:56.000000000 -0800
@@ -597,6 +597,8 @@
 
     { my $x = 1; sub f { eval '$x'} } f();
 
+For state vars, SVf_PADSTALE is overloaded to mean 'not yet initialised'
+
        AV *    CvPADLIST(CV *cv)
 
 =for hackers

==== //depot/maint-5.10/perl/pod/perltie.pod#2 (text) ====
Index: perl/pod/perltie.pod
--- perl/pod/perltie.pod#1~32694~       2007-12-22 01:23:09.000000000 -0800
+++ perl/pod/perltie.pod        2008-01-30 11:50:56.000000000 -0800
@@ -900,12 +900,14 @@
 X<PRINT>
 
 This method will be triggered every time the tied handle is printed to
-with the C<print()> function.
-Beyond its self reference it also expects the list that was passed to
-the print function.
+with the C<print()> or C<say()> functions.  Beyond its self reference
+it also expects the list that was passed to the print function.
 
     sub PRINT { $r = shift; $$r++; print join($,,map(uc($_),@_)),$\ }
 
+C<say()> acts just like C<print()> except $\ will be localized to C<\n> so
+you need do nothing special to handle C<say()> in C<PRINT()>.
+
 =item PRINTF this, LIST
 X<PRINTF>
 

==== //depot/maint-5.10/perl/pp_hot.c#5 (text) ====
Index: perl/pp_hot.c
--- perl/pp_hot.c#4~33132~      2008-01-30 10:18:00.000000000 -0800
+++ perl/pp_hot.c       2008-01-30 11:50:56.000000000 -0800
@@ -731,6 +731,11 @@
        *MARK = SvTIED_obj((SV*)io, mg);
        PUTBACK;
        ENTER;
+       if( PL_op->op_type == OP_SAY ) {
+               /* local $\ = "\n" */
+               SAVEGENERICSV(PL_ors_sv);
+               PL_ors_sv = newSVpvs("\n");
+       }
        call_method("PRINT", G_SCALAR);
        LEAVE;
        SPAGAIN;
@@ -2034,6 +2039,7 @@
     const I32 oldsave = PL_savestack_ix;
     STRLEN slen;
     bool doutf8 = FALSE;
+    I32 matched;
 #ifdef PERL_OLD_COPY_ON_WRITE
     bool is_cow;
 #endif
@@ -2120,7 +2126,8 @@
 
     /* only replace once? */
     once = !(rpm->op_pmflags & PMf_GLOBAL);
-
+    matched = CALLREGEXEC(rx, s, strend, orig, 0, TARG, NULL,
+                        r_flags | REXEC_CHECKED);
     /* known replacement string? */
     if (dstr) {
        /* replacement needing upgrading? */
@@ -2152,8 +2159,7 @@
        && (I32)clen <= RX_MINLENRET(rx) && (once || !(r_flags & 
REXEC_COPY_STR))
        && !(RX_EXTFLAGS(rx) & RXf_LOOKBEHIND_SEEN)
        && (!doutf8 || SvUTF8(TARG))) {
-       if (!CALLREGEXEC(rx, s, strend, orig, 0, TARG, NULL,
-                        r_flags | REXEC_CHECKED))
+       if (!matched)
        {
            SPAGAIN;
            PUSHs(&PL_sv_no);
@@ -2257,8 +2263,7 @@
        RETURN;
     }
 
-    if (CALLREGEXEC(rx, s, strend, orig, 0, TARG, NULL,
-                   r_flags | REXEC_CHECKED))
+    if (matched)
     {
        if (force_on_match) {
            force_on_match = 0;

==== //depot/maint-5.10/perl/proto.h#2 (text+w) ====
Index: perl/proto.h
--- perl/proto.h#1~32694~       2007-12-22 01:23:09.000000000 -0800
+++ perl/proto.h        2008-01-30 11:50:56.000000000 -0800
@@ -1088,6 +1088,10 @@
                        __attribute__nonnull__(pTHX_1)
                        __attribute__nonnull__(pTHX_2);
 
+PERL_CALLCONV int      Perl_magic_clearisa(pTHX_ SV* sv, MAGIC* mg)
+                       __attribute__nonnull__(pTHX_1)
+                       __attribute__nonnull__(pTHX_2);
+
 PERL_CALLCONV int      Perl_magic_clearpack(pTHX_ SV* sv, MAGIC* mg)
                        __attribute__nonnull__(pTHX_1)
                        __attribute__nonnull__(pTHX_2);

==== //depot/maint-5.10/perl/regexec.c#4 (text) ====
Index: perl/regexec.c
--- perl/regexec.c#3~33130~     2008-01-30 09:34:11.000000000 -0800
+++ perl/regexec.c      2008-01-30 11:50:56.000000000 -0800
@@ -3763,8 +3763,12 @@
                
                PL_regoffs = re->offs; /* essentially NOOP on GOSUB */
                
-               *PL_reglastparen = 0;
-               *PL_reglastcloseparen = 0;
+               /* see regtry, specifically PL_reglast(?:close)?paren is a 
pointer! (i dont know why) :dmq */
+               PL_reglastparen = &re->lastparen;
+               PL_reglastcloseparen = &re->lastcloseparen;
+               re->lastparen = 0;
+               re->lastcloseparen = 0;
+
                PL_reginput = locinput;
                PL_regsize = 0;
 
@@ -3805,6 +3809,10 @@
            regcpblow(ST.cp);
            cur_eval = ST.prev_eval;
            cur_curlyx = ST.prev_curlyx;
+           
+           PL_reglastparen = &rex->lastparen;
+           PL_reglastcloseparen = &rex->lastcloseparen;
+           
            /* XXXX This is too dramatic a measure... */
            PL_reg_maxiter = 0;
             if ( nochange_depth )
@@ -3818,6 +3826,9 @@
            ReREFCNT_dec(rex);
            SETREX(rex,ST.prev_rex);
            rexi = RXi_GET(rex); 
+           PL_reglastparen = &rex->lastparen;
+           PL_reglastcloseparen = &rex->lastcloseparen;
+
            PL_reginput = locinput;
            REGCP_UNWIND(ST.lastcp);
            regcppop(rex);

==== //depot/maint-5.10/perl/t/mro/basic.t#2 (text) ====
Index: perl/t/mro/basic.t
--- perl/t/mro/basic.t#1~32694~ 2007-12-22 01:23:09.000000000 -0800
+++ perl/t/mro/basic.t  2008-01-30 11:50:56.000000000 -0800
@@ -3,7 +3,7 @@
 use strict;
 use warnings;
 
-require q(./test.pl); plan(tests => 38);
+require q(./test.pl); plan(tests => 40);
 
 {
     package MRO_A;
@@ -173,6 +173,19 @@
 
     ok(eq_array(mro::get_linear_isa('ISACLEAR1'),[qw/ISACLEAR1/]));
     ok(eq_array(mro::get_linear_isa('ISACLEAR2'),[qw/ISACLEAR2/]));
+
+    # [perl #49564]  This is a pretty obscure way of clearing @ISA but
+    # it tests a regression that affects XS code calling av_clear too.
+    {
+        package ISACLEAR3;
+        our @ISA = qw/WW XX/;
+    }
+    ok(eq_array(mro::get_linear_isa('ISACLEAR3'),[qw/ISACLEAR3 WW XX/]));
+    {
+        package ISACLEAR3;
+        reset 'I';
+    }
+    ok(eq_array(mro::get_linear_isa('ISACLEAR3'),[qw/ISACLEAR3/]));
 }
 
 # Check that recursion bails out "cleanly" in a variety of cases

==== //depot/maint-5.10/perl/t/op/pat.t#4 (xtext) ====
Index: perl/t/op/pat.t
--- perl/t/op/pat.t#3~33133~    2008-01-30 10:46:51.000000000 -0800
+++ perl/t/op/pat.t     2008-01-30 11:50:56.000000000 -0800
@@ -4511,6 +4511,39 @@
         }
     }
 }
+{
+     local $Message = "\$REGMARK in replacement -- Bug #49190";
+     my $_ = "A";
+     s/(*:B)A/$REGMARK/;
+     iseq $_, "B";
+     $_ = "CCCCBAA";
+     s/(*:X)A+|(*:Y)B+|(*:Z)C+/$REGMARK/g;
+     iseq $_, "ZYX";
+}
+{
+    our @ctl_n=();
+    our @plus=();
+    our $nested_tags;
+    $nested_tags = qr{
+        <
+           (\w+)
+           (?{
+                   push @ctl_n,$^N;
+                   push @plus,$+;
+           })
+        >
+        (??{$nested_tags})*
+        </\s* \w+ \s*>
+    }x;
+
+    my $match= '<bla><blubb></blubb></bla>' =~ m/^$nested_tags$/;
+    ok($match,'nested construct matches');
+    iseq("@ctl_n","bla blubb",'$^N inside of (?{}) works as expected');
+    iseq("@plus","bla blubb",'$+ inside of (?{}) works as expected');
+}
+
+
+
 
 # Test counter is at bottom of file. Put new tests above here.
 #-------------------------------------------------------------------
@@ -4570,6 +4603,6 @@
 iseq(0+$::test,$::TestCount,"Got the right number of tests!");
 # Don't forget to update this!
 BEGIN {
-    $::TestCount = 4013;
+    $::TestCount = 4018;
     print "1..$::TestCount\n";
 }

==== //depot/maint-5.10/perl/t/op/state.t#2 (text) ====
Index: perl/t/op/state.t
--- perl/t/op/state.t#1~32694~  2007-12-22 01:23:09.000000000 -0800
+++ perl/t/op/state.t   2008-01-30 11:50:56.000000000 -0800
@@ -10,7 +10,7 @@
 use strict;
 use feature ":5.10";
 
-plan tests => 123;
+plan tests => 130;
 
 ok( ! defined state $uninit, q(state vars are undef by default) );
 
@@ -354,6 +354,50 @@
     eval $forbidden;
     like $@, qr/Initialization of state variables in list context currently 
forbidden/, "Currently forbidden: $forbidden";
 }
+
+# [perl #49522] state variable not available
+
+{
+    my @warnings;
+    local $SIG{__WARN__} = sub { push @warnings, $_[0] };
+
+    eval q{
+       use warnings;
+
+       sub f_49522 {
+           state $s = 88;
+           sub g_49522 { $s }
+           sub { $s };
+       }
+
+       sub h_49522 {
+           state $t = 99;
+           sub i_49522 {
+               sub { $t };
+           }
+       }
+    };
+    is $@, '', "eval f_49522";
+    # shouldn't be any 'not available' or 'not stay shared' warnings
+    ok [EMAIL PROTECTED], "suppress warnings part 1 [EMAIL PROTECTED]";
+
+    @warnings = ();
+    my $f = f_49522();
+    is $f->(), 88, "state var closure 1";
+    is g_49522(), 88, "state var closure 2";
+    ok [EMAIL PROTECTED], "suppress warnings part 2 [EMAIL PROTECTED]";
+
+
+    @warnings = ();
+    $f = i_49522();
+    h_49522(); # initialise $t
+    is $f->(), 99, "state var closure 3";
+    ok [EMAIL PROTECTED], "suppress warnings part 3 [EMAIL PROTECTED]";
+
+
+}
+
+
 __DATA__
 state ($a) = 1;
 (state $a) = 1;

==== //depot/maint-5.10/perl/t/op/tiehandle.t#2 (xtext) ====
Index: perl/t/op/tiehandle.t
--- perl/t/op/tiehandle.t#1~32694~      2007-12-22 01:23:09.000000000 -0800
+++ perl/t/op/tiehandle.t       2008-01-30 11:50:56.000000000 -0800
@@ -10,9 +10,11 @@
 my @data = ();
 
 require './test.pl';
-plan(tests => 41);
+plan(tests => 50);
 
 sub compare {
+    local $Level = $Level + 1;
+
     return unless @expect;
     return ::fail() unless(@_ == @expect);
 
@@ -163,6 +165,32 @@
 }
 
 {
+    package Bar::Say;
+    use feature 'say';
+    use base qw(Implement);
+
+    my $ors;
+    sub PRINT     {
+        $ors = $\;
+        my $self = shift;
+        return $self->SUPER::PRINT(@_);
+    }
+
+    my $fh = Symbol::gensym;
+    @expect = (TIEHANDLE => 'Bar::Say');
+    ::ok( my $obj = tie *$fh, 'Bar::Say' );
+
+    local $\ = 'something';
+    @expect = (PRINT => $obj, "stuff", "and", "things");
+    ::ok( print $fh @expect[2..4] );
+    ::is( $ors, 'something' );
+    
+    ::ok( say $fh @expect[2..4] );
+    ::is( $ors, "\n",        'say sets $\ to \n in PRINT' );
+    ::is( $\,   "something", "  and it's localized" );
+}
+
+{
     # Test for change #11536
     package Foo;
     use strict;
@@ -245,4 +273,3 @@
     sub READLINE { "foobar\n" }
 }
 
-
End of Patch.

Reply via email to