1#!perl 2 3BEGIN { 4 if ($ENV{PERL_CORE}){ 5 chdir('t') if -d 't'; 6 @INC = ('.', '../lib', '../ext/B/t'); 7 } else { 8 unshift @INC, 't'; 9 push @INC, "../../t"; 10 } 11 require Config; 12 if (($Config::Config{'extensions'} !~ /\bB\b/) ){ 13 print "1..0 # Skip -- Perl configured without B module\n"; 14 exit 0; 15 } 16 if (!$Config::Config{useperlio}) { 17 print "1..0 # Skip -- need perlio to walk the optree\n"; 18 exit 0; 19 } 20 # require q(test.pl); # now done by OptreeCheck 21} 22use OptreeCheck; 23plan tests => 9; 24 25 26=head1 f_map.t 27 28Code test snippets here are adapted from `perldoc -f map` 29 30Due to a bleadperl optimization (Dave Mitchell, circa may 04), the 31(map|grep)(start|while) opcodes have different flags in 5.9, their 32private flags /1, /2 are gone in blead (for the cases covered) 33 34When the optree stuff was integrated into 5.8.6, these tests failed, 35and were todo'd. Theyre now done, by version-specific tweaking in 36mkCheckRex(), therefore the skip is removed too. 37 38=for gentest 39 40# chunk: #!perl 41# examples shamelessly snatched from perldoc -f map 42 43=cut 44 45=for gentest 46 47# chunk: # translates a list of numbers to the corresponding characters. 48@chars = map(chr, @nums); 49 50=cut 51 52checkOptree(note => q{}, 53 bcopts => q{-exec}, 54 code => q{@chars = map(chr, @nums); }, 55 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); 56# 1 <;> nextstate(main 475 (eval 10):1) v 57# 2 <0> pushmark s 58# 3 <0> pushmark s 59# 4 <#> gv[*nums] s 60# 5 <1> rv2av[t7] lKM/1 61# 6 <@> mapstart lK 62# 7 <|> mapwhile(other->8)[t8] lK 63# 8 <#> gvsv[*_] s 64# 9 <1> chr[t5] sK/1 65# goto 7 66# a <0> pushmark s 67# b <#> gv[*chars] s 68# c <1> rv2av[t2] lKRM*/1 69# d <2> aassign[t9] KS/COMMON 70# e <1> leavesub[1 ref] K/REFC,1 71EOT_EOT 72# 1 <;> nextstate(main 559 (eval 15):1) v 73# 2 <0> pushmark s 74# 3 <0> pushmark s 75# 4 <$> gv(*nums) s 76# 5 <1> rv2av[t4] lKM/1 77# 6 <@> mapstart lK 78# 7 <|> mapwhile(other->8)[t5] lK 79# 8 <$> gvsv(*_) s 80# 9 <1> chr[t3] sK/1 81# goto 7 82# a <0> pushmark s 83# b <$> gv(*chars) s 84# c <1> rv2av[t1] lKRM*/1 85# d <2> aassign[t6] KS/COMMON 86# e <1> leavesub[1 ref] K/REFC,1 87EONT_EONT 88 89 90=for gentest 91 92# chunk: %hash = map { getkey($_) => $_ } @array; 93 94=cut 95 96checkOptree(note => q{}, 97 bcopts => q{-exec}, 98 code => q{%hash = map { getkey($_) => $_ } @array; }, 99 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); 100# 1 <;> nextstate(main 476 (eval 10):1) v:{ 101# 2 <0> pushmark s 102# 3 <0> pushmark s 103# 4 <#> gv[*array] s 104# 5 <1> rv2av[t8] lKM/1 105# 6 <@> mapstart lK* 106# 7 <|> mapwhile(other->8)[t9] lK 107# 8 <0> enter l 108# 9 <;> nextstate(main 475 (eval 10):1) v:{ 109# a <0> pushmark s 110# b <0> pushmark s 111# c <#> gvsv[*_] s 112# d <#> gv[*getkey] s/EARLYCV 113# e <1> entersub[t5] lKS/TARG,1 114# f <#> gvsv[*_] s 115# g <@> list lK 116# h <@> leave lKP 117# goto 7 118# i <0> pushmark s 119# j <#> gv[*hash] s 120# k <1> rv2hv[t2] lKRM*/1 121# l <2> aassign[t10] KS/COMMON 122# m <1> leavesub[1 ref] K/REFC,1 123EOT_EOT 124# 1 <;> nextstate(main 560 (eval 15):1) v:{ 125# 2 <0> pushmark s 126# 3 <0> pushmark s 127# 4 <$> gv(*array) s 128# 5 <1> rv2av[t3] lKM/1 129# 6 <@> mapstart lK* 130# 7 <|> mapwhile(other->8)[t4] lK 131# 8 <0> enter l 132# 9 <;> nextstate(main 559 (eval 15):1) v:{ 133# a <0> pushmark s 134# b <0> pushmark s 135# c <$> gvsv(*_) s 136# d <$> gv(*getkey) s/EARLYCV 137# e <1> entersub[t2] lKS/TARG,1 138# f <$> gvsv(*_) s 139# g <@> list lK 140# h <@> leave lKP 141# goto 7 142# i <0> pushmark s 143# j <$> gv(*hash) s 144# k <1> rv2hv[t1] lKRM*/1 145# l <2> aassign[t5] KS/COMMON 146# m <1> leavesub[1 ref] K/REFC,1 147EONT_EONT 148 149 150=for gentest 151 152# chunk: { 153 %hash = (); 154 foreach $_ (@array) { 155 $hash{getkey($_)} = $_; 156 } 157} 158 159=cut 160 161checkOptree(note => q{}, 162 bcopts => q{-exec}, 163 code => q{{ %hash = (); foreach $_ (@array) { $hash{getkey($_)} = $_; } } }, 164 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); 165# 1 <;> nextstate(main 478 (eval 10):1) v:{ 166# 2 <{> enterloop(next->u last->u redo->3) 167# 3 <;> nextstate(main 475 (eval 10):1) v 168# 4 <0> pushmark s 169# 5 <0> pushmark s 170# 6 <#> gv[*hash] s 171# 7 <1> rv2hv[t2] lKRM*/1 172# 8 <2> aassign[t3] vKS 173# 9 <;> nextstate(main 476 (eval 10):1) v:{ 174# a <0> pushmark sM 175# b <#> gv[*array] s 176# c <1> rv2av[t6] sKRM/1 177# d <#> gv[*_] s 178# e <1> rv2gv sKRM/1 179# f <{> enteriter(next->q last->t redo->g) lKS/8 180# r <0> iter s 181# s <|> and(other->g) K/1 182# g <;> nextstate(main 475 (eval 10):1) v:{ 183# h <#> gvsv[*_] s 184# i <#> gv[*hash] s 185# j <1> rv2hv sKR/1 186# k <0> pushmark s 187# l <#> gvsv[*_] s 188# m <#> gv[*getkey] s/EARLYCV 189# n <1> entersub[t10] sKS/TARG,1 190# o <2> helem sKRM*/2 191# p <2> sassign vKS/2 192# q <0> unstack s 193# goto r 194# t <2> leaveloop K/2 195# u <2> leaveloop K/2 196# v <1> leavesub[1 ref] K/REFC,1 197EOT_EOT 198# 1 <;> nextstate(main 562 (eval 15):1) v:{ 199# 2 <{> enterloop(next->u last->u redo->3) 200# 3 <;> nextstate(main 559 (eval 15):1) v 201# 4 <0> pushmark s 202# 5 <0> pushmark s 203# 6 <$> gv(*hash) s 204# 7 <1> rv2hv[t1] lKRM*/1 205# 8 <2> aassign[t2] vKS 206# 9 <;> nextstate(main 560 (eval 15):1) v:{ 207# a <0> pushmark sM 208# b <$> gv(*array) s 209# c <1> rv2av[t3] sKRM/1 210# d <$> gv(*_) s 211# e <1> rv2gv sKRM/1 212# f <{> enteriter(next->q last->t redo->g) lKS/8 213# r <0> iter s 214# s <|> and(other->g) K/1 215# g <;> nextstate(main 559 (eval 15):1) v:{ 216# h <$> gvsv(*_) s 217# i <$> gv(*hash) s 218# j <1> rv2hv sKR/1 219# k <0> pushmark s 220# l <$> gvsv(*_) s 221# m <$> gv(*getkey) s/EARLYCV 222# n <1> entersub[t4] sKS/TARG,1 223# o <2> helem sKRM*/2 224# p <2> sassign vKS/2 225# q <0> unstack s 226# goto r 227# t <2> leaveloop K/2 228# u <2> leaveloop K/2 229# v <1> leavesub[1 ref] K/REFC,1 230EONT_EONT 231 232 233=for gentest 234 235# chunk: #%hash = map { "\L$_", 1 } @array; # perl guesses EXPR. wrong 236%hash = map { +"\L$_", 1 } @array; # perl guesses BLOCK. right 237 238=cut 239 240checkOptree(note => q{}, 241 bcopts => q{-exec}, 242 code => q{%hash = map { +"\L$_", 1 } @array; }, 243 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); 244# 1 <;> nextstate(main 476 (eval 10):1) v 245# 2 <0> pushmark s 246# 3 <0> pushmark s 247# 4 <#> gv[*array] s 248# 5 <1> rv2av[t7] lKM/1 249# 6 <@> mapstart lK* 250# 7 <|> mapwhile(other->8)[t9] lK 251# 8 <0> pushmark s 252# 9 <#> gvsv[*_] s 253# a <1> lc[t4] sK/1 254# b <@> stringify[t5] sK/1 255# c <$> const[IV 1] s 256# d <@> list lK 257# - <@> scope lK 258# goto 7 259# e <0> pushmark s 260# f <#> gv[*hash] s 261# g <1> rv2hv[t2] lKRM*/1 262# h <2> aassign[t10] KS/COMMON 263# i <1> leavesub[1 ref] K/REFC,1 264EOT_EOT 265# 1 <;> nextstate(main 560 (eval 15):1) v 266# 2 <0> pushmark s 267# 3 <0> pushmark s 268# 4 <$> gv(*array) s 269# 5 <1> rv2av[t4] lKM/1 270# 6 <@> mapstart lK* 271# 7 <|> mapwhile(other->8)[t5] lK 272# 8 <0> pushmark s 273# 9 <$> gvsv(*_) s 274# a <1> lc[t2] sK/1 275# b <@> stringify[t3] sK/1 276# c <$> const(IV 1) s 277# d <@> list lK 278# - <@> scope lK 279# goto 7 280# e <0> pushmark s 281# f <$> gv(*hash) s 282# g <1> rv2hv[t1] lKRM*/1 283# h <2> aassign[t6] KS/COMMON 284# i <1> leavesub[1 ref] K/REFC,1 285EONT_EONT 286 287 288=for gentest 289 290# chunk: %hash = map { ("\L$_", 1) } @array; # this also works 291 292=cut 293 294checkOptree(note => q{}, 295 bcopts => q{-exec}, 296 code => q{%hash = map { ("\L$_", 1) } @array; }, 297 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); 298# 1 <;> nextstate(main 476 (eval 10):1) v 299# 2 <0> pushmark s 300# 3 <0> pushmark s 301# 4 <#> gv[*array] s 302# 5 <1> rv2av[t7] lKM/1 303# 6 <@> mapstart lK* 304# 7 <|> mapwhile(other->8)[t9] lK 305# 8 <0> pushmark s 306# 9 <#> gvsv[*_] s 307# a <1> lc[t4] sK/1 308# b <@> stringify[t5] sK/1 309# c <$> const[IV 1] s 310# d <@> list lKP 311# - <@> scope lK 312# goto 7 313# e <0> pushmark s 314# f <#> gv[*hash] s 315# g <1> rv2hv[t2] lKRM*/1 316# h <2> aassign[t10] KS/COMMON 317# i <1> leavesub[1 ref] K/REFC,1 318EOT_EOT 319# 1 <;> nextstate(main 560 (eval 15):1) v 320# 2 <0> pushmark s 321# 3 <0> pushmark s 322# 4 <$> gv(*array) s 323# 5 <1> rv2av[t4] lKM/1 324# 6 <@> mapstart lK* 325# 7 <|> mapwhile(other->8)[t5] lK 326# 8 <0> pushmark s 327# 9 <$> gvsv(*_) s 328# a <1> lc[t2] sK/1 329# b <@> stringify[t3] sK/1 330# c <$> const(IV 1) s 331# d <@> list lKP 332# - <@> scope lK 333# goto 7 334# e <0> pushmark s 335# f <$> gv(*hash) s 336# g <1> rv2hv[t1] lKRM*/1 337# h <2> aassign[t6] KS/COMMON 338# i <1> leavesub[1 ref] K/REFC,1 339EONT_EONT 340 341 342=for gentest 343 344# chunk: %hash = map { lc($_), 1 } @array; # as does this. 345 346=cut 347 348checkOptree(note => q{}, 349 bcopts => q{-exec}, 350 code => q{%hash = map { lc($_), 1 } @array; }, 351 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); 352# 1 <;> nextstate(main 476 (eval 10):1) v 353# 2 <0> pushmark s 354# 3 <0> pushmark s 355# 4 <#> gv[*array] s 356# 5 <1> rv2av[t6] lKM/1 357# 6 <@> mapstart lK* 358# 7 <|> mapwhile(other->8)[t8] lK 359# 8 <0> pushmark s 360# 9 <#> gvsv[*_] s 361# a <1> lc[t4] sK/1 362# b <$> const[IV 1] s 363# c <@> list lK 364# - <@> scope lK 365# goto 7 366# d <0> pushmark s 367# e <#> gv[*hash] s 368# f <1> rv2hv[t2] lKRM*/1 369# g <2> aassign[t9] KS/COMMON 370# h <1> leavesub[1 ref] K/REFC,1 371EOT_EOT 372# 1 <;> nextstate(main 589 (eval 26):1) v 373# 2 <0> pushmark s 374# 3 <0> pushmark s 375# 4 <$> gv(*array) s 376# 5 <1> rv2av[t3] lKM/1 377# 6 <@> mapstart lK* 378# 7 <|> mapwhile(other->8)[t4] lK 379# 8 <0> pushmark s 380# 9 <$> gvsv(*_) s 381# a <1> lc[t2] sK/1 382# b <$> const(IV 1) s 383# c <@> list lK 384# - <@> scope lK 385# goto 7 386# d <0> pushmark s 387# e <$> gv(*hash) s 388# f <1> rv2hv[t1] lKRM*/1 389# g <2> aassign[t5] KS/COMMON 390# h <1> leavesub[1 ref] K/REFC,1 391EONT_EONT 392 393 394=for gentest 395 396# chunk: %hash = map +( lc($_), 1 ), @array; # this is EXPR and works! 397 398=cut 399 400checkOptree(note => q{}, 401 bcopts => q{-exec}, 402 code => q{%hash = map +( lc($_), 1 ), @array; }, 403 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); 404# 1 <;> nextstate(main 475 (eval 10):1) v 405# 2 <0> pushmark s 406# 3 <0> pushmark s 407# 4 <#> gv[*array] s 408# 5 <1> rv2av[t6] lKM/1 409# 6 <@> mapstart lK 410# 7 <|> mapwhile(other->8)[t7] lK 411# 8 <0> pushmark s 412# 9 <#> gvsv[*_] s 413# a <1> lc[t4] sK/1 414# b <$> const[IV 1] s 415# c <@> list lKP 416# goto 7 417# d <0> pushmark s 418# e <#> gv[*hash] s 419# f <1> rv2hv[t2] lKRM*/1 420# g <2> aassign[t8] KS/COMMON 421# h <1> leavesub[1 ref] K/REFC,1 422EOT_EOT 423# 1 <;> nextstate(main 593 (eval 28):1) v 424# 2 <0> pushmark s 425# 3 <0> pushmark s 426# 4 <$> gv(*array) s 427# 5 <1> rv2av[t3] lKM/1 428# 6 <@> mapstart lK 429# 7 <|> mapwhile(other->8)[t4] lK 430# 8 <0> pushmark s 431# 9 <$> gvsv(*_) s 432# a <1> lc[t2] sK/1 433# b <$> const(IV 1) s 434# c <@> list lKP 435# goto 7 436# d <0> pushmark s 437# e <$> gv(*hash) s 438# f <1> rv2hv[t1] lKRM*/1 439# g <2> aassign[t5] KS/COMMON 440# h <1> leavesub[1 ref] K/REFC,1 441EONT_EONT 442 443 444=for gentest 445 446# chunk: %hash = map ( lc($_), 1 ), @array; # evaluates to (1, @array) 447 448=cut 449 450checkOptree(note => q{}, 451 bcopts => q{-exec}, 452 code => q{%hash = map ( lc($_), 1 ), @array; }, 453 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); 454# 1 <;> nextstate(main 475 (eval 10):1) v 455# 2 <0> pushmark s 456# 3 <0> pushmark s 457# 4 <0> pushmark s 458# 5 <$> const[IV 1] sM 459# 6 <@> mapstart lK 460# 7 <|> mapwhile(other->8)[t5] lK 461# 8 <#> gvsv[*_] s 462# 9 <1> lc[t4] sK/1 463# goto 7 464# a <0> pushmark s 465# b <#> gv[*hash] s 466# c <1> rv2hv[t2] lKRM*/1 467# d <2> aassign[t6] KS/COMMON 468# e <#> gv[*array] s 469# f <1> rv2av[t8] K/1 470# g <@> list K 471# h <1> leavesub[1 ref] K/REFC,1 472EOT_EOT 473# 1 <;> nextstate(main 597 (eval 30):1) v 474# 2 <0> pushmark s 475# 3 <0> pushmark s 476# 4 <0> pushmark s 477# 5 <$> const(IV 1) sM 478# 6 <@> mapstart lK 479# 7 <|> mapwhile(other->8)[t3] lK 480# 8 <$> gvsv(*_) s 481# 9 <1> lc[t2] sK/1 482# goto 7 483# a <0> pushmark s 484# b <$> gv(*hash) s 485# c <1> rv2hv[t1] lKRM*/1 486# d <2> aassign[t4] KS/COMMON 487# e <$> gv(*array) s 488# f <1> rv2av[t5] K/1 489# g <@> list K 490# h <1> leavesub[1 ref] K/REFC,1 491EONT_EONT 492 493 494=for gentest 495 496# chunk: @hashes = map +{ lc($_), 1 }, @array # EXPR, so needs , at end 497 498=cut 499 500checkOptree(note => q{}, 501 bcopts => q{-exec}, 502 code => q{@hashes = map +{ lc($_), 1 }, @array }, 503 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); 504# 1 <;> nextstate(main 475 (eval 10):1) v 505# 2 <0> pushmark s 506# 3 <0> pushmark s 507# 4 <#> gv[*array] s 508# 5 <1> rv2av[t6] lKM/1 509# 6 <@> mapstart lK 510# 7 <|> mapwhile(other->8)[t7] lK 511# 8 <0> pushmark s 512# 9 <#> gvsv[*_] s 513# a <1> lc[t4] sK/1 514# b <$> const[IV 1] s 515# c <@> anonhash sK*/1 516# goto 7 517# d <0> pushmark s 518# e <#> gv[*hashes] s 519# f <1> rv2av[t2] lKRM*/1 520# g <2> aassign[t8] KS/COMMON 521# h <1> leavesub[1 ref] K/REFC,1 522EOT_EOT 523# 1 <;> nextstate(main 601 (eval 32):1) v 524# 2 <0> pushmark s 525# 3 <0> pushmark s 526# 4 <$> gv(*array) s 527# 5 <1> rv2av[t3] lKM/1 528# 6 <@> mapstart lK 529# 7 <|> mapwhile(other->8)[t4] lK 530# 8 <0> pushmark s 531# 9 <$> gvsv(*_) s 532# a <1> lc[t2] sK/1 533# b <$> const(IV 1) s 534# c <@> anonhash sK*/1 535# goto 7 536# d <0> pushmark s 537# e <$> gv(*hashes) s 538# f <1> rv2av[t1] lKRM*/1 539# g <2> aassign[t5] KS/COMMON 540# h <1> leavesub[1 ref] K/REFC,1 541EONT_EONT 542