B::Deparse: sv_no != 0
[p5sagit/p5-mst-13.2.git] / ext / B / B / Bblock.pm
index ba6293b..35a80ea 100644 (file)
@@ -1,11 +1,16 @@
 package B::Bblock;
+
+our $VERSION = '1.00';
+
 use Exporter ();
 @ISA = "Exporter";
 @EXPORT_OK = qw(find_leaders);
 
 use B qw(peekop walkoptree walkoptree_exec
-        main_root main_start svref_2object OPf_SPECIAL OPf_STACKED);
-use B::Terse;
+        main_root main_start svref_2object
+         OPf_SPECIAL OPf_STACKED );
+
+use B::Concise qw(concise_cv concise_main set_style_standard);
 use strict;
 
 my $bblock;
@@ -17,19 +22,19 @@ sub mark_leader {
        $bblock->{$$op} = $op;
     }
 }
-sub remove_sortblocks{
-    foreach (keys %$bblock) {
-        my $leader = $$bblock{$_};
-       delete  $$bblock{$_} if ( $leader == 0);
+
+sub remove_sortblock{
+    foreach (keys %$bblock){
+        my $leader=$$bblock{$_};       
+       delete $$bblock{$_} if( $leader == 0);   
     }
 }
-
 sub find_leaders {
     my ($root, $start) = @_;
     $bblock = {};
     mark_leader($start) if ( ref $start ne "B::NULL" );
     walkoptree($root, "mark_if_leader") if ((ref $root) ne "B::NULL") ;
-    remove_sortblocks();
+    remove_sortblock();
     return $bblock;
 }
 
@@ -59,8 +64,6 @@ sub walk_bblocks {
        }
        printf "    %s\n", peekop($lastop);
     }
-    print "-------\n";
-    walkoptree_exec($start, "terse");
 }
 
 sub walk_bblocks_obj {
@@ -88,39 +91,32 @@ sub B::LOOP::mark_if_leader {
 
 sub B::LOGOP::mark_if_leader {
     my $op = shift;
-    my $ppaddr = $op->ppaddr;
+    my $opname = $op->name;
     mark_leader($op->next);
-    if ($ppaddr eq "pp_entertry") {
+    if ($opname eq "entertry") {
        mark_leader($op->other->next);
     } else {
        mark_leader($op->other);
     }
 }
 
-sub B::CONDOP::mark_if_leader {
-    my $op = shift;
-    mark_leader($op->next);
-    mark_leader($op->true);
-    mark_leader($op->false);
-}
-
 sub B::LISTOP::mark_if_leader {
     my $op = shift;
     my $first=$op->first;
-    $first=$first->next        while ($first->ppaddr eq "pp_null"); #remove optimed
+    $first=$first->next while ($first->name eq "null");
     mark_leader($op->first) unless (exists( $bblock->{$$first}));
     mark_leader($op->next);
-    if ($op->ppaddr eq "pp_sort" && $op->flags
-       & OPf_SPECIAL && $op->flags & OPf_STACKED){     
-         my $root=$op->first->sibling->first;
-         my $leader=$root->first;
-         $bblock->{$$leader} = 0;
-}
+    if ($op->name eq "sort" and $op->flags & OPf_SPECIAL
+       and $op->flags & OPf_STACKED){
+        my $root=$op->first->sibling->first;
+        my $leader=$root->first;
+        $bblock->{$$leader} = 0;
+    }
 }
 
 sub B::PMOP::mark_if_leader {
     my $op = shift;
-    if ($op->ppaddr ne "pp_pushre") {
+    if ($op->name ne "pushre") {
        my $replroot = $op->pmreplroot;
        if ($$replroot) {
            mark_leader($replroot);
@@ -134,6 +130,7 @@ sub B::PMOP::mark_if_leader {
 
 sub compile {
     my @options = @_;
+    B::clearsym();
     if (@options) {
        return sub {
            my $objname;
@@ -141,10 +138,19 @@ sub compile {
                $objname = "main::$objname" unless $objname =~ /::/;
                eval "walk_bblocks_obj(\\&$objname)";
                die "walk_bblocks_obj(\\&$objname) failed: $@" if $@;
+               print "-------\n";
+               set_style_standard("terse");
+               eval "concise_cv('exec', \\&$objname)";
+               die "concise_cv('exec', \\&$objname) failed: $@" if $@;
            }
        }
     } else {
-       return sub { walk_bblocks(main_root, main_start) };
+       return sub {
+           walk_bblocks(main_root, main_start);
+           print "-------\n";
+           set_style_standard("terse");
+           concise_main("exec");
+       };
     }
 }
 
@@ -155,7 +161,6 @@ sub compile {
 #     The ops pointed at by nextop, redoop and lastop->op_next of a LOOP
 #     The ops pointed at by op_next and op_other of a LOGOP, except
 #     for pp_entertry which has op_next and op_other->op_next
-#     The ops pointed at by op_true and op_false of a CONDOP
 #     The op pointed at by op_pmreplstart of a PMOP
 #     The op pointed at by op_other->op_pmreplstart of pp_substcont?
 #     [The op after a pp_return] Omit
@@ -170,11 +175,47 @@ B::Bblock - Walk basic blocks
 
 =head1 SYNOPSIS
 
-       perl -MO=Bblock[,OPTIONS] foo.pl
+  # External interface
+  perl -MO=Bblock[,OPTIONS] foo.pl
+
+  # Programmatic API
+  use B::Bblock qw(find_leaders);
+  my $leaders = find_leaders($root_op, $start_op);
 
 =head1 DESCRIPTION
 
-See F<ext/B/README>.
+This module is used by the B::CC back end.  It walks "basic blocks".
+A basic block is a series of operations which is known to execute from
+start to finish, with no possiblity of branching or halting.
+
+It can be used either stand alone or from inside another program.
+
+=for _private
+Somebody who understands the stand-alone options document them, please.
+
+=head2 Functions
+
+=over 4
+
+=item B<find_leaders>
+
+  my $leaders = find_leaders($root_op, $start_op);
+
+Given the root of the op tree and an op from which to start
+processing, it will return a hash ref representing all the ops which
+start a block.
+
+=for _private
+The above description may be somewhat wrong.
+
+The values of %$leaders are the op objects themselves.  Keys are $$op
+addresses.
+
+=for _private
+Above cribbed from B::CC's comments.  What's a $$op address?
+
+=back
+
 
 =head1 AUTHOR