1850e2753Smillert#!./perl -w 2850e2753Smillert 3850e2753SmillertBEGIN { ## no critic strict 4850e2753Smillert if ( $ENV{PERL_CORE} ) { 5*b39c5158Smillert unshift @INC, '../../t/lib'; 6*b39c5158Smillert } else { 7850e2753Smillert unshift @INC, 't'; 8850e2753Smillert } 9850e2753Smillert require Config; 10850e2753Smillert if ( ( $Config::Config{'extensions'} !~ /\bB\b/ ) ) { 11850e2753Smillert print "1..0 # Skip -- Perl configured without B module\n"; 12850e2753Smillert exit 0; 13850e2753Smillert } 14850e2753Smillert} 15850e2753Smillert 16850e2753Smillertuse strict; 17850e2753Smillertuse warnings; 18850e2753Smillertuse Test::More tests => 4 * 3; 19850e2753Smillertuse B 'svref_2object'; 20850e2753Smillert 21850e2753Smillert# use Data::Dumper 'Dumper'; 22850e2753Smillert 23850e2753Smillertsub foo { 24850e2753Smillert my ( $x, $y, $z ); 25850e2753Smillert 26850e2753Smillert # hh => {}, 27850e2753Smillert $z = $x * $y; 28850e2753Smillert 29850e2753Smillert # hh => { mypragma => 42 } 30850e2753Smillert use mypragma; 31850e2753Smillert $z = $x + $y; 32850e2753Smillert 33850e2753Smillert # hh => { mypragma => 0 } 34850e2753Smillert no mypragma; 35850e2753Smillert $z = $x - $y; 36850e2753Smillert} 37850e2753Smillert 38850e2753Smillert{ 39850e2753Smillert 40850e2753Smillert # Pragmas don't appear til they're used. 41850e2753Smillert my $cop = find_op_cop( \&foo, qr/multiply/ ); 42850e2753Smillert isa_ok( $cop, 'B::COP', 'found pp_multiply opnode' ); 43850e2753Smillert 44850e2753Smillert my $rhe = $cop->hints_hash; 45850e2753Smillert isa_ok( $rhe, 'B::RHE', 'got hints_hash' ); 46850e2753Smillert 47850e2753Smillert my $hints_hash = $rhe->HASH; 48850e2753Smillert is( ref($hints_hash), 'HASH', 'Got hash reference' ); 49850e2753Smillert 50850e2753Smillert ok( not( exists $hints_hash->{mypragma} ), q[! exists mypragma] ); 51850e2753Smillert} 52850e2753Smillert 53850e2753Smillert{ 54850e2753Smillert 55850e2753Smillert # Pragmas can be fetched. 56850e2753Smillert my $cop = find_op_cop( \&foo, qr/add/ ); 57850e2753Smillert isa_ok( $cop, 'B::COP', 'found pp_add opnode' ); 58850e2753Smillert 59850e2753Smillert my $rhe = $cop->hints_hash; 60850e2753Smillert isa_ok( $rhe, 'B::RHE', 'got hints_hash' ); 61850e2753Smillert 62850e2753Smillert my $hints_hash = $rhe->HASH; 63850e2753Smillert is( ref($hints_hash), 'HASH', 'Got hash reference' ); 64850e2753Smillert 65850e2753Smillert is( $hints_hash->{mypragma}, 42, q[mypragma => 42] ); 66850e2753Smillert} 67850e2753Smillert 68850e2753Smillert{ 69850e2753Smillert 70850e2753Smillert # Pragmas can be changed. 71850e2753Smillert my $cop = find_op_cop( \&foo, qr/subtract/ ); 72850e2753Smillert isa_ok( $cop, 'B::COP', 'found pp_subtract opnode' ); 73850e2753Smillert 74850e2753Smillert my $rhe = $cop->hints_hash; 75850e2753Smillert isa_ok( $rhe, 'B::RHE', 'got hints_hash' ); 76850e2753Smillert 77850e2753Smillert my $hints_hash = $rhe->HASH; 78850e2753Smillert is( ref($hints_hash), 'HASH', 'Got hash reference' ); 79850e2753Smillert 80850e2753Smillert is( $hints_hash->{mypragma}, 0, q[mypragma => 0] ); 81850e2753Smillert} 82850e2753Smillertexit; 83850e2753Smillert 84850e2753Smillertour $COP; 85850e2753Smillert 86850e2753Smillertsub find_op_cop { 87850e2753Smillert my ( $sub, $op ) = @_; 88850e2753Smillert my $cv = svref_2object($sub); 89850e2753Smillert local $COP; 90850e2753Smillert 91850e2753Smillert if ( not _find_op_cop( $cv->ROOT, $op ) ) { 92850e2753Smillert $COP = undef; 93850e2753Smillert } 94850e2753Smillert 95850e2753Smillert return $COP; 96850e2753Smillert} 97850e2753Smillert 98850e2753Smillert{ 99850e2753Smillert 100850e2753Smillert # Make B::NULL objects evaluate as false. 101850e2753Smillert package B::NULL; 102850e2753Smillert use overload 'bool' => sub () { !!0 }; 103850e2753Smillert} 104850e2753Smillert 105850e2753Smillertsub _find_op_cop { 106850e2753Smillert my ( $op, $name ) = @_; 107850e2753Smillert 108850e2753Smillert # Fail on B::NULL or whatever. 109850e2753Smillert return 0 if not $op; 110850e2753Smillert 111850e2753Smillert # Succeed when we find our match. 112850e2753Smillert return 1 if $op->name =~ $name; 113850e2753Smillert 114850e2753Smillert # Stash the latest seen COP opnode. This has our hints hash. 115850e2753Smillert if ( $op->isa('B::COP') ) { 116850e2753Smillert 117850e2753Smillert # print Dumper( 118850e2753Smillert # { cop => $op, 119850e2753Smillert # hints => $op->hints_hash->HASH 120850e2753Smillert # } 121850e2753Smillert # ); 122850e2753Smillert $COP = $op; 123850e2753Smillert } 124850e2753Smillert 125850e2753Smillert # Recurse depth first passing success up if it happens. 126850e2753Smillert if ( $op->can('first') ) { 127850e2753Smillert return 1 if _find_op_cop( $op->first, $name ); 128850e2753Smillert } 129850e2753Smillert return 1 if _find_op_cop( $op->sibling, $name ); 130850e2753Smillert 131850e2753Smillert # Oh well. Hopefully our caller knows where to try next. 132850e2753Smillert return 0; 133850e2753Smillert} 134850e2753Smillert 135