File Coverage

blib/lib/B/Bblock.pm
Criterion Covered Total %
statement 9 99 9.0
branch 0 34 0.0
condition 0 21 0.0
subroutine 3 17 17.6
pod 1 6 16.6
total 13 177 7.3


line stmt bran cond sub pod time code
1             # Maintained now in B::C by Reini Urban
2             package B::Bblock;
3              
4             our $VERSION = '1.04';
5              
6 15     15   684 use Exporter ();
  15         17  
  15         686  
7             @ISA = "Exporter";
8             our @EXPORT_OK = qw(find_leaders);
9              
10 15         940 use B qw(peekop walkoptree walkoptree_exec
11             main_root main_start svref_2object
12 15     15   58 OPf_SPECIAL OPf_STACKED );
  15         17  
13              
14 15     15   48 use strict;
  15         16  
  15         12270  
15              
16             my $bblock;
17             my @bblock_ends;
18              
19             sub mark_leader {
20 0     0 0   my $op = shift;
21 0 0         if ($$op) {
22 0           $bblock->{$$op} = $op;
23             }
24             }
25              
26             sub remove_sortblock {
27 0     0 0   foreach ( keys %$bblock ) {
28 0           my $leader = $$bblock{$_};
29 0 0         delete $$bblock{$_} if ( $leader == 0 );
30             }
31             }
32              
33             sub find_leaders {
34 0     0 1   my ( $root, $start ) = @_;
35 0           $bblock = {};
36 0 0         mark_leader($start) if ( ref $start ne "B::NULL" );
37 0 0         walkoptree( $root, "mark_if_leader" ) if ( ( ref $root ) ne "B::NULL" );
38 0           remove_sortblock();
39 0           return $bblock;
40             }
41              
42             # Debugging
43             sub walk_bblocks {
44 0     0 0   my ( $root, $start ) = @_;
45 0           my ( $op, $lastop, $leader, $bb );
46 0           $bblock = {};
47 0           mark_leader($start);
48 0           walkoptree( $root, "mark_if_leader" );
49 0           my @leaders = values %$bblock;
50 0           while ( $leader = shift @leaders ) {
51 0           $lastop = $leader;
52 0           $op = $leader->next;
53 0   0       while ( $$op && !exists( $bblock->{$$op} ) ) {
54 0           $bblock->{$$op} = $leader;
55 0           $lastop = $op;
56 0           $op = $op->next;
57             }
58 0           push( @bblock_ends, [ $leader, $lastop ] );
59             }
60 0           foreach $bb (@bblock_ends) {
61 0           ( $leader, $lastop ) = @$bb;
62 0           printf "%s .. %s\n", peekop($leader), peekop($lastop);
63 0           for ( $op = $leader ; $$op != $$lastop ; $op = $op->next ) {
64 0           printf " %s\n", peekop($op);
65             }
66 0           printf " %s\n", peekop($lastop);
67             }
68             }
69              
70             sub walk_bblocks_obj {
71 0     0 0   my $cvref = shift;
72 0           my $cv = svref_2object($cvref);
73 0           walk_bblocks( $cv->ROOT, $cv->START );
74             }
75              
76       0     sub B::OP::mark_if_leader { }
77              
78             sub B::COP::mark_if_leader {
79 0     0     my $op = shift;
80 0 0         if ( $op->label ) {
81 0           mark_leader($op);
82             }
83             }
84              
85             sub B::LOOP::mark_if_leader {
86 0     0     my $op = shift;
87 0           mark_leader( $op->next );
88 0           mark_leader( $op->nextop );
89 0           mark_leader( $op->redoop );
90 0           mark_leader( $op->lastop->next );
91             }
92              
93             sub B::LOGOP::mark_if_leader {
94 0     0     my $op = shift;
95 0           my $opname = $op->name;
96 0           mark_leader( $op->next );
97 0 0         if ( $opname eq "entertry" ) {
98 0           mark_leader( $op->other->next );
99             }
100             else {
101 0           mark_leader( $op->other );
102             }
103             }
104              
105             sub B::LISTOP::mark_if_leader {
106 0     0     my $op = shift;
107 0           my $first = $op->first;
108 0           $first = $first->next while ( $first->name eq "null" );
109 0 0         mark_leader( $op->first ) unless ( exists( $bblock->{$$first} ) );
110 0           mark_leader( $op->next );
111 0 0 0       if ( $op->name eq "sort"
      0        
112             and $op->flags & OPf_SPECIAL
113             and $op->flags & OPf_STACKED )
114             {
115 0           my $root = $op->first->sibling->first;
116 0           my $leader = $root->first;
117 0           $bblock->{$$leader} = 0;
118             }
119             }
120              
121             sub B::PMOP::mark_if_leader {
122 0     0     my $op = shift;
123 0 0 0       if ( $op->type
      0        
      0        
124             and $op->name ne "pushre"
125             and ($] > 5.008005 or $op->name ne "substcont") )
126             {
127             #warn $op->name, $op->type if $] == 5.008004;
128 0           my $replroot = $op->pmreplroot;
129 0 0         if ($$replroot) {
130 0           mark_leader( $replroot );
131 0           mark_leader( $op->next );
132 0           mark_leader( $op->pmreplstart );
133             }
134             }
135             }
136              
137             # PMOP stuff omitted
138              
139             sub compile {
140 0     0 0   my @options = @_;
141 0           my $have_B_Concise;
142 0           B::clearsym();
143              
144 0 0         eval { require B::Concise; 1 } and $have_B_Concise = 1;
  0            
  0            
145 0 0         B::Concise->import(qw(concise_cv concise_main set_style_standard))
146             if $have_B_Concise;
147              
148 0 0 0       if ( @options and $have_B_Concise ) {
149             return sub {
150 0     0     my $objname;
151 0           foreach $objname (@options) {
152 0 0         $objname = "main::$objname" unless $objname =~ /::/;
153 0           print "walk_bblocks $objname\n";
154 0           eval "walk_bblocks_obj(\\&$objname)";
155 0 0         die "walk_bblocks_obj(\\&$objname) failed: $@" if $@;
156 0           print "-------\n";
157 0           set_style_standard("terse");
158 0           eval "concise_cv('exec', \\&$objname)";
159 0 0         die "concise_cv('exec', \\&$objname) failed: $@" if $@;
160             }
161             }
162 0           }
163             else {
164             return sub {
165 0     0     walk_bblocks( main_root, main_start );
166 0           print "-------\n";
167 0 0         if ($have_B_Concise) {
168 0           set_style_standard("terse");
169 0           concise_main("exec");
170             }
171 0           };
172             }
173             }
174              
175             1;
176              
177             __END__