Change 30072 by [EMAIL PROTECTED] on 2007/01/29 22:40:01

        UNITCHECK for XS code. Turned out to be harder that expected.
        We need to get the XS BOOT section to run any UNITCHECK blocks for us.

Affected files ...

... //depot/perl/ext/XS/APItest/APItest.pm#18 edit
... //depot/perl/ext/XS/APItest/APItest.xs#35 edit
... //depot/perl/ext/XS/APItest/t/xs_special_subs.t#2 edit
... //depot/perl/lib/ExtUtils/ParseXS.pm#19 edit
... //depot/perl/op.c#886 edit

Differences ...

==== //depot/perl/ext/XS/APItest/APItest.pm#18 (text) ====
Index: perl/ext/XS/APItest/APItest.pm
--- perl/ext/XS/APItest/APItest.pm#17~30067~    2007-01-29 12:05:52.000000000 
-0800
+++ perl/ext/XS/APItest/APItest.pm      2007-01-29 14:40:01.000000000 -0800
@@ -38,12 +38,36 @@
 our $VERSION = '0.12';
 
 use vars '$WARNINGS_ON_BOOTSTRAP';
+use vars map "\$${_}_called_PP", qw(BEGIN UNITCHECK CHECK INIT END);
+
+# Do these here to verify that XS code and Perl code get called at the same
+# times
+BEGIN {
+    $BEGIN_called_PP++;
+}
+UNITCHECK {
+    $UNITCHECK_called_PP++;
+}
+{
+    # Need $W false by default, as some tests run under -w, and under -w we
+    # can get warnings about "Too late to run CHECK" block (and INIT block)
+    no warnings 'void';
+    CHECK {
+       $CHECK_called_PP++;
+    }
+    INIT {
+       $INIT_called_PP++;
+    }
+}
+END {
+    $END_called_PP++;
+}
+
 if ($WARNINGS_ON_BOOTSTRAP) {
     bootstrap XS::APItest $VERSION;
 } else {
+    # More CHECK and INIT blocks that could warn:
     local $^W;
-    # Need $W false by default, as some tests run under -w, and under -w we
-    # can get warnings about "Too late to run CHECK" block (and INIT block)
     bootstrap XS::APItest $VERSION;
 }
 

==== //depot/perl/ext/XS/APItest/APItest.xs#35 (text) ====
Index: perl/ext/XS/APItest/APItest.xs
--- perl/ext/XS/APItest/APItest.xs#34~30067~    2007-01-29 12:05:52.000000000 
-0800
+++ perl/ext/XS/APItest/APItest.xs      2007-01-29 14:40:01.000000000 -0800
@@ -580,7 +580,7 @@
 void
 UNITCHECK()
     CODE:
-       sv_inc(get_sv("XS::APItest::CHECK_called", GV_ADD|GV_ADDMULTI));
+       sv_inc(get_sv("XS::APItest::UNITCHECK_called", GV_ADD|GV_ADDMULTI));
 
 void
 INIT()

==== //depot/perl/ext/XS/APItest/t/xs_special_subs.t#2 (text) ====
Index: perl/ext/XS/APItest/t/xs_special_subs.t
--- perl/ext/XS/APItest/t/xs_special_subs.t#1~30067~    2007-01-29 
12:05:52.000000000 -0800
+++ perl/ext/XS/APItest/t/xs_special_subs.t     2007-01-29 14:40:01.000000000 
-0800
@@ -7,78 +7,149 @@
         print "1..0 # Skip: XS::APItest was not built\n";
         exit 0;
     }
+    $XS::APItest::WARNINGS_ON_BOOTSTRAP++;
 }
 
 use strict;
 use warnings;
