File Coverage

blib/lib/Acme/Perl/VM/PP.pm
Criterion Covered Total %
statement 424 786 53.9
branch 130 344 37.7
condition 7 29 24.1
subroutine 53 93 56.9
pod 62 84 73.8
total 676 1336 50.6


line stmt bran cond sub pod time code
1             package Acme::Perl::VM::PP;
2 22     22   132 use strict;
  22         40  
  22         1056  
3 22     22   251 use warnings;
  22         43  
  22         881  
4              
5 22     22   121 use Acme::Perl::VM qw(:perl_h);
  22         42  
  22         24647  
6 22     22   179 use Acme::Perl::VM::B;
  22         57  
  22         334450  
7              
8              
9             #NOTE:
10             # perl APVM
11             #
12             # dSP (nothing)
13             # SP $#PL_stack
14             # *SP $PL_stack[-1]
15             # dMARK my $mark = POPMARK
16             # MARK $mark
17             # *MARK $PL_stack[$mark]
18             # dORIGMARK my $origmark = $mark
19             # ORIGMARK $origmark
20             # SPAGAIN (nothing)
21             # PUTBACK (nothing)
22              
23             sub pp_nextstate{
24 210     210 1 323 $PL_curcop = $PL_op;
25              
26 210         857 $#PL_stack = $PL_cxstack[-1]->oldsp;
27 210         642 FREETMPS;
28              
29 210         1615 return $PL_op->next;
30             }
31              
32             sub pp_pushmark{
33 87     87 1 292 PUSHMARK;
34 87         861 return $PL_op->next;
35             }
36              
37             sub pp_const{
38 149 50   149 1 1042 my $sv = is_not_null($PL_op->sv) ? $PL_op->sv : PAD_SV($PL_op->targ);
39 149         480 PUSH($sv);
40 149         1275 return $PL_op->next;
41             }
42              
43             sub pp_gv{
44 38     38 1 121 PUSH( GVOP_gv($PL_op) );
45 38         386 return $PL_op->next;
46             }
47              
48             sub pp_gvsv{
49 8 100   8 1 38 if($PL_op->private & OPpLVAL_INTRO){
50 3         11 PUSH(save_scalar(GVOP_gv($PL_op)));
51             }
52             else{
53 5         13 PUSH(GVOP_gv($PL_op)->SV);
54             }
55 8         58 return $PL_op->next;
56             }
57              
58             sub _do_kv{
59 0     0   0 my $hv = POP;
60              
61 0 0       0 if($hv->class ne 'HV'){
62 0         0 apvm_die 'panic: do_kv';
63             }
64              
65 0         0 my $gimme = GIMME_V;
66              
67 0 0       0 if($gimme == G_VOID){
    0          
68 0         0 return $PL_op->next;
69             }
70             elsif($gimme == G_SCALAR){
71              
72 0 0 0     0 if($PL_op->flags & OPf_MOD || LVRET){
73 0         0 not_implemented $PL_op->name . ' for lvalue';
74             }
75              
76 0         0 my $num = keys %{ $hv->object_2svref };
  0         0  
77 0         0 mPUSH( svref_2object(\$num) );
78 0         0 return $PL_op->next;
79             }
80              
81              
82 0         0 my($dokeys, $dovalues);
83 0 0       0 if($PL_op->name eq 'keys'){
    0          
84 0         0 $dokeys = TRUE;
85             }
86             elsif($PL_op->name eq 'values'){
87 0         0 $dovalues = TRUE;
88             }
89             else{
90 0         0 $dokeys = $dovalues = TRUE;
91             }
92              
93 0         0 my $hash_ref = $hv->object_2svref;
94 0         0 while(my $k = each %{$hash_ref}){
  0         0  
95 0 0       0 mPUSH( svref_2object(\$k) ) if $dokeys;
96 0 0       0 PUSH( svref_2object(\$hash_ref->{$k}) ) if $dovalues;
97             }
98 0         0 return $PL_op->next;
99             }
100              
101             sub pp_rv2gv{
102 3     3 1 11 my $sv = TOP;
103              
104 3 100       19 if($sv->ROK){
105 1         8 $sv = $sv->RV;
106             }
107              
108 3 50       32 if($sv->class ne 'GV'){
109 0         0 apvm_die 'Not a GLOB reference';
110             }
111              
112 3 50       25 if($PL_op->private & OPpLVAL_INTRO){
113 0         0 not_implemented 'rv2gv for OPpLVAL_INTRO';
114             }
115              
116 3         13 SET($sv);
117 3         20 return $PL_op->next;
118             }
119              
120             sub pp_rv2sv{
121 0     0 1 0 my $sv = TOP;
122 0         0 my $gv;
123              
124 0 0       0 if($sv->ROK){
125 0 0       0 if(!is_scalar($sv)){
126 0         0 apvm_die 'Not a SCALAR reference';
127             }
128             }
129             else{
130 0 0       0 if($sv->class ne 'GV'){
131 0         0 not_implemented 'rv2xv for soft references';
132             }
133 0         0 $gv = $sv;
134             }
135              
136 0 0       0 if($PL_op->flags & OPf_MOD){
137 0 0       0 if($PL_op->private & OPpLVAL_INTRO){
    0          
138 0 0       0 if($PL_op->first->name eq 'null'){
139 0         0 $sv = save_scalar(TOP);
140             }
141             else{
142 0         0 $sv = save_scalar($gv);
143             }
144             }
145             elsif($PL_op->private & OPpDEREF){
146 0         0 vivify_ref($sv, $PL_op->private & OPpDEREF);
147             }
148             }
149 0         0 SET($sv);
150 0         0 return $PL_op->next;
151             }
152              
153             sub pp_rv2av{
154 14     14 1 51 my $sv = TOP;
155 14         22 my $name;
156             my $class;
157 0         0 my $save;
158              
159 14 100       104 if($PL_op->name eq 'rv2av'){
160 12         19 $name = 'an ARRAY';
161 12         18 $class = 'AV';
162 12         26 $save = \&save_ary;
163             }
164             else{
165 2         3 $name = 'a HASH';
166 2         3 $class = 'HV';
167 2         3 $save = \&save_hash;
168             }
169 14         37 my $gimme = GIMME_V;
170              
171 14 50       52 if($sv->ROK){
172 0         0 $sv = $sv->RV;
173              
174 0 0       0 if($sv->class ne $class){
175 0         0 apvm_die "Not $name reference";
176             }
177 0 0 0     0 if($PL_op->flags & OPf_REF){
    0          
    0          
178 0         0 SET($sv);
179 0         0 return $PL_op->next;
180             }
181             elsif(LVRET){
182 0         0 not_implemented 'rv2av for lvalue';
183             }
184             elsif($PL_op->flags & OPf_MOD
185             && $PL_op->private & OPpLVAL_INTRO){
186 0         0 apvm_die q{Can't localize through a reference};
187             }
188             }
189             else{
190 14 100       200 if($sv->class eq $class){
191 1 50       16 if($PL_op->flags & OPf_REF){
    50          
192 0         0 SET($sv);
193 0         0 return $PL_op->next;
194             }
195             elsif(LVRET){
196 0         0 not_implemented 'rv2av for lvalue';
197             }
198             }
199             else{
200 13 50       92 if($sv->class ne 'GV'){
201 0         0 not_implemented 'rv2av for symbolic reference';
202             }
203              
204 13 100       67 if($PL_op->private & OPpLVAL_INTRO){
205 2         8 $sv = $save->($sv);
206             }
207             else{
208 11         44 $sv = $sv->$class();
209             }
210              
211 13 100       64 if($PL_op->flags & OPf_REF){
    50          
212 4         9 SET($sv);
213 4         31 return $PL_op->next;
214             }
215             elsif(LVRET){
216 0         0 not_implemented 'rv2av for lvalue';
217             }
218             }
219             }
220              
221 10 50       29 if($class eq 'AV'){ # rv2av
222 10 100       33 if($gimme == G_ARRAY){
    50          
223 8         21 POP;
224 8         48 PUSH( $sv->ARRAY );
225             }
226             elsif($gimme == G_SCALAR){
227 2         23 SETval( $sv->FILL + 1 );
228             }
229             }
230             else{ # rv2hv
231 0 0       0 if($gimme == G_ARRAY){
    0          
232 0         0 return &_do_kv;
233             }
234             elsif($gimme == G_SCALAR){
235 0         0 SET(hv_scalar($sv));
236             }
237             }
238              
239 10         73 return $PL_op->next;
240             }
241             sub pp_rv2hv{
242 2     2 1 7 goto &pp_rv2av;
243             }
244              
245             sub pp_padsv{
246 113     113 1 325 my $targ = GET_TARGET;
247 113         357 PUSH($targ);
248              
249 113 100       455 if($PL_op->flags & OPf_MOD){
250 66 100       356 if(($PL_op->private & (OPpLVAL_INTRO|OPpPAD_STATE)) == OPpLVAL_INTRO){
251 21         73 SAVECLEARSV($targ);
252             }
253             }
254 113         1001 return $PL_op->next;
255             }
256              
257             sub pp_padav{
258 1     1 1 5 my $targ = GET_TARGET;
259              
260 1 50       9 if(($PL_op->private & (OPpLVAL_INTRO|OPpPAD_STATE)) == OPpLVAL_INTRO){
261 1         5 SAVECLEARSV($targ);
262             }
263 1 50       11 if($PL_op->flags & OPf_REF){
    50          
264 0         0 PUSH($targ);
265 0         0 return $PL_op->next;;
266             }
267             elsif(LVRET){
268 0         0 not_implemented 'padav for lvalue';
269             }
270              
271 1         3 my $gimme = GIMME_V;
272 1 50       7 if($gimme == G_ARRAY){
    50          
273 0         0 PUSH( $targ->ARRAY );
274             }
275             elsif($gimme == G_SCALAR){
276 1         5 my $sv = sv_newmortal();
277 1         22 $sv->setval($targ->FILL + 1);
278 1         4 PUSH($sv);
279             }
280              
281 1         28 return $PL_op->next;
282             }
283              
284             sub pp_padhv{
285 1     1 1 5 my $targ = GET_TARGET;
286              
287 1 50       8 if(($PL_op->private & (OPpLVAL_INTRO|OPpPAD_STATE)) == OPpLVAL_INTRO){
288 1         5 SAVECLEARSV($targ);
289             }
290              
291 1         12 PUSH($targ);
292              
293 1 50       13 if($PL_op->flags & OPf_REF){
    50          
294 0         0 return $PL_op->next;
295             }
296             elsif(LVRET){
297 0         0 not_implemented 'padhv for lvalue';
298             }
299              
300 1         3 my $gimme = GIMME_V;
301 1 50       7 if($gimme == G_ARRAY){
    50          
302 0         0 return &_do_kv;
303             }
304             elsif($gimme == G_SCALAR){
305 1         6 SET( hv_scalar($targ) );
306             }
307              
308 1         22 return $PL_op->next;;
309             }
310              
311             sub pp_anonlist{
312 4     4 1 12 my $mark = POPMARK;
313 4         16 my @ary = mark_list($mark);
314              
315 4 50       29 if($PL_op->flags & OPf_SPECIAL){
316 4         6 my $ref = \@ary;
317 4         23 mPUSH(svref_2object(\$ref));
318             }
319             else{
320 0         0 mPUSH(svref_2object(\@ary));
321             }
322 4         49 return $PL_op->next;
323             }
324             sub pp_anonhash{
325 4     4 1 11 my $mark = POPMARK;
326 4         8 my $origmark = $mark;
327 4         6 my %hash;
328              
329 4         13 while($mark < $#PL_stack){
330 5         12 my $key = $PL_stack[++$mark];
331 5         6 my $val;
332 5 50       12 if($mark < $#PL_stack){
333 5         6 $val = ${ $PL_stack[++$mark]->object_2svref };
  5         17  
334             }
335             else{
336 0         0 apvm_warn 'Odd number of elements';
337             }
338 5         21 $hash{ ${ $key->object_2svref } } = $val;
  5         32  
339             }
340 4         10 $#PL_stack = $origmark;
341 4 50       19 if($PL_op->flags & OPf_SPECIAL){
342 4         9 my $ref = \%hash;
343 4         39 mPUSH(svref_2object(\$ref));
344             }
345             else{
346 0         0 mPUSH(svref_2object(\%hash));
347             }
348 4         35 return $PL_op->next;
349             }
350              
351             sub _refto{
352 1     1   2 my($sv) = @_;
353              
354 1 50       9 if($sv->class eq 'PVLV'){
355 0         0 not_implemented 'ref to PVLV';
356             }
357 1         3 my $rv = $sv->object_2svref;
358 1         7 return sv_2mortal( svref_2object(\$rv) );
359             }
360              
361             sub pp_srefgen{
362 1     1 1 4 $PL_stack[-1] = _refto($PL_stack[-1]);
363 1         7 return $PL_op->next;
364             }
365             sub pp_refgen{
366 0     0 1 0 my $mark = POPMARK;
367 0 0       0 if(GIMME_V == G_ARRAY){
368 0         0 while(++$mark <= $#PL_stack){
369 0         0 $PL_stack[$mark] = _refto($PL_stack[$mark]);
370             }
371             }
372             else{
373 0 0       0 if(++$mark <= $#PL_stack){
374 0         0 $PL_stack[$mark] = _refto($PL_stack[-1]);
375             }
376             else{
377 0         0 $PL_stack[$mark] = _refto(sv_undef);
378             }
379 0         0 $#PL_stack = $mark;
380             }
381 0         0 return $PL_op->next;
382             }
383              
384             sub pp_list{
385 5     5 1 17 my $mark = POPMARK;
386              
387 5 100       15 if(GIMME_V != G_ARRAY){
388 2 50       11 if(++$mark <= $#PL_stack){
389 2         16 $PL_stack[$mark] = $PL_stack[-1];
390             }
391             else{
392 0         0 $PL_stack[$mark] = sv_undef;
393             }
394 2         8 $#PL_stack = $mark;
395             }
396 5         56 return $PL_op->next;
397             }
398              
399              
400             sub _method_common{
401 14     14   19 my($meth) = @_;
402              
403 14         44 my $name = SvPV($meth);
404 14         42 my $sv = $PL_stack[ TOPMARK() + 1];
405              
406 14 50       39 if(!sv_defined($sv)){
407 0         0 apvm_die q{Can't call method "%s" on an undefined value}, $name;
408             }
409              
410 14         21 my $invocant = ${$sv->object_2svref};
  14         37  
411              
412 14         15 my $code = do{
413 14         26 local $@;
414 14         24 eval{ $invocant->can($name) };
  14         87  
415             };
416              
417 14 50       36 if(!$code){
418 0   0     0 apvm_die q{Can't locate object method "%s" via package "%s"}, $name, ref($invocant) || $invocant;
419             }
420              
421 14         70 return svref_2object($code);
422             }
423              
424             sub pp_method{
425 0     0 1 0 my $sv = TOP;
426              
427 0 0       0 if($sv->ROK){
428 0 0       0 if($sv->RV->class eq 'CV'){
429 0         0 SET($sv->RV);
430 0         0 return $PL_op->next;
431             }
432             }
433              
434 0         0 SET(_method_common($sv));
435 0         0 return $PL_op->next;
436             }
437             sub pp_method_named{
438 14 50   14 1 68 my $sv = is_not_null($PL_op->sv) ? $PL_op->sv : PAD_SV($PL_op->targ);
439              
440 14         43 PUSH(_method_common($sv));
441 14         103 return $PL_op->next;
442             }
443              
444             sub pp_entersub{
445 134     134 1 405 my $sv = POP;
446 134         492 my $cv = $sv->toCV();
447              
448 134 50       431 if(is_null($cv)){
449 0         0 apvm_die 'Undefined subroutine %s called', gv_fullname($sv, '&');
450             }
451 134         597 my $hasargs = ($PL_op->flags & OPf_STACKED) != 0;
452              
453 134         374 ENTER;
454 134         351 SAVETMPS;
455              
456 134         769 my $mark = POPMARK;
457 134         418 my $gimme = GIMME_V;
458              
459 134 100       555 if(!cv_external($cv)){
460 131         730 my $cx = PUSHBLOCK(SUB =>
461             oldsp => $mark,
462             gimme => $gimme,
463              
464             cv => $cv,
465             hasargs => $hasargs,
466             retop => $PL_op->next,
467             );
468              
469             #XXX: How to do {$cv->DEPTH++}?
470 131         958 PAD_SET_CUR($cv->PADLIST, $cv->DEPTH+1);
471              
472 131 100       388 if($hasargs){
473 21         66 my $av = PAD_SV(0);
474              
475 21         92 $cx->savearray(\@_);
476 21         95 *_ = $av->object_2svref;
477 21         85 $cx->CURPAD_SAVE();
478 21         83 $cx->argarray($av);
479              
480             #@_ = mark_list($mark);
481 21         99 av_assign($av, splice @PL_stack, $mark+1);
482             }
483              
484 131         1971 return $cv->START;
485             }
486             else{
487 3         5 my @args;
488 3         24 av_assign(svref_2object(\@args), splice @PL_stack, $mark+1);
489              
490 3 50       11 if($gimme == G_SCALAR){
    50          
491 0         0 my $ret = $cv->object_2svref->(@args);
492 0         0 mPUSH(svref_2object(\$ret));
493             }
494             elsif($gimme == G_ARRAY){
495 0         0 my @ret = $cv->object_2svref->(@args);
496 0         0 mPUSH(map{ svref_2object(\$_) } @ret);
  0         0  
497             }
498             else{
499 3         17 $cv->object_2svref->(@args);
500             }
501 3         1828 return $PL_op->next;
502             }
503             }
504              
505             sub pp_leavesub{
506 109     109 1 321 my $cx = POPBLOCK;
507 109         270 my $newsp = $cx->oldsp;
508 109         321 my $gimme = $cx->gimme;
509              
510 109 100       340 if($gimme == G_SCALAR){
    100          
511 40         64 my $mark = $newsp + 1;
512              
513 40 50       109 if($mark <= $#PL_stack){
514 40         129 $PL_stack[$mark] = sv_mortalcopy(TOP);
515             }
516             else{
517 0         0 $PL_stack[$mark] = sv_undef;
518             }
519 40         93 $#PL_stack = $mark;
520             }
521             elsif($gimme == G_ARRAY){
522 53         179 for(my $mark = $newsp + 1; $mark <= $#PL_stack; $mark++){
523 101         289 $PL_stack[$mark] = sv_mortalcopy($PL_stack[$mark]);
524             }
525             }
526             else{
527 16         38 $#PL_stack = $newsp;
528             }
529              
530 109         325 LEAVE;
531              
532 109         304 POPSUB($cx);
533             # XXX: How to do {$cv->DEPTH = $cx->olddepth}?
534              
535 109         1113 return $cx->retop;
536             }
537             sub pp_return{
538 7     7 1 20 my $mark = POPMARK;
539              
540 7         23 my $cxix = dopoptosub($#PL_cxstack);
541 7 50       21 if($cxix < 0){
542 0         0 apvm_die q{Can't return outside a subroutine};
543             }
544              
545 7 100       22 if($cxix < $#PL_cxstack){
546 6         19 dounwind($cxix);
547             }
548              
549 7         23 my $cx = POPBLOCK;
550 7         11 my $popsub2;
551             my $retop;
552              
553 7 50       24 if($cx->type eq 'SUB'){
554 7         21 $popsub2 = TRUE;
555 7         20 $retop = $cx->retop;
556             }
557             else{
558 0         0 not_implemented 'return for ' . $cx->type
559             }
560              
561 7         21 my $newsp = $cx->oldsp;
562 7         15 my $gimme = $cx->gimme;
563 7 100       29 if($gimme == G_SCALAR){
    50          
564 1 50       4 if($mark < $#PL_stack){
565 1         4 $PL_stack[++$newsp] = sv_mortalcopy(TOP);
566             }
567             else{
568 0         0 $PL_stack[++$newsp] = sv_undef;
569             }
570             }
571             elsif($gimme == G_ARRAY){
572 6         21 while(++$mark <= $#PL_stack){
573 7         24 $PL_stack[++$newsp] = sv_mortalcopy($PL_stack[$mark]);
574             }
575             }
576 7         16 $#PL_stack = $newsp;
577              
578 7         20 LEAVE;
579              
580 7 50       18 if($popsub2){
581 7         19 POPSUB($cx);
582             }
583 7         55 return $retop;
584             }
585              
586             sub pp_enter{
587              
588 17     17 1 57 my $gimme = OP_GIMME($PL_op, -1);
589              
590 17 50       49 if($gimme == -1){
591 17 50       38 if(@PL_cxstack){
592 17         54 $gimme = $PL_cxstack[-1]->gimme;
593             }
594             else{
595 0         0 $gimme = G_SCALAR;
596             }
597             }
598              
599 17         47 ENTER;
600 17         43 SAVETMPS;
601              
602 17         54 PUSHBLOCK(BLOCK =>
603             oldsp => $#PL_stack,
604             gimme => $gimme
605             );
606              
607 17         132 return $PL_op->next;
608             }
609             sub pp_leave{
610              
611 11     11 1 36 my $cx = POPBLOCK;
612 11         34 my $newsp = $cx->oldsp;
613 11         34 my $gimme = OP_GIMME($PL_op, -1);
614 11 50       109 if($gimme == -1){
615 11 50       37 if(@PL_cxstack){
616 11         37 $gimme = $PL_cxstack[-1]->gimme;
617             }
618             else{
619 0         0 $gimme = G_SCALAR;
620             }
621             }
622              
623 11 100       35 if($gimme == G_VOID){
    100          
624 3         8 $#PL_stack = $newsp;
625             }
626             elsif($gimme == G_SCALAR){
627 2         7 my $mark = $newsp + 1;
628 2 50       8 if($mark <= $#PL_stack){
629 2         9 $PL_stack[$mark] = sv_mortalcopy(TOP);
630             }
631             else{
632 0         0 $PL_stack[$mark] = sv_undef;
633             }
634 2         8 $#PL_stack = $mark;
635             }
636             else{ # G_ARRAY
637 6         23 for(my $mark = $newsp + 1; $mark <= $#PL_stack; $mark++){
638 7         23 $PL_stack[$mark] = sv_mortalcopy($PL_stack[$mark]);
639             }
640             }
641              
642 11         30 LEAVE;
643              
644 11         127 return $PL_op->next;
645             }
646              
647              
648             sub pp_enterloop{
649              
650 4     4 1 13 ENTER;
651 4         10 SAVETMPS;
652 4         12 ENTER;
653              
654 4         24 PUSHBLOCK(LOOP =>
655             oldsp => $#PL_stack,
656             gimme => GIMME_V,
657              
658             resetsp => $#PL_stack,
659             );
660              
661 4         39 return $PL_op->next;
662             }
663              
664             sub pp_leaveloop{
665 5     5 1 16 my $cx = POPBLOCK;
666              
667 5         14 my $mark = $cx->oldsp;
668 5         22 my $gimme = $cx->gimme;
669 5         17 my $newsp = $cx->resetsp;
670              
671 5 100       33 if($gimme == G_SCALAR){
    100          
672 1 50       7 if($mark < $#PL_stack){
673 1         5 $PL_stack[++$newsp] = sv_mortalcopy($PL_stack[-1]);
674             }
675             else{
676 0         0 $PL_stack[++$newsp] = sv_undef;
677             }
678             }
679             elsif($gimme == G_ARRAY){
680 3         12 while($mark < $#PL_stack){
681 3         17 $PL_stack[++$newsp] = sv_mortalcopy($PL_stack[++$mark]);
682             }
683             }
684              
685 5         9 $#PL_stack = $newsp;
686              
687 5         19 POPLOOP($cx);
688              
689 5         18 LEAVE;
690 5         15 LEAVE;
691              
692 5         92 return $PL_op->next;
693             }
694              
695             sub _range_is_numeric{
696 4     4   7 my($min, $max) = @_;
697             return looks_like_number(${$min->object_2svref})
698 4   66     6 && looks_like_number(${$max->object_2svref});
699             }
700              
701             sub pp_enteriter{
702 2     2 1 6 my $mark = POPMARK;
703 2         3 my $sv;
704             my $iterdata;
705 2         5 my $padvar = FALSE;
706 2         3 my $for_def = FALSE;
707              
708 2         6 ENTER;
709 2         6 SAVETMPS;
710              
711 2 50       15 if($PL_op->targ){
712 2         3 if(USE_ITHREADS){
713             #SAVEPADSV($PL_op->targ);
714             $padvar = TRUE;
715             $iterdata = $PL_op->targ;
716             }
717             else{
718 2         148 SAVE($PL_curpad[$PL_op->targ]);
719 2         12 $sv = $PL_curpad[$PL_op->targ];
720 2         12 $iterdata = $sv;
721             }
722             }
723             else{
724 0         0 my $gv = POP;
725 0         0 $sv = save_scalar($gv);
726 0         0 if(USE_ITHREADS){
727             $iterdata = $gv;
728             }
729             else{
730 0         0 $iterdata = $sv;
731             }
732             }
733              
734             # if($PL_op->private & OPpITER_DEF){
735             # $for_def = TRUE;
736             # }
737              
738 2         6 ENTER;
739              
740 2         7 my $cx = PUSHBLOCK(FOREACH =>
741             oldsp => $#PL_stack,
742             gimme => GIMME_V,
743              
744             resetsp => $mark,
745             iterdata => $iterdata,
746             padvar => $padvar,
747             for_def => $for_def,
748             );
749              
750 2 50       11 if($PL_op->flags & OPf_STACKED){
751 2         7 my $iterary = POP;
752 2 50       42 if($iterary->class ne 'AV'){
753 2         7 my $sv = POP;
754 2         4 my $right = $iterary;
755 2 50       7 if(_range_is_numeric($sv, $right)){
756 2         9 $cx->iterix(SvIV($sv));
757 2         7 $cx->itermax(SvIV($right));
758             }
759             else{
760 0         0 $cx->iterlval(SvPV($sv));
761 0         0 $cx->iterary(SvPV($sv));
762             }
763             }
764             else{
765 0         0 $cx->iterary([$iterary->ARRAY]);
766              
767 0 0       0 if($PL_op->private & OPpITER_REVERSED){
768 0         0 $cx->itermax(0);
769 0         0 $cx->iterix($iterary->FILL + 1);
770             }
771             else{
772 0         0 $cx->iterix(-1);
773             }
774             }
775              
776             # XXX: original code does not have this adjustment.
777             # is it OK?
778 2         16 $cx->oldsp($#PL_stack);
779             }
780             else{
781 0         0 $cx->iterary(\@PL_stack);
782 0 0       0 if($PL_op->private & OPpITER_REVERSED){
783 0         0 $cx->itermax($mark + 1);
784 0         0 $cx->iterix($cx->oldsp + 1);
785             }
786             else{
787 0         0 $cx->iterix($mark);
788             }
789             }
790 2         21 return $PL_op->next;
791             }
792             sub pp_iter{
793 22     22 1 27 my $cx = $PL_cxstack[-1];
794              
795 22         67 my $itersv = $cx->ITERVAR;
796 22         59 my $iterary = $cx->iterary;
797              
798 22 50       51 if(ref($iterary) ne 'ARRAY'){ # iterate range
799 22 50       63 if(my $cur = $cx->iterlval){
800 0         0 not_implemented 'string range in foreach';
801             }
802              
803             # integer increment
804 22 100       79 if($cx->iterix > $cx->itermax){
805 2         10 PUSH(sv_no);
806 2         15 return $PL_op->next;
807             }
808              
809 20         72 $itersv->setval($cx->iterix);
810 20         80 $cx->iterix($cx->iterix+1);
811              
812 20         57 PUSH(sv_yes);
813 20         148 return $PL_op->next;
814             }
815              
816             # iteratte array
817 0 0       0 if($PL_op->private & OPpITER_REVERSED){
818 0 0       0 if($cx->iterix <= $cx->itermax){
819 0         0 PUSH(sv_no);
820 0         0 return $PL_op->next;
821             }
822 0         0 $cx->iterix($cx->iterix-1);
823             }
824             else{
825 0 0       0 my $max = $iterary == \@PL_stack ? $cx->oldsp : $#{$iterary};
  0         0  
826 0 0       0 if($cx->iterix >= $max){
827 0         0 PUSH(sv_no);
828 0         0 return $PL_op->next;
829             }
830 0         0 $cx->iterix($cx->iterix+1);
831             }
832              
833 0   0     0 my $sv = $iterary->[$cx->iterix] || sv_no;
834 0         0 $itersv->setsv($sv);
835              
836 0         0 PUSH(sv_yes);
837 0         0 return $PL_op->next;
838             }
839              
840             sub pp_lineseq{
841 0     0 1 0 return $PL_op->next;
842             }
843              
844             sub pp_unstack{
845 21     21 1 69 $#PL_stack = $PL_cxstack[-1]->oldsp;
846              
847 21         60 FREETMPS;
848 21         51 LEAVE_SCOPE($PL_scopestack[-1]);
849              
850 21         228 return $PL_op->next;
851             }
852              
853             sub pp_stub{
854 0 0   0 1 0 if(GIMME_V == G_SCALAR){
855 0         0 PUSH(sv_undef);
856             }
857 0         0 return $PL_op->next;
858             }
859              
860              
861             sub _dopoptoloop{
862 0     0   0 my $cxix;
863 0 0       0 if($PL_op->flags & OPf_SPECIAL){
864 0         0 $cxix = dopoptoloop($#PL_cxstack);
865 0 0       0 if($cxix < 0){
866 0         0 apvm_die q{Can't "%s" outside a loop block}, $PL_op->name
867             }
868             }
869             else{
870 0         0 $cxix = dopoptolabel($PL_op->pv);
871 0 0       0 if($cxix < 0){
872 0         0 apvm_die q{Label not found for "%s %s"}, $PL_op->name, $PL_op->pv;
873             }
874             }
875              
876 0         0 return $cxix;
877             }
878              
879             sub pp_last{
880 0     0 1 0 my $cxix = _dopoptoloop();
881 0 0       0 if($cxix < $#PL_cxstack){
882 0         0 dounwind($cxix);
883             }
884              
885 0         0 my $cx = POPBLOCK;
886 0         0 my $newsp= $cx->oldsp;
887 0         0 my $mark = $newsp;
888 0         0 my $type = $cx->type;
889 0         0 my $nextop;
890              
891 0 0       0 if($type eq 'LOOP'){
    0          
892 0         0 $newsp = $cx->resetsp;
893 0         0 $nextop = $cx->myop->lastop->next;
894             }
895             elsif($type eq 'SUB'){
896 0         0 $nextop = $cx->retop;
897             }
898             else{
899 0         0 not_implemented "last($type)";
900             }
901              
902 0         0 my $gimme = $cx->gimme;
903 0 0       0 if($gimme == G_SCALAR){
    0          
904 0 0       0 if($mark < $#PL_stack){
905 0         0 $PL_stack[++$newsp] = sv_mortalcopy($PL_stack[-1]);
906             }
907             else{
908 0         0 $PL_stack[++$newsp] = sv_undef;
909             }
910             }
911             elsif($gimme == G_SCALAR){
912 0         0 while($mark < $#PL_stack){
913 0         0 $PL_stack[++$newsp] = sv_mortalcopy($PL_stack[-1]);
914             }
915             }
916 0         0 $#PL_stack = $newsp;
917 0         0 LEAVE;
918              
919 0 0       0 if($type eq 'LOOP'){
    0          
920 0         0 POPLOOP($cx);
921 0         0 LEAVE;
922             }
923             elsif($type eq 'SUB'){
924 0         0 POPSUB($cx);
925             }
926 0         0 return $nextop;
927             }
928              
929             sub pp_next{
930 0     0 1 0 my $cxix = _dopoptoloop();
931 0 0       0 if($cxix < $#PL_cxstack){
932 0         0 dounwind($cxix);
933             }
934              
935 0         0 my $cx = TOPBLOCK;
936 0         0 LEAVE_SCOPE($PL_scopestack[-1]);
937 0         0 $PL_curcop = $cx->oldcop;
938 0         0 return $cx->nextop;
939             }
940             sub pp_redo{
941 0     0 1 0 my $cxix = _dopoptoloop();
942              
943 0         0 my $op = $PL_cxstack[$cxix]->myop->redoop;
944              
945 0 0       0 if($op->name eq 'enter'){
946 0         0 $cxix++;
947 0         0 $op = $op->next;
948             }
949              
950 0 0       0 if($cxix < $#PL_cxstack){
951 0         0 dounwind($cxix);
952             }
953              
954 0         0 my $cx = TOPBLOCK;
955 0         0 LEAVE_SCOPE($PL_scopestack[-2]);
956 0         0 FREETMPS;
957              
958 0         0 $PL_curcop = $cx->oldcop;
959 0         0 return $op;
960             }
961              
962              
963             sub pp_sassign{
964 31     31 1 93 my $right = POP;
965 31         92 my $left = TOP;
966              
967 31 100       178 if($PL_op->private & OPpASSIGN_BACKWARDS){
968 1         2 ($left, $right) = ($right, $left);
969             }
970 31         176 $right->setsv($left);
971 31         97 SET($right);
972 31         356 return $PL_op->next;
973             }
974              
975             sub pp_aassign{
976 9     9 1 21 my $last_l_elem = $#PL_stack;
977 9         23 my $last_r_elem = POPMARK();
978 9         35 my $first_r_elem = POPMARK() + 1;
979 9         26 my $first_l_elem = $last_r_elem + 1;
980              
981 9         77 my @lhs = @PL_stack[$first_l_elem .. $last_l_elem];
982 9         23 my @rhs = @PL_stack[$first_r_elem .. $last_r_elem];
983              
984 9 50       51 if($PL_op->private & OPpASSIGN_COMMON){
985 0         0 for(my $r_elem = $first_r_elem; $r_elem <= $last_r_elem; $r_elem++){
986 0         0 $PL_stack[$r_elem] = sv_mortalcopy($PL_stack[$r_elem]);
987             }
988             }
989              
990 9         15 my $ary_ref;
991             my $hash_ref;
992              
993 9         12 my $l_elem = $first_l_elem;
994 9         10 my $r_elem = $first_r_elem;
995              
996 9         23 my $gimme = GIMME_V;
997 9         14 my $hv;
998              
999 9         23 while($l_elem <= $last_l_elem){
1000 15         100 my $sv = $PL_stack[$l_elem++];
1001              
1002 15 100       236 if($sv->class eq 'AV'){
    100          
1003 2         12 $ary_ref = $sv->object_2svref;
1004 2         4 @{ $ary_ref } = ();
  2         5  
1005 2         7 while($r_elem <= $last_r_elem){
1006 2         5 push @{$ary_ref}, ${ $PL_stack[$r_elem]->object_2svref };
  2         3  
  2         13  
1007 2         17 $PL_stack[$r_elem++] = svref_2object(\$ary_ref->[-1]);
1008             }
1009             }
1010             elsif($sv->class eq 'HV'){
1011 1         2 $hv = $sv;
1012 1         8 $hash_ref = $sv->object_2svref;
1013 1         2 %{$hash_ref} = ();
  1         2  
1014              
1015 1         3 while($r_elem < $last_r_elem){
1016 1         3 my $key = $PL_stack[$r_elem++];
1017 1         2 my $val = $PL_stack[$r_elem++];
1018              
1019 1   33     6 $sv->store_ent($key, $val || sv_undef);
1020             }
1021              
1022 1 50       5 if($r_elem == $last_r_elem){
1023 0         0 apvm_warn 'Odd number of elements in hash assignment';
1024 0         0 $r_elem++;
1025             }
1026             }
1027             else{
1028 12 100       30 if($$sv == ${sv_undef()}){ # (undef) = (...)
  12 50       53  
1029 6 50       15 if($r_elem <= $last_r_elem){
1030 6         17 $r_elem++;
1031             }
1032             }
1033             elsif($r_elem <= $last_r_elem){
1034 6         32 $sv->setsv($PL_stack[$r_elem]);
1035 6         25 $PL_stack[$r_elem++] = $sv;
1036             }
1037             }
1038             }
1039              
1040 9 100       24 if($gimme == G_VOID){
    50          
1041 8         20 $#PL_stack = $first_r_elem - 1;
1042             }
1043             elsif($gimme == G_SCALAR){
1044 0         0 $#PL_stack = $first_r_elem;
1045 0         0 SETval($last_r_elem - $first_r_elem + 1);
1046             }
1047             else{
1048 1         2 $l_elem = $first_l_elem + ($r_elem + $first_r_elem);
1049 1         3 while($r_elem <= $#PL_stack){
1050 1 50       7 $PL_stack[$r_elem++] = ($l_elem <= $last_l_elem) ? $PL_stack[$l_elem++] : sv_undef;
1051             }
1052              
1053 1 50       4 if($ary_ref){
    0          
1054 1         3 $#PL_stack = $last_r_elem;
1055             }
1056             elsif($hash_ref){
1057 0         0 $#PL_stack = $first_r_elem;
1058 0         0 SET($hv);
1059              
1060 0         0 return &_do_kv;
1061             }
1062             else{
1063 0         0 $#PL_stack = $first_r_elem + ($last_l_elem - $first_l_elem);
1064             }
1065             }
1066              
1067 9         96 return $PL_op->next;
1068             }
1069              
1070             sub pp_cond_expr{
1071 4 100   4 1 13 if(SvTRUE(POP)){
1072 2         25 return $PL_op->other;
1073             }
1074             else{
1075 2         21 return $PL_op->next;
1076             }
1077             }
1078              
1079             sub pp_and{
1080 22 100   22 1 53 if(!SvTRUE(TOP)){
1081 2         19 return $PL_op->next;
1082             }
1083             else{
1084 20         40 --$#PL_stack;
1085 20         145 return $PL_op->other;
1086             }
1087             }
1088             sub pp_or{
1089 0 0   0 1 0 if(SvTRUE(TOP)){
1090 0         0 return $PL_op->next;
1091             }
1092             else{
1093 0         0 --$#PL_stack;
1094 0         0 return $PL_op->other;
1095             }
1096             }
1097             sub pp_andassign{
1098 0 0   0 0 0 if(!SvTRUE(TOP)){
1099 0         0 return $PL_op->next;
1100             }
1101             else{
1102 0         0 return $PL_op->other;
1103             }
1104             }
1105             sub pp_orassign{
1106 1 50   1 0 3 if(SvTRUE(TOP)){
1107 0         0 return $PL_op->next;
1108             }
1109             else{
1110 1         14 return $PL_op->other;
1111             }
1112             }
1113              
1114             sub pp_stringify{
1115 0     0 0 0 my $sv = TOP;
1116 0         0 SETval(SvPV($sv));
1117 0         0 return $PL_op->next;
1118             }
1119              
1120             sub pp_defined{
1121 0     0 1 0 my $sv = POP;
1122 0         0 my $type = $sv->class;
1123 0         0 my $ref = $sv->object_2svref;
1124              
1125 0         0 my $defined;
1126 0 0       0 if($type eq 'AV'){
    0          
    0          
1127 0         0 $defined = defined @{$ref};
  0         0  
1128             }
1129             elsif($type eq 'HV'){
1130 0         0 $defined = defined %{$ref};
  0         0  
1131             }
1132             elsif($type eq 'CV'){
1133 0         0 $defined = defined &{$ref};
  0         0  
1134             }
1135             else{
1136 0         0 $defined = defined ${$ref};
  0         0  
1137             }
1138 0 0       0 PUSH($defined ? sv_yes : sv_no);
1139 0         0 return $PL_op->next;
1140             }
1141              
1142             sub pp_range{
1143 2 50   2 1 6 if(GIMME_V == G_ARRAY){
1144 2         35 return $PL_op->next;
1145             }
1146              
1147 0 0       0 if(SvTRUE(GET_TARGET)){
1148 0         0 return $PL_op->other;
1149             }
1150             else{
1151 0         0 return $PL_op->next;
1152             }
1153             }
1154              
1155             sub pp_flip{
1156 2 50   2 0 7 if(GIMME_V == G_ARRAY){
1157 2         21 return $PL_op->first->other;
1158             }
1159              
1160 0         0 not_implemented 'flip-flop in scalar context';
1161             }
1162             sub pp_flop{
1163 2 50   2 0 6 if(GIMME_V == G_ARRAY){
1164 2         26 my $right = POP;
1165 2         6 my $left = POP;
1166              
1167 2         3 my $i = ${$left->object_2svref};
  2         24  
1168 2         3 my $max = ${$right->object_2svref};
  2         5  
1169              
1170 2 50 66     9 if(_range_is_numeric($left, $right) && $i >= $max){
1171 0         0 return $PL_op->next;
1172             }
1173              
1174              
1175 2         5 $max++;
1176 2         7 while($i ne $max){
1177 36         75 my $sv = sv_newmortal();
1178 36         98 $sv->setval($i);
1179 36         128 PUSH($sv);
1180 36         90 $i++;
1181             }
1182             }
1183             else{
1184 0         0 not_implemented 'flip-flop in scalar context';
1185             }
1186              
1187 2         18 return $PL_op->next;
1188             }
1189              
1190              
1191             sub pp_preinc{
1192 9     9 1 17 ${ TOP()->object_2svref }++;
  9         36  
1193              
1194 9         66 return $PL_op->next;
1195             }
1196             sub pp_postinc{
1197 0     0 1 0 my $targ = GET_TARGET;
1198 0         0 my $sv = TOP;
1199 0         0 my $ref = $sv->object_2svref;
1200              
1201 0 0       0 if(defined ${$sv}){
  0         0  
1202 0         0 $targ->setsv($sv);
1203             }
1204             else{
1205 0         0 $targ->setval(0);
1206             }
1207 0         0 ${$ref}++;
  0         0  
1208              
1209 0         0 SET($targ);
1210 0         0 return $PL_op->next;
1211             }
1212              
1213             sub pp_eq{
1214 0     0 1 0 my $right = POP;
1215 0         0 my $left = TOP;
1216 0 0       0 SET(SvNV($left) == SvNV($right) ? sv_yes : sv_no);
1217 0         0 return $PL_op->next;
1218             }
1219             sub pp_ne{
1220 0     0 1 0 my $right = POP;
1221 0         0 my $left = TOP;
1222 0 0       0 SET(SvNV($left) != SvNV($right) ? sv_yes : sv_no);
1223 0         0 return $PL_op->next;
1224             }
1225             sub pp_lt{
1226 1     1 1 4 my $right = POP;
1227 1         4 my $left = TOP;
1228 1 0       6 SET(SvNV($left) < SvNV($right) ? sv_yes : sv_no);
1229 0         0 return $PL_op->next;
1230             }
1231             sub pp_le{
1232 0     0 1 0 my $right = POP;
1233 0         0 my $left = TOP;
1234 0 0       0 SET(SvNV($left) <= SvNV($right) ? sv_yes : sv_no);
1235 0         0 return $PL_op->next;
1236             }
1237             sub pp_gt{
1238 0     0 1 0 my $right = POP;
1239 0         0 my $left = TOP;
1240 0 0       0 SET(SvNV($left) > SvNV($right) ? sv_yes : sv_no);
1241 0         0 return $PL_op->next;
1242             }
1243             sub pp_ge{
1244 0     0 1 0 my $right = POP;
1245 0         0 my $left = TOP;
1246 0 0       0 SET(SvNV($left) >= SvNV($right) ? sv_yes : sv_no);
1247 0         0 return $PL_op->next;
1248             }
1249             sub pp_ncmp{
1250 0     0 0 0 my $right = POP;
1251 0         0 my $left = TOP;
1252 0         0 SET(SvNV($left) <=> SvNV($right));
1253 0         0 return $PL_op->next;
1254             }
1255              
1256             sub pp_seq{
1257 0     0 0 0 my $right = POP;
1258 0         0 my $left = TOP;
1259 0 0       0 SET(SvPV($left) eq SvPV($right) ? sv_yes : sv_no);
1260 0         0 return $PL_op->next;
1261             }
1262             sub pp_sne{
1263 0     0 0 0 my $right = POP;
1264 0         0 my $left = TOP;
1265 0 0       0 SET(SvPV($left) ne SvPV($right) ? sv_yes : sv_no);
1266 0         0 return $PL_op->next;
1267             }
1268             sub pp_slt{
1269 0     0 0 0 my $right = POP;
1270 0         0 my $left = TOP;
1271 0 0       0 SET(SvPV($left) lt SvPV($right) ? sv_yes : sv_no);
1272 0         0 return $PL_op->next;
1273             }
1274             sub pp_sle{
1275 0     0 0 0 my $right = POP;
1276 0         0 my $left = TOP;
1277 0 0       0 SET(SvPV($left) le SvPV($right) ? sv_yes : sv_no);
1278 0         0 return $PL_op->next;
1279             }
1280             sub pp_sgt{
1281 0     0 0 0 my $right = POP;
1282 0         0 my $left = TOP;
1283 0 0       0 SET(SvPV($left) gt SvPV($right) ? sv_yes : sv_no);
1284 0         0 return $PL_op->next;
1285             }
1286             sub pp_sge{
1287 0     0 0 0 my $right = POP;
1288 0         0 my $left = TOP;
1289 0 0       0 SET(SvPV($left) ge SvPV($right) ? sv_yes : sv_no);
1290 0         0 return $PL_op->next;
1291             }
1292             sub pp_scmp{
1293 0     0 0 0 my $right = POP;
1294 0         0 my $left = TOP;
1295 0         0 SET(SvPV($left) cmp SvPV($right));
1296 0         0 return $PL_op->next;
1297             }
1298              
1299              
1300             sub pp_add{
1301 29     29 1 73 my $targ = GET_ATARGET;
1302 29         70 my $right = POP;
1303 29         67 my $left = TOP;
1304              
1305 29         80 SET( $targ->setval(SvNV($left) + SvNV($right)) );
1306 29         199 return $PL_op->next;
1307             }
1308              
1309             sub pp_multiply{
1310 0     0 0 0 my $targ = GET_ATARGET;
1311 0         0 my $right = POP;
1312 0         0 my $left = TOP;
1313              
1314 0         0 SET( $targ->setval(SvNV($left) * SvNV($right)) );
1315 0         0 return $PL_op->next;
1316             }
1317              
1318             sub pp_concat{
1319 2     2 1 7 my $targ = GET_ATARGET;
1320 2         5 my $right= POP;
1321 2         7 my $left = TOP;
1322              
1323 2         7 SET( $targ->setval(SvPV($left) . SvPV($right)) );
1324 2         31 return $PL_op->next;
1325             }
1326              
1327             sub pp_readline{
1328 5     5 1 14 $PL_last_in_gv = POP;
1329 5 100       81 if($PL_last_in_gv->class ne 'GV'){
1330 1         60 PUSH($PL_last_in_gv);
1331 1         4 &pp_rv2gv;
1332 1         4 $PL_last_in_gv = POP;
1333             }
1334              
1335             # do_readline
1336 5         30 my $targ = GET_TARGETSTACKED;
1337 5         21 my $istream = $PL_last_in_gv->object_2svref;
1338              
1339 5         14 my $gimme = GIMME_V;
1340 5 100       13 if($gimme == G_ARRAY){
1341 2         30 mPUSH(map{ svref_2object(\$_) } readline $istream);
  3         16  
1342             }
1343             else{
1344 3         32 $targ->setval(scalar readline $istream);
1345 3         10 PUSH($targ);
1346             }
1347              
1348 5         43 return $PL_op->next;
1349             }
1350              
1351             sub pp_print{
1352 6     6 1 15 my $mark = POPMARK;
1353 6         9 my $origmark = $mark;
1354 6 50       40 my $gv = ($PL_op->flags & OPf_STACKED) ? $PL_stack[++$mark]->object_2svref : defoutgv;
1355              
1356 6         8 my $ret = print {$gv} mark_list($mark);
  6         20  
1357              
1358 6         13 $#PL_stack = $origmark;
1359 6 50       19 PUSH( $ret ? sv_yes : sv_no );
1360 6         48 return $PL_op->next;
1361             }
1362             sub pp_say{
1363 0     0 1 0 my $mark = POPMARK;
1364 0         0 my $origmark = $mark;
1365 0 0       0 my $gv = ($PL_op->flags & OPf_STACKED) ? $PL_stack[++$mark]->object_2svref : defoutgv;
1366              
1367 0         0 local $\ = "\n";
1368 0         0 my $ret = print {$gv} mark_list($mark);
  0         0  
1369              
1370 0         0 $#PL_stack = $origmark;
1371 0 0       0 PUSH( $ret ? sv_yes : sv_no );
1372 0         0 return $PL_op->next;
1373             }
1374              
1375             sub pp_bless{
1376 0     0 0 0 my $pkg;
1377 0 0       0 if(MAXARG == 1){
1378 0         0 $pkg = $PL_curcop->stashpv;
1379             }
1380             else{
1381 0         0 my $sv = POP;
1382 0 0       0 if($sv->ROK){
1383 0         0 apvm_die 'Attempt to bless into a reference';
1384             }
1385 0         0 $pkg = SvPV($sv);
1386 0 0       0 if($pkg eq ''){
1387 0         0 apvm_warn q{Explicit blessing to '' (assuming package main)};
1388             }
1389             }
1390 0         0 bless ${TOP->object_2svref}, $pkg;
  0         0  
1391 0         0 return $PL_op->next;
1392             }
1393              
1394             sub pp_push{
1395 0     0 0 0 my $mark = POPMARK;
1396 0         0 my $av = $PL_stack[++$mark];
1397 0         0 my $n = push @{$av->object_2svref}, mark_list($mark);
  0         0  
1398 0         0 SETval($n);
1399 0         0 return $PL_op->next;
1400             }
1401              
1402             sub pp_pop{
1403 0     0 0 0 my $av = POP;
1404 0         0 my $val = pop @{$av->object_2svref};
  0         0  
1405 0         0 mPUSH(svref_2object(\$val));
1406 0         0 return $PL_op->next;
1407             }
1408              
1409             sub pp_shift{
1410 1     1 0 4 my $av = POP;
1411 1         2 my $val = shift @{$av->object_2svref};
  1         266  
1412 0         0 mPUSH(svref_2object(\$val));
1413 0         0 return $PL_op->next;
1414             }
1415              
1416             sub pp_unshift{
1417 0     0 0 0 my $mark = POPMARK;
1418 0         0 my $av = $PL_stack[++$mark];
1419 0         0 my $n = unshift @{$av->object_2svref}, mark_list($mark);
  0         0  
1420 0         0 SETval($n);
1421 0         0 return $PL_op->next;
1422             }
1423              
1424             sub pp_join{
1425 0     0 0 0 my $mark = POPMARK;
1426              
1427 0         0 my $delim = $PL_stack[++$mark];
1428 0         0 SETval(join SvPV($delim), mark_list($mark));
1429 0         0 return $PL_op->next;
1430             }
1431              
1432             sub pp_aelemfast{
1433 1 50   1 1 12 my $av = $PL_op->flags & OPf_SPECIAL ? PAD_SV($PL_op->targ) : GVOP_gv($PL_op)->AV;
1434 1   33     10 my $lval = $PL_op->flags & OPf_MOD || LVRET;
1435              
1436 1         9 PUSH( svref_2object(\$av->object_2svref->[$PL_op->private]) );
1437 1         7 return $PL_op->next;
1438             }
1439              
1440             sub pp_aelem{
1441 0     0 1 0 my $elemsv = POP;
1442 0         0 my $av = TOP;
1443 0   0     0 my $lval = $PL_op->flags & OPf_MOD || LVRET;
1444              
1445 0 0       0 if($elemsv->ROK){
1446 0         0 apvm_warn q{Use of reference %s as array index}, $elemsv->object_2svref;
1447             }
1448              
1449 0         0 SET( svref_2object(\$av->object_2svref->[SvIV($elemsv)]) );
1450 0         0 return $PL_op->next;
1451             }
1452              
1453             sub pp_helem{
1454 1     1 1 3 my $keysv = POP;
1455 1         13 my $hv = TOP;
1456 1   33     9 my $lval = $PL_op->flags & OPf_MOD || LVRET;
1457              
1458 1         5 SET( svref_2object(\$hv->object_2svref->{SvPV($keysv)}) );
1459 1         7 return $PL_op->next;
1460             }
1461             sub pp_keys{
1462 0     0 1 0 return &_do_kv;
1463             }
1464             sub pp_values{
1465 0     0 1 0 return &_do_kv;
1466             }
1467              
1468             sub pp_wantarray{
1469 12     12 0 36 my $cxix = dopoptosub($#PL_cxstack);
1470 12 50       27 if($cxix < 0){
1471 0         0 PUSH(sv_undef);
1472             }
1473             else{
1474 12         40 my $gimme = $PL_cxstack[$cxix]->gimme;
1475 12 100       33 if($gimme == G_ARRAY){
    100          
1476 4         12 PUSH(sv_yes);
1477             }
1478             elsif($gimme == G_SCALAR){
1479 4         11 PUSH(sv_no);
1480             }
1481             else{
1482 4         26 PUSH(sv_undef);
1483             }
1484             }
1485 12         93 return $PL_op->next;
1486             }
1487              
1488             sub pp_undef{
1489 6 50   6 1 30 if(!$PL_op->private){
1490 6         27 PUSH(sv_undef);
1491 6         38 return $PL_op->next;
1492             }
1493              
1494 0         0 not_implemented 'undef(expr)';
1495             }
1496              
1497             sub pp_scalar{
1498 0     0 1 0 return $PL_op->next;
1499             }
1500              
1501             sub pp_not{
1502 0 0   0 1 0 SET( !SvTRUE(TOP) ? sv_yes : sv_no );
1503 0         0 return $PL_op->next;
1504             }
1505              
1506             sub pp_qr{
1507 1     1 0 6 my $re = $PL_op->precomp;
1508              
1509 1         38 mPUSH(svref_2object(\qr/$re/));
1510 1         22 return $PL_op->next;
1511             }
1512              
1513              
1514             1;
1515             __END__