Change 30720 by [EMAIL PROTECTED] on 2007/03/23 13:35:25

        Integrate:
        [ 30067]
        BEGIN blocks in XS should work. (Given that CHECK, INIT and END all do)
        
        [ 30072]
        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.
        
        [ 30076]
        Also check BEGIN/UNITCHECK/CHECK/INIT/END for require.

Affected files ...

... //depot/maint-5.8/perl/MANIFEST#354 integrate
... //depot/maint-5.8/perl/ext/XS/APItest/APItest.pm#14 integrate
... //depot/maint-5.8/perl/ext/XS/APItest/APItest.xs#19 integrate
... //depot/maint-5.8/perl/ext/XS/APItest/t/xs_special_subs.t#1 add
... //depot/maint-5.8/perl/ext/XS/APItest/t/xs_special_subs_require.t#1 add
... //depot/maint-5.8/perl/op.c#210 integrate

Differences ...

==== //depot/maint-5.8/perl/MANIFEST#354 (text) ====
Index: perl/MANIFEST
--- perl/MANIFEST#353~30719~    2007-03-23 05:54:47.000000000 -0700
+++ perl/MANIFEST       2007-03-23 06:35:25.000000000 -0700
@@ -1038,6 +1038,8 @@
 ext/XS/APItest/t/printf.t      XS::APItest extension
 ext/XS/APItest/t/push.t                XS::APItest extension
 ext/XS/APItest/t/svsetsv.t     Test behaviour of sv_setsv with/without 
PERL_CORE
+ext/XS/APItest/t/xs_special_subs.t     Test that XS BEGIN/CHECK/INIT/END work
+ext/XS/APItest/t/xs_special_subs_require.t     for require too
 ext/XS/Typemap/Makefile.PL     XS::Typemap extension
 ext/XS/Typemap/README          XS::Typemap extension
 ext/XS/Typemap/stdio.c         XS::Typemap extension

==== //depot/maint-5.8/perl/ext/XS/APItest/APItest.pm#14 (text) ====
Index: perl/ext/XS/APItest/APItest.pm
--- perl/ext/XS/APItest/APItest.pm#13~30719~    2007-03-23 05:54:47.000000000 
-0700
+++ perl/ext/XS/APItest/APItest.pm      2007-03-23 06:35:25.000000000 -0700
@@ -36,9 +36,38 @@
 sub G_NODEBUG()        {  32 }
 sub G_METHOD() {  64 }
 
-our $VERSION = '0.11';
+our $VERSION = '0.12';
 
-bootstrap XS::APItest $VERSION;
+use vars '$WARNINGS_ON_BOOTSTRAP';
+use vars map "\$${_}_called_PP", qw(BEGIN CHECK INIT END);
+
+# Do these here to verify that XS code and Perl code get called at the same
+# times
+BEGIN {
+    $BEGIN_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;
+    bootstrap XS::APItest $VERSION;
+}
 
 1;
 __END__

==== //depot/maint-5.8/perl/ext/XS/APItest/APItest.xs#19 (text) ====
Index: perl/ext/XS/APItest/APItest.xs
--- perl/ext/XS/APItest/APItest.xs#18~30719~    2007-03-23 05:54:47.000000000 
-0700
+++ perl/ext/XS/APItest/APItest.xs      2007-03-23 06:35:25.000000000 -0700
@@ -523,3 +523,28 @@
 
 bool
 sv_setsv_cow_hashkey_notcore()
+
+void
+BEGIN()
+    CODE:
+       sv_inc(get_sv("XS::APItest::BEGIN_called", GV_ADD|GV_ADDMULTI));
+
+void
+CHECK()
+    CODE:
+       sv_inc(get_sv("XS::APItest::CHECK_called", GV_ADD|GV_ADDMULTI));
+
+void
+UNITCHECK()
+    CODE:
+       sv_inc(get_sv("XS::APItest::UNITCHECK_called", GV_ADD|GV_ADDMULTI));
+
+void
+INIT()
+    CODE:
+       sv_inc(get_sv("XS::APItest::INIT_called", GV_ADD|GV_ADDMULTI));
+
+void
+END()
+    CODE:
+       sv_inc(get_sv("XS::APItest::END_called", GV_ADD|GV_ADDMULTI));