-use Test::More tests => 40;
+use Test::More tests => 100;
 
 # Doing this longhand cut&paste makes it clear
 # BEGIN and INIT are FIFO, CHECK and END are LIFO
 BEGIN {
+    print "# First BEGIN\n";
     is($XS::APItest::BEGIN_called, undef, "BEGIN not yet called");
+    is($XS::APItest::BEGIN_called_PP, undef, "BEGIN not yet called");
+    is($XS::APItest::UNITCHECK_called, undef, "UNITCHECK not yet called");
+    is($XS::APItest::UNITCHECK_called_PP, undef, "UNITCHECK not yet called");
     is($XS::APItest::CHECK_called, undef, "CHECK not yet called");
+    is($XS::APItest::CHECK_called_PP, undef, "CHECK not yet called");
     is($XS::APItest::INIT_called, undef, "INIT not yet called");
+    is($XS::APItest::INIT_called_PP, undef, "INIT not yet called");
     is($XS::APItest::END_called, undef, "END not yet called");
+    is($XS::APItest::END_called_PP, undef, "END not yet called");
 }
 
 CHECK {
+    print "# First CHECK\n";
     is($XS::APItest::BEGIN_called, 1, "BEGIN called");
+    is($XS::APItest::BEGIN_called_PP, 1, "BEGIN called");
+    is($XS::APItest::UNITCHECK_called, 1, "UNITCHECK called");
+    is($XS::APItest::UNITCHECK_called_PP, 1, "UNITCHECK called");
     is($XS::APItest::CHECK_called, 1, "CHECK called");
+    is($XS::APItest::CHECK_called_PP, 1, "CHECK called");
     is($XS::APItest::INIT_called, undef, "INIT not yet called");
+    is($XS::APItest::INIT_called_PP, undef, "INIT not yet called");
     is($XS::APItest::END_called, undef, "END not yet called");
+    is($XS::APItest::END_called_PP, undef, "END not yet called");
 }
 
 INIT {
+    print "# First INIT\n";
     is($XS::APItest::BEGIN_called, 1, "BEGIN called");
+    is($XS::APItest::BEGIN_called_PP, 1, "BEGIN called");
+    is($XS::APItest::UNITCHECK_called, 1, "UNITCHECK called");
+    is($XS::APItest::UNITCHECK_called_PP, 1, "UNITCHECK called");
     is($XS::APItest::CHECK_called, 1, "CHECK called");
+    is($XS::APItest::CHECK_called_PP, 1, "CHECK called");
     is($XS::APItest::INIT_called, undef, "INIT not yet called");
+    is($XS::APItest::INIT_called_PP, undef, "INIT not yet called");
     is($XS::APItest::END_called, undef, "END not yet called");
+    is($XS::APItest::END_called_PP, undef, "END not yet called");
 }
 
 END {
+    print "# First END\n";
     is($XS::APItest::BEGIN_called, 1, "BEGIN called");
+    is($XS::APItest::BEGIN_called_PP, 1, "BEGIN called");
+    is($XS::APItest::UNITCHECK_called, 1, "UNITCHECK called");
+    is($XS::APItest::UNITCHECK_called_PP, 1, "UNITCHECK called");
     is($XS::APItest::CHECK_called, 1, "CHECK called");
+    is($XS::APItest::CHECK_called_PP, 1, "CHECK called");
     is($XS::APItest::INIT_called, 1, "INIT called");
+    is($XS::APItest::INIT_called_PP, 1, "INIT called");
     is($XS::APItest::END_called, 1, "END called");
+    is($XS::APItest::END_called_PP, 1, "END called");
 }
 
+print "# First body\n";
 is($XS::APItest::BEGIN_called, 1, "BEGIN called");
+is($XS::APItest::BEGIN_called_PP, 1, "BEGIN called");
+is($XS::APItest::UNITCHECK_called, 1, "UNITCHECK called");
+is($XS::APItest::UNITCHECK_called_PP, 1, "UNITCHECK called");
 is($XS::APItest::CHECK_called, 1, "CHECK called");
+is($XS::APItest::CHECK_called_PP, 1, "CHECK called");
 is($XS::APItest::INIT_called, 1, "INIT called");
+is($XS::APItest::INIT_called_PP, 1, "INIT called");
 is($XS::APItest::END_called, undef, "END not yet called");
+is($XS::APItest::END_called_PP, undef, "END not yet called");
 
 use XS::APItest;
 
+print "# Second body\n";
 is($XS::APItest::BEGIN_called, 1, "BEGIN called");
+is($XS::APItest::BEGIN_called_PP, 1, "BEGIN called");
+is($XS::APItest::UNITCHECK_called, 1, "UNITCHECK called");
+is($XS::APItest::UNITCHECK_called_PP, 1, "UNITCHECK called");
 is($XS::APItest::CHECK_called, 1, "CHECK called");
+is($XS::APItest::CHECK_called_PP, 1, "CHECK called");
 is($XS::APItest::INIT_called, 1, "INIT called");
+is($XS::APItest::INIT_called_PP, 1, "INIT called");
 is($XS::APItest::END_called, undef, "END not yet called");
