📄 c.pm
字号:
my $sv; foreach $sv (@_) { svref_2object($sv)->save; }} sub Dummy_BootStrap { } sub B::GV::savecv { my $gv = shift; my $package=$gv->STASH->NAME; my $name = $gv->NAME; my $cv = $gv->CV; my $sv = $gv->SV; my $av = $gv->AV; my $hv = $gv->HV; # We may be looking at this package just because it is a branch in the # symbol table which is on the path to a package which we need to save # e.g. this is 'Getopt' and we need to save 'Getopt::Long' # return unless ($unused_sub_packages{$package}); return unless ($$cv || $$av || $$sv || $$hv); $gv->save;}sub mark_package{ my $package = shift; unless ($unused_sub_packages{$package}) { no strict 'refs'; $unused_sub_packages{$package} = 1; if (defined @{$package.'::ISA'}) { foreach my $isa (@{$package.'::ISA'}) { if ($isa eq 'DynaLoader') { unless (defined(&{$package.'::bootstrap'})) { warn "Forcing bootstrap of $package\n"; eval { $package->bootstrap }; } }# else { unless ($unused_sub_packages{$isa}) { warn "$isa saved (it is in $package\'s \@ISA)\n"; mark_package($isa); } } } } } return 1;} sub should_save{ no strict qw(vars refs); my $package = shift; $package =~ s/::$//; return $unused_sub_packages{$package} = 0 if ($package =~ /::::/); # skip ::::ISA::CACHE etc. # warn "Considering $package\n";#debug foreach my $u (grep($unused_sub_packages{$_},keys %unused_sub_packages)) { # If this package is a prefix to something we are saving, traverse it # but do not mark it for saving if it is not already # e.g. to get to Getopt::Long we need to traverse Getopt but need # not save Getopt return 1 if ($u =~ /^$package\:\:/); } if (exists $unused_sub_packages{$package}) { # warn "Cached $package is ".$unused_sub_packages{$package}."\n"; delete_unsaved_hashINC($package) unless $unused_sub_packages{$package} ; return $unused_sub_packages{$package}; } # Omit the packages which we use (and which cause grief # because of fancy "goto &$AUTOLOAD" stuff). # XXX Surely there must be a nicer way to do this. if ($package eq "FileHandle" || $package eq "Config" || $package eq "SelectSaver" || $package =~/^(B|IO)::/) { delete_unsaved_hashINC($package); return $unused_sub_packages{$package} = 0; } # Now see if current package looks like an OO class this is probably too strong. foreach my $m (qw(new DESTROY TIESCALAR TIEARRAY TIEHASH TIEHANDLE)) { if (UNIVERSAL::can($package, $m)) { warn "$package has method $m: saving package\n";#debug return mark_package($package); } } delete_unsaved_hashINC($package); return $unused_sub_packages{$package} = 0;}sub delete_unsaved_hashINC{ my $packname=shift; $packname =~ s/\:\:/\//g; $packname .= '.pm';# warn "deleting $packname" if $INC{$packname} ;# debug delete $INC{$packname};}sub walkpackages { my ($symref, $recurse, $prefix) = @_; my $sym; my $ref; no strict 'vars'; local(*glob); $prefix = '' unless defined $prefix; while (($sym, $ref) = each %$symref) { *glob = $ref; if ($sym =~ /::$/) { $sym = $prefix . $sym; if ($sym ne "main::" && $sym ne "<none>::" && &$recurse($sym)) { walkpackages(\%glob, $recurse, $sym); } } }}sub save_unused_subs { no strict qw(refs); &descend_marked_unused; warn "Prescan\n"; walkpackages(\%{"main::"}, sub { should_save($_[0]); return 1 }); warn "Saving methods\n"; walksymtable(\%{"main::"}, "savecv", \&should_save);}sub save_context{ my $curpad_nam = (comppadlist->ARRAY)[0]->save; my $curpad_sym = (comppadlist->ARRAY)[1]->save; my $inc_hv = svref_2object(\%INC)->save; my $inc_av = svref_2object(\@INC)->save; my $amagic_generate= amagic_generation; $init->add( "PL_curpad = AvARRAY($curpad_sym);", "GvHV(PL_incgv) = $inc_hv;", "GvAV(PL_incgv) = $inc_av;", "av_store(CvPADLIST(PL_main_cv),0,SvREFCNT_inc($curpad_nam));", "av_store(CvPADLIST(PL_main_cv),1,SvREFCNT_inc($curpad_sym));", "PL_amagic_generation= $amagic_generate;" );}sub descend_marked_unused { foreach my $pack (keys %unused_sub_packages) { mark_package($pack); }} sub save_main { warn "Starting compile\n"; warn "Walking tree\n"; seek(STDOUT,0,0); #exclude print statements in BEGIN{} into output walkoptree(main_root, "save"); warn "done main optree, walking symtable for extras\n" if $debug_cv; save_unused_subs(); my $init_av = init_av->save; $init->add(sprintf("PL_main_root = s\\_%x;", ${main_root()}), sprintf("PL_main_start = s\\_%x;", ${main_start()}), "PL_initav = (AV *) $init_av;"); save_context(); warn "Writing output\n"; output_boilerplate(); print "\n"; output_all("perl_init"); print "\n"; output_main();}sub init_sections { my @sections = (init => \$init, decl => \$decl, sym => \$symsect, binop => \$binopsect, condop => \$condopsect, cop => \$copsect, padop => \$padopsect, listop => \$listopsect, logop => \$logopsect, loop => \$loopsect, op => \$opsect, pmop => \$pmopsect, pvop => \$pvopsect, svop => \$svopsect, unop => \$unopsect, sv => \$svsect, xpv => \$xpvsect, xpvav => \$xpvavsect, xpvhv => \$xpvhvsect, xpvcv => \$xpvcvsect, xpviv => \$xpvivsect, xpvnv => \$xpvnvsect, xpvmg => \$xpvmgsect, xpvlv => \$xpvlvsect, xrv => \$xrvsect, xpvbm => \$xpvbmsect, xpvio => \$xpviosect); my ($name, $sectref); while (($name, $sectref) = splice(@sections, 0, 2)) { $$sectref = new B::C::Section $name, \%symtable, 0; }} sub mark_unused{ my ($arg,$val) = @_; $unused_sub_packages{$arg} = $val;}sub compile { my @options = @_; my ($option, $opt, $arg); OPTION: while ($option = shift @options) { if ($option =~ /^-(.)(.*)/) { $opt = $1; $arg = $2; } else { unshift @options, $option; last OPTION; } if ($opt eq "-" && $arg eq "-") { shift @options; last OPTION; } if ($opt eq "w") { $warn_undefined_syms = 1; } elsif ($opt eq "D") { $arg ||= shift @options; foreach $arg (split(//, $arg)) { if ($arg eq "o") { B->debug(1); } elsif ($arg eq "c") { $debug_cops = 1; } elsif ($arg eq "A") { $debug_av = 1; } elsif ($arg eq "C") { $debug_cv = 1; } elsif ($arg eq "M") { $debug_mg = 1; } else { warn "ignoring unknown debug option: $arg\n"; } } } elsif ($opt eq "o") { $arg ||= shift @options; open(STDOUT, ">$arg") or return "$arg: $!\n"; } elsif ($opt eq "v") { $verbose = 1; } elsif ($opt eq "u") { $arg ||= shift @options; mark_unused($arg,undef); } elsif ($opt eq "f") { $arg ||= shift @options; if ($arg eq "cog") { $pv_copy_on_grow = 1; } elsif ($arg eq "no-cog") { $pv_copy_on_grow = 0; } } elsif ($opt eq "O") { $arg = 1 if $arg eq ""; $pv_copy_on_grow = 0; if ($arg >= 1) { # Optimisations for -O1 $pv_copy_on_grow = 1; } } elsif ($opt eq "l") { $max_string_len = $arg; } } init_sections(); if (@options) { return sub { my $objname; foreach $objname (@options) { eval "save_object(\\$objname)"; } output_all(); } } else { return sub { save_main() }; }}1;__END__=head1 NAMEB::C - Perl compiler's C backend=head1 SYNOPSIS perl -MO=C[,OPTIONS] foo.pl=head1 DESCRIPTIONThis compiler backend takes Perl source and generates C source codecorresponding to the internal structures that perl uses to runyour program. When the generated C source is compiled and run, itcuts out the time which perl would have taken to load and parseyour program into its internal semi-compiled form. That means thatcompiling with this backend will not help improve the runtimeexecution speed of your program but may improve the start-up time.Depending on the environment in which your program runs this may beeither a help or a hindrance.=head1 OPTIONSIf there are any non-option arguments, they are taken to benames of objects to be saved (probably doesn't work properly yet).Without extra arguments, it saves the main program.=over 4=item B<-ofilename>Output to filename instead of STDOUT=item B<-v>Verbose compilation (currently gives a few compilation statistics).=item B<-->Force end of options=item B<-uPackname>Force apparently unused subs from package Packname to be compiled.This allows programs to use eval "foo()" even when sub foo is neverseen to be used at compile time. The down side is that any subs whichreally are never used also have code generated. This option isnecessary, for example, if you have a signal handler foo which youinitialise with C<$SIG{BAR} = "foo">. A better fix, though, is justto change it to C<$SIG{BAR} = \&foo>. You can have multiple B<-u>options. The compiler tries to figure out which packages may possiblyhave subs in which need compiling but the current version doesn't doit very well. In particular, it is confused by nested packages (i.e.of the form C<A::B>) where package C<A> does not contain any subs.=item B<-D>Debug options (concatenated or separate flags like C<perl -D>).=item B<-Do>OPs, prints each OP as it's processed=item B<-Dc>COPs, prints COPs as processed (incl. file & line num)=item B<-DA>prints AV information on saving=item B<-DC>prints CV information on saving=item B<-DM>prints MAGIC information on saving=item B<-f>Force optimisations on or off one at a time.=item B<-fcog>Copy-on-grow: PVs declared and initialised statically.=item B<-fno-cog>No copy-on-grow.=item B<-On>Optimisation level (n = 0, 1, 2, ...). B<-O> means B<-O1>. Currently,B<-O1> and higher set B<-fcog>.=item B<-llimit>Some C compilers impose an arbitrary limit on the length of stringconstants (e.g. 2048 characters for Microsoft Visual C++). TheB<-llimit> options tells the C backend not to generate string literalsexceeding that limit.=back=head1 EXAMPLES perl -MO=C,-ofoo.c foo.pl perl cc_harness -o foo foo.cNote that C<cc_harness> lives in the C<B> subdirectory of your perllibrary directory. The utility called C<perlcc> may also be used tohelp make use of this compiler. perl -MO=C,-v,-DcA,-l2048 bar.pl > /dev/null=head1 BUGSPlenty. Current status: experimental.=head1 AUTHORMalcolm Beattie, C<mbeattie@sable.ox.ac.uk>=cut
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -