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   433417 use strict;
  56         127  
  56         1637  
4 56     56   274 use warnings;
  56         116  
  56         1213  
5 56     56   1259 use 5.008004;
  56         206  
6 56     56   1657 use FFI::Platypus;
  56         124  
  56         7440  
7              
8             # ABSTRACT: An FFI function object
9             our $VERSION = '2.06_01'; # TRIAL VERSION
10              
11              
12             use overload '&{}' => sub {
13 98     98   25961 my $ffi = shift;
14 98     98   464 sub { $ffi->call(@_) };
  98         1013  
15             }, 'bool' => sub {
16 9     9   391 my $ffi = shift;
17 9         61 return $ffi;
18 56     56   418 }, fallback => 1;
  56         147  
  56         785  
19              
20             package FFI::Platypus::Function::Function;
21              
22 56     56   29409 use parent qw( FFI::Platypus::Function );
  56         15607  
  56         351  
23              
24             sub attach
25             {
26 867     867   3448 my($self, $perl_name, $proto) = @_;
27              
28 867         1299 my $frame = -1;
29 867         1378 my($caller, $filename, $line);
30              
31 867         1180 do {
32 1735         13091 ($caller, $filename, $line) = caller(++$frame);
33             } while( $caller =~ /^FFI::Platypus(|::Function|::Function::Wrapper|::Declare)$/ );
34              
35 867 100       3192 $perl_name = join '::', $caller, $perl_name
36             unless $perl_name =~ /::/;
37              
38 867         9361 $self->_attach($perl_name, "$filename:$line", $proto);
39 867         6560 $self;
40             }
41              
42             sub sub_ref
43             {
44 24     24   71 my($self) = @_;
45              
46 24         50 my $frame = -1;
47 24         84 my($caller, $filename, $line);
48              
49 24         46 do {
50 65         678 ($caller, $filename, $line) = caller(++$frame);
51             } while( $caller =~ /^FFI::Platypus(|::Function|::Function::Wrapper|::Declare)$/ );
52              
53 24         291 $self->_sub_ref("$filename:$line");
54             }
55              
56             package FFI::Platypus::Function::Wrapper;
57              
58 56     56   18797 use parent qw( FFI::Platypus::Function );
  56         137  
  56         262  
59              
60             sub new
61             {
62 32     32   132 my($class, $function, $wrapper) = @_;
63 32         161 bless [ $function, $wrapper ], $class;
64             }
65              
66             sub call
67             {
68 19     19   2609 my($function, $wrapper) = @{ shift() };
  19         143  
69 19         52 @_ = ($function, @_);
70 19         77 goto &$wrapper;
71             }
72              
73             sub attach
74             {
75 21     21   88 my($self, $perl_name, $proto) = @_;
76 21         44 my($function, $wrapper) = @{ $self };
  21         539  
77              
78 21 100       109 unless($perl_name =~ /::/)
79             {
80 20         52 my $caller;
81 20         39 my $frame = -1;
82 20         39 do { $caller = caller(++$frame) } while( $caller =~ /^FFI::Platypus(|::Declare)$/ );
  37         204  
83 20         88 $perl_name = join '::', $caller, $perl_name
84             }
85              
86 21         71 my $xsub = $function->sub_ref;
87              
88             {
89 21         57 my $code = sub {
90 46     46   20586 unshift @_, $xsub;
91 46         224 goto &$wrapper;
92 21         130 };
93 21 100       85 if(defined $proto)
94             {
95 4         16 _set_prototype($proto, $code);
96             }
97 56     56   18661 no strict 'refs';
  56         155  
  56         9173  
98 21         51 *{$perl_name} = $code;
  21         116  
99             }
100              
101 21         77 $self;
102             }
103              
104             sub sub_ref
105             {
106 1     1   2 my($self) = @_;
107 1         3 my($function, $wrapper) = @{ $self };
  1         3  
108 1         3 my $xsub = $function->sub_ref;
109              
110             return sub {
111 1     1   7 unshift @_, $xsub;
112 1         4 goto &$wrapper;
113 1         6 };
114             }
115              
116             1;
117              
118             __END__