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

📄 concise.pm

📁 source of perl for linux application,
💻 PM
📖 第 1 页 / 共 4 页
字号:
# B::OP::terse (see Terse.pm) now just calls thissub b_terse {    my($op, $level) = @_;    # This isn't necessarily right, but there's no easy way to get    # from an OP to the right CV. This is a limitation of the    # ->terse() interface style, and there isn't much to do about    # it. In particular, we can die in concise_op if the main pad    # isn't long enough, or has the wrong kind of entries, compared to    # the pad a sub was compiled with. The fix for that would be to    # make a backwards compatible "terse" format that never even    # looked at the pad, just like the old B::Terse. I don't think    # that's worth the effort, though.    $curcv = main_cv unless $curcv;    if ($order eq "exec" and $lastnext and $$lastnext != $$op) {	# insert a 'goto'	my $h = {"seq" => seq($lastnext), "class" => class($lastnext),		 "addr" => sprintf("%#x", $$lastnext)};	print # $walkHandle	    fmt_line($h, $op, $style{"terse"}[1], $level+1);    }    $lastnext = $op->next;    print # $walkHandle 	concise_op($op, $level, $style{"terse"}[0]);}sub tree {    my $op = shift;    my $level = shift;    my $style = $tree_decorations[$tree_style];    my($space, $single, $kids, $kid, $nokid, $last, $lead, $size) = @$style;    my $name = concise_op($op, $level, $treefmt);    if (not $op->flags & OPf_KIDS) {	return $name . "\n";    }    my @lines;    for (my $kid = $op->first; $$kid; $kid = $kid->sibling) {	push @lines, tree($kid, $level+1);    }    my $i;    for ($i = $#lines; substr($lines[$i], 0, 1) eq " "; $i--) {	$lines[$i] = $space . $lines[$i];    }    if ($i > 0) {	$lines[$i] = $last . $lines[$i];	while ($i-- > 1) {	    if (substr($lines[$i], 0, 1) eq " ") {		$lines[$i] = $nokid . $lines[$i];	    } else {		$lines[$i] = $kid . $lines[$i];	    }	}	$lines[$i] = $kids . $lines[$i];    } else {	$lines[0] = $single . $lines[0];    }    return("$name$lead" . shift @lines,           map(" " x (length($name)+$size) . $_, @lines));}# *** Warning: fragile kludge ahead ***# Because the B::* modules run in the same interpreter as the code# they're compiling, their presence tends to distort the view we have of# the code we're looking at. In particular, perl gives sequence numbers# to COPs. If the program we're looking at were run on its own, this# would start at 1. Because all of B::Concise and all the modules it# uses are compiled first, though, by the time we get to the user's# program the sequence number is already pretty high, which could be# distracting if you're trying to tell OPs apart. Therefore we'd like to# subtract an offset from all the sequence numbers we display, to# restore the simpler view of the world. The trick is to know what that# offset will be, when we're still compiling B::Concise!  If we# hardcoded a value, it would have to change every time B::Concise or# other modules we use do. To help a little, what we do here is compile# a little code at the end of the module, and compute the base sequence# number for the user's program as being a small offset later, so all we# have to worry about are changes in the offset.# [For 5.8.x and earlier perl is generating sequence numbers for all ops,#  and using them to reference labels]# When you say "perl -MO=Concise -e '$a'", the output should look like:# 4  <@> leave[t1] vKP/REFC ->(end)# 1     <0> enter ->2 #^ smallest OP sequence number should be 1# 2     <;> nextstate(main 1 -e:1) v ->3 #                         ^ smallest COP sequence number should be 1# -     <1> ex-rv2sv vK/1 ->4# 3        <$> gvsv(*a) s ->4# If the second of the marked numbers there isn't 1, it means you need# to update the corresponding magic number in the next line.# Remember, this needs to stay the last things in the module.# Why is this different for MacOS?  Does it matter?my $cop_seq_mnum = $^O eq 'MacOS' ? 12 : 11;$cop_seq_base = svref_2object(eval 'sub{0;}')->START->cop_seq + $cop_seq_mnum;1;__END__=head1 NAMEB::Concise - Walk Perl syntax tree, printing concise info about ops=head1 SYNOPSIS    perl -MO=Concise[,OPTIONS] foo.pl    use B::Concise qw(set_style add_callback);=head1 DESCRIPTIONThis compiler backend prints the internal OPs of a Perl program's syntaxtree in one of several space-efficient text formats suitable for debuggingthe inner workings of perl or other compiler backends. It can print OPs inthe order they appear in the OP tree, in the order they will execute, orin a text approximation to their tree structure, and the format of theinformation displayed is customizable. Its function is similar to that ofperl's B<-Dx> debugging flag or the B<B::Terse> module, but it is moresophisticated and flexible.=head1 EXAMPLEHere's two outputs (or 'renderings'), using the -exec and -basic(i.e. default) formatting conventions on the same code snippet.    % perl -MO=Concise,-exec -e '$a = $b + 42'    1  <0> enter    2  <;> nextstate(main 1 -e:1) v    3  <#> gvsv[*b] s    4  <$> const[IV 42] s *  5  <2> add[t3] sK/2    6  <#> gvsv[*a] s    7  <2> sassign vKS/2    8  <@> leave[1 ref] vKP/REFCIn this -exec rendering, each opcode is executed in the order shown.The add opcode, marked with '*', is discussed in more detail.The 1st column is the op's sequence number, starting at 1, and isdisplayed in base 36 by default.  Here they're purely linear; thesequences are very helpful when looking at code with loops andbranches.The symbol between angle brackets indicates the op's type, forexample; <2> is a BINOP, <@> a LISTOP, and <#> is a PADOP, which isused in threaded perls. (see L</"OP class abbreviations">).The opname, as in B<'add[t1]'>, may be followed by op-specificinformation in parentheses or brackets (ex B<'[t1]'>).The op-flags (ex B<'sK/2'>) are described in (L</"OP flagsabbreviations">).    % perl -MO=Concise -e '$a = $b + 42'    8  <@> leave[1 ref] vKP/REFC ->(end)    1     <0> enter ->2    2     <;> nextstate(main 1 -e:1) v ->3    7     <2> sassign vKS/2 ->8 *  5        <2> add[t1] sK/2 ->6    -           <1> ex-rv2sv sK/1 ->4    3              <$> gvsv(*b) s ->4    4           <$> const(IV 42) s ->5    -        <1> ex-rv2sv sKRM*/1 ->7    6           <$> gvsv(*a) s ->7The default rendering is top-down, so they're not in execution order.This form reflects the way the stack is used to parse and evaluateexpressions; the add operates on the two terms below it in the tree.Nullops appear as C<ex-opname>, where I<opname> is an op that has beenoptimized away by perl.  They're displayed with a sequence-number of'-', because they are not executed (they don't appear in previousexample), they're printed here because they reflect the parse.The arrow points to the sequence number of the next op; they're notdisplayed in -exec mode, for obvious reasons.Note that because this rendering was done on a non-threaded perl, thePADOPs in the previous examples are now SVOPs, and some (but not all)of the square brackets have been replaced by round ones.  This is asubtle feature to provide some visual distinction between renderingson threaded and un-threaded perls.=head1 OPTIONSArguments that don't start with a hyphen are taken to be the names ofsubroutines to render; if no such functions are specified, the mainbody of the program (outside any subroutines, and not including use'dor require'd files) is rendered.  Passing C<BEGIN>, C<UNITCHECK>,C<CHECK>, C<INIT>, or C<END> will cause all of the correspondingspecial blocks to be printed.  Arguments must follow options.Options affect how things are rendered (ie printed).  They're presentedhere by their visual effect, 1st being strongest.  They're groupedaccording to how they interrelate; within each group the options aremutually exclusive (unless otherwise stated).=head2 Options for Opcode OrderingThese options control the 'vertical display' of opcodes.  The display'order' is also called 'mode' elsewhere in this document.=over 4=item B<-basic>Print OPs in the order they appear in the OP tree (a preordertraversal, starting at the root). The indentation of each OP shows itslevel in the tree, and the '->' at the end of the line indicates thenext opcode in execution order.  This mode is the default, so the flagis included simply for completeness.=item B<-exec>Print OPs in the order they would normally execute (for the majorityof constructs this is a postorder traversal of the tree, ending at theroot). In most cases the OP that usually follows a given OP willappear directly below it; alternate paths are shown by indentation. Incases like loops when control jumps out of a linear path, a 'goto'line is generated.=item B<-tree>Print OPs in a text approximation of a tree, with the root of the treeat the left and 'left-to-right' order of children transformed into'top-to-bottom'. Because this mode grows both to the right and down,it isn't suitable for large programs (unless you have a very wideterminal).=back=head2 Options for Line-StyleThese options select the line-style (or just style) used to rendereach opcode, and dictates what info is actually printed into each line.=over 4=item B<-concise>Use the author's favorite set of formatting conventions. This is thedefault, of course.=item B<-terse>Use formatting conventions that emulate the output of B<B::Terse>. Thebasic mode is almost indistinguishable from the real B<B::Terse>, and theexec mode looks very similar, but is in a more logical order and lackscurly brackets. B<B::Terse> doesn't have a tree mode, so the tree modeis only vaguely reminiscent of B<B::Terse>.=item B<-linenoise>Use formatting conventions in which the name of each OP, rather than beingwritten out in full, is represented by a one- or two-character abbreviation.This is mainly a joke.=item B<-debug>Use formatting conventions reminiscent of B<B::Debug>; these aren'tvery concise at all.=item B<-env>Use formatting conventions read from the environment variablesC<B_CONCISE_FORMAT>, C<B_CONCISE_GOTO_FORMAT>, and C<B_CONCISE_TREE_FORMAT>.=back=head2 Options for tree-specific formatting=over 4=item B<-compact>Use a tree format in which the minimum amount of space is used for thelines connecting nodes (one character in most cases). This squeezes outa few precious columns of screen real estate.=item B<-loose>Use a tree format that uses longer edges to separate OP nodes. This formattends to look better than the compact one, especially in ASCII, and isthe default.=item B<-vt>Use tree connecting characters drawn from the VT100 line-drawing set.This looks better if your terminal supports it.=item B<-ascii>Draw the tree with standard ASCII characters like C<+> and C<|>. These don'tlook as clean as the VT100 characters, but they'll work with almost anyterminal (or the horizontal scrolling mode of less(1)) and are suitablefor text documentation or email. This is the default.=backThese are pairwise exclusive, i.e. compact or loose, vt or ascii.=head2 Options controlling sequence numbering=over 4=item B<-base>I<n>Print OP sequence numbers in base I<n>. If I<n> is greater than 10, thedigit for 11 will be 'a', and so on. If I<n> is greater than 36, the digitfor 37 will be 'A', and so on until 62. Values greater than 62 are notcurrently supported. The default is 36.=item B<-bigendian>Print sequence numbers with the most significant digit first. This is theusual convention for Arabic numerals, and the default.=item B<-littleendian>Print seqence numbers with the least significant digit first.  This isobviously mutually exclusive with bigendian.=back=head2 Other options=over 4=item B<-src>With this option, the rendering of each statement (starting with thenextstate OP) will be preceded by the 1st line of source code thatgenerates it.  For example:    1  <0> enter    # 1: my $i;    2  <;> nextstate(main 1 junk.pl:1) v:{    3  <0> padsv[$i:1,10] vM/LVINTRO    # 3: for $i (0..9) {    4  <;> nextstate(main 3 junk.pl:3) v:{    5  <0> pushmark s    6  <$> const[IV 0] s    7  <$> const[IV 9] s    8  <{> enteriter(next->j last->m redo->9)[$i:1,10] lKS    k  <0> iter s    l  <|> and(other->9) vK/1    # 4:     print "line ";    9      <;> nextstate(main 2 junk.pl:4) v    a      <0> pushmark s    b      <$> const[PV "line "] s    c      <@> print vK    # 5:     print "$i\n";    ...=item B<-stash="somepackage">With this, "somepackage" will be required, then the stash isinspected, and each function is rendered.=backThe following options are pairwise exclusive.=over 4=item B<-main>Include the main program in the output, even if subroutines were alsospecified.  This rendering is normally suppressed when a subroutinename or reference is given.=item B<-nomain>This restores the default behavior after you've changed it with '-main'(it's not normally needed).  If no subroutine name/ref is given, main isrendered, regardless of this flag.=item B<-nobanner>Renderings usually include a banner line identifying the function nameor stringified subref.  This suppresses the printing of the banner.TBC: Remove the stringified coderef; while it provides a 'cookie' foreach function rendered, the cookies used should be 1,2,3.. not arandom hex-address.  It also complicates string comparison of twodifferent trees.=item B<-banner>restores default banner behavior.=item B<-banneris> => subrefTBC: a hookpoint (and an option to set it) for a user-suppliedfunction to produce a banner appropriate for users needs.  It's notideal, because the rendering-state variables, which are a naturalcandidate for use in concise.t, are unavailable to the user.=back=head2 Option StickinessIf you invoke Concise more than once in a program, you should know thatthe options are 'sticky'.  This means that the options you provide inthe first call will be remembered for the 2nd call, unless youre-specify or change them.=head1 ABBREVIATIONSThe concise style uses symbols to convey maximum info with minimalclutter (like hex addresses).  With just a little practice, you canstart to see the flowers, not just the branches, in the trees.=head2 OP class abbreviationsThese symbols appear before the op-name, and indicate theB:: namespace that represents the ops in your Perl code.    0      OP (aka BASEOP)  An OP with no children    1      UNOP             An OP with one child    2      BINOP            An OP with two children    |      LOGOP            A control branch OP    @      LISTOP           An OP that could have lots of children    /      PMOP             An OP with a regular expression    $      SVOP             An OP with an SV    "      PVOP             An OP with a string    {      LOOP             An OP that holds pointers for a loop    ;      COP              An OP that marks the start of a statement    #      PADOP            An OP with a GV on the pad=head2 OP flags abbreviationsOP flags are either public or private.  The public flags alter thebehavior of each opcode in consistent ways, and are represented by 0or more single characters.    v      OPf_WANT_VOID    Want nothing (void context)    s      OPf_WANT_SCALAR  Want single value (scalar context)    l      OPf_WANT_LIST    Want list of any length (list context)                            Want is unknown    K      OPf_KIDS         There is a firstborn child.    P      OPf_PARENS       This operator was parenthesized.                             (Or block needs explicit scope entry.)    R      OPf_REF          Certified reference.                             (Return container, not containee).    M      OPf_MOD          Will modify (lvalue).    S      OPf_STACKED      Some arg is arriving on the stack.    *      OPf_SPECIAL      Do something weird for this op (see op.h)

⌨️ 快捷键说明

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