1#!perl 2 3# This file specifies an array-of-hashes that define snippets of code that 4# can be run by various measurement and profiling tools. 5# 6# The basic idea is that any time you add an optimisation that is intended 7# to make a particular construct faster, then you should add that construct 8# to this file. 9# 10# Under the normal test suite, the test file benchmarks.t does a basic 11# compile and run of each of these snippets; not to test performance, 12# but just to ensure that the code doesn't have errors. 13# 14# Over time, it is intended that various measurement and profiling tools 15# will be written that can run selected (or all) snippets in various 16# environments. These will not be run as part of a normal test suite run. 17# 18# It is intended that the tests in this file will be lightweight; e.g. 19# a hash access, an empty function call, or a single regex match etc. 20# 21# This file is designed to be read in by 'do' (and in such a way that 22# multiple versions of this file from different releases can be read in 23# by a single process). 24# 25# The top-level array has name/hash pairs (we use an array rather than a 26# hash so that duplicate keys can be spotted) Each name is a token that 27# describes a particular test. Code will be compiled in the package named 28# after the token, so it should match /^(\w|::)+$/a. It is intended that 29# this can be used on the command line of tools to select particular 30# tests. 31# In addition, the package names are arranged into an informal hierarchy 32# whose top members are (this is subject to change): 33# 34# call:: subroutine and method handling 35# expr:: expressions: e.g. $x=1, $foo{bar}[0] 36# loop:: structural code like for, while(), etc 37# regex:: regular expressions 38# string:: string handling 39# 40# 41# Each hash has three fields: 42# 43# desc is a description of the test 44# setup is a string containing setup code 45# code is a string containing the code to run in a loop 46# 47# So typically a benchmark tool might do something like 48# 49# eval "package $token; $setup; for (1..1000000) { $code }" 50# 51# Currently the only tool that uses this file is Porting/bench.pl; 52# try C<perl Porting/bench.pl --help> for more info 53 54 55[ 56 'call::sub::empty' => { 57 desc => 'function call with no args or body', 58 setup => 'sub f { }', 59 code => 'f()', 60 }, 61 'call::sub::amp_empty' => { 62 desc => '&foo function call with no args or body', 63 setup => 'sub f { }; @_ = ();', 64 code => '&f', 65 }, 66 'call::sub::args3' => { 67 desc => 'function call with 3 local lexical vars', 68 setup => 'sub f { my ($a, $b, $c) = @_; 1 }', 69 code => 'f(1,2,3)', 70 }, 71 'call::sub::args2_ret1' => { 72 desc => 'function call with 2 local lex vars and 1 return value', 73 setup => 'my $x; sub f { my ($a, $b) = @_; $a+$b }', 74 code => '$x = f(1,2)', 75 }, 76 'call::sub::args2_ret1temp' => { 77 desc => 'function call with 2 local lex vars and 1 return TEMP value', 78 setup => 'my $x; sub f { my ($a, $b) = @_; \$a }', 79 code => '$x = f(1,2)', 80 }, 81 'call::sub::args3_ret3' => { 82 desc => 'function call with 3 local lex vars and 3 return values', 83 setup => 'my @a; sub f { my ($a, $b, $c) = @_; $a+$b, $c, 1 }', 84 code => '@a = f(1,2,3)', 85 }, 86 'call::sub::args3_ret3str' => { 87 desc => 'function call with 3 local lex vars and 3 string return values', 88 setup => 'my @a; sub f { my ($a, $b, $c) = @_; my @s = ("aa","bb","cc"); @s }', 89 code => '@a = f(1,2,3)', 90 }, 91 'call::sub::args3_ret3temp' => { 92 desc => 'function call with 3 local lex vars and 3 TEMP return values', 93 setup => 'my @a; sub f { my ($a, $b, $c) = @_; 1..3 }', 94 code => '@a = f(1,2,3)', 95 }, 96 'call::sub::recursive' => { 97 desc => 'basic recursive function call', 98 setup => 'my $x; sub f { my ($i) = @_; $i > 0 ? $i + f($i-1) : 0 }', 99 code => '$x = f(1)', 100 }, 101 102 'call::goto::empty' => { 103 desc => 'goto &funtion with no args or body', 104 setup => 'sub f { goto &g } sub g {}', 105 code => 'f()', 106 }, 107 'call::goto::args3' => { 108 desc => 'goto &funtion with 3 local lexical vars', 109 setup => 'sub f { goto &g } sub g { my ($a, $b, $c) = @_ }', 110 code => 'f(1,2,3)', 111 }, 112 113 114 'expr::array::lex_1const_0' => { 115 desc => 'lexical $array[0]', 116 setup => 'my @a = (1)', 117 code => '$a[0]', 118 }, 119 'expr::array::lex_1const_m1' => { 120 desc => 'lexical $array[-1]', 121 setup => 'my @a = (1)', 122 code => '$a[-1]', 123 }, 124 'expr::array::lex_2const' => { 125 desc => 'lexical $array[const][const]', 126 setup => 'my @a = ([1,2])', 127 code => '$a[0][1]', 128 }, 129 'expr::array::lex_2var' => { 130 desc => 'lexical $array[$i1][$i2]', 131 setup => 'my ($i1,$i2) = (0,1); my @a = ([1,2])', 132 code => '$a[$i1][$i2]', 133 }, 134 'expr::array::ref_lex_2var' => { 135 desc => 'lexical $arrayref->[$i1][$i2]', 136 setup => 'my ($i1,$i2) = (0,1); my $r = [[1,2]]', 137 code => '$r->[$i1][$i2]', 138 }, 139 'expr::array::ref_lex_3const' => { 140 desc => 'lexical $arrayref->[const][const][const]', 141 setup => 'my $r = [[[1,2]]]', 142 code => '$r->[0][0][0]', 143 }, 144 'expr::array::ref_expr_lex_3const' => { 145 desc => '(lexical expr)->[const][const][const]', 146 setup => 'my $r = [[[1,2]]]', 147 code => '($r||0)->[0][0][0]', 148 }, 149 150 151 'expr::array::pkg_1const_0' => { 152 desc => 'package $array[0]', 153 setup => '@a = (1)', 154 code => '$a[0]', 155 }, 156 'expr::array::pkg_1const_m1' => { 157 desc => 'package $array[-1]', 158 setup => '@a = (1)', 159 code => '$a[-1]', 160 }, 161 'expr::array::pkg_2const' => { 162 desc => 'package $array[const][const]', 163 setup => '@a = ([1,2])', 164 code => '$a[0][1]', 165 }, 166 'expr::array::pkg_2var' => { 167 desc => 'package $array[$i1][$i2]', 168 setup => '($i1,$i2) = (0,1); @a = ([1,2])', 169 code => '$a[$i1][$i2]', 170 }, 171 'expr::array::ref_pkg_2var' => { 172 desc => 'package $arrayref->[$i1][$i2]', 173 setup => '($i1,$i2) = (0,1); $r = [[1,2]]', 174 code => '$r->[$i1][$i2]', 175 }, 176 'expr::array::ref_pkg_3const' => { 177 desc => 'package $arrayref->[const][const][const]', 178 setup => '$r = [[[1,2]]]', 179 code => '$r->[0][0][0]', 180 }, 181 'expr::array::ref_expr_pkg_3const' => { 182 desc => '(package expr)->[const][const][const]', 183 setup => '$r = [[[1,2]]]', 184 code => '($r||0)->[0][0][0]', 185 }, 186 187 188 'expr::arrayhash::lex_3var' => { 189 desc => 'lexical $h{$k1}[$i]{$k2}', 190 setup => 'my ($i, $k1, $k2) = (0,"foo","bar");' 191 . 'my %h = (foo => [ { bar => 1 } ])', 192 code => '$h{$k1}[$i]{$k2}', 193 }, 194 'expr::arrayhash::pkg_3var' => { 195 desc => 'package $h{$k1}[$i]{$k2}', 196 setup => '($i, $k1, $k2) = (0,"foo","bar");' 197 . '%h = (foo => [ { bar => 1 } ])', 198 code => '$h{$k1}[$i]{$k2}', 199 }, 200 201 202 'expr::assign::scalar_lex_int' => { 203 desc => 'lexical $x = 1', 204 setup => 'my $x', 205 code => '$x = 1', 206 }, 207 'expr::assign::scalar_lex_str' => { 208 desc => 'lexical $x = "abc"', 209 setup => 'my $x', 210 code => '$x = "abc"', 211 }, 212 'expr::assign::scalar_lex_strint' => { 213 desc => 'lexical $x = 1 where $x was previously a string', 214 setup => 'my $x = "abc"', 215 code => '$x = 1', 216 }, 217 'expr::assign::scalar_lex_intstr' => { 218 desc => 'lexical $x = "abc" where $x was previously an int', 219 setup => 'my $x = 1;', 220 code => '$x = "abc"', 221 }, 222 'expr::assign::2list_lex' => { 223 desc => 'lexical ($x, $y) = (1, 2)', 224 setup => 'my ($x, $y)', 225 code => '($x, $y) = (1, 2)', 226 }, 227 228 229 'expr::hash::lex_1const' => { 230 desc => 'lexical $hash{const}', 231 setup => 'my %h = ("foo" => 1)', 232 code => '$h{foo}', 233 }, 234 'expr::hash::lex_2const' => { 235 desc => 'lexical $hash{const}{const}', 236 setup => 'my %h = (foo => { bar => 1 })', 237 code => '$h{foo}{bar}', 238 }, 239 'expr::hash::lex_2var' => { 240 desc => 'lexical $hash{$k1}{$k2}', 241 setup => 'my ($k1,$k2) = qw(foo bar); my %h = ($k1 => { $k2 => 1 })', 242 code => '$h{$k1}{$k2}', 243 }, 244 'expr::hash::ref_lex_2var' => { 245 desc => 'lexical $hashref->{$k1}{$k2}', 246 setup => 'my ($k1,$k2) = qw(foo bar); my $r = {$k1 => { $k2 => 1 }}', 247 code => '$r->{$k1}{$k2}', 248 }, 249 'expr::hash::ref_lex_3const' => { 250 desc => 'lexical $hashref->{const}{const}{const}', 251 setup => 'my $r = {foo => { bar => { baz => 1 }}}', 252 code => '$r->{foo}{bar}{baz}', 253 }, 254 'expr::hash::ref_expr_lex_3const' => { 255 desc => '(lexical expr)->{const}{const}{const}', 256 setup => 'my $r = {foo => { bar => { baz => 1 }}}', 257 code => '($r||0)->{foo}{bar}{baz}', 258 }, 259 260 261 'expr::hash::pkg_1const' => { 262 desc => 'package $hash{const}', 263 setup => '%h = ("foo" => 1)', 264 code => '$h{foo}', 265 }, 266 'expr::hash::pkg_2const' => { 267 desc => 'package $hash{const}{const}', 268 setup => '%h = (foo => { bar => 1 })', 269 code => '$h{foo}{bar}', 270 }, 271 'expr::hash::pkg_2var' => { 272 desc => 'package $hash{$k1}{$k2}', 273 setup => '($k1,$k2) = qw(foo bar); %h = ($k1 => { $k2 => 1 })', 274 code => '$h{$k1}{$k2}', 275 }, 276 'expr::hash::ref_pkg_2var' => { 277 desc => 'package $hashref->{$k1}{$k2}', 278 setup => '($k1,$k2) = qw(foo bar); $r = {$k1 => { $k2 => 1 }}', 279 code => '$r->{$k1}{$k2}', 280 }, 281 'expr::hash::ref_pkg_3const' => { 282 desc => 'package $hashref->{const}{const}{const}', 283 setup => '$r = {foo => { bar => { baz => 1 }}}', 284 code => '$r->{foo}{bar}{baz}', 285 }, 286 'expr::hash::ref_expr_pkg_3const' => { 287 desc => '(package expr)->{const}{const}{const}', 288 setup => '$r = {foo => { bar => { baz => 1 }}}', 289 code => '($r||0)->{foo}{bar}{baz}', 290 }, 291 292 293 'expr::hash::exists_lex_2var' => { 294 desc => 'lexical exists $hash{$k1}{$k2}', 295 setup => 'my ($k1,$k2) = qw(foo bar); my %h = ($k1 => { $k2 => 1 });', 296 code => 'exists $h{$k1}{$k2}', 297 }, 298 'expr::hash::delete_lex_2var' => { 299 desc => 'lexical delete $hash{$k1}{$k2}', 300 setup => 'my ($k1,$k2) = qw(foo bar); my %h = ($k1 => { $k2 => 1 });', 301 code => 'delete $h{$k1}{$k2}', 302 }, 303 304 305 # using a const string as second arg to index triggers using FBM. 306 # the FBM matcher special-cases 1,2-byte strings. 307 # 308 'expr::index::short_const1' => { 309 desc => 'index of a short string against a 1 char const substr', 310 setup => 'my $x = "aaaab"', 311 code => 'index $x, "b"', 312 }, 313 'expr::index::long_const1' => { 314 desc => 'index of a long string against a 1 char const substr', 315 setup => 'my $x = "a" x 1000 . "b"', 316 code => 'index $x, "b"', 317 }, 318 'expr::index::short_const2aabc_bc' => { 319 desc => 'index of a short string against a 2 char const substr', 320 setup => 'my $x = "aaaabc"', 321 code => 'index $x, "bc"', 322 }, 323 'expr::index::long_const2aabc_bc' => { 324 desc => 'index of a long string against a 2 char const substr', 325 setup => 'my $x = "a" x 1000 . "bc"', 326 code => 'index $x, "bc"', 327 }, 328 'expr::index::long_const2aa_ab' => { 329 desc => 'index of a long string aaa.. against const substr "ab"', 330 setup => 'my $x = "a" x 1000', 331 code => 'index $x, "ab"', 332 }, 333 'expr::index::long_const2bb_ab' => { 334 desc => 'index of a long string bbb.. against const substr "ab"', 335 setup => 'my $x = "b" x 1000', 336 code => 'index $x, "ab"', 337 }, 338 'expr::index::long_const2aa_bb' => { 339 desc => 'index of a long string aaa.. against const substr "bb"', 340 setup => 'my $x = "a" x 1000', 341 code => 'index $x, "bb"', 342 }, 343 # this one is designed to be pathological 344 'expr::index::long_const2ab_aa' => { 345 desc => 'index of a long string abab.. against const substr "aa"', 346 setup => 'my $x = "ab" x 500', 347 code => 'index $x, "aa"', 348 }, 349 # near misses with gaps, 1st letter 350 'expr::index::long_const2aaxx_xy' => { 351 desc => 'index of a long string with "xx"s against const substr "xy"', 352 setup => 'my $x = "aaaaaaaaxx" x 100', 353 code => 'index $x, "xy"', 354 }, 355 # near misses with gaps, 2nd letter 356 'expr::index::long_const2aayy_xy' => { 357 desc => 'index of a long string with "yy"s against const substr "xy"', 358 setup => 'my $x = "aaaaaaaayy" x 100', 359 code => 'index $x, "xy"', 360 }, 361 # near misses with gaps, duplicate letter 362 'expr::index::long_const2aaxy_xx' => { 363 desc => 'index of a long string with "xy"s against const substr "xx"', 364 setup => 'my $x = "aaaaaaaaxy" x 100', 365 code => 'index $x, "xx"', 366 }, 367 # alternating near misses with gaps 368 'expr::index::long_const2aaxxaayy_xy' => { 369 desc => 'index of a long string with "xx/yy"s against const substr "xy"', 370 setup => 'my $x = "aaaaaaaaxxbbbbbbbbyy" x 50', 371 code => 'index $x, "xy"', 372 }, 373 'expr::index::short_const3aabcd_bcd' => { 374 desc => 'index of a short string against a 3 char const substr', 375 setup => 'my $x = "aaaabcd"', 376 code => 'index $x, "bcd"', 377 }, 378 'expr::index::long_const3aabcd_bcd' => { 379 desc => 'index of a long string against a 3 char const substr', 380 setup => 'my $x = "a" x 1000 . "bcd"', 381 code => 'index $x, "bcd"', 382 }, 383 'expr::index::long_const3ab_abc' => { 384 desc => 'index of a long string of "ab"s against a 3 char const substr "abc"', 385 setup => 'my $x = "ab" x 500', 386 code => 'index $x, "abc"', 387 }, 388 'expr::index::long_const3bc_abc' => { 389 desc => 'index of a long string of "bc"s against a 3 char const substr "abc"', 390 setup => 'my $x = "bc" x 500', 391 code => 'index $x, "abc"', 392 }, 393 'expr::index::utf8_position_1' => { 394 desc => 'index of a utf8 string, matching at position 1', 395 setup => 'my $x = "abc". chr(0x100); chop $x', 396 code => 'index $x, "b"', 397 }, 398 399 400 # list assign, OP_AASSIGN 401 402 403 # (....) = () 404 405 'expr::aassign::ma_empty' => { 406 desc => 'my array assigned empty', 407 setup => '', 408 code => 'my @a = ()', 409 }, 410 'expr::aassign::lax_empty' => { 411 desc => 'non-empty lexical array assigned empty', 412 setup => 'my @a = 1..3;', 413 code => '@a = ()', 414 }, 415 'expr::aassign::llax_empty' => { 416 desc => 'non-empty lexical var and array assigned empty', 417 setup => 'my ($x, @a) = 1..4;', 418 code => '($x, @a) = ()', 419 }, 420 'expr::aassign::3m_empty' => { 421 desc => 'three my vars assigned empty', 422 setup => '', 423 code => 'my ($x,$y,$z) = ()', 424 }, 425 'expr::aassign::3l_empty' => { 426 desc => 'three lexical vars assigned empty', 427 setup => 'my ($x,$y,$z)', 428 code => '($x,$y,$z) = ()', 429 }, 430 'expr::aassign::pa_empty' => { 431 desc => 'package array assigned empty', 432 setup => '', 433 code => '@a = ()', 434 }, 435 'expr::aassign::pax_empty' => { 436 desc => 'non-empty package array assigned empty', 437 setup => '@a = (1,2,3)', 438 code => '@a = ()', 439 }, 440 'expr::aassign::3p_empty' => { 441 desc => 'three package vars assigned empty', 442 setup => '($x,$y,$z) = 1..3;', 443 code => '($x,$y,$z) = ()', 444 }, 445 446 # (....) = (1,2,3) 447 448 'expr::aassign::ma_3c' => { 449 desc => 'my array assigned 3 consts', 450 setup => '', 451 code => 'my @a = (1,2,3)', 452 }, 453 'expr::aassign::lax_3c' => { 454 desc => 'non-empty lexical array assigned 3 consts', 455 setup => 'my @a = 1..3;', 456 code => '@a = (1,2,3)', 457 }, 458 'expr::aassign::llax_3c' => { 459 desc => 'non-empty lexical var and array assigned 3 consts', 460 setup => 'my ($x, @a) = 1..4;', 461 code => '($x, @a) = (1,2,3)', 462 }, 463 'expr::aassign::3m_3c' => { 464 desc => 'three my vars assigned 3 consts', 465 setup => '', 466 code => 'my ($x,$y,$z) = (1,2,3)', 467 }, 468 'expr::aassign::3l_3c' => { 469 desc => 'three lexical vars assigned 3 consts', 470 setup => 'my ($x,$y,$z)', 471 code => '($x,$y,$z) = (1,2,3)', 472 }, 473 'expr::aassign::pa_3c' => { 474 desc => 'package array assigned 3 consts', 475 setup => '', 476 code => '@a = (1,2,3)', 477 }, 478 'expr::aassign::pax_3c' => { 479 desc => 'non-empty package array assigned 3 consts', 480 setup => '@a = (1,2,3)', 481 code => '@a = (1,2,3)', 482 }, 483 'expr::aassign::3p_3c' => { 484 desc => 'three package vars assigned 3 consts', 485 setup => '($x,$y,$z) = 1..3;', 486 code => '($x,$y,$z) = (1,2,3)', 487 }, 488 489 # (....) = @lexical 490 491 'expr::aassign::ma_la' => { 492 desc => 'my array assigned lexical array', 493 setup => 'my @init = 1..3;', 494 code => 'my @a = @init', 495 }, 496 'expr::aassign::lax_la' => { 497 desc => 'non-empty lexical array assigned lexical array', 498 setup => 'my @init = 1..3; my @a = 1..3;', 499 code => '@a = @init', 500 }, 501 'expr::aassign::llax_la' => { 502 desc => 'non-empty lexical var and array assigned lexical array', 503 setup => 'my @init = 1..3; my ($x, @a) = 1..4;', 504 code => '($x, @a) = @init', 505 }, 506 'expr::aassign::3m_la' => { 507 desc => 'three my vars assigned lexical array', 508 setup => 'my @init = 1..3;', 509 code => 'my ($x,$y,$z) = @init', 510 }, 511 'expr::aassign::3l_la' => { 512 desc => 'three lexical vars assigned lexical array', 513 setup => 'my @init = 1..3; my ($x,$y,$z)', 514 code => '($x,$y,$z) = @init', 515 }, 516 'expr::aassign::pa_la' => { 517 desc => 'package array assigned lexical array', 518 setup => 'my @init = 1..3;', 519 code => '@a = @init', 520 }, 521 'expr::aassign::pax_la' => { 522 desc => 'non-empty package array assigned lexical array', 523 setup => 'my @init = 1..3; @a = @init', 524 code => '@a = @init', 525 }, 526 'expr::aassign::3p_la' => { 527 desc => 'three package vars assigned lexical array', 528 setup => 'my @init = 1..3; ($x,$y,$z) = 1..3;', 529 code => '($x,$y,$z) = @init', 530 }, 531 532 # (....) = @package 533 534 'expr::aassign::ma_pa' => { 535 desc => 'my array assigned package array', 536 setup => '@init = 1..3;', 537 code => 'my @a = @init', 538 }, 539 'expr::aassign::lax_pa' => { 540 desc => 'non-empty lexical array assigned package array', 541 setup => '@init = 1..3; my @a = 1..3;', 542 code => '@a = @init', 543 }, 544 'expr::aassign::llax_pa' => { 545 desc => 'non-empty lexical var and array assigned package array', 546 setup => '@init = 1..3; my ($x, @a) = 1..4;', 547 code => '($x, @a) = @init', 548 }, 549 'expr::aassign::3m_pa' => { 550 desc => 'three my vars assigned package array', 551 setup => '@init = 1..3;', 552 code => 'my ($x,$y,$z) = @init', 553 }, 554 'expr::aassign::3l_pa' => { 555 desc => 'three lexical vars assigned package array', 556 setup => '@init = 1..3; my ($x,$y,$z)', 557 code => '($x,$y,$z) = @init', 558 }, 559 'expr::aassign::pa_pa' => { 560 desc => 'package array assigned package array', 561 setup => '@init = 1..3;', 562 code => '@a = @init', 563 }, 564 'expr::aassign::pax_pa' => { 565 desc => 'non-empty package array assigned package array', 566 setup => '@init = 1..3; @a = @init', 567 code => '@a = @init', 568 }, 569 'expr::aassign::3p_pa' => { 570 desc => 'three package vars assigned package array', 571 setup => '@init = 1..3; ($x,$y,$z) = 1..3;', 572 code => '($x,$y,$z) = @init', 573 }, 574 575 # (....) = @_; 576 577 'expr::aassign::ma_defary' => { 578 desc => 'my array assigned @_', 579 setup => '@_ = 1..3;', 580 code => 'my @a = @_', 581 }, 582 'expr::aassign::lax_defary' => { 583 desc => 'non-empty lexical array assigned @_', 584 setup => '@_ = 1..3; my @a = 1..3;', 585 code => '@a = @_', 586 }, 587 'expr::aassign::llax_defary' => { 588 desc => 'non-empty lexical var and array assigned @_', 589 setup => '@_ = 1..3; my ($x, @a) = 1..4;', 590 code => '($x, @a) = @_', 591 }, 592 'expr::aassign::3m_defary' => { 593 desc => 'three my vars assigned @_', 594 setup => '@_ = 1..3;', 595 code => 'my ($x,$y,$z) = @_', 596 }, 597 'expr::aassign::3l_defary' => { 598 desc => 'three lexical vars assigned @_', 599 setup => '@_ = 1..3; my ($x,$y,$z)', 600 code => '($x,$y,$z) = @_', 601 }, 602 'expr::aassign::pa_defary' => { 603 desc => 'package array assigned @_', 604 setup => '@_ = 1..3;', 605 code => '@a = @_', 606 }, 607 'expr::aassign::pax_defary' => { 608 desc => 'non-empty package array assigned @_', 609 setup => '@_ = 1..3; @a = @_', 610 code => '@a = @_', 611 }, 612 'expr::aassign::3p_defary' => { 613 desc => 'three package vars assigned @_', 614 setup => '@_ = 1..3; ($x,$y,$z) = 1..3;', 615 code => '($x,$y,$z) = @_', 616 }, 617 618 619 # (....) = ($lex1,$lex2,$lex3); 620 621 'expr::aassign::ma_3l' => { 622 desc => 'my array assigned lexicals', 623 setup => 'my ($v1,$v2,$v3) = 1..3;', 624 code => 'my @a = ($v1,$v2,$v3)', 625 }, 626 'expr::aassign::lax_3l' => { 627 desc => 'non-empty lexical array assigned lexicals', 628 setup => 'my ($v1,$v2,$v3) = 1..3; my @a = 1..3;', 629 code => '@a = ($v1,$v2,$v3)', 630 }, 631 'expr::aassign::llax_3l' => { 632 desc => 'non-empty lexical var and array assigned lexicals', 633 setup => 'my ($v1,$v2,$v3) = 1..3; my ($x, @a) = 1..4;', 634 code => '($x, @a) = ($v1,$v2,$v3)', 635 }, 636 'expr::aassign::3m_3l' => { 637 desc => 'three my vars assigned lexicals', 638 setup => 'my ($v1,$v2,$v3) = 1..3;', 639 code => 'my ($x,$y,$z) = ($v1,$v2,$v3)', 640 }, 641 'expr::aassign::3l_3l' => { 642 desc => 'three lexical vars assigned lexicals', 643 setup => 'my ($v1,$v2,$v3) = 1..3; my ($x,$y,$z)', 644 code => '($x,$y,$z) = ($v1,$v2,$v3)', 645 }, 646 'expr::aassign::pa_3l' => { 647 desc => 'package array assigned lexicals', 648 setup => 'my ($v1,$v2,$v3) = 1..3;', 649 code => '@a = ($v1,$v2,$v3)', 650 }, 651 'expr::aassign::pax_3l' => { 652 desc => 'non-empty package array assigned lexicals', 653 setup => 'my ($v1,$v2,$v3) = 1..3; @a = @_', 654 code => '@a = ($v1,$v2,$v3)', 655 }, 656 'expr::aassign::3p_3l' => { 657 desc => 'three package vars assigned lexicals', 658 setup => 'my ($v1,$v2,$v3) = 1..3; ($x,$y,$z) = 1..3;', 659 code => '($x,$y,$z) = ($v1,$v2,$v3)', 660 }, 661 662 663 # (....) = ($pkg1,$pkg2,$pkg3); 664 665 'expr::aassign::ma_3p' => { 666 desc => 'my array assigned 3 package vars', 667 setup => '($v1,$v2,$v3) = 1..3;', 668 code => 'my @a = ($v1,$v2,$v3)', 669 }, 670 'expr::aassign::lax_3p' => { 671 desc => 'non-empty lexical array assigned 3 package vars', 672 setup => '($v1,$v2,$v3) = 1..3; my @a = 1..3;', 673 code => '@a = ($v1,$v2,$v3)', 674 }, 675 'expr::aassign::llax_3p' => { 676 desc => 'non-empty lexical var and array assigned 3 package vars', 677 setup => '($v1,$v2,$v3) = 1..3; my ($x, @a) = 1..4;', 678 code => '($x, @a) = ($v1,$v2,$v3)', 679 }, 680 'expr::aassign::3m_3p' => { 681 desc => 'three my vars assigned 3 package vars', 682 setup => '($v1,$v2,$v3) = 1..3;', 683 code => 'my ($x,$y,$z) = ($v1,$v2,$v3)', 684 }, 685 'expr::aassign::3l_3p' => { 686 desc => 'three lexical vars assigned 3 package vars', 687 setup => '($v1,$v2,$v3) = 1..3; my ($x,$y,$z)', 688 code => '($x,$y,$z) = ($v1,$v2,$v3)', 689 }, 690 'expr::aassign::pa_3p' => { 691 desc => 'package array assigned 3 package vars', 692 setup => '($v1,$v2,$v3) = 1..3;', 693 code => '@a = ($v1,$v2,$v3)', 694 }, 695 'expr::aassign::pax_3p' => { 696 desc => 'non-empty package array assigned 3 package vars', 697 setup => '($v1,$v2,$v3) = 1..3; @a = @_', 698 code => '@a = ($v1,$v2,$v3)', 699 }, 700 'expr::aassign::3p_3p' => { 701 desc => 'three package vars assigned 3 package vars', 702 setup => '($v1,$v2,$v3) = 1..3; ($x,$y,$z) = 1..3;', 703 code => '($x,$y,$z) = ($v1,$v2,$v3)', 704 }, 705 706 707 # (....) = (1,2,$shared); 708 709 'expr::aassign::llax_2c1s' => { 710 desc => 'non-empty lexical var and array assigned 2 consts and 1 shared var', 711 setup => 'my ($x, @a) = 1..4;', 712 code => '($x, @a) = (1,2,$x)', 713 }, 714 'expr::aassign::3l_2c1s' => { 715 desc => 'three lexical vars assigned 2 consts and 1 shared var', 716 setup => 'my ($x,$y,$z) = 1..3;', 717 code => '($x,$y,$z) = (1,2,$x)', 718 }, 719 'expr::aassign::3p_2c1s' => { 720 desc => 'three package vars assigned 2 consts and 1 shared var', 721 setup => '($x,$y,$z) = 1..3;', 722 code => '($x,$y,$z) = (1,2,$x)', 723 }, 724 725 726 # ($a,$b) = ($b,$a); 727 728 'expr::aassign::2l_swap' => { 729 desc => 'swap two lexical vars', 730 setup => 'my ($a,$b) = (1,2)', 731 code => '($a,$b) = ($b,$a)', 732 }, 733 'expr::aassign::2p_swap' => { 734 desc => 'swap two package vars', 735 setup => '($a,$b) = (1,2)', 736 code => '($a,$b) = ($b,$a)', 737 }, 738 'expr::aassign::2laelem_swap' => { 739 desc => 'swap two lexical vars', 740 setup => 'my @a = (1,2)', 741 code => '($a[0],$a[1]) = ($a[1],$a[0])', 742 }, 743 744 # misc list assign 745 746 'expr::aassign::5l_4l1s' => { 747 desc => 'long list of lexical vars, 1 shared', 748 setup => 'my ($a,$b,$c,$d,$e) = 1..5', 749 code => '($a,$b,$c,$d,$e) = ($a,$a,$c,$d,$e)', 750 }, 751 752 'expr::aassign::5p_4p1s' => { 753 desc => 'long list of package vars, 1 shared', 754 setup => '($a,$b,$c,$d,$e) = 1..5', 755 code => '($a,$b,$c,$d,$e) = ($a,$a,$c,$d,$e)', 756 }, 757 'expr::aassign::5l_defary' => { 758 desc => 'long list of lexical vars to assign @_ to', 759 setup => '@_ = 1..5', 760 code => 'my ($a,$b,$c,$d,$e) = @_', 761 }, 762 'expr::aassign::5l1la_defary' => { 763 desc => 'long list of lexical vars plus long slurp to assign @_ to', 764 setup => '@_ = 1..20', 765 code => 'my ($a,$b,$c,$d,$e,@rest) = @_', 766 }, 767 'expr::aassign::1l_2l' => { 768 desc => 'single lexical LHS', 769 setup => 'my $x = 1;', 770 code => '(undef,$x) = ($x,$x)', 771 }, 772 'expr::aassign::2l_1l' => { 773 desc => 'single lexical RHS', 774 setup => 'my $x = 1;', 775 code => '($x,$x) = ($x)', 776 }, 777 'expr::aassign::2l_1ul' => { 778 desc => 'undef and single lexical RHS', 779 setup => 'my $x = 1;', 780 code => '($x,$x) = (undef, $x)', 781 }, 782 783 784 'expr::arith::add_lex_ii' => { 785 desc => 'add two integers and assign to a lexical var', 786 setup => 'my ($x,$y,$z) = 1..3;', 787 code => '$z = $x + $y', 788 }, 789 'expr::arith::add_pkg_ii' => { 790 desc => 'add two integers and assign to a package var', 791 setup => 'my ($x,$y) = 1..2; $z = 3;', 792 code => '$z = $x + $y', 793 }, 794 'expr::arith::add_lex_nn' => { 795 desc => 'add two NVs and assign to a lexical var', 796 setup => 'my ($x,$y,$z) = (1.1, 2.2, 3.3);', 797 code => '$z = $x + $y', 798 }, 799 'expr::arith::add_pkg_nn' => { 800 desc => 'add two NVs and assign to a package var', 801 setup => 'my ($x,$y); ($x,$y,$z) = (1.1, 2.2, 3.3);', 802 code => '$z = $x + $y', 803 }, 804 'expr::arith::add_lex_ni' => { 805 desc => 'add an int and an NV and assign to a lexical var', 806 setup => 'my ($x,$y,$z) = (1, 2.2, 3.3);', 807 code => '$z = $x + $y', 808 }, 809 'expr::arith::add_pkg_ni' => { 810 desc => 'add an int and an NV and assign to a package var', 811 setup => 'my ($x,$y); ($x,$y,$z) = (1, 2.2, 3.3);', 812 code => '$z = $x + $y', 813 }, 814 815 'expr::arith::sub_lex_ii' => { 816 desc => 'subtract two integers and assign to a lexical var', 817 setup => 'my ($x,$y,$z) = 1..3;', 818 code => '$z = $x - $y', 819 }, 820 'expr::arith::sub_pkg_ii' => { 821 desc => 'subtract two integers and assign to a package var', 822 setup => 'my ($x,$y) = 1..2; $z = 3;', 823 code => '$z = $x - $y', 824 }, 825 'expr::arith::sub_lex_nn' => { 826 desc => 'subtract two NVs and assign to a lexical var', 827 setup => 'my ($x,$y,$z) = (1.1, 2.2, 3.3);', 828 code => '$z = $x - $y', 829 }, 830 'expr::arith::sub_pkg_nn' => { 831 desc => 'subtract two NVs and assign to a package var', 832 setup => 'my ($x,$y); ($x,$y,$z) = (1.1, 2.2, 3.3);', 833 code => '$z = $x - $y', 834 }, 835 'expr::arith::sub_lex_ni' => { 836 desc => 'subtract an int and an NV and assign to a lexical var', 837 setup => 'my ($x,$y,$z) = (1, 2.2, 3.3);', 838 code => '$z = $x - $y', 839 }, 840 'expr::arith::sub_pkg_ni' => { 841 desc => 'subtract an int and an NV and assign to a package var', 842 setup => 'my ($x,$y); ($x,$y,$z) = (1, 2.2, 3.3);', 843 code => '$z = $x - $y', 844 }, 845 846 'expr::arith::mult_lex_ii' => { 847 desc => 'multiply two integers and assign to a lexical var', 848 setup => 'my ($x,$y,$z) = 1..3;', 849 code => '$z = $x * $y', 850 }, 851 'expr::arith::mult_pkg_ii' => { 852 desc => 'multiply two integers and assign to a package var', 853 setup => 'my ($x,$y) = 1..2; $z = 3;', 854 code => '$z = $x * $y', 855 }, 856 'expr::arith::mult_lex_nn' => { 857 desc => 'multiply two NVs and assign to a lexical var', 858 setup => 'my ($x,$y,$z) = (1.1, 2.2, 3.3);', 859 code => '$z = $x * $y', 860 }, 861 'expr::arith::mult_pkg_nn' => { 862 desc => 'multiply two NVs and assign to a package var', 863 setup => 'my ($x,$y); ($x,$y,$z) = (1.1, 2.2, 3.3);', 864 code => '$z = $x * $y', 865 }, 866 'expr::arith::mult_lex_ni' => { 867 desc => 'multiply an int and an NV and assign to a lexical var', 868 setup => 'my ($x,$y,$z) = (1, 2.2, 3.3);', 869 code => '$z = $x * $y', 870 }, 871 'expr::arith::mult_pkg_ni' => { 872 desc => 'multiply an int and an NV and assign to a package var', 873 setup => 'my ($x,$y); ($x,$y,$z) = (1, 2.2, 3.3);', 874 code => '$z = $x * $y', 875 }, 876 877 'expr::arith::preinc' => { 878 desc => '++$x', 879 setup => 'my $x = 1;', 880 code => '++$x', 881 }, 882 'expr::arith::predec' => { 883 desc => '--$x', 884 setup => 'my $x = 1;', 885 code => '--$x', 886 }, 887 'expr::arith::postinc' => { 888 desc => '$x++', 889 setup => 'my $x = 1; my $y', 890 code => '$y = $x++', # scalar context so not optimised to ++$x 891 }, 892 'expr::arith::postdec' => { 893 desc => '$x--', 894 setup => 'my $x = 1; my $y', 895 code => '$y = $x--', # scalar context so not optimised to --$x 896 }, 897 898 'loop::block' => { 899 desc => 'empty basic loop', 900 setup => ';', 901 code => '{1;}', 902 }, 903 904 'loop::do' => { 905 desc => 'basic do block', 906 setup => 'my $x; my $y = 2;', 907 code => '$x = do {1; $y}', # the ';' stops the do being optimised 908 }, 909 910 'loop::for::my_range1' => { 911 desc => 'empty for loop with my var and 1 integer range', 912 setup => '', 913 code => 'for my $x (1..1) {}', 914 }, 915 'loop::for::lex_range1' => { 916 desc => 'empty for loop with lexical var and 1 integer range', 917 setup => 'my $x;', 918 code => 'for $x (1..1) {}', 919 }, 920 'loop::for::pkg_range1' => { 921 desc => 'empty for loop with package var and 1 integer range', 922 setup => '$x = 1;', 923 code => 'for $x (1..1) {}', 924 }, 925 'loop::for::defsv_range1' => { 926 desc => 'empty for loop with $_ and integer 1 range', 927 setup => ';', 928 code => 'for (1..1) {}', 929 }, 930 'loop::for::my_range4' => { 931 desc => 'empty for loop with my var and 4 integer range', 932 setup => '', 933 code => 'for my $x (1..4) {}', 934 }, 935 'loop::for::lex_range4' => { 936 desc => 'empty for loop with lexical var and 4 integer range', 937 setup => 'my $x;', 938 code => 'for $x (1..4) {}', 939 }, 940 'loop::for::pkg_range4' => { 941 desc => 'empty for loop with package var and 4 integer range', 942 setup => '$x = 1;', 943 code => 'for $x (1..4) {}', 944 }, 945 'loop::for::defsv_range4' => { 946 desc => 'empty for loop with $_ and integer 4 range', 947 setup => ';', 948 code => 'for (1..4) {}', 949 }, 950 951 'loop::for::my_list1' => { 952 desc => 'empty for loop with my var and 1 integer list', 953 setup => '', 954 code => 'for my $x (1) {}', 955 }, 956 'loop::for::lex_list1' => { 957 desc => 'empty for loop with lexical var and 1 integer list', 958 setup => 'my $x;', 959 code => 'for $x (1) {}', 960 }, 961 'loop::for::pkg_list1' => { 962 desc => 'empty for loop with package var and 1 integer list', 963 setup => '$x = 1;', 964 code => 'for $x (1) {}', 965 }, 966 'loop::for::defsv_list1' => { 967 desc => 'empty for loop with $_ and integer 1 list', 968 setup => ';', 969 code => 'for (1) {}', 970 }, 971 'loop::for::my_list4' => { 972 desc => 'empty for loop with my var and 4 integer list', 973 setup => '', 974 code => 'for my $x (1,2,3,4) {}', 975 }, 976 'loop::for::lex_list4' => { 977 desc => 'empty for loop with lexical var and 4 integer list', 978 setup => 'my $x;', 979 code => 'for $x (1,2,3,4) {}', 980 }, 981 'loop::for::pkg_list4' => { 982 desc => 'empty for loop with package var and 4 integer list', 983 setup => '$x = 1;', 984 code => 'for $x (1,2,3,4) {}', 985 }, 986 'loop::for::defsv_list4' => { 987 desc => 'empty for loop with $_ and integer 4 list', 988 setup => '', 989 code => 'for (1,2,3,4) {}', 990 }, 991 992 'loop::for::my_array1' => { 993 desc => 'empty for loop with my var and 1 integer array', 994 setup => 'my @a = (1);', 995 code => 'for my $x (@a) {}', 996 }, 997 'loop::for::lex_array1' => { 998 desc => 'empty for loop with lexical var and 1 integer array', 999 setup => 'my $x; my @a = (1);', 1000 code => 'for $x (@a) {}', 1001 }, 1002 'loop::for::pkg_array1' => { 1003 desc => 'empty for loop with package var and 1 integer array', 1004 setup => '$x = 1; my @a = (1);', 1005 code => 'for $x (@a) {}', 1006 }, 1007 'loop::for::defsv_array1' => { 1008 desc => 'empty for loop with $_ and integer 1 array', 1009 setup => 'my @a = (@a);', 1010 code => 'for (1) {}', 1011 }, 1012 'loop::for::my_array4' => { 1013 desc => 'empty for loop with my var and 4 integer array', 1014 setup => 'my @a = (1..4);', 1015 code => 'for my $x (@a) {}', 1016 }, 1017 'loop::for::lex_array4' => { 1018 desc => 'empty for loop with lexical var and 4 integer array', 1019 setup => 'my $x; my @a = (1..4);', 1020 code => 'for $x (@a) {}', 1021 }, 1022 'loop::for::pkg_array4' => { 1023 desc => 'empty for loop with package var and 4 integer array', 1024 setup => '$x = 1; my @a = (1..4);', 1025 code => 'for $x (@a) {}', 1026 }, 1027 'loop::for::defsv_array4' => { 1028 desc => 'empty for loop with $_ and integer 4 array', 1029 setup => 'my @a = (1..4);', 1030 code => 'for (@a) {}', 1031 }, 1032 1033 'loop::for::next4' => { 1034 desc => 'for loop containing only next with my var and integer 4 array', 1035 setup => 'my @a = (1..4);', 1036 code => 'for my $x (@a) {next}', 1037 }, 1038 1039 'loop::grep::expr_3int' => { 1040 desc => 'grep $_ > 0, 1,2,3', 1041 setup => 'my @a', 1042 code => '@a = grep $_ > 0, 1,2,3', 1043 }, 1044 1045 'loop::grep::block_3int' => { 1046 desc => 'grep { 1; $_ > 0} 1,2,3', 1047 setup => 'my @a', 1048 code => '@a = grep { 1; $_ > 0} 1,2,3', 1049 }, 1050 1051 'loop::map::expr_3int' => { 1052 desc => 'map $_+1, 1,2,3', 1053 setup => 'my @a', 1054 code => '@a = map $_+1, 1,2,3', 1055 }, 1056 1057 'loop::map::block_3int' => { 1058 desc => 'map { 1; $_+1} 1,2,3', 1059 setup => 'my @a', 1060 code => '@a = map { 1; $_+1} 1,2,3', 1061 }, 1062 1063 'loop::while::i1' => { 1064 desc => 'empty while loop 1 iteration', 1065 setup => 'my $i = 0;', 1066 code => 'while (++$i % 2) {}', 1067 }, 1068 'loop::while::i4' => { 1069 desc => 'empty while loop 4 iterations', 1070 setup => 'my $i = 0;', 1071 code => 'while (++$i % 4) {}', 1072 }, 1073 1074]; 1075