File Coverage

blib/lib/Acme/Perl/VM/B.pm
Criterion Covered Total %
statement 54 97 55.6
branch 1 8 12.5
condition 1 6 16.6
subroutine 16 31 51.6
pod n/a
total 72 142 50.7


line stmt bran cond sub pod time code
1             package Acme::Perl::VM::B;
2              
3 22     22   143 use strict;
  22         45  
  22         2140  
4 22     22   134 use warnings;
  22         44  
  22         895  
5              
6 22     22   380 use Exporter qw(import);
  22         51  
  22         777  
7              
8 22     22   143 use B();
  22         43  
  22         7713  
9             our @EXPORT = grep{ /^[A-Z]/ } @B::EXPORT_OK; # constants
10             push @EXPORT, qw(sv_undef svref_2object);
11             B->import(@EXPORT);
12              
13             unless(defined &OPpPAD_STATE){
14             constant->import(OPpPAD_STATE => 0x00);
15             push @EXPORT, qw(OPpPAD_STATE);
16             }
17             unless(defined &G_WANT){
18             constant->import(G_WANT => G_SCALAR() | G_ARRAY() | G_VOID());
19             push @EXPORT, qw(G_WANT);
20             }
21             unless(defined &OPpITER_REVERSED){
22             constant->import(OPpITER_REVERSED => 0x00);
23             push @EXPORT, qw(OPpITER_REVERSED);
24             }
25              
26             push @EXPORT, qw(NULL TRUE FALSE USE_ITHREADS sv_yes sv_no);
27             use constant {
28 22         42 NULL => bless(\do{ my $addr = 0 }, 'B::SPECIAL'),
  22         5051  
29             TRUE => 1,
30             FALSE => 0,
31             USE_ITHREADS => defined(&B::regex_padav),
32              
33             sv_yes => B::sv_yes,
34             sv_no => B::sv_no,
35 22     22   147 };
  22         42  
36              
37              
38             package
39             B::OBJECT;
40              
41 22     22   133 use B qw(class);
  22         44  
  22         48354  
42              
43             sub dump{
44 0     0   0 my($obj) = @_;
45 0         0 require Devel::Peek;
46 0         0 Devel::Peek::Dump($obj->object_2svref);
47 0         0 return;
48             }
49              
50             package
51             B::OP;
52              
53             sub dump{
54 0     0   0 my($obj) = @_;
55 0         0 require B::Debug;
56              
57 0         0 $obj->debug;
58 0         0 return;
59             }
60              
61             package
62             B::SPECIAL;
63              
64             my %special_sv = (
65             ${ B::sv_undef() } => \(undef),
66             ${ B::sv_yes() } => \(1 == 1),
67             ${ B::sv_no() } => \(1 != 1),
68             );
69              
70             unless(@B::specialsv_name){
71             @B::specialsv_name = qw(
72             Nullsv
73             &PL_sv_undef
74             &PL_sv_yes
75             &PL_sv_no
76             pWARN_ALL
77             pWARN_NONE
78             pWARN_STD
79             );
80             }
81              
82             sub object_2svref{
83 36     36   43 my($obj) = @_;
84              
85 36   33     206 return $special_sv{ $$obj } || do{
86             Carp::confess($obj->special_name, ' is not a normal SV object');
87             };
88             }
89              
90             sub setval{
91 0     0   0 my($obj) = @_;
92              
93 0         0 Acme::Perl::VM::apvm_die('Modification of read-only value (%s) attempted', $obj->special_name);
94             }
95              
96 0     0   0 sub STASH(){ undef }
97              
98             sub POK(){ 0 }
99             sub ROK(){ 0 }
100              
101             sub special_name{
102 0     0   0 my($obj) = @_;
103 0   0     0 return $B::specialsv_name[$$obj] || sprintf 'SPECIAL(0x%x)', $$obj;
104             }
105              
106             package
107             B::SV;
108              
109             # for sv_setsv()
110             sub setsv{
111 37     37   67 my($dst, $src) = @_;
112              
113 37         136 my $dst_ref = $dst->object_2svref;
114 37         48 ${$dst_ref} = ${$src->object_2svref};
  37         88  
  37         137  
115 37         152 bless $dst, ref(B::svref_2object( $dst_ref ));
116              
117 37         205 return $dst;
118             }
119              
120             # for sv_setpv()/sv_setiv()/sv_setnv() etc.
121             sub setval{
122 94     94   129 my($dst, $val) = @_;
123              
124 94         305 my $dst_ref = $dst->object_2svref;
125 94         131 ${$dst_ref} = $val;
  94         178  
126 94         318 bless $dst, ref(B::svref_2object( $dst_ref ));
127              
128 94         261 return $dst;
129             }
130              
131             sub clear{
132 19     19   32 my($sv) = @_;
133              
134 19         30 ${$sv->object_2svref} = undef;
  19         51  
135 19         50 return;
136             }
137              
138             sub toCV{
139 0     0   0 my($sv) = @_;
140 0         0 Carp::croak(sprintf 'Cannot convert %s to a CV', B::class($sv));
141             }
142              
143 21     21   112 sub STASH(){ undef }
144              
145             package
146             B::PVMG;
147              
148             sub ROK{
149 0     0   0 my($obj) = @_;
150 0         0 my $dummy = ${ $obj->object_2svref }; # invoke mg_get()
  0         0  
151 0         0 return $obj->SUPER::ROK;
152             }
153              
154             package
155             B::CV;
156              
157 216     216   522 sub toCV{ $_[0] }
158              
159             sub clear{
160 0     0   0 Carp::croak('Cannot clear a CV');
161             }
162              
163             sub ROK(){ 0 }
164              
165             package
166             B::GV;
167              
168              
169 19     19   90 sub toCV{ $_[0]->CV }
170              
171             sub clear{
172 0     0   0 Carp::croak('Cannot clear a CV');
173             }
174              
175             sub ROK(){ 0 }
176              
177             package
178             B::AV;
179              
180             sub setsv{
181 0     0   0 my($sv) = @_;
182 0         0 Carp::croak('Cannot call setsv() for ' . B::class($sv));
183             }
184              
185             sub clear{
186 1     1   2 my($sv) = @_;
187              
188 1         3 @{$sv->object_2svref} = ();
  1         7  
189 1         3 return;
190             }
191              
192             unless(__PACKAGE__->can('OFF')){
193             # some versions of B::Debug requires this
194             constant->import(OFF => 0);
195             }
196              
197             sub ROK(){ 0 }
198              
199             package
200             B::HV;
201              
202             sub ROK(){ 0 }
203              
204             *setsv = \&B::AV::setsv;
205              
206             sub clear{
207 1     1   2 my($sv) = @_;
208              
209 1         2 %{$sv->object_2svref} = ();
  1         4  
210 1         2 return;
211             }
212              
213             sub fetch{
214 0     0   0 my($hv, $key, $lval) = @_;
215              
216 0 0       0 if($lval){
217 0         0 return B::svref_2object(\$hv->object_2svref->{$key});
218             }
219             else{
220 0         0 my $ref = $hv->object_2svref;
221              
222 0 0       0 if(exists $ref->{$key}){
223 0         0 return B::svref_2object(\$ref->{$key});
224             }
225             else{
226 0         0 return Acme::Perl::VM::B::NULL;
227             }
228             }
229             }
230              
231             sub fetch_ent{
232 0     0   0 my($hv, $keysv, $lval) = @_;
233 0         0 return $hv->fetch(${ $keysv->object_2svref }, $lval);
  0         0  
234             }
235              
236             sub exists{
237 0     0   0 my($hv, $key) = @_;
238 0         0 return exists $hv->object_2svref->{$key};
239             }
240             sub exists_ent{
241 0     0   0 my($hv, $keysv) = @_;
242 0         0 return exists $hv->object_2svref->{${ $keysv->object_2svref}};
  0         0  
243             }
244              
245             sub store{
246 0     0   0 my($hv, $key, $val) = @_;
247              
248 0         0 $hv->object_2svref->{$key} = ${ $val->object_2svref };
  0         0  
249 0 0       0 return B::svref_2object(\$hv->object_2svref->{$key}) if defined wantarray;
250             }
251             sub store_ent{
252 1     1   2 my($hv, $keysv, $val) = @_;
253              
254 1         2 $hv->object_2svref->{${ $keysv->object_2svref }} = ${ $val->object_2svref };
  1         6  
  1         4  
255 1 50       7 return B::svref_2object(\$hv->object_2svref->{${ $keysv->object_2svref }}) if defined wantarray;
  0            
256             }
257             1;
258              
259             __END__