--- ./utils/h2xs.PL-pre	Sun Mar 16 22:09:12 2003
+++ ./utils/h2xs.PL	Mon Apr 21 22:28:46 2003
@@ -241,6 +241,11 @@ Do not use the pragma C<strict>.
 
 Do not use the pragma C<warnings>.
 
+=item B<--late-load>
+
+Do not use C<BEGIN{}> block to load XS code (see L<XSLoader/"Order of
+initialization: early load()">).
+
 =item B<-v>, B<--version>=I<version>
 
 Specify a version number for this extension.  This version number is added
@@ -518,6 +523,7 @@ OPTIONS:
         --skip-autoloader Do not use the module C<AutoLoader>
         --skip-strict     Do not use the pragma C<strict>
         --skip-warnings   Do not use the pragma C<warnings>
+        --late-load       Do not use BEGIN block to load XS code
     -v, --version         Specify a version number for this extension.
     -x, --autogen-xsubs   Autogenerate XSUBs using C::Scan.
 
@@ -558,6 +564,7 @@ my ($opt_A,
     $skip_autoloader,
     $skip_strict,
     $skip_warnings,
+    $late_load,
    );
 
 Getopt::Long::Configure('bundling');
@@ -594,6 +601,7 @@ my %options = (
                 'skip-autoloader'    => \$skip_autoloader,
                 'skip-warnings'      => \$skip_warnings,
                 'skip-strict'        => \$skip_strict,
+                'late-load'          => \$late_load,
               );
 
 GetOptions(%options) || usage;
@@ -1048,10 +1056,6 @@ require Exporter;
 END
 
 my $use_Dyna = (not $opt_X and $compat_version < 5.006);
-print PM <<"END" if $use_Dyna;  # use DynaLoader, unless XS was disabled
-require DynaLoader;
-END
-
 
 # Are we using AutoLoader or not?
 unless ($skip_autoloader) { # no autoloader whatsoever.
@@ -1068,22 +1072,15 @@ if ( $compat_version < 5.006 ) {
     $vars .= ' @EXPORT @EXPORT_OK %EXPORT_TAGS' unless $skip_exporter;
     $vars .= ' $AUTOLOAD' unless $opt_X || $opt_c || $opt_A;
     $vars .= ' $XS_VERSION' if $opt_B && !$opt_X;
-    print PM "use vars qw($vars);";
+    print PM "use vars qw($vars);\n";
 }
 
-# Determine @ISA.
-my @modISA;
-push @modISA, 'Exporter'	unless $skip_exporter; 
-push @modISA, 'DynaLoader' 	if $use_Dyna;  # no XS
-my $myISA = "our \@ISA = qw(@modISA);";
-$myISA =~ s/^our // if $compat_version < 5.006;
-
-print PM "\n$myISA\n\n";
-
 my @exported_names = (@const_names, @fnames_no_prefix, map '$'.$_, @vdecls);
 
-my $tmp='';
-$tmp .= <<"END" unless $skip_exporter;
+my $tmp;
+unless ($skip_exporter) {
+  $tmp = <<"END" unless $skip_exporter;
+
 # Items to export into callers namespace by default. Note: do not export
 # names by default without a very good reason. Use EXPORT_OK instead.
 # Do not simply export all your public functions/methods/constants.
@@ -1102,42 +1099,71 @@ our \@EXPORT = qw(
 );
 
 END
+  $tmp =~ s/^our //mg if $compat_version < 5.006;
+  print PM $tmp;
+}
+
+print PM autoload ($module, $compat_version) unless $opt_c or $opt_X;
+
+print PM <<'EOP' if $compat_version >= 5.006 and not $late_load;
+our ($VERSION, @ISA);
+EOP
+
+# Use the early-load boilerplate
+print PM "BEGIN {\n" unless $late_load;
 
+$tmp='';
 $tmp .= "our \$VERSION = '$TEMPLATE_VERSION';\n";
 if ($opt_B) {
     $tmp .= "our \$XS_VERSION = \$VERSION;\n" unless $opt_X;
     $tmp .= "\$VERSION = eval \$VERSION;  # see L<perlmodstyle>\n";
 }
-$tmp .= "\n";
 
-$tmp =~ s/^our //mg if $compat_version < 5.006;
+# Determine @ISA.
+my @modISA;
+push @modISA, 'Exporter'	unless $skip_exporter; 
+$tmp .= "our \@ISA = qw(@modISA);\n";
+$tmp =~ s/^our //mg if $compat_version < 5.006 or not $late_load;
+$tmp =~ s/^(?=.)/    /mg unless $late_load;
 print PM $tmp;
 
-if (@vdecls) {
-    printf PM "our(@{[ join ', ', map '$'.$_, @vdecls ]});\n\n";
-}
-
-
-print PM autoload ($module, $compat_version) unless $opt_c or $opt_X;
 
 if( ! $opt_X ){ # print bootstrap, unless XS is disabled
+  $tmp = <<EOT;
+# Initializations (or subs) needed for running BOOT: section of XS go here
+
+EOT
   if ($use_Dyna) {
-	$tmp = <<"END";
-bootstrap $module \$VERSION;
+	$tmp .= <<"END";
+eval {
+    require XSLoader;
+    XSLoader::load('$module', \$VERSION);
+    1;
+} or do {
+    require DynaLoader;
+    push \@ISA, 'DynaLoader';
+    bootstrap $module \$VERSION;
+};
 END
   } else {
-	$tmp = <<"END";
+	$tmp .= <<"END";
 require XSLoader;
 XSLoader::load('$module', \$VERSION);
 END
   }
   $tmp =~ s:\$VERSION:\$XS_VERSION:g if $opt_B;
+  $tmp =~ s/^(?=.)/    /mg unless $late_load;
+  $tmp =~ s/^ {8}/\t/mg;
   print PM $tmp;
 }
 
+# Finish the early-load boilerplate
+print PM "}\n" unless $late_load;
+
 # tying the variables can happen only after bootstrap
 if (@vdecls) {
     printf PM <<END;
+our(@{[ join ', ', map '$'.$_, @vdecls ]});
 {
 @{[ join "\n", map "    _tievar_$_(\$$_);", @vdecls ]}
 }
@@ -1153,9 +1179,10 @@ else {
 	$after = '=cut';
 }
 
+$tmp = ($opt_X or $late_load) ? '' : "\n# It is OK to calls our XSUBs here.";
 print PM <<"END";
 
-# Preloaded methods go here.
+# Initialization code and preloaded methods/subs go here.$tmp
 END
 
 print PM <<"END" unless $opt_A;
@@ -1845,6 +1872,8 @@ WriteMakefile(
     NAME              => '$module',
     VERSION_FROM      => '$modfname.pm', # finds \$VERSION
     PREREQ_PM         => {$prereq_pm}, # e.g., Module::Name => 1.1
+END
+print PL <<"END" unless $opt_P;
     (\$] >= 5.005 ?     ## Add these new keywords supported since 5.005
       (ABSTRACT_FROM  => '$modfname.pm', # retrieve abstract from module
        AUTHOR         => '$author <$email>') : ()),