+is($XS::APItest::END_called_PP, undef, "END not yet called");
 
 BEGIN {
+    print "# Second BEGIN\n";
     is($XS::APItest::BEGIN_called, 1, "BEGIN called");
+    is($XS::APItest::BEGIN_called_PP, 1, "BEGIN called");
+    is($XS::APItest::UNITCHECK_called, 1, "UNITCHECK called");
+    is($XS::APItest::UNITCHECK_called_PP, 1, "UNITCHECK called");
     is($XS::APItest::CHECK_called, undef, "CHECK not yet called");
+    is($XS::APItest::CHECK_called_PP, undef, "CHECK not yet called");
     is($XS::APItest::INIT_called, undef, "INIT not yet called");
+    is($XS::APItest::INIT_called_PP, undef, "INIT not yet called");
     is($XS::APItest::END_called, undef, "END not yet called");
+    is($XS::APItest::END_called_PP, undef, "END not yet called");
 }
 
 CHECK {
+    print "# Second CHECK\n";
     is($XS::APItest::BEGIN_called, 1, "BEGIN called");
+    is($XS::APItest::BEGIN_called_PP, 1, "BEGIN called");
+    is($XS::APItest::UNITCHECK_called, 1, "UNITCHECK yet called");
+    is($XS::APItest::UNITCHECK_called_PP, 1, "UNITCHECK yet called");
     is($XS::APItest::CHECK_called, undef, "CHECK not yet called");
+    is($XS::APItest::CHECK_called_PP, undef, "CHECK not yet called");
     is($XS::APItest::INIT_called, undef, "INIT not yet called");
+    is($XS::APItest::INIT_called_PP, undef, "INIT not yet called");
     is($XS::APItest::END_called, undef, "END not yet called");
+    is($XS::APItest::END_called_PP, undef, "END not yet called");
 }
 
 INIT {
+    print "# Second INIT\n";
     is($XS::APItest::BEGIN_called, 1, "BEGIN called");
+    is($XS::APItest::BEGIN_called_PP, 1, "BEGIN called");
+    is($XS::APItest::UNITCHECK_called, 1, "UNITCHECK called");
+    is($XS::APItest::UNITCHECK_called_PP, 1, "UNITCHECK called");
     is($XS::APItest::CHECK_called, 1, "CHECK called");
+    is($XS::APItest::CHECK_called_PP, 1, "CHECK called");
     is($XS::APItest::INIT_called, 1, "INIT called");
+    is($XS::APItest::INIT_called_PP, 1, "INIT called");
     is($XS::APItest::END_called, undef, "END not yet called");
+    is($XS::APItest::END_called_PP, undef, "END not yet called");
 }
 
 END {
+    print "# Second END\n";
     is($XS::APItest::BEGIN_called, 1, "BEGIN called");
+    is($XS::APItest::BEGIN_called_PP, 1, "BEGIN called");
+    is($XS::APItest::UNITCHECK_called, 1, "UNITCHECK called");
+    is($XS::APItest::UNITCHECK_called_PP, 1, "UNITCHECK called");
     is($XS::APItest::CHECK_called, 1, "CHECK called");
+    is($XS::APItest::CHECK_called_PP, 1, "CHECK called");
     is($XS::APItest::INIT_called, 1, "INIT called");
+    is($XS::APItest::INIT_called_PP, 1, "INIT called");
     is($XS::APItest::END_called, undef, "END not yet called");
+    is($XS::APItest::END_called_PP, undef, "END not yet called");
 }

==== //depot/perl/lib/ExtUtils/ParseXS.pm#19 (text) ====
Index: perl/lib/ExtUtils/ParseXS.pm
--- perl/lib/ExtUtils/ParseXS.pm#18~29418~      2006-11-29 07:17:59.000000000 
-0800
+++ perl/lib/ExtUtils/ParseXS.pm        2007-01-29 14:40:01.000000000 -0800
@@ -18,7 +18,7 @@
 my($XSS_work_idx, $cpp_next_tmp);
 
 use vars qw($VERSION);
-$VERSION = '2.17_01';
+$VERSION = '2.17_02';
 
 use vars qw(%input_expr %output_expr $ProtoUsed @InitFileCode $FH $proto_re 
$Overload $errors $Fallback
            $cplusplus $hiertype $WantPrototypes $WantVersionChk $except 
$WantLineNumbers
@@ -981,6 +981,12 @@
     print "\n    /* End of Initialisation Section */\n\n" ;
   }
 
+  if ($] >= 5.009) {
+    print <<'EOF';
+    if (PL_unitcheckav)
+         call_list(PL_scopestack_ix, PL_unitcheckav);
+EOF
+  }
   print Q(<<"EOF");
 #    XSRETURN_YES;
 #]]

==== //depot/perl/op.c#886 (text) ====
Index: perl/op.c
--- perl/op.c#885~30067~        2007-01-29 12:05:52.000000000 -0800
+++ perl/op.c   2007-01-29 14:40:01.000000000 -0800
@@ -5634,7 +5634,7 @@
        else
            s = name;
 
-       if (*s != 'B' && *s != 'E' && *s != 'C' && *s != 'I')
+       if (*s != 'B' && *s != 'E' && *s != 'C' && *s != 'I' && *s != 'U')
            goto done;
 
        if (strEQ(s, "BEGIN")) {
@@ -5661,6 +5661,11 @@
            Perl_av_create_and_unshift_one(aTHX_ &PL_checkav, (SV*)cv);
            GvCV(gv) = 0;               /* cv has been hijacked */
        }
+       else if (strEQ(s, "UNITCHECK")) {
+           /* It's never too late to run a unitcheck block */
+           Perl_av_create_and_unshift_one(aTHX_ &PL_unitcheckav, (SV*)cv);
+           GvCV(gv) = 0;               /* cv has been hijacked */
+       }
        else if (strEQ(s, "INIT")) {
            if (PL_main_start && ckWARN(WARN_VOID))
                Perl_warner(aTHX_ packWARN(WARN_VOID), "Too late to run INIT 
block");
End of Patch.

Reply via email to