File Coverage

blib/lib/FFI/Platypus/Function.pm
Criterion Covered Total %
statement 74 74 100.0
branch 6 6 100.0
condition n/a
subroutine 19 19 100.0
pod n/a
total 99 99 100.0


line stmt bran cond sub pod time code
1             package FFI::Platypus::Function;
2              
3 56     56   459981 use strict;
  56         135  
  56         1557  
4 56     56   307 use warnings;
  56         134  
  56         1312  
5 56     56   866 use 5.008004;
  56         205  
6 56     56   1810 use FFI::Platypus;
  56         125  
  56         8118  
7              
8             # ABSTRACT: An FFI function object
9             our $VERSION = '2.08'; # VERSION
10              
11              
12             use overload '&{}' => sub {
13 98     98   24901 my $ffi = shift;
14 98     98   435 sub { $ffi->call(@_) };
  98         1050  
15             }, 'bool' => sub {
16 9     9   418 my $ffi = shift;
17 9         52 return $ffi;
18 56     56   449 }, fallback => 1;
  56         161  
  56         1037  
19              
20             package FFI::Platypus::Function::Function;
21              
22 56     56   29809 use parent qw( FFI::Platypus::Function );
  56         15903  
  56         366  
23              
24             sub attach
25             {
26 867     867   3482 my($self, $perl_name, $proto) = @_;
27              
28 867         1255 my $frame = -1;
29 867         1348 my($caller, $filename, $line);
30              
31 867         1181 do {
32 1735         13102 ($caller, $filename, $line) = caller(++$frame);
33             } while( $caller =~ /^FFI::Platypus(|::Function|::Function::Wrapper|::Declare)$/ );
34              
35 867 100       3273 $perl_name = join '::', $caller, $perl_name
36             unless $perl_name =~ /::/;
37              
38 867         9444 $self->_attach($perl_name, "$filename:$line", $proto);
39 867         6018 $self;
40             }
41              
42             sub sub_ref
43             {
44 24     24   58 my($self) = @_;
45              
46 24         49 my $frame = -1;
47 24         42 my($caller, $filename, $line);
48              
49 24         45 do {
50 65         616 ($caller, $filename, $line) = caller(++$frame);
51             } while( $caller =~ /^FFI::Platypus(|::Function|::Function::Wrapper|::Declare)$/ );
52              
53 24         251 $self->_sub_ref("$filename:$line");
54             }
55              
56             package FFI::Platypus::Function::Wrapper;
57              
58 56     56   19286 use parent qw( FFI::Platypus::Function );
  56         176  
  56         246  
59              
60             sub new
61             {
62 32     32   107 my($class, $function, $wrapper) = @_;
63 32         183 bless [ $function, $wrapper ], $class;
64             }
65              
66             sub call
67             {
68 19     19   2788 my($function, $wrapper) = @{ shift() };
  19         186  
69 19         60 @_ = ($function, @_);
70 19         70 goto &$wrapper;
71             }
72              
73             sub attach
74             {
75 21     21   109 my($self, $perl_name, $proto) = @_;
76 21         48 my($function, $wrapper) = @{ $self };
  21         550  
77              
78 21 100       117 unless($perl_name =~ /::/)
79             {
80 20         38 my $caller;
81 20         41 my $frame = -1;
82 20         37 do { $caller = caller(++$frame) } while( $caller =~ /^FFI::Platypus(|::Declare)$/ );
  37         210  
83 20         84 $perl_name = join '::', $caller, $perl_name
84             }
85              
86 21         83 my $xsub = $function->sub_ref;
87              
88             {
89 21         57 my $code = sub {
90 46     46   21216 unshift @_, $xsub;
91 46         210 goto &$wrapper;
92 21         154 };
93 21 100       90 if(defined $proto)
94             {
95 4         17 _set_prototype($proto, $code);
96             }
97 56     56   18597 no strict 'refs';
  56         152  
  56         9623  
98 21         49 *{$perl_name} = $code;
  21         135  
99             }
100              
101 21         68 $self;
102             }
103              
104             sub sub_ref
105             {
106 1     1   3 my($self) = @_;
107 1         4 my($function, $wrapper) = @{ $self };
  1         4  
108 1         4 my $xsub = $function->sub_ref;
109              
110             return sub {
111 1     1   7 unshift @_, $xsub;
112 1         4 goto &$wrapper;
113 1         7 };
114             }
115              
116             1;
117              
118             __END__