⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 b.pm

📁 UNIX下perl实现代码
💻 PM
📖 第 1 页 / 共 2 页
字号:
#      B.pm##      Copyright (c) 1996, 1997, 1998 Malcolm Beattie##      You may distribute under the terms of either the GNU General Public#      License or the Artistic License, as specified in the README file.#package B;use XSLoader ();require Exporter;@ISA = qw(Exporter);# walkoptree_slow comes from B.pm (you are there),# walkoptree comes from B.xs@EXPORT_OK = qw(minus_c ppname save_BEGINs		class peekop cast_I32 cstring cchar hash threadsv_names		main_root main_start main_cv svref_2object opnumber		amagic_generation		walkoptree_slow walkoptree walkoptree_exec walksymtable		parents comppadlist sv_undef compile_stats timing_info		begin_av init_av end_av);sub OPf_KIDS ();use strict;@B::SV::ISA = 'B::OBJECT';@B::NULL::ISA = 'B::SV';@B::PV::ISA = 'B::SV';@B::IV::ISA = 'B::SV';@B::NV::ISA = 'B::IV';@B::RV::ISA = 'B::SV';@B::PVIV::ISA = qw(B::PV B::IV);@B::PVNV::ISA = qw(B::PV B::NV);@B::PVMG::ISA = 'B::PVNV';@B::PVLV::ISA = 'B::PVMG';@B::BM::ISA = 'B::PVMG';@B::AV::ISA = 'B::PVMG';@B::GV::ISA = 'B::PVMG';@B::HV::ISA = 'B::PVMG';@B::CV::ISA = 'B::PVMG';@B::IO::ISA = 'B::PVMG';@B::FM::ISA = 'B::CV';@B::OP::ISA = 'B::OBJECT';@B::UNOP::ISA = 'B::OP';@B::BINOP::ISA = 'B::UNOP';@B::LOGOP::ISA = 'B::UNOP';@B::LISTOP::ISA = 'B::BINOP';@B::SVOP::ISA = 'B::OP';@B::PADOP::ISA = 'B::OP';@B::PVOP::ISA = 'B::OP';@B::CVOP::ISA = 'B::OP';@B::LOOP::ISA = 'B::LISTOP';@B::PMOP::ISA = 'B::LISTOP';@B::COP::ISA = 'B::OP';@B::SPECIAL::ISA = 'B::OBJECT';{    # Stop "-w" from complaining about the lack of a real B::OBJECT class    package B::OBJECT;}sub B::GV::SAFENAME {  my $name = (shift())->NAME;  # The regex below corresponds to the isCONTROLVAR macro  # from toke.c  $name =~ s/^([\cA-\cZ\c\\c[\c]\c?\c_\c^])/"^".chr(64 ^ ord($1))/e;  return $name;}sub B::IV::int_value {  my ($self) = @_;  return (($self->FLAGS() & SVf_IVisUV()) ? $self->UVX : $self->IV);}my $debug;my $op_count = 0;my @parents = ();sub debug {    my ($class, $value) = @_;    $debug = $value;    walkoptree_debug($value);}sub class {    my $obj = shift;    my $name = ref $obj;    $name =~ s/^.*:://;    return $name;}sub parents { \@parents }# For debuggingsub peekop {    my $op = shift;    return sprintf("%s (0x%x) %s", class($op), $$op, $op->name);}sub walkoptree_slow {    my($op, $method, $level) = @_;    $op_count++; # just for statistics    $level ||= 0;    warn(sprintf("walkoptree: %d. %s\n", $level, peekop($op))) if $debug;    $op->$method($level);    if ($$op && ($op->flags & OPf_KIDS)) {	my $kid;	unshift(@parents, $op);	for ($kid = $op->first; $$kid; $kid = $kid->sibling) {	    walkoptree_slow($kid, $method, $level + 1);	}	shift @parents;    }}sub compile_stats {    return "Total number of OPs processed: $op_count\n";}sub timing_info {    my ($sec, $min, $hr) = localtime;    my ($user, $sys) = times;    sprintf("%02d:%02d:%02d user=$user sys=$sys",	    $hr, $min, $sec, $user, $sys);}my %symtable;sub clearsym {    %symtable = ();}sub savesym {    my ($obj, $value) = @_;#    warn(sprintf("savesym: sym_%x => %s\n", $$obj, $value)); # debug    $symtable{sprintf("sym_%x", $$obj)} = $value;}sub objsym {    my $obj = shift;    return $symtable{sprintf("sym_%x", $$obj)};}sub walkoptree_exec {    my ($op, $method, $level) = @_;    $level ||= 0;    my ($sym, $ppname);    my $prefix = "    " x $level;    for (; $$op; $op = $op->next) {	$sym = objsym($op);	if (defined($sym)) {	    print $prefix, "goto $sym\n";	    return;	}	savesym($op, sprintf("%s (0x%lx)", class($op), $$op));	$op->$method($level);	$ppname = $op->name;	if ($ppname =~	    /^(or|and|mapwhile|grepwhile|entertry|range|cond_expr)$/)	{	    print $prefix, uc($1), " => {\n";	    walkoptree_exec($op->other, $method, $level + 1);	    print $prefix, "}\n";	} elsif ($ppname eq "match" || $ppname eq "subst") {	    my $pmreplstart = $op->pmreplstart;	    if ($$pmreplstart) {		print $prefix, "PMREPLSTART => {\n";		walkoptree_exec($pmreplstart, $method, $level + 1);		print $prefix, "}\n";	    }	} elsif ($ppname eq "substcont") {	    print $prefix, "SUBSTCONT => {\n";	    walkoptree_exec($op->other->pmreplstart, $method, $level + 1);	    print $prefix, "}\n";	    $op = $op->other;	} elsif ($ppname eq "enterloop") {	    print $prefix, "REDO => {\n";	    walkoptree_exec($op->redoop, $method, $level + 1);	    print $prefix, "}\n", $prefix, "NEXT => {\n";	    walkoptree_exec($op->nextop, $method, $level + 1);	    print $prefix, "}\n", $prefix, "LAST => {\n";	    walkoptree_exec($op->lastop,  $method, $level + 1);	    print $prefix, "}\n";	} elsif ($ppname eq "subst") {	    my $replstart = $op->pmreplstart;	    if ($$replstart) {		print $prefix, "SUBST => {\n";		walkoptree_exec($replstart, $method, $level + 1);		print $prefix, "}\n";	    }	}    }}sub walksymtable {    my ($symref, $method, $recurse, $prefix) = @_;    my $sym;    my $ref;    no strict 'vars';    local(*glob);    $prefix = '' unless defined $prefix;    while (($sym, $ref) = each %$symref) {	*glob = "*main::".$prefix.$sym;	if ($sym =~ /::$/) {	    $sym = $prefix . $sym;	    if ($sym ne "main::" && $sym ne "<none>::" && &$recurse($sym)) {		walksymtable(\%glob, $method, $recurse, $sym);	    }	} else {	    svref_2object(\*glob)->EGV->$method();	}    }}{    package B::Section;    my $output_fh;    my %sections;        sub new {	my ($class, $section, $symtable, $default) = @_;	$output_fh ||= FileHandle->new_tmpfile;	my $obj = bless [-1, $section, $symtable, $default], $class;	$sections{$section} = $obj;	return $obj;    }        sub get {	my ($class, $section) = @_;	return $sections{$section};    }    sub add {	my $section = shift;	while (defined($_ = shift)) {	    print $output_fh "$section->[1]\t$_\n";	    $section->[0]++;	}    }    sub index {	my $section = shift;	return $section->[0];    }    sub name {	my $section = shift;	return $section->[1];    }    sub symtable {	my $section = shift;	return $section->[2];    }	    sub default {	my $section = shift;	return $section->[3];    }	    sub output {	my ($section, $fh, $format) = @_;	my $name = $section->name;	my $sym = $section->symtable || {};	my $default = $section->default;	seek($output_fh, 0, 0);	while (<$output_fh>) {	    chomp;	    s/^(.*?)\t//;	    if ($1 eq $name) {		s{(s\\_[0-9a-f]+)} {		    exists($sym->{$1}) ? $sym->{$1} : $default;		}ge;		printf $fh $format, $_;	    }	}    }}XSLoader::load 'B';1;__END__=head1 NAMEB - The Perl Compiler=head1 SYNOPSIS	use B;=head1 DESCRIPTIONThe C<B> module supplies classes which allow a Perl program to delveinto its own innards. It is the module used to implement the"backends" of the Perl compiler. Usage of the compiler does notrequire knowledge of this module: see the F<O> module for theuser-visible part. The C<B> module is of use to those who want towrite new compiler backends. This documentation assumes that thereader knows a fair amount about perl's internals including suchthings as SVs, OPs and the internal symbol table and syntax treeof a program.=head1 OVERVIEW OF CLASSESThe C structures used by Perl's internals to hold SV and OPinformation (PVIV, AV, HV, ..., OP, SVOP, UNOP, ...) are modelled on aclass hierarchy and the C<B> module gives access to them via a trueobject hierarchy. Structure fields which point to other objects(whether types of SV or types of OP) are represented by the C<B>module as Perl objects of the appropriate class. The bulk of the C<B>module is the methods for accessing fields of these structures. Notethat all access is read-only: you cannot modify the internals byusing this module.=head2 SV-RELATED CLASSESB::IV, B::NV, B::RV, B::PV, B::PVIV, B::PVNV, B::PVMG, B::BM, B::PVLV,B::AV, B::HV, B::CV, B::GV, B::FM, B::IO. These classes correspond inthe obvious way to the underlying C structures of similar names. Theinheritance hierarchy mimics the underlying C "inheritance". Accessmethods correspond to the underlying C macros for field access,usually with the leading "class indication" prefix removed (Sv, Av,Hv, ...). The leading prefix is only left in cases where its removalwould cause a clash in method name. For example, C<GvREFCNT> staysas-is since its abbreviation would clash with the "superclass" methodC<REFCNT> (corresponding to the C function C<SvREFCNT>).=head2 B::SV METHODS=over 4=item REFCNT=item FLAGS=back=head2 B::IV METHODS=over 4=item IVReturns the value of the IV, I<interpreted asa signed integer>. This will be misleadingif C<FLAGS & SVf_IVisUV>. Perhaps you want theC<int_value> method instead?=item IVX=item UVX=item int_valueThis method returns the value of the IV as an integer.It differs from C<IV> in that it returns the correctvalue regardless of whether it's stored signed orunsigned.=item needs64bits=item packiv=back=head2 B::NV METHODS=over 4=item NV=item NVX=back=head2 B::RV METHODS=over 4=item RV=back=head2 B::PV METHODS=over 4=item PVThis method is the one you usually want. It constructs astring using the length and offset information in the struct:for ordinary scalars it will return the string that you'd seefrom Perl, even if it contains null characters.=item PVXThis method is less often useful. It assumes that the stringstored in the struct is null-terminated, and disregards thelength information.It is the appropriate method to use if you need to get the nameof a lexical variable from a padname array. Lexical variable namesare always stored with a null terminator, and the length field(SvCUR) is overloaded for other purposes and can't be relied on here.=back=head2 B::PVMG METHODS=over 4=item MAGIC=item SvSTASH=back=head2 B::MAGIC METHODS=over 4=item MOREMAGIC=item PRIVATE=item TYPE=item FLAGS=item OBJ=item PTR=back=head2 B::PVLV METHODS=over 4=item TARGOFF

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -