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 <#> gvsv[*_] s 105# c <#> gv[*getkey] s/EARLYCV 106# d <1> entersub[t5] lKS/TARG 107# e <#> gvsv[*_] s 108# f <@> leave lKP 109# goto 7 110# g <0> pushmark s 111# h <#> gv[*hash] s 112# i <1> rv2hv[t2] lKRM*/1 < 5.019006 113# i <1> rv2hv lKRM*/1 >=5.019006 114# j <2> aassign[t10] KS/COMMON 115# k <1> leavesub[1 ref] K/REFC,1 116EOT_EOT 117# 1 <;> nextstate(main 560 (eval 15):1) v:{ 118# 2 <0> pushmark s 119# 3 <0> pushmark s 120# 4 <$> gv(*array) s 121# 5 <1> rv2av[t3] lKM/1 122# 6 <@> mapstart lK* < 5.017002 123# 6 <@> mapstart lK >=5.017002 124# 7 <|> mapwhile(other->8)[t4] lK 125# 8 <0> enter l 126# 9 <;> nextstate(main 559 (eval 15):1) v:{ 127# a <0> pushmark s 128# b <$> gvsv(*_) s 129# c <$> gv(*getkey) s/EARLYCV 130# d <1> entersub[t2] lKS/TARG 131# e <$> gvsv(*_) s 132# f <@> leave lKP 133# goto 7 134# g <0> pushmark s 135# h <$> gv(*hash) s 136# i <1> rv2hv[t1] lKRM*/1 < 5.019006 137# i <1> rv2hv lKRM*/1 >=5.019006 138# j <2> aassign[t5] KS/COMMON 139# k <1> leavesub[1 ref] K/REFC,1 140EONT_EONT 141 142 143=for gentest 144 145# chunk: { 146 %hash = (); 147 foreach $_ (@array) { 148 $hash{getkey($_)} = $_; 149 } 150} 151 152=cut 153 154checkOptree(note => q{}, 155 bcopts => q{-exec}, 156 code => q{{ %hash = (); foreach $_ (@array) { $hash{getkey($_)} = $_; } } }, 157 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); 158# 1 <;> nextstate(main 478 (eval 10):1) v:{ 159# 2 <{> enterloop(next->u last->u redo->3) 160# 3 <;> nextstate(main 475 (eval 10):1) v 161# 4 <0> pushmark s 162# 5 <0> pushmark s 163# 6 <#> gv[*hash] s 164# 7 <1> rv2hv[t2] lKRM*/1 < 5.019006 165# 7 <1> rv2hv lKRM*/1 >=5.019006 166# 8 <2> aassign[t3] vKS 167# 9 <;> nextstate(main 476 (eval 10):1) v:{ 168# a <0> pushmark sM 169# b <#> gv[*array] s 170# c <1> rv2av[t6] sKRM/1 171# d <#> gv[*_] s 172# e <1> rv2gv sKRM/1 173# f <{> enteriter(next->q last->t redo->g) lKS/8 174# r <0> iter s 175# s <|> and(other->g) K/1 176# g <;> nextstate(main 475 (eval 10):1) v:{ 177# h <#> gvsv[*_] s 178# i <#> gv[*hash] s 179# j <1> rv2hv sKR/1 180# k <0> pushmark s 181# l <#> gvsv[*_] s 182# m <#> gv[*getkey] s/EARLYCV 183# n <1> entersub[t10] sKS/TARG 184# o <2> helem sKRM*/2 185# p <2> sassign vKS/2 186# q <0> unstack s 187# goto r 188# t <2> leaveloop KP/2 189# u <2> leaveloop K/2 190# v <1> leavesub[1 ref] K/REFC,1 191EOT_EOT 192# 1 <;> nextstate(main 562 (eval 15):1) v:{ 193# 2 <{> enterloop(next->u last->u redo->3) 194# 3 <;> nextstate(main 559 (eval 15):1) v 195# 4 <0> pushmark s 196# 5 <0> pushmark s 197# 6 <$> gv(*hash) s 198# 7 <1> rv2hv[t1] lKRM*/1 < 5.019006 199# 7 <1> rv2hv lKRM*/1 >=5.019006 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 < 5.019006 258# g <1> rv2hv lKRM*/1 >=5.019006 259# h <2> aassign[t10] KS/COMMON 260# i <1> leavesub[1 ref] K/REFC,1 261EOT_EOT 262# 1 <;> nextstate(main 560 (eval 15):1) v 263# 2 <0> pushmark s 264# 3 <0> pushmark s 265# 4 <$> gv(*array) s 266# 5 <1> rv2av[t4] lKM/1 267# 6 <@> mapstart lK* < 5.017002 268# 6 <@> mapstart lK >=5.017002 269# 7 <|> mapwhile(other->8)[t5] lK 270# 8 <0> pushmark s 271# 9 <$> gvsv(*_) s 272# a <1> lc[t2] sK/1 273# b <@> stringify[t3] sK/1 274# c <$> const(IV 1) s 275# d <@> list lK 276# - <@> scope lK < 5.017002 277# goto 7 278# e <0> pushmark s 279# f <$> gv(*hash) s 280# g <1> rv2hv[t1] lKRM*/1 < 5.019006 281# g <1> rv2hv lKRM*/1 >=5.019006 282# h <2> aassign[t6] KS/COMMON 283# i <1> leavesub[1 ref] K/REFC,1 284EONT_EONT 285 286 287=for gentest 288 289# chunk: %hash = map { ("\L$_", 1) } @array; # this also works 290 291=cut 292 293checkOptree(note => q{}, 294 bcopts => q{-exec}, 295 code => q{%hash = map { ("\L$_", 1) } @array; }, 296 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); 297# 1 <;> nextstate(main 476 (eval 10):1) v 298# 2 <0> pushmark s 299# 3 <0> pushmark s 300# 4 <#> gv[*array] s 301# 5 <1> rv2av[t7] lKM/1 302# 6 <@> mapstart lK* < 5.017002 303# 6 <@> mapstart lK >=5.017002 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 < 5.017002 312# goto 7 313# e <0> pushmark s 314# f <#> gv[*hash] s 315# g <1> rv2hv[t2] lKRM*/1 < 5.019006 316# g <1> rv2hv lKRM*/1 >=5.019006 317# h <2> aassign[t10] KS/COMMON 318# i <1> leavesub[1 ref] K/REFC,1 319EOT_EOT 320# 1 <;> nextstate(main 560 (eval 15):1) v 321# 2 <0> pushmark s 322# 3 <0> pushmark s 323# 4 <$> gv(*array) s 324# 5 <1> rv2av[t4] lKM/1 325# 6 <@> mapstart lK* < 5.017002 326# 6 <@> mapstart lK >=5.017002 327# 7 <|> mapwhile(other->8)[t5] lK 328# 8 <0> pushmark s 329# 9 <$> gvsv(*_) s 330# a <1> lc[t2] sK/1 331# b <@> stringify[t3] sK/1 332# c <$> const(IV 1) s 333# d <@> list lKP 334# - <@> scope lK < 5.017002 335# goto 7 336# e <0> pushmark s 337# f <$> gv(*hash) s 338# g <1> rv2hv[t1] lKRM*/1 < 5.019006 339# g <1> rv2hv lKRM*/1 >=5.019006 340# h <2> aassign[t6] KS/COMMON 341# i <1> leavesub[1 ref] K/REFC,1 342EONT_EONT 343 344 345=for gentest 346 347# chunk: %hash = map { lc($_), 1 } @array; # as does this. 348 349=cut 350 351checkOptree(note => q{}, 352 bcopts => q{-exec}, 353 code => q{%hash = map { lc($_), 1 } @array; }, 354 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); 355# 1 <;> nextstate(main 476 (eval 10):1) v 356# 2 <0> pushmark s 357# 3 <0> pushmark s 358# 4 <#> gv[*array] s 359# 5 <1> rv2av[t6] lKM/1 360# 6 <@> mapstart lK* < 5.017002 361# 6 <@> mapstart lK >=5.017002 362# 7 <|> mapwhile(other->8)[t8] lK 363# 8 <0> pushmark s 364# 9 <#> gvsv[*_] s 365# a <1> lc[t4] sK/1 366# b <$> const[IV 1] s 367# c <@> list lK 368# - <@> scope lK < 5.017002 369# goto 7 370# d <0> pushmark s 371# e <#> gv[*hash] s 372# f <1> rv2hv[t2] lKRM*/1 < 5.019006 373# f <1> rv2hv lKRM*/1 >=5.019006 374# g <2> aassign[t9] KS/COMMON 375# h <1> leavesub[1 ref] K/REFC,1 376EOT_EOT 377# 1 <;> nextstate(main 589 (eval 26):1) v 378# 2 <0> pushmark s 379# 3 <0> pushmark s 380# 4 <$> gv(*array) s 381# 5 <1> rv2av[t3] lKM/1 382# 6 <@> mapstart lK* < 5.017002 383# 6 <@> mapstart lK >=5.017002 384# 7 <|> mapwhile(other->8)[t4] lK 385# 8 <0> pushmark s 386# 9 <$> gvsv(*_) s 387# a <1> lc[t2] sK/1 388# b <$> const(IV 1) s 389# c <@> list lK 390# - <@> scope lK < 5.017002 391# goto 7 392# d <0> pushmark s 393# e <$> gv(*hash) s 394# f <1> rv2hv[t1] lKRM*/1 < 5.019006 395# f <1> rv2hv lKRM*/1 >=5.019006 396# g <2> aassign[t5] KS/COMMON 397# h <1> leavesub[1 ref] K/REFC,1 398EONT_EONT 399 400 401=for gentest 402 403# chunk: %hash = map +( lc($_), 1 ), @array; # this is EXPR and works! 404 405=cut 406 407checkOptree(note => q{}, 408 bcopts => q{-exec}, 409 code => q{%hash = map +( lc($_), 1 ), @array; }, 410 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); 411# 1 <;> nextstate(main 475 (eval 10):1) v 412# 2 <0> pushmark s 413# 3 <0> pushmark s 414# 4 <#> gv[*array] s 415# 5 <1> rv2av[t6] lKM/1 416# 6 <@> mapstart lK 417# 7 <|> mapwhile(other->8)[t7] lK 418# 8 <0> pushmark s 419# 9 <#> gvsv[*_] s 420# a <1> lc[t4] sK/1 421# b <$> const[IV 1] s 422# c <@> list lKP 423# goto 7 424# d <0> pushmark s 425# e <#> gv[*hash] s 426# f <1> rv2hv[t2] lKRM*/1 < 5.019006 427# f <1> rv2hv lKRM*/1 >=5.019006 428# g <2> aassign[t8] KS/COMMON 429# h <1> leavesub[1 ref] K/REFC,1 430EOT_EOT 431# 1 <;> nextstate(main 593 (eval 28):1) v 432# 2 <0> pushmark s 433# 3 <0> pushmark s 434# 4 <$> gv(*array) s 435# 5 <1> rv2av[t3] lKM/1 436# 6 <@> mapstart lK 437# 7 <|> mapwhile(other->8)[t4] lK 438# 8 <0> pushmark s 439# 9 <$> gvsv(*_) s 440# a <1> lc[t2] sK/1 441# b <$> const(IV 1) s 442# c <@> list lKP 443# goto 7 444# d <0> pushmark s 445# e <$> gv(*hash) s 446# f <1> rv2hv[t1] lKRM*/1 < 5.019006 447# f <1> rv2hv lKRM*/1 >=5.019006 448# g <2> aassign[t5] KS/COMMON 449# h <1> leavesub[1 ref] K/REFC,1 450EONT_EONT 451 452 453=for gentest 454 455# chunk: %hash = map ( lc($_), 1 ), @array; # evaluates to (1, @array) 456 457=cut 458 459checkOptree(note => q{}, 460 bcopts => q{-exec}, 461 code => q{%hash = map ( lc($_), 1 ), @array; }, 462 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); 463# 1 <;> nextstate(main 475 (eval 10):1) v 464# 2 <0> pushmark s 465# 3 <0> pushmark s 466# 4 <0> pushmark s 467# 5 <$> const[IV 1] sM 468# 6 <@> mapstart lK 469# 7 <|> mapwhile(other->8)[t5] lK 470# 8 <#> gvsv[*_] s 471# 9 <1> lc[t4] sK/1 472# goto 7 473# a <0> pushmark s 474# b <#> gv[*hash] s 475# c <1> rv2hv[t2] lKRM*/1 < 5.019006 476# c <1> rv2hv lKRM*/1 >=5.019006 477# d <2> aassign[t6] KS/COMMON 478# e <#> gv[*array] s 479# f <1> rv2av[t8] K/1 480# g <@> list K 481# h <1> leavesub[1 ref] K/REFC,1 482EOT_EOT 483# 1 <;> nextstate(main 597 (eval 30):1) v 484# 2 <0> pushmark s 485# 3 <0> pushmark s 486# 4 <0> pushmark s 487# 5 <$> const(IV 1) sM 488# 6 <@> mapstart lK 489# 7 <|> mapwhile(other->8)[t3] lK 490# 8 <$> gvsv(*_) s 491# 9 <1> lc[t2] sK/1 492# goto 7 493# a <0> pushmark s 494# b <$> gv(*hash) s 495# c <1> rv2hv[t1] lKRM*/1 < 5.019006 496# c <1> rv2hv lKRM*/1 >=5.019006 497# d <2> aassign[t4] KS/COMMON 498# e <$> gv(*array) s 499# f <1> rv2av[t5] K/1 500# g <@> list K 501# h <1> leavesub[1 ref] K/REFC,1 502EONT_EONT 503 504 505=for gentest 506 507# chunk: @hashes = map +{ lc($_), 1 }, @array # EXPR, so needs , at end 508 509=cut 510 511checkOptree(note => q{}, 512 bcopts => q{-exec}, 513 code => q{@hashes = map +{ lc($_), 1 }, @array }, 514 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); 515# 1 <;> nextstate(main 475 (eval 10):1) v 516# 2 <0> pushmark s 517# 3 <0> pushmark s 518# 4 <#> gv[*array] s 519# 5 <1> rv2av[t6] lKM/1 520# 6 <@> mapstart lK 521# 7 <|> mapwhile(other->8)[t7] lK 522# 8 <0> pushmark s 523# 9 <#> gvsv[*_] s 524# a <1> lc[t4] sK/1 525# b <$> const[IV 1] s 526# c <@> anonhash sK*/1 527# goto 7 528# d <0> pushmark s 529# e <#> gv[*hashes] s 530# f <1> rv2av[t2] lKRM*/1 531# g <2> aassign[t8] KS/COMMON 532# h <1> leavesub[1 ref] K/REFC,1 533EOT_EOT 534# 1 <;> nextstate(main 601 (eval 32):1) v 535# 2 <0> pushmark s 536# 3 <0> pushmark s 537# 4 <$> gv(*array) s 538# 5 <1> rv2av[t3] lKM/1 539# 6 <@> mapstart lK 540# 7 <|> mapwhile(other->8)[t4] lK 541# 8 <0> pushmark s 542# 9 <$> gvsv(*_) s 543# a <1> lc[t2] sK/1 544# b <$> const(IV 1) s 545# c <@> anonhash sK*/1 546# goto 7 547# d <0> pushmark s 548# e <$> gv(*hashes) s 549# f <1> rv2av[t1] lKRM*/1 550# g <2> aassign[t5] KS/COMMON 551# h <1> leavesub[1 ref] K/REFC,1 552EONT_EONT 553