4 require Config; import Config;
5 if ($Config{'extensions'} !~ /\bDevel\/Peek\b/) {
6 print "1..0 # Skip: Devel::Peek was not built\n";
11 my $core = !!$ENV{PERL_CORE};
12 require($core ? '../../t/test.pl' : './t/test.pl');
21 open(SAVERR, ">&STDERR") or die "Can't dup STDERR: $!";
23 # If I reference any lexicals in this, I get the entire outer subroutine (or
24 # MAIN) dumped too, which isn't really what I want, as it's a lot of faff to
33 use constant thr => $Config{useithreads};
37 my $repeat_todo = $_[4];
40 if (open(OUT,">peek$$")) {
41 open(STDERR, ">&OUT") or die "Can't dup OUT: $!";
43 my $sub = eval "sub { Dump $_[1] }";
45 print STDERR "*****\n";
46 # second dump to compare with the first to make sure nothing
52 print STDERR "*****\n";
53 # second dump to compare with the first to make sure nothing
57 open(STDERR, ">&SAVERR") or die "Can't restore STDERR: $!";
59 if (open(IN, "peek$$")) {
61 $pattern =~ s/\$ADDR/0x[[:xdigit:]]+/g;
62 $pattern =~ s/\$FLOAT/(?:\\d*\\.\\d+(?:e[-+]\\d+)?|\\d+)/g;
63 # handle DEBUG_LEAKING_SCALARS prefix
64 $pattern =~ s/^(\s*)(SV =.* at )/(?:$1ALLOCATED at .*?\n)?$1$2/mg;
66 # Need some clear generic mechanism to eliminate (or add) lines
67 # of dump output dependant on perl version. The (previous) use of
68 # things like $IVNV gave the illusion that the string passed in was
69 # a regexp into which variables were interpolated, but this wasn't
70 # actually true as those 'variables' actually also ate the
71 # whitespace on the line. So it seems better to mark lines that
72 # need to be eliminated. I considered (?# ... ) and (?{ ... }),
73 # but whilst embedded code or comment syntax would keep it as a
74 # legitimate regexp, it still isn't true. Seems easier and clearer
75 # things that look like comments.
77 # Could do this is in a s///mge but seems clearer like this:
78 $pattern = join '', map {
79 # If we identify the version condition, take *it* out whatever
82 : $_ # Didn't match, so this line is in
83 } split /^/, $pattern;
85 $pattern =~ s/\$PADMY/
86 ($] < 5.009) ? 'PADBUSY,PADMY' : 'PADMY';
88 $pattern =~ s/\$PADTMP/
89 ($] < 5.009) ? 'PADBUSY,PADTMP' : 'PADTMP';
92 ($] < 5.011) ? 'RV' : 'IV';
94 $pattern =~ s/^\h+COW_REFCNT = .*\n//mg
95 if $Config{ccflags} =~
96 /-DPERL_(?:OLD_COPY_ON_WRITE|NO_COW)/
98 print $pattern, "\n" if $DEBUG;
99 my ($dump, $dump2) = split m/\*\*\*\*\*\n/, scalar <IN>;
100 print $dump, "\n" if $DEBUG;
101 like( $dump, qr/\A$pattern\Z/ms, $_[0])
102 or note("line " . (caller)[2]);
104 local $TODO = $repeat_todo;
105 is($dump2, $dump, "$_[0] (unchanged by dump)")
106 or note("line " . (caller)[2]);
112 die "$0: failed to open peek$$: !\n";
115 die "$0: failed to create peek$$: $!\n";
125 1 while unlink("peek$$");
128 do_test('assignment of immediate constant (string)',
130 'SV = PV\\($ADDR\\) at $ADDR
132 FLAGS = \\(POK,(?:IsCOW,)?pPOK\\)
139 do_test('immediate constant (string)',
141 'SV = PV\\($ADDR\\) at $ADDR
143 FLAGS = \\(.*POK,READONLY,(?:IsCOW,)?pPOK\\) # $] < 5.021004
144 FLAGS = \\(.*POK,(?:IsCOW,)?READONLY,PROTECT,pPOK\\) # $] >=5.021004
151 do_test('assignment of immediate constant (integer)',
153 'SV = IV\\($ADDR\\) at $ADDR
155 FLAGS = \\(IOK,pIOK\\)
158 do_test('immediate constant (integer)',
160 'SV = IV\\($ADDR\\) at $ADDR
162 FLAGS = \\(.*IOK,READONLY,pIOK\\) # $] < 5.021004
163 FLAGS = \\(.*IOK,READONLY,PROTECT,pIOK\\) # $] >=5.021004
166 do_test('assignment of immediate constant (integer)',
168 'SV = IV\\($ADDR\\) at $ADDR
170 FLAGS = \\($PADMY,IOK,pIOK\\)
173 # If perl is built with PERL_PRESERVE_IVUV then maths is done as integers
174 # where possible and this scalar will be an IV. If NO_PERL_PRESERVE_IVUV then
175 # maths is done in floating point always, and this scalar will be an NV.
176 # ([NI]) captures the type, referred to by \1 in this regexp and $type for
177 # building subsequent regexps.
178 my $type = do_test('result of addition',
180 'SV = ([NI])V\\($ADDR\\) at $ADDR
182 FLAGS = \\(PADTMP,\1OK,p\1OK\\) # $] < 5.019003
183 FLAGS = \\(\1OK,p\1OK\\) # $] >=5.019003
188 do_test('floating point value',
191 || $Config{ccflags} =~ /-DPERL_(?:NO_COW|OLD_COPY_ON_WRITE)/
193 'SV = PVNV\\($ADDR\\) at $ADDR
195 FLAGS = \\(NOK,pNOK\\)
197 NV = 789\\.(?:1(?:000+\d+)?|0999+\d+)
202 'SV = PVNV\\($ADDR\\) at $ADDR
204 FLAGS = \\(NOK,pNOK\\)
206 NV = 789\\.(?:1(?:000+\d+)?|0999+\d+)
209 do_test('integer constant',
211 'SV = IV\\($ADDR\\) at $ADDR
213 FLAGS = \\(.*IOK,READONLY,pIOK\\) # $] < 5.021004
214 FLAGS = \\(.*IOK,READONLY,PROTECT,pIOK\\) # $] >=5.021004
219 'SV = NULL\\(0x0\\) at $ADDR
221 FLAGS = \\(READONLY\\) # $] < 5.021004
222 FLAGS = \\(READONLY,PROTECT\\) # $] >=5.021004
225 do_test('reference to scalar',
227 'SV = $RV\\($ADDR\\) at $ADDR
231 SV = PV\\($ADDR\\) at $ADDR
233 FLAGS = \\(POK,(?:IsCOW,)?pPOK\\)
243 SV = PVNV\\($ADDR\\) at $ADDR
245 FLAGS = \\(IOK,NOK,pIOK,pNOK\\)
251 SV = IV\\($ADDR\\) at $ADDR
253 FLAGS = \\(IOK,pIOK\\)
256 do_test('reference to array',
258 'SV = $RV\\($ADDR\\) at $ADDR
262 SV = PVAV\\($ADDR\\) at $ADDR
273 SV = IV\\($ADDR\\) at $ADDR
275 FLAGS = \\(IOK,pIOK\\)
277 Elt No. 1' . $c_pattern);
279 do_test('reference to hash',
281 'SV = $RV\\($ADDR\\) at $ADDR
285 SV = PVHV\\($ADDR\\) at $ADDR
287 FLAGS = \\(SHAREKEYS\\)
289 NV = $FLOAT # $] < 5.009
290 ARRAY = $ADDR \\(0:7, 1:1\\)
291 hash quality = 100.0%
295 Elt "123" HASH = $ADDR' . $c_pattern,
297 $] > 5.009 && $] < 5.015
298 && 'The hash iterator used in dump.c sets the OOK flag');
300 do_test('reference to anon sub with empty prototype',
302 'SV = $RV\\($ADDR\\) at $ADDR
306 SV = PVCV\\($ADDR\\) at $ADDR
308 FLAGS = \\($PADMY,POK,pPOK,ANON,WEAKOUTSIDE,CVGV_RC\\) # $] < 5.015 || !thr
309 FLAGS = \\($PADMY,POK,pPOK,ANON,WEAKOUTSIDE,CVGV_RC,DYNFILE\\) # $] >= 5.015 && thr
313 COMP_STASH = $ADDR\\t"main"
314 START = $ADDR ===> \\d+
316 XSUB = 0x0 # $] < 5.009
317 XSUBANY = 0 # $] < 5.009
318 GVGV::GV = $ADDR\\t"main" :: "__ANON__[^"]*"
319 FILE = ".*\\b(?i:peek\\.t)"
323 FLAGS = 0x404 # $] < 5.009
324 FLAGS = 0x490 # $] >= 5.009 && ($] < 5.015 || !thr)
325 FLAGS = 0x1490 # $] >= 5.015 && thr
328 PADNAME = $ADDR\\($ADDR\\) PAD = $ADDR\\($ADDR\\)
329 OUTSIDE = $ADDR \\(MAIN\\)');
331 do_test('reference to named subroutine without prototype',
333 'SV = $RV\\($ADDR\\) at $ADDR
337 SV = PVCV\\($ADDR\\) at $ADDR
339 FLAGS = \\((?:HASEVAL(?:,NAMED)?)?\\) # $] < 5.015 || !thr
340 FLAGS = \\(DYNFILE(?:,HASEVAL(?:,NAMED)?)?\\) # $] >= 5.015 && thr
343 COMP_STASH = $ADDR\\t"main"
344 START = $ADDR ===> \\d+
346 XSUB = 0x0 # $] < 5.009
347 XSUBANY = 0 # $] < 5.009
348 NAME = "do_test" # $] >=5.021004
349 GVGV::GV = $ADDR\\t"main" :: "do_test" # $] < 5.021004
350 FILE = ".*\\b(?i:peek\\.t)"
354 FLAGS = 0x(?:[c4]00)?0 # $] < 5.015 || !thr
355 FLAGS = 0x[cd145]000 # $] >= 5.015 && thr
358 PADNAME = $ADDR\\($ADDR\\) PAD = $ADDR\\($ADDR\\)
359 \\d+\\. $ADDR<\\d+> \\(\\d+,\\d+\\) "\\$todo"
360 \\d+\\. $ADDR<\\d+> \\(\\d+,\\d+\\) "\\$repeat_todo"
361 \\d+\\. $ADDR<\\d+> \\(\\d+,\\d+\\) "\\$pattern"
362 \\d+\\. $ADDR<\\d+> \\(\\d+,\\d+\\) "\\$do_eval"
363 \\d+\\. $ADDR<\\d+> \\(\\d+,\\d+\\) "\\$sub"
364 \\d+\\. $ADDR<\\d+> FAKE "\\$DEBUG" # $] < 5.009
365 \\d+\\. $ADDR<\\d+> FAKE "\\$DEBUG" flags=0x0 index=0 # $] >= 5.009
366 \\d+\\. $ADDR<\\d+> \\(\\d+,\\d+\\) "\\$dump"
367 \\d+\\. $ADDR<\\d+> \\(\\d+,\\d+\\) "\\$dump2"
368 OUTSIDE = $ADDR \\(MAIN\\)');
371 # note the conditionals on ENGINE and INTFLAGS were introduced in 5.19.9
372 do_test('reference to regexp',
374 'SV = $RV\\($ADDR\\) at $ADDR
378 SV = REGEXP\\($ADDR\\) at $ADDR
380 FLAGS = \\(OBJECT,POK,FAKE,pPOK\\) # $] < 5.017006
381 FLAGS = \\(OBJECT,FAKE\\) # $] >= 5.017006
382 PV = $ADDR "\\(\\?\\^:tic\\)"
384 LEN = 0 # $] < 5.017006
385 STASH = $ADDR\\t"Regexp"'
389 EXTFLAGS = 0x680000 \(CHECK_ALL,USE_INTUIT_NOML,USE_INTUIT_ML\)
390 (?: ENGINE = $ADDR \(STANDARD\)
391 )? INTFLAGS = 0x0(?: \(\))?
404 )? MOTHER_RE = $ADDR'
405 . ($] < 5.019003 ? '' : '
406 SV = REGEXP\($ADDR\) at $ADDR
409 PV = $ADDR "\(\?\^:tic\)"
412 EXTFLAGS = 0x680000 \(CHECK_ALL,USE_INTUIT_NOML,USE_INTUIT_ML\)
413 (?: ENGINE = $ADDR \(STANDARD\)
414 )? INTFLAGS = 0x0(?: \(\))?
433 SAVED_COPY = 0x0)?') . '
442 do_test('reference to regexp',
444 'SV = $RV\\($ADDR\\) at $ADDR
448 SV = PVMG\\($ADDR\\) at $ADDR
450 FLAGS = \\(OBJECT,SMG\\)
456 MG_TYPE = PERL_MAGIC_qr\(r\)
458 PAT = "\(\?^:tic\)" # $] >= 5.009
459 REFCNT = 2 # $] >= 5.009
460 STASH = $ADDR\\t"Regexp"');
463 do_test('reference to blessed hash',
465 'SV = $RV\\($ADDR\\) at $ADDR
469 SV = PVHV\\($ADDR\\) at $ADDR
471 FLAGS = \\(OBJECT,SHAREKEYS\\)
474 STASH = $ADDR\\t"Tac"
482 : 'The hash iterator used in dump.c sets the OOK flag'
483 : "Something causes the HV's array to become allocated");
487 'SV = PVGV\\($ADDR\\) at $ADDR
489 FLAGS = \\(MULTI(?:,IN_PAD)?\\) # $] >= 5.009
490 FLAGS = \\(GMG,SMG,MULTI(?:,IN_PAD)?\\) # $] < 5.009
494 MAGIC = $ADDR # $] < 5.009
495 MG_VIRTUAL = &PL_vtbl_glob # $] < 5.009
496 MG_TYPE = PERL_MAGIC_glob\(\*\) # $] < 5.009
497 MG_OBJ = $ADDR # $] < 5.009
500 GvSTASH = $ADDR\\t"main"
501 FLAGS = $ADDR # $] >=5.021004
511 GPFLAGS = 0x0 # $] < 5.009
512 GPFLAGS = 0x0 \(\) # $] >= 5.021004
514 FILE = ".*\\b(?i:peek\\.t)"
515 FLAGS = $ADDR # $] < 5.021004
518 if (ord('A') == 193) {
519 do_test('string with Unicode',
520 chr(256).chr(0).chr(512),
521 'SV = PV\\($ADDR\\) at $ADDR
523 FLAGS = \\((?:$PADTMP,)?POK,READONLY,pPOK,UTF8\\) # $] < 5.019003
524 FLAGS = \\((?:$PADTMP,)?POK,(?:IsCOW,)?pPOK,UTF8\\) # $] >=5.019003
525 PV = $ADDR "\\\214\\\101\\\0\\\235\\\101"\\\0 \[UTF8 "\\\x\{100\}\\\x\{0\}\\\x\{200\}"\]
528 COW_REFCNT = 1 # $] < 5.019007
531 do_test('string with Unicode',
532 chr(256).chr(0).chr(512),
533 'SV = PV\\($ADDR\\) at $ADDR
535 FLAGS = \\((?:$PADTMP,)?POK,READONLY,pPOK,UTF8\\) # $] < 5.019003
536 FLAGS = \\((?:$PADTMP,)?POK,(?:IsCOW,)?pPOK,UTF8\\) # $] >=5.019003
537 PV = $ADDR "\\\304\\\200\\\0\\\310\\\200"\\\0 \[UTF8 "\\\x\{100\}\\\x\{0\}\\\x\{200\}"\]
540 COW_REFCNT = 1 # $] < 5.019007
544 if (ord('A') == 193) {
545 do_test('reference to hash containing Unicode',
546 {chr(256)=>chr(512)},
547 'SV = $RV\\($ADDR\\) at $ADDR
551 SV = PVHV\\($ADDR\\) at $ADDR
553 FLAGS = \\(SHAREKEYS,HASKFLAGS\\)
555 NV = $FLOAT # $] < 5.009
556 ARRAY = $ADDR \\(0:7, 1:1\\)
557 hash quality = 100.0%
561 Elt "\\\214\\\101" \[UTF8 "\\\x\{100\}"\] HASH = $ADDR
562 SV = PV\\($ADDR\\) at $ADDR
564 FLAGS = \\(POK,(?:IsCOW,)?pPOK,UTF8\\)
565 PV = $ADDR "\\\235\\\101"\\\0 \[UTF8 "\\\x\{200\}"\]
568 COW_REFCNT = 1 # $] < 5.019007
573 : 'The hash iterator used in dump.c sets the OOK flag'
574 : 'sv_length has been called on the element, and cached the result in MAGIC');
576 do_test('reference to hash containing Unicode',
577 {chr(256)=>chr(512)},
578 'SV = $RV\\($ADDR\\) at $ADDR
582 SV = PVHV\\($ADDR\\) at $ADDR
584 FLAGS = \\(SHAREKEYS,HASKFLAGS\\)
587 ARRAY = $ADDR \\(0:7, 1:1\\)
588 hash quality = 100.0%
592 Elt "\\\304\\\200" \[UTF8 "\\\x\{100\}"\] HASH = $ADDR
593 SV = PV\\($ADDR\\) at $ADDR
595 FLAGS = \\(POK,(?:IsCOW,)?pPOK,UTF8\\)
596 PV = $ADDR "\\\310\\\200"\\\0 \[UTF8 "\\\x\{200\}"\]
599 COW_REFCNT = 1 # $] < 5.019007
604 : 'The hash iterator used in dump.c sets the OOK flag'
605 : 'sv_length has been called on the element, and cached the result in MAGIC');
610 do_test('scalar with pos magic',
612 'SV = PVMG\\($ADDR\\) at $ADDR
614 FLAGS = \\($PADMY,SMG,POK,(?:IsCOW,)?pPOK\\)
622 MG_VIRTUAL = &PL_vtbl_mglob
623 MG_TYPE = PERL_MAGIC_regex_global\\(g\\)
624 MG_FLAGS = 0x01 # $] < 5.019003
625 MG_FLAGS = 0x41 # $] >=5.019003
627 BYTES # $] >=5.019003
631 # TAINTEDDIR is not set on: OS2, AMIGAOS, WIN32, MSDOS
632 # environment variables may be invisibly case-forced, hence the (?i:PATH)
633 # C<scalar(@ARGV)> is turned into an IV on VMS hence the (?:IV)?
634 # Perl 5.18 ensures all env vars end up as strings only, hence the (?:,pIOK)?
635 # Perl 5.18 ensures even magic vars have public OK, hence the (?:,POK)?
636 # VMS is setting FAKE and READONLY flags. What VMS uses for storing
637 # ENV hashes is also not always null terminated.
640 # Save and restore PATH, since fresh_perl ends up using that in Windows.
641 my $path = $ENV{PATH};
642 do_test('tainted value in %ENV',
643 $ENV{PATH}=@ARGV, # scalar(@ARGV) is a handy known tainted value
644 'SV = PVMG\\($ADDR\\) at $ADDR
646 FLAGS = \\(GMG,SMG,RMG(?:,POK)?(?:,pIOK)?,pPOK\\)
653 MG_VIRTUAL = &PL_vtbl_envelem
654 MG_TYPE = PERL_MAGIC_envelem\\(e\\)
658 MG_PTR = $ADDR (?:"(?i:PATH)"|=> HEf_SVKEY
659 SV = PV(?:IV)?\\($ADDR\\) at $ADDR
661 FLAGS = \\((?:TEMP,)?POK,(?:FAKE,READONLY,)?pPOK\\)
663 )? PV = $ADDR "(?i:PATH)"(?:\\\0)?
667 MG_VIRTUAL = &PL_vtbl_taint
668 MG_TYPE = PERL_MAGIC_taint\\(t\\)');
672 do_test('blessed reference',
673 bless(\\undef, 'Foobar'),
674 'SV = $RV\\($ADDR\\) at $ADDR
678 SV = PVMG\\($ADDR\\) at $ADDR
680 FLAGS = \\(OBJECT,ROK\\)
684 SV = NULL\\(0x0\\) at $ADDR
686 FLAGS = \\(READONLY\\) # $] < 5.021004
687 FLAGS = \\(READONLY,PROTECT\\) # $] >=5.021004
691 STASH = $ADDR\s+"Foobar"');
697 do_test('constant subroutine',
699 'SV = $RV\\($ADDR\\) at $ADDR
703 SV = PVCV\\($ADDR\\) at $ADDR
705 FLAGS = \\(POK,pPOK,CONST,ISXSUB\\) # $] < 5.015
706 FLAGS = \\(POK,pPOK,CONST,DYNFILE,ISXSUB\\) # $] >= 5.015
710 COMP_STASH = 0x0 # $] < 5.021004
711 COMP_STASH = $ADDR "main" # $] >=5.021004
712 ROOT = 0x0 # $] < 5.009
714 XSUBANY = $ADDR \\(CONST SV\\)
715 SV = PV\\($ADDR\\) at $ADDR
717 FLAGS = \\(.*POK,READONLY,(?:IsCOW,)?pPOK\\) # $] < 5.021004
718 FLAGS = \\(.*POK,(?:IsCOW,)?READONLY,PROTECT,pPOK\\) # $] >=5.021004
719 PV = $ADDR "Perl rules"\\\0
723 GVGV::GV = $ADDR\\t"main" :: "const"
724 FILE = ".*\\b(?i:peek\\.t)"
728 FLAGS = 0x200 # $] < 5.009
729 FLAGS = 0xc00 # $] >= 5.009 && $] < 5.013
730 FLAGS = 0xc # $] >= 5.013 && $] < 5.015
731 FLAGS = 0x100c # $] >= 5.015
734 OUTSIDE = 0x0 \\(null\\)');
736 do_test('isUV should show on PVMG',
737 do { my $v = $1; $v = ~0; $v },
738 'SV = PVMG\\($ADDR\\) at $ADDR
740 FLAGS = \\(IOK,pIOK,IsUV\\)
747 'SV = $RV\\($ADDR\\) at $ADDR
751 SV = PVIO\\($ADDR\\) at $ADDR
756 STASH = $ADDR\s+"IO::File"
767 SUBPROCESS = 0 # $] < 5.009
773 'SV = $RV\\($ADDR\\) at $ADDR
777 SV = PVFM\\($ADDR\\) at $ADDR
779 FLAGS = \\(\\) # $] < 5.015 || !thr
780 FLAGS = \\(DYNFILE\\) # $] >= 5.015 && thr
785 START = $ADDR ===> \\d+
787 XSUB = 0x0 # $] < 5.009
788 XSUBANY = 0 # $] < 5.009
789 GVGV::GV = $ADDR\\t"main" :: "PIE"
790 FILE = ".*\\b(?i:peek\\.t)"(?:
794 FLAGS = 0x0 # $] < 5.015 || !thr
795 FLAGS = 0x1000 # $] >= 5.015 && thr
797 LINES = 0 # $] < 5.017_003
799 PADNAME = $ADDR\\($ADDR\\) PAD = $ADDR\\($ADDR\\)
800 OUTSIDE = $ADDR \\(MAIN\\)');
802 do_test('blessing to a class with embedded NUL characters',
803 (bless {}, "\0::foo::\n::baz::\t::\0"),
804 'SV = $RV\\($ADDR\\) at $ADDR
808 SV = PVHV\\($ADDR\\) at $ADDR
810 FLAGS = \\(OBJECT,SHAREKEYS\\)
813 STASH = $ADDR\\t"\\\\0::foo::\\\\n::baz::\\\\t::\\\\0"
821 : 'The hash iterator used in dump.c sets the OOK flag'
822 : "Something causes the HV's array to become allocated");
824 do_test('ENAME on a stash',
826 'SV = $RV\\($ADDR\\) at $ADDR
830 SV = PVHV\\($ADDR\\) at $ADDR
832 FLAGS = \\(OOK,SHAREKEYS\\)
834 NV = $FLOAT # $] < 5.009
835 AUX_FLAGS = 0 # $] > 5.019008
838 FILL = 0 \(cached = 0\)
844 ENAME = "RWOM" # $] > 5.012
849 do_test('ENAMEs on a stash',
851 'SV = $RV\\($ADDR\\) at $ADDR
855 SV = PVHV\\($ADDR\\) at $ADDR
857 FLAGS = \\(OOK,SHAREKEYS\\)
859 NV = $FLOAT # $] < 5.009
860 AUX_FLAGS = 0 # $] > 5.019008
863 FILL = 0 \(cached = 0\)
869 NAMECOUNT = 2 # $] > 5.012
870 ENAME = "RWOM", "KLANK" # $] > 5.012
875 do_test('ENAMEs on a stash with no NAME',
877 'SV = $RV\\($ADDR\\) at $ADDR
881 SV = PVHV\\($ADDR\\) at $ADDR
883 FLAGS = \\(OOK,SHAREKEYS\\) # $] < 5.017
884 FLAGS = \\(OOK,OVERLOAD,SHAREKEYS\\) # $] >=5.017 && $]<5.021004
885 FLAGS = \\(OOK,SHAREKEYS,OVERLOAD\\) # $] >=5.021004
887 NV = $FLOAT # $] < 5.009
888 AUX_FLAGS = 0 # $] > 5.019008
891 FILL = 0 \(cached = 0\)
896 NAMECOUNT = -3 # $] > 5.012
897 ENAME = "RWOM", "KLANK" # $] > 5.012
900 my %small = ("Perl", "Rules", "Beer", "Foamy");
902 do_test('small hash',
904 'SV = $RV\\($ADDR\\) at $ADDR
908 SV = PVHV\\($ADDR\\) at $ADDR
910 FLAGS = \\(PADMY,SHAREKEYS\\)
912 NV = $FLOAT # $] < 5.009
913 ARRAY = $ADDR \\(0:[67],.*\\)
914 hash quality = [0-9.]+%
918 (?: Elt "(?:Perl|Beer)" HASH = $ADDR
919 SV = PV\\($ADDR\\) at $ADDR
921 FLAGS = \\(POK,(?:IsCOW,)?pPOK\\)
922 PV = $ADDR "(?:Rules|Foamy)"\\\0
930 do_test('small hash after keys',
932 'SV = $RV\\($ADDR\\) at $ADDR
936 SV = PVHV\\($ADDR\\) at $ADDR
938 FLAGS = \\(PADMY,OOK,SHAREKEYS\\)
940 NV = $FLOAT # $] < 5.009
941 AUX_FLAGS = 0 # $] > 5.019008
942 ARRAY = $ADDR \\(0:[67],.*\\)
943 hash quality = [0-9.]+%
945 FILL = [12] \\(cached = 0\\)
950 (?: Elt "(?:Perl|Beer)" HASH = $ADDR
951 SV = PV\\($ADDR\\) at $ADDR
953 FLAGS = \\(POK,(?:IsCOW,)?pPOK\\)
954 PV = $ADDR "(?:Rules|Foamy)"\\\0
962 do_test('small hash after keys and scalar',
964 'SV = $RV\\($ADDR\\) at $ADDR
968 SV = PVHV\\($ADDR\\) at $ADDR
970 FLAGS = \\(PADMY,OOK,SHAREKEYS\\)
972 NV = $FLOAT # $] < 5.009
973 AUX_FLAGS = 0 # $] > 5.019008
974 ARRAY = $ADDR \\(0:[67],.*\\)
975 hash quality = [0-9.]+%
977 FILL = ([12]) \\(cached = \1\\)
982 (?: Elt "(?:Perl|Beer)" HASH = $ADDR
983 SV = PV\\($ADDR\\) at $ADDR
985 FLAGS = \\(POK,(?:IsCOW,)?pPOK\\)
986 PV = $ADDR "(?:Rules|Foamy)"\\\0
992 # This should immediately start with the FILL cached correctly.
993 my %large = (0..1999);
995 do_test('large hash',
997 'SV = $RV\\($ADDR\\) at $ADDR
1001 SV = PVHV\\($ADDR\\) at $ADDR
1003 FLAGS = \\(PADMY,OOK,SHAREKEYS\\)
1005 NV = $FLOAT # $] < 5.009
1006 AUX_FLAGS = 0 # $] > 5.019008
1007 ARRAY = $ADDR \\(0:\d+,.*\\)
1008 hash quality = \d+\\.\d+%
1010 FILL = (\d+) \\(cached = \1\\)
1018 # Dump with arrays, hashes, and operator return values
1020 do_test('Dump @array', '@array', <<'ARRAY', '', '', 1);
1021 SV = PVAV\($ADDR\) at $ADDR
1030 SV = IV\($ADDR\) at $ADDR
1032 FLAGS = \(IOK,pIOK\)
1035 SV = IV\($ADDR\) at $ADDR
1037 FLAGS = \(IOK,pIOK\)
1040 SV = IV\($ADDR\) at $ADDR
1042 FLAGS = \(IOK,pIOK\)
1046 do_test('Dump @array,1', '@array,1', <<'ARRAY', '', '', 1);
1047 SV = PVAV\($ADDR\) at $ADDR
1056 SV = IV\($ADDR\) at $ADDR
1058 FLAGS = \(IOK,pIOK\)
1063 do_test('Dump %hash', '%hash', <<'HASH', '', '', 1);
1064 SV = PVHV\($ADDR\) at $ADDR
1066 FLAGS = \(SHAREKEYS\)
1067 ARRAY = $ADDR \(0:7, 1:1\)
1068 hash quality = 100.0%
1072 Elt "1" HASH = $ADDR
1073 SV = IV\($ADDR\) at $ADDR
1075 FLAGS = \(IOK,pIOK\)
1080 do_test('rvalue substr', 'substr $_, 1, 2', <<'SUBSTR', '', '', 1);
1081 SV = PV\($ADDR\) at $ADDR
1083 FLAGS = \(PADTMP,POK,pPOK\)
1089 # Dump with no arguments
1091 like $@, qr/^Not enough arguments for Devel::Peek::Dump/, 'Dump;';
1093 like $@, qr/^Not enough arguments for Devel::Peek::Dump/, 'Dump()';
1096 skip "Not built with usemymalloc", 2
1097 unless $Config{usemymalloc} eq 'y';
1098 my $x = __PACKAGE__;
1099 ok eval { fill_mstats($x); 1 }, 'fill_mstats on COW scalar'
1102 ok eval { fill_mstats($y); 1 }, 'fill_mstats on undef scalar';
1105 # This is more a test of fbm_compile/pp_study (non) interaction than dumping
1106 # prowess, but short of duplicating all the gubbins of this file, I can't see
1107 # a way to make a better place for it:
1114 unless ($Config{useithreads}) {
1115 # These end up as copies in pads under ithreads, which rather defeats the
1116 # the point of what we're trying to test here.
1118 do_test('regular string constant', perl,
1119 'SV = PV\\($ADDR\\) at $ADDR
1121 FLAGS = \\(PADMY,POK,READONLY,(?:IsCOW,)?pPOK\\)
1122 PV = $ADDR "rules"\\\0
1128 eval 'index "", perl';
1130 # FIXME - really this shouldn't say EVALED. It's a false posistive on
1131 # 0x40000000 being used for several things, not a flag for "I'm in a string
1134 do_test('string constant now an FBM', perl,
1135 'SV = PVMG\\($ADDR\\) at $ADDR
1137 FLAGS = \\(PADMY,SMG,POK,READONLY,(?:IsCOW,)?pPOK,VALID,EVALED\\)
1138 PV = $ADDR "rules"\\\0
1143 MG_VIRTUAL = &PL_vtbl_regexp
1144 MG_TYPE = PERL_MAGIC_bm\\(B\\)
1146 MG_PTR = $ADDR "(?:\\\\\d){256}"
1147 RARE = \d+ # $] < 5.019002
1148 PREVIOUS = 1 # $] < 5.019002
1152 is(study perl, '', "Not allowed to study an FBM");
1154 do_test('string constant still an FBM', perl,
1155 'SV = PVMG\\($ADDR\\) at $ADDR
1157 FLAGS = \\(PADMY,SMG,POK,READONLY,(?:IsCOW,)?pPOK,VALID,EVALED\\)
1158 PV = $ADDR "rules"\\\0
1163 MG_VIRTUAL = &PL_vtbl_regexp
1164 MG_TYPE = PERL_MAGIC_bm\\(B\\)
1166 MG_PTR = $ADDR "(?:\\\\\d){256}"
1167 RARE = \d+ # $] < 5.019002
1168 PREVIOUS = 1 # $] < 5.019002
1172 do_test('regular string constant', beer,
1173 'SV = PV\\($ADDR\\) at $ADDR
1175 FLAGS = \\(PADMY,POK,READONLY,(?:IsCOW,)?pPOK\\)
1176 PV = $ADDR "foamy"\\\0
1182 is(study beer, 1, "Our studies were successful");
1184 do_test('string constant quite unaffected', beer, 'SV = PV\\($ADDR\\) at $ADDR
1186 FLAGS = \\(PADMY,POK,READONLY,(?:IsCOW,)?pPOK\\)
1187 PV = $ADDR "foamy"\\\0
1193 my $want = 'SV = PVMG\\($ADDR\\) at $ADDR
1195 FLAGS = \\(PADMY,SMG,POK,READONLY,(?:IsCOW,)?pPOK,VALID,EVALED\\)
1196 PV = $ADDR "foamy"\\\0
1201 MG_VIRTUAL = &PL_vtbl_regexp
1202 MG_TYPE = PERL_MAGIC_bm\\(B\\)
1204 MG_PTR = $ADDR "(?:\\\\\d){256}"
1205 RARE = \d+ # $] < 5.019002
1206 PREVIOUS = \d+ # $] < 5.019002
1210 is (eval 'index "not too foamy", beer', 8, 'correct index');
1212 do_test('string constant now FBMed', beer, $want);
1216 is(study $pie, 1, "Our studies were successful");
1218 do_test('string constant still FBMed', beer, $want);
1220 do_test('second string also unaffected', $pie, 'SV = PV\\($ADDR\\) at $ADDR
1222 FLAGS = \\(PADMY,POK,(?:IsCOW,)?pPOK\\)
1223 PV = $ADDR "good"\\\0
1230 # (One block of study tests removed when study was made a no-op.)
1233 open(OUT,">peek$$") or die "Failed to open peek $$: $!";
1234 open(STDERR, ">&OUT") or die "Can't dup OUT: $!";
1236 open(STDERR, ">&SAVERR") or die "Can't restore STDERR: $!";
1237 pass "no crash with DeadCode";
1240 # note the conditionals on ENGINE and INTFLAGS were introduced in 5.19.9
1241 do_test('UTF-8 in a regular expression',
1243 'SV = IV\($ADDR\) at $ADDR
1247 SV = REGEXP\($ADDR\) at $ADDR
1249 FLAGS = \(OBJECT,FAKE,UTF8\)
1250 PV = $ADDR "\(\?\^u:\\\\\\\\x\{100\}\)" \[UTF8 "\(\?\^u:\\\\\\\\x\{100\}\)"\]
1252 STASH = $ADDR "Regexp"
1253 COMPFLAGS = 0x0 \(\)
1254 EXTFLAGS = 0x680040 \(CHECK_ALL,USE_INTUIT_NOML,USE_INTUIT_ML\)
1255 (?: ENGINE = $ADDR \(STANDARD\)
1256 )? INTFLAGS = 0x0(?: \(\))?
1269 )? MOTHER_RE = $ADDR'
1270 . ($] < 5.019003 ? '' : '
1271 SV = REGEXP\($ADDR\) at $ADDR
1274 PV = $ADDR "\(\?\^u:\\\\\\\\x\{100\}\)" \[UTF8 "\(\?\^u:\\\\\\\\x\{100\}\)"\]
1276 COMPFLAGS = 0x0 \(\)
1277 EXTFLAGS = 0x680040 \(CHECK_ALL,USE_INTUIT_NOML,USE_INTUIT_ML\)
1278 (?: ENGINE = $ADDR \(STANDARD\)
1279 )? INTFLAGS = 0x0(?: \(\))?
1298 SAVED_COPY = 0x0)?') . '
1307 { # perl #117793: Extend SvREFCNT* to work on any perl variable type
1309 my $base_count = Devel::Peek::SvREFCNT(%hash);
1311 is(Devel::Peek::SvREFCNT(%hash), $base_count + 1, "SvREFCNT on non-scalar");
1312 ok(!eval { &Devel::Peek::SvREFCNT(1) }, "requires prototype");
1319 open(OUT,">peek$$") or die $!;
1320 open(STDERR, ">&OUT") or die "Can't dup OUT: $!";
1322 open(STDERR, ">&SAVERR") or die "Can't restore STDERR: $!";
1324 open(IN, "peek$$") or die $!;
1325 my $dump = do { local $/; <IN> };
1327 1 while unlink "peek$$";
1334 eval "sub $x {}; 1" or die $@;
1339 _dump(_get_coderef("\x{df}::\xdf")),
1340 qr/GVGV::GV = 0x[[:xdigit:]]+\s+\Q"\xdf" :: "\xdf"/,
1341 "GVGV's are correctly escaped for latin1 :: latin1",
1345 _dump(_get_coderef("\x{30cd}::\x{30cd}")),
1346 qr/GVGV::GV = 0x[[:xdigit:]]+\s+\Q"\x{30cd}" :: "\x{30cd}"/,
1347 "GVGV's are correctly escaped for UTF8 :: UTF8",
1351 _dump(_get_coderef("\x{df}::\x{30cd}")),
1352 qr/GVGV::GV = 0x[[:xdigit:]]+\s+\Q"\xdf" :: "\x{30cd}"/,
1353 "GVGV's are correctly escaped for latin1 :: UTF8",
1357 _dump(_get_coderef("\x{30cd}::\x{df}")),
1358 qr/GVGV::GV = 0x[[:xdigit:]]+\s+\Q"\x{30cd}" :: "\xdf"/,
1359 "GVGV's are correctly escaped for UTF8 :: latin1",
1363 _dump(_get_coderef("\x{30cb}::\x{df}::\x{30cd}")),
1364 qr/GVGV::GV = 0x[[:xdigit:]]+\s+\Q"\x{30cb}::\x{df}" :: "\x{30cd}"/,
1365 "GVGV's are correctly escaped for UTF8 :: latin 1 :: UTF8",
1368 my $dump = _dump(*{"\x{30cb}::\x{df}::\x{30dc}"});
1372 qr/NAME = \Q"\x{30dc}"/,
1373 "NAME is correctly escaped for UTF8 globs",
1378 qr/GvSTASH = 0x[[:xdigit:]]+\s+\Q"\x{30cb}::\x{df}"/,
1379 "GvSTASH is correctly escaped for UTF8 globs"
1384 qr/EGV = 0x[[:xdigit:]]+\s+\Q"\x{30dc}"/,
1385 "EGV is correctly escaped for UTF8 globs"
1388 $dump = _dump(*{"\x{df}::\x{30cc}"});
1392 qr/NAME = \Q"\x{30cc}"/,
1393 "NAME is correctly escaped for UTF8 globs with latin1 stashes",
1398 qr/GvSTASH = 0x[[:xdigit:]]+\s+\Q"\xdf"/,
1399 "GvSTASH is correctly escaped for UTF8 globs with latin1 stashes"
1404 qr/EGV = 0x[[:xdigit:]]+\s+\Q"\x{30cc}"/,
1405 "EGV is correctly escaped for UTF8 globs with latin1 stashes"
1409 _dump(bless {}, "\0::\1::\x{30cd}"),
1410 qr/STASH = 0x[[:xdigit:]]+\s+\Q"\0::\x{01}::\x{30cd}"/,
1411 "STASH for blessed hashrefs is correct"
1414 BEGIN { $::{doof} = "\0\1\x{30cd}" }
1417 qr/PROTOTYPE = \Q"\0\x{01}\x{30cd}"/,
1418 "PROTOTYPE is escaped correctly"
1422 my $coderef = eval <<"EOP";
1423 use feature 'lexical_subs';
1424 no warnings 'experimental::lexical_subs';
1425 my sub bar (\$\x{30cd}) {1}; \\&bar
1429 qr/PROTOTYPE = "\$\Q\x{30cd}"/,
1430 "PROTOTYPE works on lexical subs"
1435 eval "sub $_[0] { my \$x; \$x++; return sub { eval q{\$x} } } $_[0]()";
1437 sub basic { my $x; return eval q{sub { eval q{$x} }} }
1440 qr/OUTSIDE = 0x[[:xdigit:]]+\s+\Q(basic)/,
1445 _dump(get_outside("\x{30ce}")),
1446 qr/OUTSIDE = 0x[[:xdigit:]]+\s+\Q(\x{30ce})/,
1447 'OUTSIDE + UTF8 works'
1450 # TODO AUTOLOAD = stashname, which requires using a XS autoload
1451 # and calling Dump() on the cv
1455 sub test_utf8_stashes {
1456 my ($stash_name, $test) = @_;
1458 $dump = _dump(\%{"${stash_name}::"});
1460 my $format = utf8::is_utf8($stash_name) ? '\x{%2x}' : '\x%2x';
1461 $escaped_stash_name = join "", map {
1462 $_ eq ':' ? $_ : sprintf $format, ord $_
1463 } split //, $stash_name;
1467 qr/\QNAME = "$escaped_stash_name"/,
1468 "NAME is correct escaped for $test"
1473 qr/\QENAME = "$escaped_stash_name"/,
1474 "ENAME is correct escaped for $test"
1479 [ "\x{30cd}", "UTF8 stashes" ],
1480 [ "\x{df}", "latin 1 stashes" ],
1481 [ "\x{df}::\x{30cd}", "latin1 + UTF8 stashes" ],
1482 [ "\x{30cd}::\x{df}", "UTF8 + latin1 stashes" ],
1484 test_utf8_stashes(@$test);
1489 my $runperl_args = { switches => ['-Ilib'] };
1491 my ($prog, $expected, $name, $test) = @_;
1494 my $u = 'use Devel::Peek "DumpProg"; DumpProg();';
1496 # Interface between Test::Builder & test.pl
1497 my $builder = Test::More->builder();
1498 t::curr_test($builder->current_test() + 1);
1500 utf8::encode($prog);
1502 if ( $test eq 'is' ) {
1503 t::fresh_perl_is($prog . $u, $expected, $runperl_args, $name)
1506 t::fresh_perl_like($prog . $u, $expected, $runperl_args, $name)
1509 $builder->current_test(t::curr_test() - 1);
1512 my $threads = $Config{'useithreads'};
1517 qr/PACKAGE = "test"/,
1518 "DumpProg() + package declaration"
1521 "use utf8; package \x{30cd};",
1522 qr/PACKAGE = "\\x\Q{30cd}"/,
1523 "DumpProg() + UTF8 package declaration"
1526 "use utf8; sub \x{30cc}::\x{30cd} {1}; \x{30cc}::\x{30cd};",
1527 ($threads ? qr/PADIX = \d+/ : qr/GV = \Q\x{30cc}::\x{30cd}\E/)
1530 "use utf8; \x{30cc}: { last \x{30cc} }",
1531 qr/LABEL = \Q"\x{30cc}"/
1535 test_DumpProg(@$test);
1539 dumpindent is 4 at - line 1.
1541 1 TYPE = leave ===> NULL
1543 FLAGS = (VOID,KIDS,PARENS,SLABBED,LASTSIB)
1547 2 TYPE = enter ===> 3
1548 FLAGS = (UNKNOWN,SLABBED)
1551 3 TYPE = nextstate ===> 4
1552 FLAGS = (VOID,SLABBED)
1557 5 TYPE = entersub ===> 1
1559 FLAGS = (VOID,KIDS,STACKED,SLABBED,LASTSIB)
1562 6 TYPE = null ===> (5)
1564 FLAGS = (UNKNOWN,KIDS,SLABBED,LASTSIB)
1566 4 TYPE = pushmark ===> 7
1567 FLAGS = (SCALAR,SLABBED)
1570 8 TYPE = null ===> (6)
1572 FLAGS = (SCALAR,KIDS,SLABBED,LASTSIB)
1576 FLAGS = (SCALAR,SLABBED,LASTSIB)
1585 $e =~ s/GV_OR_PADIX/$threads ? "PADIX = 2" : "GV = t::DumpProg"/e;
1586 $e =~ s/.*PRIVATE = \(0x1\).*\n// if $] < 5.021004;
1588 test_DumpProg("package t;", $e, "DumpProg() has no 'Attempt to free X prematurely' warning", "is" );