File Coverage

blib/lib/B/Hooks/EndOfScope/XS.pm
Criterion Covered Total %
statement 19 19 100.0
branch 2 2 100.0
condition n/a
subroutine 6 6 100.0
pod 1 1 100.0
total 28 28 100.0


line stmt bran cond sub pod time code
1             package B::Hooks::EndOfScope::XS;
2             # ABSTRACT: Execute code after a scope finished compilation - XS implementation
3              
4 8     8   68395 use strict;
  8         27  
  8         211  
5 8     8   36 use warnings;
  8         16  
  8         279  
6              
7             our $VERSION = '0.25';
8              
9             # Limit the V::M-based (XS) version to perl 5.8.4+
10             #
11             # Given the unorthodox stuff we do to work around the hinthash double-free
12             # might as well play it safe and only implement it in the PP version
13             # and leave it at that
14             # https://rt.perl.org/Public/Bug/Display.html?id=27040#txn-82797
15             #
16 8     8   157 use 5.008004;
  8         24  
17              
18 8     8   3623 use Variable::Magic 0.48 ();
  8         8463  
  8         302  
19 8         73 use Sub::Exporter::Progressive 0.001006 -setup => {
20             exports => ['on_scope_end'],
21             groups => { default => ['on_scope_end'] },
22 8     8   3230 };
  8         7590  
23              
24             my $wiz = Variable::Magic::wizard
25             data => sub { [$_[1]] },
26             free => sub { $_->() for @{ $_[1] }; () },
27             # When someone localise %^H, our magic doesn't want to be copied
28             # down. We want it to be around only for the scope we've initially
29             # attached ourselves to. Merely having MGf_LOCAL and a noop svt_local
30             # callback achieves this. If anything wants to attach more magic of our
31             # kind to a localised %^H, things will continue to just work as we'll be
32             # attached with a new and empty callback list.
33             local => \undef
34             ;
35              
36             sub on_scope_end (&) {
37 14     14 1 5907 $^H |= 0x020000;
38              
39 14 100       65 if (my $stack = Variable::Magic::getdata %^H, $wiz) {
40 1         3 push @{ $stack }, $_[0];
  1         19  
41             }
42             else {
43 13         66 Variable::Magic::cast %^H, $wiz, $_[0];
44             }
45             }
46              
47             1;
48              
49             __END__