File Coverage

blib/lib/B/CallChecker.pm
Criterion Covered Total %
statement 21 21 100.0
branch n/a
condition n/a
subroutine 7 7 100.0
pod n/a
total 28 28 100.0


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             B::CallChecker - custom B-based op checking for subroutines
4              
5             =head1 SYNOPSIS
6              
7             use B::CallChecker
8             qw(cv_get_call_checker cv_set_call_checker);
9              
10             ($ckfun, $ckobj) = cv_get_call_checker(\&foo);
11             cv_set_call_checker(\&foo, \&ckfun_bar, $ckobj);
12              
13             use B::CallChecker qw(
14             ck_entersub_args_list ck_entersub_args_proto
15             ck_entersub_args_proto_or_list
16             );
17              
18             $entersubop = ck_entersub_args_list($entersubop);
19             $entersubop = ck_entersub_args_proto(
20             $entersubop, $namegv, $ckobj);
21             $entersubop = ck_entersub_args_proto_or_list(
22             $entersubop, $namegv, $ckobj);
23              
24             =head1 DESCRIPTION
25              
26             This module allows pure Perl code to attach a magical annotation to
27             a Perl subroutine, resulting in resolvable calls to that subroutine
28             being mutated at compile time by arbitrary Perl code. The ops of the
29             subroutine call are manipulated via the L system. Despite coding in
30             Perl, the programmer must be aware of implementation details normally
31             only encountered in XS.
32              
33             During compilation, when an C op tree is constructed for a
34             subroutine call, the call is not marked with C<&>, and the callee can be
35             identified at compile time as a particular subroutine I, part of
36             the op check phase for the C op is implemented by a function
37             attached to the subroutine. Two items are attached to the subroutine
38             for this purpose: I is a subroutine reference and I is a
39             reference to anything. The C op gets modified by a process
40             amounting to
41              
42             $entersubop = $ckfun->($entersubop, $namegv, $ckobj);
43              
44             In this call, I is a reference to the C op (in
45             C form, see L), which may be replaced by the check function,
46             and I is a reference to a glob supplying the name that should
47             be used by the check function to refer to I if it needs to emit
48             any diagnostics. If possible, errors should be queued up in the parser
49             state, and the fixup function should return a well-formed op tree (albeit
50             possibly a silly or null one). Aborting by C is also permissible,
51             but it aborts compilation immediately, and the fixup function should
52             make sure to free the op tree first.
53              
54             The I and I for a particular I can be determined
55             using L and replaced using L.
56             By default, a I's I is L, and
57             I is I itself, which implements standard prototype processing.
58             It is permitted to apply the check function in non-standard situations,
59             such as to a call to a different subroutine or to a method call.
60              
61             =cut
62              
63             package B::CallChecker;
64              
65 1     1   26815 { use 5.008; }
  1         4  
  1         58  
66 1     1   6 use warnings;
  1         2  
  1         36  
67 1     1   5 use strict;
  1         6  
  1         38  
68              
69 1     1   4 use B ();
  1         1  
  1         15  
70 1     1   2388 use Devel::CallChecker 0.003 ();
  1         15329  
  1         66  
71 1     1   15 use XSLoader;
  1         3  
  1         173  
72              
73             our $VERSION = "0.001";
74              
75 1     1   7 use parent "Exporter";
  1         2  
  1         6  
76             our @EXPORT_OK = qw(
77             cv_get_call_checker cv_set_call_checker
78             ck_entersub_args_list ck_entersub_args_proto
79             ck_entersub_args_proto_or_list
80             );
81              
82             XSLoader::load(__PACKAGE__, $VERSION);
83              
84             =head1 FUNCTIONS
85              
86             =over
87              
88             =item cv_get_call_checker(SUB)
89              
90             I must be a reference to a subroutine. This function retrieves
91             the function that will be used to fix up calls to I. It returns a
92             two-element list, in which the first element (I) is a reference to
93             a subroutine and the second element (I) is a reference to anything.
94              
95             =item cv_set_call_checker(SUB, CKFUN, CKOBJ)
96              
97             I must be a reference to a subroutine. This function sets the
98             function that will be used to fix up calls to I.
99              
100             =item ck_entersub_args_list(ENTERSUBOP)
101              
102             Performs the default fixup of the arguments part of an C op
103             tree, consisting of applying list context to each of the argument ops.
104             Note that this cannot be used directly as the fixup function to attach
105             to a subroutine.
106              
107             =item ck_entersub_args_proto(ENTERSUBOP, NAMEGV, PROTOOBJ)
108              
109             Performs the fixup of the arguments part of an C op tree based
110             on a subroutine prototype.
111              
112             I supplies the subroutine prototype to be applied to the call.
113             It must be a reference. The referent may be a normal defined scalar,
114             of which the string value will be used. Alternatively, for convenience,
115             the referent may be a subroutine which has a prototype. The prototype
116             supplied, in whichever form, does not need to match the actual callee
117             referenced by the op tree.
118              
119             =item ck_entersub_args_proto_or_list(ENTERSUBOP, NAMEGV, PROTOOBJ)
120              
121             Performs the fixup of the arguments part of an C op tree either
122             based on a subroutine prototype or using default list-context processing.
123             This is the standard treatment used on a subroutine call, not marked
124             with C<&>, where the callee can be identified at compile time.
125              
126             I supplies the subroutine prototype to be applied to the
127             call, or indicates that there is no prototype. It must be a reference.
128             The referent may be a normal scalar, in which case if it is defined then
129             the string value will be used as a prototype, and if it is undefined
130             then there is no prototype. Alternatively, for convenience, the referent
131             may be a subroutine, of which the prototype will be used if it has one.
132             The prototype (or lack thereof) supplied, in whichever form, does not
133             need to match the actual callee referenced by the op tree.
134              
135             =back
136              
137             =head1 SEE ALSO
138              
139             L,
140             L
141              
142             =head1 AUTHOR
143              
144             Andrew Main (Zefram)
145              
146             =head1 COPYRIGHT
147              
148             Copyright (C) 2011, 2012 Andrew Main (Zefram)
149              
150             =head1 LICENSE
151              
152             This module is free software; you can redistribute it and/or modify it
153             under the same terms as Perl itself.
154              
155             =cut
156              
157             1;