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   447017 use strict;
  56         117  
  56         2122  
4 56     56   270 use warnings;
  56         109  
  56         2767  
5 56     56   969 use 5.008004;
  56         242  
6 56     56   2028 use FFI::Platypus;
  56         117  
  56         8174  
7              
8             # ABSTRACT: An FFI function object
9             our $VERSION = '2.11'; # VERSION
10              
11              
12             use overload '&{}' => sub {
13 98     98   35167 my $ffi = shift;
14 98     98   516 sub { $ffi->call(@_) };
  98         1228  
15             }, 'bool' => sub {
16 9     9   471 my $ffi = shift;
17 9         41 return $ffi;
18 56     56   393 }, fallback => 1;
  56         103  
  56         907  
19              
20             package FFI::Platypus::Function::Function;
21              
22 56     56   29449 use parent qw( FFI::Platypus::Function );
  56         17816  
  56         386  
23              
24             sub attach
25             {
26 859     859   5477 my($self, $perl_name, $proto) = @_;
27              
28 859         1319 my $frame = -1;
29 859         1238 my($caller, $filename, $line);
30              
31 859         1216 do {
32 1719         11812 ($caller, $filename, $line) = caller(++$frame);
33             } while( $caller =~ /^FFI::Platypus(|::Function|::Function::Wrapper|::Declare)$/ );
34              
35 859 100       3086 $perl_name = join '::', $caller, $perl_name
36             unless $perl_name =~ /::/;
37              
38 859         10616 $self->_attach($perl_name, "$filename:$line", $proto);
39 859         6283 $self;
40             }
41              
42             sub sub_ref
43             {
44 24     24   173 my($self) = @_;
45              
46 24         54 my $frame = -1;
47 24         108 my($caller, $filename, $line);
48              
49 24         47 do {
50 65         613 ($caller, $filename, $line) = caller(++$frame);
51             } while( $caller =~ /^FFI::Platypus(|::Function|::Function::Wrapper|::Declare)$/ );
52              
53 24         1673 $self->_sub_ref("$filename:$line");
54             }
55              
56             package FFI::Platypus::Function::Wrapper;
57              
58 56     56   24925 use parent qw( FFI::Platypus::Function );
  56         159  
  56         287  
59              
60             sub new
61             {
62 32     32   104 my($class, $function, $wrapper) = @_;
63 32         196 bless [ $function, $wrapper ], $class;
64             }
65              
66             sub call
67             {
68 19     19   3339 my($function, $wrapper) = @{ shift() };
  19         164  
69 19         60 @_ = ($function, @_);
70 19         76 goto &$wrapper;
71             }
72              
73             sub attach
74             {
75 21     21   61 my($self, $perl_name, $proto) = @_;
76 21         47 my($function, $wrapper) = @{ $self };
  21         638  
77              
78 21 100       146 unless($perl_name =~ /::/)
79             {
80 20         44 my $caller;
81 20         40 my $frame = -1;
82 20         46 do { $caller = caller(++$frame) } while( $caller =~ /^FFI::Platypus(|::Declare)$/ );
  37         238  
83 20         85 $perl_name = join '::', $caller, $perl_name
84             }
85              
86 21         111 my $xsub = $function->sub_ref;
87              
88             {
89 21         44 my $code = sub {
90 46     46   322086 unshift @_, $xsub;
91 46         241 goto &$wrapper;
92 21         216 };
93 21 100       169 if(defined $proto)
94             {
95 4         17 _set_prototype($proto, $code);
96             }
97 56     56   22677 no strict 'refs';
  56         147  
  56         10223  
98 21         102 *{$perl_name} = $code;
  21         218  
99             }
100              
101 21         94 $self;
102             }
103              
104             sub sub_ref
105             {
106 1     1   4 my($self) = @_;
107 1         3 my($function, $wrapper) = @{ $self };
  1         4  
108 1         4 my $xsub = $function->sub_ref;
109              
110             return sub {
111 1     1   8 unshift @_, $xsub;
112 1         4 goto &$wrapper;
113 1         10 };
114             }
115              
116             1;
117              
118             __END__