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