==== //depot/maint-5.8/perl/ext/XS/APItest/t/xs_special_subs.t#1 (text) ====
Index: perl/ext/XS/APItest/t/xs_special_subs.t
--- /dev/null   2007-03-19 09:41:43.516454971 -0700
+++ perl/ext/XS/APItest/t/xs_special_subs.t     2007-03-23 06:35:25.000000000 
-0700
@@ -0,0 +1,139 @@
+#!perl -w
+
+BEGIN {
+    chdir 't' if -d 't';
+    @INC = '../lib';
+    push @INC, "::lib:$MacPerl::Architecture:" if $^O eq 'MacOS';
+    require Config; import Config;
+    if ($Config{'extensions'} !~ /\bXS\/APItest\b/) {
+        print "1..0 # Skip: XS::APItest was not built\n";
+        exit 0;
+    }
+    # Hush the used only once warning.
+    $XS::APItest::WARNINGS_ON_BOOTSTRAP = $MacPerl::Architecture;
+    $XS::APItest::WARNINGS_ON_BOOTSTRAP = 1;
+}
+
+use strict;
+use warnings;
+use Test::More tests => 80;
+
+# 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::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::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::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::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::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::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::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::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::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::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/maint-5.8/perl/ext/XS/APItest/t/xs_special_subs_require.t#1 (text) 
====
Index: perl/ext/XS/APItest/t/xs_special_subs_require.t
--- /dev/null   2007-03-19 09:41:43.516454971 -0700
+++ perl/ext/XS/APItest/t/xs_special_subs_require.t     2007-03-23 
06:35:25.000000000 -0700
@@ -0,0 +1,147 @@
+#!perl -w
+BEGIN {
+    chdir 't' if -d 't';
+    @INC = '../lib';
+    push @INC, "::lib:$MacPerl::Architecture:" if $^O eq 'MacOS';
+    require Config; import Config;
+    if ($Config{'extensions'} !~ /\bXS\/APItest\b/) {
+        print "1..0 # Skip: XS::APItest was not built\n";
+        exit 0;
+    }
+    # Hush the used only once warning.
+    $XS::APItest::WARNINGS_ON_BOOTSTRAP = $MacPerl::Architecture;
+    $XS::APItest::WARNINGS_ON_BOOTSTRAP = 1;
+}
+
+use strict;
+use warnings;
+use Test::More tests => 83;
+
+# 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::CHECK_called, undef, "CHECK not called");
+    is($XS::APItest::CHECK_called_PP, undef, "CHECK not called");
+    is($XS::APItest::INIT_called, undef, "INIT not called");
+    is($XS::APItest::INIT_called_PP, undef, "INIT not 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, undef, "BEGIN not yet called");
+    is($XS::APItest::BEGIN_called_PP, undef, "BEGIN not yet called");
+    is($XS::APItest::CHECK_called, undef, "CHECK not called (too late)");
+    is($XS::APItest::CHECK_called_PP, undef, "CHECK not called (too late)");
+    is($XS::APItest::INIT_called, undef, "INIT not called");
+    is($XS::APItest::INIT_called_PP, undef, "INIT not 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, undef, "BEGIN not yet called");
+    is($XS::APItest::BEGIN_called_PP, undef, "BEGIN not yet called");
+    is($XS::APItest::CHECK_called, undef, "CHECK not called (too late)");
+    is($XS::APItest::CHECK_called_PP, undef, "CHECK not called (too late)");
+    is($XS::APItest::INIT_called, undef, "INIT not called");
+    is($XS::APItest::INIT_called_PP, undef, "INIT not 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::CHECK_called, undef, "CHECK not called (too late)");
+    is($XS::APItest::CHECK_called_PP, undef, "CHECK not called (too late)");
+    is($XS::APItest::INIT_called, undef, "INIT not called (too late)");
+    is($XS::APItest::INIT_called_PP, undef, "INIT not called (too late)");
+    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, undef, "BEGIN not yet called");
+is($XS::APItest::BEGIN_called_PP, undef, "BEGIN not yet called");
+is($XS::APItest::CHECK_called, undef, "CHECK not called (too late)");
+is($XS::APItest::CHECK_called_PP, undef, "CHECK not called (too late)");
+is($XS::APItest::INIT_called, undef, "INIT not called (too late)");
+is($XS::APItest::INIT_called_PP, undef, "INIT not called (too late)");
+is($XS::APItest::END_called, undef, "END not yet called");
+is($XS::APItest::END_called_PP, undef, "END not yet called");
+
+{
+    my @trap;
+    local $SIG{__WARN__} = sub { push @trap, join "!", @_ };
+    require XS::APItest;
+
+    @trap = sort @trap;
+    is(scalar @trap, 2, "There were 2 warnings");
+    is($trap[0], "Too late to run CHECK block.\n");
+    is($trap[1], "Too late to run INIT block.\n");
+}
+
+print "# Second body\n";
+is($XS::APItest::BEGIN_called, 1, "BEGIN called");
+is($XS::APItest::BEGIN_called_PP, 1, "BEGIN called");
+is($XS::APItest::CHECK_called, undef, "CHECK not called (too late)");
+is($XS::APItest::CHECK_called_PP, undef, "CHECK not called (too late)");
+is($XS::APItest::INIT_called, undef, "INIT not called (too late)");
+is($XS::APItest::INIT_called_PP, undef, "INIT not called (too late)");
+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, undef, "BEGIN not yet called");
+    is($XS::APItest::BEGIN_called_PP, undef, "BEGIN not yet called");
+    is($XS::APItest::CHECK_called, undef, "CHECK not called");
+    is($XS::APItest::CHECK_called_PP, undef, "CHECK not called");
+    is($XS::APItest::INIT_called, undef, "INIT not called");
+    is($XS::APItest::INIT_called_PP, undef, "INIT not 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, undef, "BEGIN not yet called");
+    is($XS::APItest::BEGIN_called_PP, undef, "BEGIN not yet called");
+    is($XS::APItest::CHECK_called, undef, "CHECK not called");
+    is($XS::APItest::CHECK_called_PP, undef, "CHECK not called");
+    is($XS::APItest::INIT_called, undef, "INIT not called");
+    is($XS::APItest::INIT_called_PP, undef, "INIT not 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, undef, "BEGIN not yet called");
+    is($XS::APItest::BEGIN_called_PP, undef, "BEGIN not yet called");
+    is($XS::APItest::CHECK_called, undef, "CHECK not called (too late)");
+    is($XS::APItest::CHECK_called_PP, undef, "CHECK not called (too late)");
+    is($XS::APItest::INIT_called, undef, "INIT not called (too late)");
+    is($XS::APItest::INIT_called_PP, undef, "INIT not called (too late)");
+    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::CHECK_called, undef, "CHECK not called (too late)");
+    is($XS::APItest::CHECK_called_PP, undef, "CHECK not called (too late)");
+    is($XS::APItest::INIT_called, undef, "INIT not called (too late)");
+    is($XS::APItest::INIT_called_PP, undef, "INIT not called (too late)");
+    is($XS::APItest::END_called, 1, "END called");
+    is($XS::APItest::END_called_PP, 1, "END called");
+}

==== //depot/maint-5.8/perl/op.c#210 (text) ====
Index: perl/op.c
--- perl/op.c#209~30717~        2007-03-23 04:58:22.000000000 -0700
+++ perl/op.c   2007-03-23 06:35:25.000000000 -0700
@@ -4901,8 +4901,18 @@
            goto done;
 
        if (strEQ(s, "BEGIN")) {
+           const I32 oldscope = PL_scopestack_ix;
+           ENTER;
+           SAVECOPFILE(&PL_compiling);
+           SAVECOPLINE(&PL_compiling);
+
            Perl_av_create_and_push(aTHX_ &PL_beginav, (SV*)cv);
            GvCV(gv) = 0;               /* cv has been hijacked */
+           call_list(oldscope, PL_beginav);
+
+           PL_curcop = &PL_compiling;
+           CopHINTS_set(&PL_compiling, PL_hints);
+           LEAVE;
        }
        else if (strEQ(s, "END")) {
            Perl_av_create_and_unshift_one(aTHX_ &PL_endav, (SV*)cv);
End of Patch.

Reply via email to