1package B::OPCheck; # git description: v0.31-4-gd081d88
2# ABSTRACT: PL_check hacks using Perl callbacks
3
4use 5.008;
5
6use strict;
7use warnings;
8
9use Carp;
10use XSLoader;
11use Scalar::Util;
12use Scope::Guard;
13use B::Utils 0.08 ();
14
15our $VERSION = '0.32';
16
17XSLoader::load 'B::OPCheck', $VERSION;
18
19sub import {
20    my ($class, $opname, $mode, $sub) = @_;
21
22    $^H |= 0x120000; # set HINT_LOCALIZE_HH + an unused bit to work around a %^H bug
23
24    my $by_opname = $^H{OPCHECK_leavescope} ||= {};
25    my $guards = $by_opname->{$opname} ||= [];
26    push @$guards, Scope::Guard->new(sub {
27        leavescope($opname, $mode, $sub);
28    });
29
30    enterscope($opname, $mode, $sub);
31}
32
33sub unimport {
34    my ($class, $opname) = @_;
35
36    if ( defined $opname ) {
37        my $by_opname = $^H{OPCHECK_leavescope};
38        delete $by_opname->{$opname};
39        return if scalar keys %$by_opname; # don't delete other things
40    }
41
42    delete $^H{OPCHECK_leavescope};
43    $^H &= ~0x120000;
44}
45
461;
47
48__END__
49
50=pod
51
52=encoding UTF-8
53
54=head1 NAME
55
56B::OPCheck - PL_check hacks using Perl callbacks
57
58=head1 VERSION
59
60version 0.32
61
62=head1 SYNOPSIS
63
64    use B::Generate; # to change things
65
66    use B::OPCheck entersub => check => sub {
67        my $op = shift; # op has been checked by normal PL_check
68        sodomize($op);
69    };
70
71    foo(); # this entersub will have the callback triggered
72
73=head1 DESCRIPTION
74
75PL_check is an array indexed by opcode number (op_type) that contains function
76pointers invoked as the last stage of optree compilation, per op.
77
78This hook is called in bottom up order, as the code is parsed and the optree is
79prepared.
80
81This is how modules like L<autobox> do their magic
82
83This module provides an api for registering PL_check hooks lexically, allowing
84you to alter the behavior of certain ops using L<B::Generate> from perl space.
85
86=head1 CHECK TYPES
87
88=over 4
89
90=item check
91
92Called after normal PL_checking. The return value is ignored.
93
94=item after
95
96Not yet implemented.
97
98Allows you to return a processed B::OP. The op has been processed by PL_check
99already.
100
101=item before
102
103Not yet implemented.
104
105Allows you to return a processed B::OP to be passed to normal PL_check.
106
107=item replace
108
109Not yet implemented.
110
111Allows you to return a processed B::OP yourself, skipping normal PL_check
112handling completely.
113
114=back
115
116=head1 SUPPORT
117
118Bugs may be submitted through L<the RT bug tracker|https://rt.cpan.org/Public/Dist/Display.html?Name=B-OPCheck>
119(or L<bug-B-OPCheck@rt.cpan.org|mailto:bug-B-OPCheck@rt.cpan.org>).
120
121=head1 AUTHORS
122
123=over 4
124
125=item *
126
127Chia-liang Kao <clkao@clkao.org>
128
129=item *
130
131יובל קוג'מן (Yuval Kogman) <nothingmuch@woobling.org>
132
133=back
134
135=head1 CONTRIBUTORS
136
137=for stopwords Karen Etheridge Florian Ragwitz Alexandr Ciornii
138
139=over 4
140
141=item *
142
143Karen Etheridge <ether@cpan.org>
144
145=item *
146
147Florian Ragwitz <rafl@debian.org>
148
149=item *
150
151Alexandr Ciornii <alexchorny@gmail.com>
152
153=back
154
155=head1 COPYRIGHT AND LICENCE
156
157This software is copyright (c) 2009 by Chia-liang Kao, יובל קוג'מן (Yuval Kogman).
158
159This is free software; you can redistribute it and/or modify it under
160the same terms as the Perl 5 programming language system itself.
161
162=cut
163