File Coverage

blib/lib/B/XSUB/Dumber.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2              
3             package B::XSUB::Dumber;
4              
5 1     1   9677 use strict;
  1         3  
  1         36  
6 1     1   5 use warnings;
  1         2  
  1         34  
7              
8 1     1   16 use Carp qw(croak);
  1         2  
  1         90  
9 1     1   6 use B qw(svref_2object class);
  1         2  
  1         60  
10 1     1   488 use B::Generate;
  0            
  0            
11             use Scalar::Util qw(reftype);
12             use XSLoader;
13              
14             our $VERSION = '0.01';
15              
16             XSLoader::load __PACKAGE__, $VERSION;
17              
18             use base qw(B::OPCheck);
19              
20             sub null {
21             my $op = shift;
22             return class($op) eq "NULL";
23             }
24              
25             sub import {
26             my ( $class, @subs ) = @_;
27              
28             my $xsubs = $^H{$class} || do {
29             my %xsubs;
30             use B::Utils;
31             $class->SUPER::import(entersub => check => sub {
32             my $op = shift;
33              
34             # FIXME only if !hasargs
35              
36             return unless null $op->first->sibling; # method
37              
38             my $kid = $op->first;
39             $kid = $kid->first->sibling; # skip ex-list, pushmark
40             while ( not null $kid->sibling ) {
41             $kid = $kid->sibling;
42             }
43              
44             my $cvop = $kid->first;
45              
46             if ($cvop->name eq "gv") {
47             my $gv = $cvop->gv;
48             my $cv = $gv->CV;
49             if ( my $xsub = $cv->XSUB ) {
50             if ( $xsubs{$xsub} ) {
51             $op->ppaddr(simple_xsub_ppaddr());
52             #$op->ppaddr($xsub); # not possible, it's not a PP (returns an OP*)
53             }
54             }
55             }
56             });
57              
58             \%xsubs;
59             };
60              
61             foreach my $sub ( @subs ) {
62             my $ref;
63              
64             unless ( ref($sub) ) {
65             $ref = eval 'package ' . caller(). '; no strict "refs"; \&{$sub}';
66             warn $@ if $@;
67             } elsif ( reftype($sub) eq 'CODE' ) {
68             $ref = $sub;
69             }
70              
71             unless ( ref($ref) && reftype($ref) eq 'CODE' ) {
72             croak "Must supply a sub name or a code reference to an XSUB";
73             }
74              
75             my $xsub = svref_2object($ref)->XSUB;
76              
77             unless ( $xsub ) {
78             croak "$sub is not an XSUB";
79             }
80              
81             $xsubs->{$xsub}++;
82             }
83             }
84              
85             sub unimport {
86             my $class = shift;
87             $class->SUPER::unimport(); # FIXME only call if really everything is removed, and with the right opname and callback sub
88             }
89              
90             __PACKAGE__
91              
92             __END__