1 // Copyright 2015 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <fstream> 6 7 #include "src/v8.h" 8 9 #include "src/compiler.h" 10 #include "src/interpreter/bytecode-array-iterator.h" 11 #include "src/interpreter/bytecode-generator.h" 12 #include "src/interpreter/interpreter.h" 13 #include "test/cctest/cctest.h" 14 #include "test/cctest/interpreter/bytecode-expectations-printer.h" 15 #include "test/cctest/test-feedback-vector.h" 16 17 namespace v8 { 18 namespace internal { 19 namespace interpreter { 20 21 #define XSTR(A) #A 22 #define STR(A) XSTR(A) 23 24 #define UNIQUE_VAR() "var a" STR(__COUNTER__) " = 0;\n" 25 26 #define REPEAT_2(...) __VA_ARGS__ __VA_ARGS__ 27 #define REPEAT_4(...) REPEAT_2(__VA_ARGS__) REPEAT_2(__VA_ARGS__) 28 #define REPEAT_8(...) REPEAT_4(__VA_ARGS__) REPEAT_4(__VA_ARGS__) 29 #define REPEAT_16(...) REPEAT_8(__VA_ARGS__) REPEAT_8(__VA_ARGS__) 30 #define REPEAT_32(...) REPEAT_16(__VA_ARGS__) REPEAT_16(__VA_ARGS__) 31 #define REPEAT_64(...) REPEAT_32(__VA_ARGS__) REPEAT_32(__VA_ARGS__) 32 #define REPEAT_128(...) REPEAT_64(__VA_ARGS__) REPEAT_64(__VA_ARGS__) 33 #define REPEAT_256(...) REPEAT_128(__VA_ARGS__) REPEAT_128(__VA_ARGS__) 34 35 #define REPEAT_127(...) \ 36 REPEAT_64(__VA_ARGS__) \ 37 REPEAT_32(__VA_ARGS__) \ 38 REPEAT_16(__VA_ARGS__) \ 39 REPEAT_8(__VA_ARGS__) \ 40 REPEAT_4(__VA_ARGS__) \ 41 REPEAT_2(__VA_ARGS__) \ 42 __VA_ARGS__ 43 44 #define REPEAT_249(...) \ 45 REPEAT_127(__VA_ARGS__) \ 46 REPEAT_64(__VA_ARGS__) \ 47 REPEAT_32(__VA_ARGS__) \ 48 REPEAT_16(__VA_ARGS__) \ 49 REPEAT_8(__VA_ARGS__) \ 50 REPEAT_2(__VA_ARGS__) 51 52 #define REPEAT_2_UNIQUE_VARS() UNIQUE_VAR() UNIQUE_VAR() 53 #define REPEAT_4_UNIQUE_VARS() REPEAT_2_UNIQUE_VARS() REPEAT_2_UNIQUE_VARS() 54 #define REPEAT_8_UNIQUE_VARS() REPEAT_4_UNIQUE_VARS() REPEAT_4_UNIQUE_VARS() 55 #define REPEAT_16_UNIQUE_VARS() REPEAT_8_UNIQUE_VARS() REPEAT_8_UNIQUE_VARS() 56 #define REPEAT_32_UNIQUE_VARS() REPEAT_16_UNIQUE_VARS() REPEAT_16_UNIQUE_VARS() 57 #define REPEAT_64_UNIQUE_VARS() REPEAT_32_UNIQUE_VARS() REPEAT_32_UNIQUE_VARS() 58 #define REPEAT_128_UNIQUE_VARS() REPEAT_64_UNIQUE_VARS() REPEAT_64_UNIQUE_VARS() 59 60 #define REPEAT_249_UNIQUE_VARS() \ 61 REPEAT_128_UNIQUE_VARS() \ 62 REPEAT_64_UNIQUE_VARS() \ 63 REPEAT_32_UNIQUE_VARS() \ 64 REPEAT_16_UNIQUE_VARS() \ 65 REPEAT_8_UNIQUE_VARS() \ 66 UNIQUE_VAR() 67 68 static const char* kGoldenFileDirectory = 69 "test/cctest/interpreter/bytecode_expectations/"; 70 71 class InitializedIgnitionHandleScope : public InitializedHandleScope { 72 public: 73 InitializedIgnitionHandleScope() { 74 i::FLAG_ignition = true; 75 i::FLAG_always_opt = false; 76 i::FLAG_allow_natives_syntax = true; 77 CcTest::i_isolate()->interpreter()->Initialize(); 78 } 79 }; 80 81 void SkipGoldenFileHeader(std::istream& stream) { // NOLINT 82 std::string line; 83 int separators_seen = 0; 84 while (std::getline(stream, line)) { 85 if (line == "---") separators_seen += 1; 86 if (separators_seen == 2) return; 87 } 88 } 89 90 std::string LoadGolden(const std::string& golden_filename) { 91 std::ifstream expected_file((kGoldenFileDirectory + golden_filename).c_str()); 92 CHECK(expected_file.is_open()); 93 SkipGoldenFileHeader(expected_file); 94 std::ostringstream expected_stream; 95 // Restore the first separator, which was consumed by SkipGoldenFileHeader 96 expected_stream << "---\n" << expected_file.rdbuf(); 97 return expected_stream.str(); 98 } 99 100 template <size_t N> 101 std::string BuildActual(const BytecodeExpectationsPrinter& printer, 102 const char* (&snippet_list)[N], 103 const char* prologue = nullptr, 104 const char* epilogue = nullptr) { 105 std::ostringstream actual_stream; 106 for (const char* snippet : snippet_list) { 107 std::string source_code; 108 if (prologue) source_code += prologue; 109 source_code += snippet; 110 if (epilogue) source_code += epilogue; 111 printer.PrintExpectation(actual_stream, source_code); 112 } 113 return actual_stream.str(); 114 } 115 116 bool CompareTexts(const std::string& generated, const std::string& expected) { 117 std::istringstream generated_stream(generated); 118 std::istringstream expected_stream(expected); 119 std::string generated_line; 120 std::string expected_line; 121 // Line number does not include golden file header. 122 int line_number = 0; 123 124 do { 125 std::getline(generated_stream, generated_line); 126 std::getline(expected_stream, expected_line); 127 128 if (!generated_stream.good() && !expected_stream.good()) { 129 return true; 130 } 131 132 if (!generated_stream.good()) { 133 std::cerr << "Expected has extra lines after line " << line_number 134 << "\n"; 135 std::cerr << " Expected: '" << expected_line << "'\n"; 136 return false; 137 } else if (!expected_stream.good()) { 138 std::cerr << "Generated has extra lines after line " << line_number 139 << "\n"; 140 std::cerr << " Generated: '" << generated_line << "'\n"; 141 return false; 142 } 143 144 if (generated_line != expected_line) { 145 std::cerr << "Inputs differ at line " << line_number << "\n"; 146 std::cerr << " Generated: '" << generated_line << "'\n"; 147 std::cerr << " Expected: '" << expected_line << "'\n"; 148 return false; 149 } 150 line_number++; 151 } while (true); 152 } 153 154 using ConstantPoolType = BytecodeExpectationsPrinter::ConstantPoolType; 155 156 TEST(PrimitiveReturnStatements) { 157 InitializedIgnitionHandleScope scope; 158 BytecodeExpectationsPrinter printer(CcTest::isolate(), 159 ConstantPoolType::kNumber); 160 const char* snippets[] = { 161 "", 162 163 "return;\n", 164 165 "return null;\n", 166 167 "return true;\n", 168 169 "return false;\n", 170 171 "return 0;\n", 172 173 "return +1;\n", 174 175 "return -1;\n", 176 177 "return +127;\n", 178 179 "return -128;\n", 180 }; 181 182 CHECK(CompareTexts(BuildActual(printer, snippets), 183 LoadGolden("PrimitiveReturnStatements.golden"))); 184 } 185 186 TEST(PrimitiveExpressions) { 187 InitializedIgnitionHandleScope scope; 188 BytecodeExpectationsPrinter printer(CcTest::isolate(), 189 ConstantPoolType::kNumber); 190 const char* snippets[] = { 191 "var x = 0; return x;\n", 192 193 "var x = 0; return x + 3;\n", 194 195 "var x = 0; return x - 3;\n", 196 197 "var x = 4; return x * 3;\n", 198 199 "var x = 4; return x / 3;\n", 200 201 "var x = 4; return x % 3;\n", 202 203 "var x = 1; return x | 2;\n", 204 205 "var x = 1; return x ^ 2;\n", 206 207 "var x = 1; return x & 2;\n", 208 209 "var x = 10; return x << 3;\n", 210 211 "var x = 10; return x >> 3;\n", 212 213 "var x = 10; return x >>> 3;\n", 214 215 "var x = 0; return (x, 3);\n", 216 }; 217 218 CHECK(CompareTexts(BuildActual(printer, snippets), 219 LoadGolden("PrimitiveExpressions.golden"))); 220 } 221 222 TEST(LogicalExpressions) { 223 InitializedIgnitionHandleScope scope; 224 BytecodeExpectationsPrinter printer(CcTest::isolate(), 225 ConstantPoolType::kNumber); 226 const char* snippets[] = { 227 "var x = 0; return x || 3;\n", 228 229 "var x = 0; return (x == 1) || 3;\n", 230 231 "var x = 0; return x && 3;\n", 232 233 "var x = 0; return (x == 0) && 3;\n", 234 235 "var x = 0; return x || (1, 2, 3);\n", 236 237 "var a = 2, b = 3, c = 4; return a || (a, b, a, b, c = 5, 3);\n", 238 239 "var x = 1; var a = 2, b = 3; return x || (" // 240 REPEAT_32("\n a = 1, b = 2, ") // 241 "3);\n", 242 243 "var x = 0; var a = 2, b = 3; return x && (" // 244 REPEAT_32("\n a = 1, b = 2, ") // 245 "3);\n", 246 247 "var x = 1; var a = 2, b = 3; return (x > 3) || (" // 248 REPEAT_32("\n a = 1, b = 2, ") // 249 "3);\n", 250 251 "var x = 0; var a = 2, b = 3; return (x < 5) && (" // 252 REPEAT_32("\n a = 1, b = 2, ") // 253 "3);\n", 254 255 "return 0 && 3;\n", 256 257 "return 1 || 3;\n", 258 259 "var x = 1; return x && 3 || 0, 1;\n", 260 }; 261 262 CHECK(CompareTexts(BuildActual(printer, snippets), 263 LoadGolden("LogicalExpressions.golden"))); 264 } 265 266 TEST(Parameters) { 267 InitializedIgnitionHandleScope scope; 268 BytecodeExpectationsPrinter printer(CcTest::isolate(), 269 ConstantPoolType::kNumber); 270 printer.set_wrap(false); 271 printer.set_test_function_name("f"); 272 273 const char* snippets[] = { 274 "function f() { return this; }", 275 276 "function f(arg1) { return arg1; }", 277 278 "function f(arg1) { return this; }", 279 280 "function f(arg1, arg2, arg3, arg4, arg5, arg6, arg7) { return arg4; }", 281 282 "function f(arg1, arg2, arg3, arg4, arg5, arg6, arg7) { return this; }", 283 284 "function f(arg1) { arg1 = 1; }", 285 286 "function f(arg1, arg2, arg3, arg4) { arg2 = 1; }", 287 }; 288 289 CHECK(CompareTexts(BuildActual(printer, snippets, "", "\nf();"), 290 LoadGolden("Parameters.golden"))); 291 } 292 293 TEST(IntegerConstants) { 294 InitializedIgnitionHandleScope scope; 295 BytecodeExpectationsPrinter printer(CcTest::isolate(), 296 ConstantPoolType::kNumber); 297 const char* snippets[] = { 298 "return 12345678;\n", 299 300 "var a = 1234; return 5678;\n", 301 302 "var a = 1234; return 1234;\n", 303 }; 304 305 CHECK(CompareTexts(BuildActual(printer, snippets), 306 LoadGolden("IntegerConstants.golden"))); 307 } 308 309 TEST(HeapNumberConstants) { 310 InitializedIgnitionHandleScope scope; 311 BytecodeExpectationsPrinter printer(CcTest::isolate(), 312 ConstantPoolType::kNumber); 313 const char* snippets[] = { 314 "return 1.2;\n", 315 316 "var a = 1.2; return 2.6;\n", 317 318 "var a = 3.14; return 3.14;\n", 319 320 "var a;" // 321 REPEAT_256("\na = 1.414;") // 322 " a = 3.14;\n", 323 }; 324 325 CHECK(CompareTexts(BuildActual(printer, snippets), 326 LoadGolden("HeapNumberConstants.golden"))); 327 } 328 329 TEST(StringConstants) { 330 InitializedIgnitionHandleScope scope; 331 BytecodeExpectationsPrinter printer(CcTest::isolate(), 332 ConstantPoolType::kString); 333 const char* snippets[] = { 334 "return \"This is a string\";\n", 335 336 "var a = \"First string\"; return \"Second string\";\n", 337 338 "var a = \"Same string\"; return \"Same string\";\n", 339 }; 340 341 CHECK(CompareTexts(BuildActual(printer, snippets), 342 LoadGolden("StringConstants.golden"))); 343 } 344 345 TEST(PropertyLoads) { 346 InitializedIgnitionHandleScope scope; 347 BytecodeExpectationsPrinter printer(CcTest::isolate(), 348 ConstantPoolType::kString); 349 printer.set_wrap(false); 350 printer.set_test_function_name("f"); 351 352 const char* snippets[] = { 353 "function f(a) { return a.name; }\n" 354 "f({name : \"test\"});\n", 355 356 "function f(a) { return a[\"key\"]; }\n" 357 "f({key : \"test\"});\n", 358 359 "function f(a) { return a[100]; }\n" 360 "f({100 : \"test\"});\n", 361 362 "function f(a, b) { return a[b]; }\n" 363 "f({arg : \"test\"}, \"arg\");\n", 364 365 "function f(a) { var b = a.name; return a[-124]; }\n" 366 "f({\"-124\" : \"test\", name : 123 })", 367 368 "function f(a) {\n" 369 " var b;\n" 370 " b = a.name;\n" 371 REPEAT_127(" b = a.name;\n") 372 " return a.name;\n" 373 "}\n" 374 "f({name : \"test\"})\n", 375 376 "function f(a, b) {\n" 377 " var c;\n" 378 " c = a[b];\n" 379 REPEAT_127(" c = a[b];\n") 380 " return a[b];\n" 381 "}\n" 382 "f({name : \"test\"}, \"name\")\n", 383 }; 384 385 CHECK(CompareTexts(BuildActual(printer, snippets), 386 LoadGolden("PropertyLoads.golden"))); 387 } 388 389 TEST(PropertyStores) { 390 InitializedIgnitionHandleScope scope; 391 BytecodeExpectationsPrinter printer(CcTest::isolate(), 392 ConstantPoolType::kString); 393 printer.set_wrap(false); 394 printer.set_test_function_name("f"); 395 396 const char* snippets[] = { 397 "function f(a) { a.name = \"val\"; }\n" 398 "f({name : \"test\"})", 399 400 "function f(a) { a[\"key\"] = \"val\"; }\n" 401 "f({key : \"test\"})", 402 403 "function f(a) { a[100] = \"val\"; }\n" 404 "f({100 : \"test\"})", 405 406 "function f(a, b) { a[b] = \"val\"; }\n" 407 "f({arg : \"test\"}, \"arg\")", 408 409 "function f(a) { a.name = a[-124]; }\n" 410 "f({\"-124\" : \"test\", name : 123 })", 411 412 "function f(a) { \"use strict\"; a.name = \"val\"; }\n" 413 "f({name : \"test\"})", 414 415 "function f(a, b) { \"use strict\"; a[b] = \"val\"; }\n" 416 "f({arg : \"test\"}, \"arg\")", 417 418 "function f(a) {\n" 419 " a.name = 1;\n" 420 REPEAT_127(" a.name = 1;\n") 421 " a.name = 2;\n" 422 "}\n" 423 "f({name : \"test\"})\n", 424 425 "function f(a) {\n" 426 " 'use strict';\n" 427 " a.name = 1;\n" 428 REPEAT_127(" a.name = 1;\n") 429 " a.name = 2;\n" 430 "}\n" 431 "f({name : \"test\"})\n", 432 433 "function f(a, b) {\n" 434 " a[b] = 1;\n" 435 REPEAT_127(" a[b] = 1;\n") 436 " a[b] = 2;\n" 437 "}\n" 438 "f({name : \"test\"})\n", 439 440 "function f(a, b) {\n" 441 " 'use strict';\n" 442 " a[b] = 1;\n" 443 REPEAT_127(" a[b] = 1;\n") 444 " a[b] = 2;\n" 445 "}\n" 446 "f({name : \"test\"})\n", 447 }; 448 449 CHECK(CompareTexts(BuildActual(printer, snippets), 450 LoadGolden("PropertyStores.golden"))); 451 } 452 453 #define FUNC_ARG "new (function Obj() { this.func = function() { return; }})()" 454 455 TEST(PropertyCall) { 456 InitializedIgnitionHandleScope scope; 457 BytecodeExpectationsPrinter printer(CcTest::isolate(), 458 ConstantPoolType::kString); 459 printer.set_wrap(false); 460 printer.set_test_function_name("f"); 461 462 const char* snippets[] = { 463 "function f(a) { return a.func(); }\n" 464 "f(" FUNC_ARG ")", 465 466 "function f(a, b, c) { return a.func(b, c); }\n" 467 "f(" FUNC_ARG ", 1, 2)", 468 469 "function f(a, b) { return a.func(b + b, b); }\n" 470 "f(" FUNC_ARG ", 1)", 471 472 "function f(a) {\n" 473 " a.func;\n" // 474 REPEAT_127(" a.func;\n") // 475 " return a.func(); }\n" 476 "f(" FUNC_ARG ")", 477 }; 478 479 CHECK(CompareTexts(BuildActual(printer, snippets), 480 LoadGolden("PropertyCall.golden"))); 481 } 482 483 TEST(LoadGlobal) { 484 InitializedIgnitionHandleScope scope; 485 BytecodeExpectationsPrinter printer(CcTest::isolate(), 486 ConstantPoolType::kString); 487 printer.set_wrap(false); 488 printer.set_test_function_name("f"); 489 490 const char* snippets[] = { 491 "var a = 1;\n" 492 "function f() { return a; }\n" 493 "f()", 494 495 "function t() { }\n" 496 "function f() { return t; }\n" 497 "f()", 498 499 "a = 1;\n" 500 "function f() { return a; }\n" 501 "f()", 502 503 "a = 1;\n" 504 "function f(b) {\n" 505 " b.name;\n" 506 REPEAT_127(" b.name;\n") 507 " return a;\n" 508 "}\n" 509 "f({name: 1});\n", 510 }; 511 512 CHECK(CompareTexts(BuildActual(printer, snippets), 513 LoadGolden("LoadGlobal.golden"))); 514 } 515 516 TEST(StoreGlobal) { 517 InitializedIgnitionHandleScope scope; 518 BytecodeExpectationsPrinter printer(CcTest::isolate(), 519 ConstantPoolType::kString); 520 printer.set_wrap(false); 521 printer.set_test_function_name("f"); 522 523 const char* snippets[] = { 524 "var a = 1;\n" 525 "function f() { a = 2; }\n" 526 "f();\n", 527 528 "var a = \"test\"; function f(b) { a = b; }\n" 529 "f(\"global\");\n", 530 531 "'use strict'; var a = 1;\n" 532 "function f() { a = 2; }\n" 533 "f();\n", 534 535 "a = 1;\n" 536 "function f() { a = 2; }\n" 537 "f();\n", 538 539 "a = 1;\n" 540 "function f(b) {\n" 541 " b.name;\n" 542 REPEAT_127(" b.name;\n") 543 " a = 2;\n" 544 "}\n" 545 "f({name: 1});\n", 546 547 "a = 1;\n" 548 "function f(b) {\n" 549 " 'use strict';\n" 550 " b.name;\n" 551 REPEAT_127(" b.name;\n") 552 " a = 2;\n" 553 "}\n" 554 "f({name: 1});\n", 555 }; 556 557 CHECK(CompareTexts(BuildActual(printer, snippets), 558 LoadGolden("StoreGlobal.golden"))); 559 } 560 561 TEST(CallGlobal) { 562 InitializedIgnitionHandleScope scope; 563 BytecodeExpectationsPrinter printer(CcTest::isolate(), 564 ConstantPoolType::kString); 565 printer.set_wrap(false); 566 printer.set_test_function_name("f"); 567 568 const char* snippets[] = { 569 "function t() { }\n" 570 "function f() { return t(); }\n" 571 "f();\n", 572 573 "function t(a, b, c) { }\n" 574 "function f() { return t(1, 2, 3); }\n" 575 "f();\n", 576 }; 577 578 CHECK(CompareTexts(BuildActual(printer, snippets), 579 LoadGolden("CallGlobal.golden"))); 580 } 581 582 TEST(CallRuntime) { 583 InitializedIgnitionHandleScope scope; 584 BytecodeExpectationsPrinter printer(CcTest::isolate(), 585 ConstantPoolType::kMixed); 586 printer.set_wrap(false); 587 printer.set_test_function_name("f"); 588 589 const char* snippets[] = { 590 "function f() { %TheHole() }\n" 591 "f();\n", 592 593 "function f(a) { return %IsArray(a) }\n" 594 "f(undefined);\n", 595 596 "function f() { return %Add(1, 2) }\n" 597 "f();\n", 598 599 "function f() { return %spread_iterable([1]) }\n" 600 "f();\n", 601 }; 602 603 CHECK(CompareTexts(BuildActual(printer, snippets), 604 LoadGolden("CallRuntime.golden"))); 605 } 606 607 TEST(IfConditions) { 608 InitializedIgnitionHandleScope scope; 609 BytecodeExpectationsPrinter printer(CcTest::isolate(), 610 ConstantPoolType::kMixed); 611 printer.set_wrap(false); 612 printer.set_test_function_name("f"); 613 614 const char* snippets[] = { 615 "function f() {\n" 616 " if (0) {\n" 617 " return 1;\n" 618 " } else {\n" 619 " return -1;\n" 620 " }\n" 621 "};\n" 622 "f();\n", 623 624 "function f() {\n" 625 " if ('lucky') {\n" 626 " return 1;\n" 627 " } else {\n" 628 " return -1;\n" 629 " }\n" 630 "};\n" 631 "f();\n", 632 633 "function f() {\n" 634 " if (false) {\n" 635 " return 1;\n" 636 " } else {\n" 637 " return -1;\n" 638 " }\n" 639 "};\n" 640 "f();\n", 641 642 "function f() {\n" 643 " if (false) {\n" 644 " return 1;\n" 645 " }\n" 646 "};\n" 647 "f();\n", 648 649 "function f() {\n" 650 " var a = 1;\n" 651 " if (a) {\n" 652 " a += 1;\n" 653 " } else {\n" 654 " return 2;\n" 655 " }\n" 656 "};\n" 657 "f();\n", 658 659 "function f(a) {\n" 660 " if (a <= 0) {\n" 661 " return 200;\n" 662 " } else {\n" 663 " return -200;\n" 664 " }\n" 665 "};\n" 666 "f(99);\n", 667 668 "function f(a, b) { if (a in b) { return 200; } }" 669 "f('prop', { prop: 'yes'});\n", 670 671 "function f(z) { var a = 0; var b = 0; if (a === 0.01) {\n" 672 REPEAT_64(" b = a; a = b;\n") 673 " return 200; } else { return -200; } } f(0.001);\n", 674 675 "function f() {\n" 676 " var a = 0; var b = 0;\n" 677 " if (a) {\n" 678 REPEAT_64(" b = a; a = b;\n") 679 " return 200; } else { return -200; }\n" 680 "};\n" 681 "f();\n", 682 683 "function f(a, b) {\n" 684 " if (a == b) { return 1; }\n" 685 " if (a === b) { return 1; }\n" 686 " if (a < b) { return 1; }\n" 687 " if (a > b) { return 1; }\n" 688 " if (a <= b) { return 1; }\n" 689 " if (a >= b) { return 1; }\n" 690 " if (a in b) { return 1; }\n" 691 " if (a instanceof b) { return 1; }\n" 692 " return 0;\n" 693 "}\n" 694 "f(1, 1);\n", 695 696 "function f() {\n" 697 " var a = 0;\n" 698 " if (a) {\n" 699 " return 20;\n" 700 " } else {\n" 701 " return -20;\n" 702 " }\n" 703 "};\n" 704 "f();\n", 705 }; 706 707 CHECK(CompareTexts(BuildActual(printer, snippets), 708 LoadGolden("IfConditions.golden"))); 709 } 710 711 TEST(DeclareGlobals) { 712 InitializedIgnitionHandleScope scope; 713 BytecodeExpectationsPrinter printer(CcTest::isolate(), 714 ConstantPoolType::kMixed); 715 printer.set_wrap(false); 716 printer.set_test_function_name("f"); 717 printer.set_execute(false); 718 printer.set_top_level(true); 719 720 const char* snippets[] = { 721 "var a = 1;\n", 722 723 "function f() {}\n", 724 725 "var a = 1;\n" 726 "a=2;\n", 727 728 "function f() {}\n" 729 "f();\n", 730 }; 731 732 CHECK(CompareTexts(BuildActual(printer, snippets), 733 LoadGolden("DeclareGlobals.golden"))); 734 } 735 736 TEST(BreakableBlocks) { 737 InitializedIgnitionHandleScope scope; 738 BytecodeExpectationsPrinter printer(CcTest::isolate(), 739 ConstantPoolType::kMixed); 740 741 const char* snippets[] = { 742 "var x = 0;\n" 743 "label: {\n" 744 " x = x + 1;\n" 745 " break label;\n" 746 " x = x + 1;\n" 747 "}\n" 748 "return x;\n", 749 750 "var sum = 0;\n" 751 "outer: {\n" 752 " for (var x = 0; x < 10; ++x) {\n" 753 " for (var y = 0; y < 3; ++y) {\n" 754 " ++sum;\n" 755 " if (x + y == 12) { break outer; }\n" 756 " }\n" 757 " }\n" 758 "}\n" 759 "return sum;\n", 760 761 "outer: {\n" 762 " let y = 10;\n" 763 " function f() { return y; }\n" 764 " break outer;\n" 765 "}\n", 766 767 "let x = 1;\n" 768 "outer: {\n" 769 " inner: {\n" 770 " let y = 2;\n" 771 " function f() { return x + y; }\n" 772 " if (y) break outer;\n" 773 " y = 3;\n" 774 " }\n" 775 "}\n" 776 "x = 4;\n", 777 }; 778 779 CHECK(CompareTexts(BuildActual(printer, snippets), 780 LoadGolden("BreakableBlocks.golden"))); 781 } 782 783 TEST(BasicLoops) { 784 InitializedIgnitionHandleScope scope; 785 BytecodeExpectationsPrinter printer(CcTest::isolate(), 786 ConstantPoolType::kMixed); 787 const char* snippets[] = { 788 "var x = 0;\n" 789 "while (false) { x = 99; break; continue; }\n" 790 "return x;\n", 791 792 "var x = 0;\n" 793 "while (false) {\n" 794 " x = x + 1;\n" 795 "};\n" 796 "return x;\n", 797 798 "var x = 0;\n" 799 "var y = 1;\n" 800 "while (x < 10) {\n" 801 " y = y * 12;\n" 802 " x = x + 1;\n" 803 " if (x == 3) continue;\n" 804 " if (x == 4) break;\n" 805 "}\n" 806 "return y;\n", 807 808 "var i = 0;\n" 809 "while (true) {\n" 810 " if (i < 0) continue;\n" 811 " if (i == 3) break;\n" 812 " if (i == 4) break;\n" 813 " if (i == 10) continue;\n" 814 " if (i == 5) break;\n" 815 " i = i + 1;\n" 816 "}\n" 817 "return i;\n", 818 819 "var i = 0;\n" 820 "while (true) {\n" 821 " while (i < 3) {\n" 822 " if (i == 2) break;\n" 823 " i = i + 1;\n" 824 " }\n" 825 " i = i + 1;\n" 826 " break;\n" 827 "}\n" 828 "return i;\n", 829 830 "var x = 10;\n" 831 "var y = 1;\n" 832 "while (x) {\n" 833 " y = y * 12;\n" 834 " x = x - 1;\n" 835 "}\n" 836 "return y;\n", 837 838 "var x = 0; var y = 1;\n" 839 "do {\n" 840 " y = y * 10;\n" 841 " if (x == 5) break;\n" 842 " if (x == 6) continue;\n" 843 " x = x + 1;\n" 844 "} while (x < 10);\n" 845 "return y;\n", 846 847 "var x = 10;\n" 848 "var y = 1;\n" 849 "do {\n" 850 " y = y * 12;\n" 851 " x = x - 1;\n" 852 "} while (x);\n" 853 "return y;\n", 854 855 "var x = 0; var y = 1;\n" 856 "do {\n" 857 " y = y * 10;\n" 858 " if (x == 5) break;\n" 859 " x = x + 1;\n" 860 " if (x == 6) continue;\n" 861 "} while (false);\n" 862 "return y;\n", 863 864 "var x = 0; var y = 1;\n" 865 "do {\n" 866 " y = y * 10;\n" 867 " if (x == 5) break;\n" 868 " x = x + 1;\n" 869 " if (x == 6) continue;\n" 870 "} while (true);\n" 871 "return y;\n", 872 873 "var x = 0;\n" 874 "for (;;) {\n" 875 " if (x == 1) break;\n" 876 " if (x == 2) continue;\n" 877 " x = x + 1;\n" 878 "}\n", 879 880 "for (var x = 0;;) {\n" 881 " if (x == 1) break;\n" 882 " if (x == 2) continue;\n" 883 " x = x + 1;\n" 884 "}\n", 885 886 "var x = 0;\n" 887 "for (;; x = x + 1) {\n" 888 " if (x == 1) break;\n" 889 " if (x == 2) continue;\n" 890 "}\n", 891 892 "for (var x = 0;; x = x + 1) {\n" 893 " if (x == 1) break;\n" 894 " if (x == 2) continue;\n" 895 "}\n", 896 897 "var u = 0;\n" 898 "for (var i = 0; i < 100; i = i + 1) {\n" 899 " u = u + 1;\n" 900 " continue;\n" 901 "}\n", 902 903 "var y = 1;\n" 904 "for (var x = 10; x; --x) {\n" 905 " y = y * 12;\n" 906 "}\n" 907 "return y;\n", 908 909 "var x = 0;\n" 910 "for (var i = 0; false; i++) {\n" 911 " x = x + 1;\n" 912 "};\n" 913 "return x;\n", 914 915 "var x = 0;\n" 916 "for (var i = 0; true; ++i) {\n" 917 " x = x + 1;\n" 918 " if (x == 20) break;\n" 919 "};\n" 920 "return x;\n", 921 922 "var a = 0;\n" 923 "while (a) {\n" 924 " { \n" 925 " let z = 1;\n" 926 " function f() { z = 2; }\n" 927 " if (z) continue;\n" 928 " z++;\n" 929 " }\n" 930 "}\n", 931 }; 932 933 CHECK(CompareTexts(BuildActual(printer, snippets), 934 LoadGolden("BasicLoops.golden"))); 935 } 936 937 TEST(JumpsRequiringConstantWideOperands) { 938 InitializedIgnitionHandleScope scope; 939 BytecodeExpectationsPrinter printer(CcTest::isolate(), 940 ConstantPoolType::kNumber); 941 const char* snippets[] = { 942 REPEAT_256("var x = 0.1;\n") 943 REPEAT_32("var x = 0.2;\n") 944 REPEAT_16("var x = 0.3;\n") 945 REPEAT_8("var x = 0.4;\n") 946 "for (var i = 0; i < 3; i++) {\n" 947 " if (i == 1) continue;\n" 948 " if (i == 2) break;\n" 949 "}\n" 950 "return 3;\n", 951 }; 952 953 CHECK(CompareTexts(BuildActual(printer, snippets), 954 LoadGolden("JumpsRequiringConstantWideOperands.golden"))); 955 } 956 957 TEST(UnaryOperators) { 958 InitializedIgnitionHandleScope scope; 959 BytecodeExpectationsPrinter printer(CcTest::isolate(), 960 ConstantPoolType::kNumber); 961 const char* snippets[] = { 962 "var x = 0;\n" 963 "while (x != 10) {\n" 964 " x = x + 10;\n" 965 "}\n" 966 "return x;\n", 967 968 "var x = false;\n" 969 "do {\n" 970 " x = !x;\n" 971 "} while(x == false);\n" 972 "return x;\n", 973 974 "var x = 101;\n" 975 "return void(x * 3);\n", 976 977 "var x = 1234;\n" 978 "var y = void (x * x - 1);\n" 979 "return y;\n", 980 981 "var x = 13;\n" 982 "return ~x;\n", 983 984 "var x = 13;\n" 985 "return +x;\n", 986 987 "var x = 13;\n" 988 "return -x;\n", 989 }; 990 991 CHECK(CompareTexts(BuildActual(printer, snippets), 992 LoadGolden("UnaryOperators.golden"))); 993 } 994 995 TEST(Typeof) { 996 InitializedIgnitionHandleScope scope; 997 BytecodeExpectationsPrinter printer(CcTest::isolate(), 998 ConstantPoolType::kString); 999 printer.set_wrap(false); 1000 printer.set_test_function_name("f"); 1001 1002 const char* snippets[] = { 1003 "function f() {\n" 1004 " var x = 13;\n" 1005 " return typeof(x);\n" 1006 "};", 1007 1008 "var x = 13;\n" 1009 "function f() {\n" 1010 " return typeof(x);\n" 1011 "};", 1012 }; 1013 1014 CHECK(CompareTexts(BuildActual(printer, snippets, "", "\nf();"), 1015 LoadGolden("Typeof.golden"))); 1016 } 1017 1018 TEST(Delete) { 1019 InitializedIgnitionHandleScope scope; 1020 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1021 ConstantPoolType::kMixed); 1022 1023 const char* snippets[] = { 1024 "var a = {x:13, y:14}; return delete a.x;\n", 1025 1026 "'use strict'; var a = {x:13, y:14}; return delete a.x;\n", 1027 1028 "var a = {1:13, 2:14}; return delete a[2];\n", 1029 1030 "var a = 10; return delete a;\n", 1031 1032 "'use strict';\n" 1033 "var a = {1:10};\n" 1034 "(function f1() {return a;});\n" 1035 "return delete a[1];\n", 1036 1037 "return delete 'test';\n", 1038 }; 1039 1040 CHECK(CompareTexts(BuildActual(printer, snippets), 1041 LoadGolden("Delete.golden"))); 1042 } 1043 1044 TEST(GlobalDelete) { 1045 InitializedIgnitionHandleScope scope; 1046 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1047 ConstantPoolType::kMixed); 1048 printer.set_wrap(false); 1049 printer.set_test_function_name("f"); 1050 1051 const char* snippets[] = { 1052 "var a = {x:13, y:14};\n" 1053 "function f() {\n" 1054 " return delete a.x;\n" 1055 "};\n" 1056 "f();\n", 1057 1058 "a = {1:13, 2:14};\n" 1059 "function f() {\n" 1060 " 'use strict';\n" 1061 " return delete a[1];\n" 1062 "};\n" 1063 "f();\n", 1064 1065 "var a = {x:13, y:14};\n" 1066 "function f() {\n" 1067 " return delete a;\n" 1068 "};\n" 1069 "f();\n", 1070 1071 "b = 30;\n" 1072 "function f() {\n" 1073 " return delete b;\n" 1074 "};\n" 1075 "f();\n", 1076 }; 1077 1078 CHECK(CompareTexts(BuildActual(printer, snippets), 1079 LoadGolden("GlobalDelete.golden"))); 1080 } 1081 1082 TEST(FunctionLiterals) { 1083 InitializedIgnitionHandleScope scope; 1084 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1085 ConstantPoolType::kMixed); 1086 1087 const char* snippets[] = { 1088 "return function(){ }\n", 1089 1090 "return (function(){ })()\n", 1091 1092 "return (function(x){ return x; })(1)\n", 1093 }; 1094 1095 CHECK(CompareTexts(BuildActual(printer, snippets), 1096 LoadGolden("FunctionLiterals.golden"))); 1097 } 1098 1099 TEST(RegExpLiterals) { 1100 InitializedIgnitionHandleScope scope; 1101 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1102 ConstantPoolType::kString); 1103 1104 const char* snippets[] = { 1105 "return /ab+d/;\n", 1106 1107 "return /(\\w+)\\s(\\w+)/i;\n", 1108 1109 "return /ab+d/.exec('abdd');\n", 1110 }; 1111 1112 CHECK(CompareTexts(BuildActual(printer, snippets), 1113 LoadGolden("RegExpLiterals.golden"))); 1114 } 1115 1116 TEST(RegExpLiteralsWide) { 1117 InitializedIgnitionHandleScope scope; 1118 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1119 ConstantPoolType::kMixed); 1120 1121 const char* snippets[] = { 1122 "var a;" // 1123 REPEAT_256("\na = 1.23;") // 1124 "\nreturn /ab+d/;\n", 1125 }; 1126 1127 CHECK(CompareTexts(BuildActual(printer, snippets), 1128 LoadGolden("RegExpLiteralsWide.golden"))); 1129 } 1130 1131 TEST(ArrayLiterals) { 1132 InitializedIgnitionHandleScope scope; 1133 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1134 ConstantPoolType::kMixed); 1135 1136 const char* snippets[] = { 1137 "return [ 1, 2 ];\n", 1138 1139 "var a = 1; return [ a, a + 1 ];\n", 1140 1141 "return [ [ 1, 2 ], [ 3 ] ];\n", 1142 1143 "var a = 1; return [ [ a, 2 ], [ a + 2 ] ];\n", 1144 }; 1145 1146 CHECK(CompareTexts(BuildActual(printer, snippets), 1147 LoadGolden("ArrayLiterals.golden"))); 1148 } 1149 1150 TEST(ArrayLiteralsWide) { 1151 InitializedIgnitionHandleScope scope; 1152 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1153 ConstantPoolType::kMixed); 1154 1155 const char* snippets[] = { 1156 "var a;" // 1157 REPEAT_256("\na = 1.23;") // 1158 "\nreturn [ 1 , 2 ];\n", 1159 }; 1160 1161 CHECK(CompareTexts(BuildActual(printer, snippets), 1162 LoadGolden("ArrayLiteralsWide.golden"))); 1163 } 1164 1165 TEST(ObjectLiterals) { 1166 InitializedIgnitionHandleScope scope; 1167 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1168 ConstantPoolType::kMixed); 1169 1170 const char* snippets[] = { 1171 "return { };\n", 1172 1173 "return { name: 'string', val: 9.2 };\n", 1174 1175 "var a = 1; return { name: 'string', val: a };\n", 1176 1177 "var a = 1; return { val: a, val: a + 1 };\n", 1178 1179 "return { func: function() { } };\n", 1180 1181 "return { func(a) { return a; } };\n", 1182 1183 "return { get a() { return 2; } };\n", 1184 1185 "return { get a() { return this.x; }, set a(val) { this.x = val } };\n", 1186 1187 "return { set b(val) { this.y = val } };\n", 1188 1189 "var a = 1; return { 1: a };\n", 1190 1191 "return { __proto__: null };\n", 1192 1193 "var a = 'test'; return { [a]: 1 };\n", 1194 1195 "var a = 'test'; return { val: a, [a]: 1 };\n", 1196 1197 "var a = 'test'; return { [a]: 1, __proto__: {} };\n", 1198 1199 "var n = 'name'; return { [n]: 'val', get a() { }, set a(b) {} };\n", 1200 }; 1201 1202 CHECK(CompareTexts(BuildActual(printer, snippets), 1203 LoadGolden("ObjectLiterals.golden"))); 1204 } 1205 1206 TEST(ObjectLiteralsWide) { 1207 InitializedIgnitionHandleScope scope; 1208 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1209 ConstantPoolType::kMixed); 1210 const char* snippets[] = { 1211 "var a;" // 1212 REPEAT_256("\na = 1.23;") // 1213 "\nreturn { name: 'string', val: 9.2 };\n", 1214 }; 1215 1216 CHECK(CompareTexts(BuildActual(printer, snippets), 1217 LoadGolden("ObjectLiteralsWide.golden"))); 1218 } 1219 1220 TEST(TopLevelObjectLiterals) { 1221 InitializedIgnitionHandleScope scope; 1222 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1223 ConstantPoolType::kMixed); 1224 printer.set_wrap(false); 1225 printer.set_test_function_name("f"); 1226 printer.set_execute(false); 1227 printer.set_top_level(true); 1228 1229 const char* snippets[] = { 1230 "var a = { func: function() { } };\n", 1231 }; 1232 1233 CHECK(CompareTexts(BuildActual(printer, snippets), 1234 LoadGolden("TopLevelObjectLiterals.golden"))); 1235 } 1236 1237 TEST(TryCatch) { 1238 InitializedIgnitionHandleScope scope; 1239 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1240 ConstantPoolType::kString); 1241 1242 const char* snippets[] = { 1243 "try { return 1; } catch(e) { return 2; }\n", 1244 1245 "var a;\n" 1246 "try { a = 1 } catch(e1) {};\n" 1247 "try { a = 2 } catch(e2) { a = 3 }\n", 1248 }; 1249 1250 CHECK(CompareTexts(BuildActual(printer, snippets), 1251 LoadGolden("TryCatch.golden"))); 1252 } 1253 1254 TEST(TryFinally) { 1255 InitializedIgnitionHandleScope scope; 1256 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1257 ConstantPoolType::kString); 1258 const char* snippets[] = { 1259 "var a = 1;\n" 1260 "try { a = 2; } finally { a = 3; }\n", 1261 1262 "var a = 1;\n" 1263 "try { a = 2; } catch(e) { a = 20 } finally { a = 3; }\n", 1264 1265 "var a; try {\n" 1266 " try { a = 1 } catch(e) { a = 2 }\n" 1267 "} catch(e) { a = 20 } finally { a = 3; }\n", 1268 }; 1269 1270 CHECK(CompareTexts(BuildActual(printer, snippets), 1271 LoadGolden("TryFinally.golden"))); 1272 } 1273 1274 TEST(Throw) { 1275 InitializedIgnitionHandleScope scope; 1276 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1277 ConstantPoolType::kString); 1278 const char* snippets[] = { 1279 "throw 1;\n", 1280 1281 "throw 'Error';\n", 1282 1283 "var a = 1; if (a) { throw 'Error'; };\n", 1284 }; 1285 1286 CHECK( 1287 CompareTexts(BuildActual(printer, snippets), LoadGolden("Throw.golden"))); 1288 } 1289 1290 TEST(CallNew) { 1291 InitializedIgnitionHandleScope scope; 1292 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1293 ConstantPoolType::kMixed); 1294 printer.set_wrap(false); 1295 printer.set_test_function_name("f"); 1296 1297 const char* snippets[] = { 1298 "function bar() { this.value = 0; }\n" 1299 "function f() { return new bar(); }\n" 1300 "f();\n", 1301 1302 "function bar(x) { this.value = 18; this.x = x;}\n" 1303 "function f() { return new bar(3); }\n" 1304 "f();\n", 1305 1306 "function bar(w, x, y, z) {\n" 1307 " this.value = 18;\n" 1308 " this.x = x;\n" 1309 " this.y = y;\n" 1310 " this.z = z;\n" 1311 "}\n" 1312 "function f() { return new bar(3, 4, 5); }\n" 1313 "f();\n", 1314 }; 1315 1316 CHECK(CompareTexts(BuildActual(printer, snippets), 1317 LoadGolden("CallNew.golden"))); 1318 } 1319 1320 TEST(ContextVariables) { 1321 // The wide check below relies on MIN_CONTEXT_SLOTS + 3 + 249 == 256, if this 1322 // ever changes, the REPEAT_XXX should be changed to output the correct number 1323 // of unique variables to trigger the wide slot load / store. 1324 STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS + 3 + 249 == 256); 1325 1326 InitializedIgnitionHandleScope scope; 1327 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1328 ConstantPoolType::kMixed); 1329 const char* snippets[] = { 1330 "var a; return function() { a = 1; };\n", 1331 1332 "var a = 1; return function() { a = 2; };\n", 1333 1334 "var a = 1; var b = 2; return function() { a = 2; b = 3 };\n", 1335 1336 "var a; (function() { a = 2; })(); return a;\n", 1337 1338 "'use strict';\n" 1339 "let a = 1;\n" 1340 "{ let b = 2; return function() { a + b; }; }\n", 1341 1342 "'use strict';\n" 1343 REPEAT_249_UNIQUE_VARS() 1344 "eval();\n" 1345 "var b = 100;\n" 1346 "return b\n", 1347 }; 1348 1349 CHECK(CompareTexts(BuildActual(printer, snippets), 1350 LoadGolden("ContextVariables.golden"))); 1351 } 1352 1353 TEST(ContextParameters) { 1354 InitializedIgnitionHandleScope scope; 1355 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1356 ConstantPoolType::kMixed); 1357 printer.set_wrap(false); 1358 printer.set_test_function_name("f"); 1359 1360 const char* snippets[] = { 1361 "function f(arg1) { return function() { arg1 = 2; }; }", 1362 1363 "function f(arg1) { var a = function() { arg1 = 2; }; return arg1; }", 1364 1365 "function f(a1, a2, a3, a4) { return function() { a1 = a3; }; }", 1366 1367 "function f() { var self = this; return function() { self = 2; }; }", 1368 }; 1369 1370 CHECK(CompareTexts(BuildActual(printer, snippets, "", "\nf();"), 1371 LoadGolden("ContextParameters.golden"))); 1372 } 1373 1374 TEST(OuterContextVariables) { 1375 InitializedIgnitionHandleScope scope; 1376 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1377 ConstantPoolType::kMixed); 1378 printer.set_wrap(false); 1379 printer.set_test_function_name("f"); 1380 1381 const char* snippets[] = { 1382 "function Outer() {\n" 1383 " var outerVar = 1;\n" 1384 " function Inner(innerArg) {\n" 1385 " this.innerFunc = function() { return outerVar * innerArg; }\n" 1386 " }\n" 1387 " this.getInnerFunc = function() { return new Inner(1).innerFunc; }\n" 1388 "}\n" 1389 "var f = new Outer().getInnerFunc();", 1390 1391 "function Outer() {\n" 1392 " var outerVar = 1;\n" 1393 " function Inner(innerArg) {\n" 1394 " this.innerFunc = function() { outerVar = innerArg; }\n" 1395 " }\n" 1396 " this.getInnerFunc = function() { return new Inner(1).innerFunc; }\n" 1397 "}\n" 1398 "var f = new Outer().getInnerFunc();", 1399 }; 1400 1401 CHECK(CompareTexts(BuildActual(printer, snippets, "", "\nf();"), 1402 LoadGolden("OuterContextVariables.golden"))); 1403 } 1404 1405 TEST(CountOperators) { 1406 InitializedIgnitionHandleScope scope; 1407 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1408 ConstantPoolType::kMixed); 1409 const char* snippets[] = { 1410 "var a = 1; return ++a;\n", 1411 1412 "var a = 1; return a++;\n", 1413 1414 "var a = 1; return --a;\n", 1415 1416 "var a = 1; return a--;\n", 1417 1418 "var a = { val: 1 }; return a.val++;\n", 1419 1420 "var a = { val: 1 }; return --a.val;\n", 1421 1422 "var name = 'var'; var a = { val: 1 }; return a[name]--;\n", 1423 1424 "var name = 'var'; var a = { val: 1 }; return ++a[name];\n", 1425 1426 "var a = 1; var b = function() { return a }; return ++a;\n", 1427 1428 "var a = 1; var b = function() { return a }; return a--;\n", 1429 1430 "var idx = 1; var a = [1, 2]; return a[idx++] = 2;\n", 1431 }; 1432 1433 CHECK(CompareTexts(BuildActual(printer, snippets), 1434 LoadGolden("CountOperators.golden"))); 1435 } 1436 1437 TEST(GlobalCountOperators) { 1438 InitializedIgnitionHandleScope scope; 1439 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1440 ConstantPoolType::kString); 1441 printer.set_wrap(false); 1442 printer.set_test_function_name("f"); 1443 1444 const char* snippets[] = { 1445 "var global = 1;\n" 1446 "function f() { return ++global; }\n" 1447 "f();\n", 1448 1449 "var global = 1;\n" 1450 "function f() { return global--; }\n" 1451 "f();\n", 1452 1453 "unallocated = 1;\n" 1454 "function f() { 'use strict'; return --unallocated; }\n" 1455 "f();\n", 1456 1457 "unallocated = 1;\n" 1458 "function f() { return unallocated++; }\n" 1459 "f();\n", 1460 }; 1461 1462 CHECK(CompareTexts(BuildActual(printer, snippets), 1463 LoadGolden("GlobalCountOperators.golden"))); 1464 } 1465 1466 TEST(CompoundExpressions) { 1467 InitializedIgnitionHandleScope scope; 1468 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1469 ConstantPoolType::kMixed); 1470 const char* snippets[] = { 1471 "var a = 1; a += 2;\n", 1472 1473 "var a = 1; a /= 2;\n", 1474 1475 "var a = { val: 2 }; a.name *= 2;\n", 1476 1477 "var a = { 1: 2 }; a[1] ^= 2;\n", 1478 1479 "var a = 1; (function f() { return a; }); a |= 24;\n", 1480 }; 1481 1482 CHECK(CompareTexts(BuildActual(printer, snippets), 1483 LoadGolden("CompoundExpressions.golden"))); 1484 } 1485 1486 TEST(GlobalCompoundExpressions) { 1487 InitializedIgnitionHandleScope scope; 1488 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1489 ConstantPoolType::kString); 1490 printer.set_wrap(false); 1491 printer.set_test_function_name("f"); 1492 1493 const char* snippets[] = { 1494 "var global = 1;\n" 1495 "function f() { return global &= 1; }\n" 1496 "f();\n", 1497 1498 "unallocated = 1;\n" 1499 "function f() { return unallocated += 1; }\n" 1500 "f();\n", 1501 }; 1502 1503 CHECK(CompareTexts(BuildActual(printer, snippets), 1504 LoadGolden("GlobalCompoundExpressions.golden"))); 1505 } 1506 1507 TEST(CreateArguments) { 1508 InitializedIgnitionHandleScope scope; 1509 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1510 ConstantPoolType::kString); 1511 printer.set_wrap(false); 1512 printer.set_test_function_name("f"); 1513 1514 const char* snippets[] = { 1515 "function f() { return arguments; }", 1516 1517 "function f() { return arguments[0]; }", 1518 1519 "function f() { 'use strict'; return arguments; }", 1520 1521 "function f(a) { return arguments[0]; }", 1522 1523 "function f(a, b, c) { return arguments; }", 1524 1525 "function f(a, b, c) { 'use strict'; return arguments; }", 1526 }; 1527 1528 CHECK(CompareTexts(BuildActual(printer, snippets, "", "\nf();"), 1529 LoadGolden("CreateArguments.golden"))); 1530 } 1531 1532 TEST(CreateRestParameter) { 1533 InitializedIgnitionHandleScope scope; 1534 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1535 ConstantPoolType::kNumber); 1536 printer.set_wrap(false); 1537 printer.set_test_function_name("f"); 1538 1539 const char* snippets[] = { 1540 "function f(...restArgs) { return restArgs; }", 1541 1542 "function f(a, ...restArgs) { return restArgs; }", 1543 1544 "function f(a, ...restArgs) { return restArgs[0]; }", 1545 1546 "function f(a, ...restArgs) { return restArgs[0] + arguments[0]; }", 1547 }; 1548 1549 CHECK(CompareTexts(BuildActual(printer, snippets, "", "\nf();"), 1550 LoadGolden("CreateRestParameter.golden"))); 1551 } 1552 1553 TEST(ForIn) { 1554 InitializedIgnitionHandleScope scope; 1555 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1556 ConstantPoolType::kMixed); 1557 const char* snippets[] = { 1558 "for (var p in null) {}\n", 1559 1560 "for (var p in undefined) {}\n", 1561 1562 "for (var p in undefined) {}\n", 1563 1564 "var x = 'potatoes';\n" 1565 "for (var p in x) { return p; }\n", 1566 1567 "var x = 0;\n" 1568 "for (var p in [1,2,3]) { x += p; }\n", 1569 1570 "var x = { 'a': 1, 'b': 2 };\n" 1571 "for (x['a'] in [10, 20, 30]) {\n" 1572 " if (x['a'] == 10) continue;\n" 1573 " if (x['a'] == 20) break;\n" 1574 "}\n", 1575 1576 "var x = [ 10, 11, 12 ] ;\n" 1577 "for (x[0] in [1,2,3]) { return x[3]; }\n", 1578 }; 1579 1580 CHECK( 1581 CompareTexts(BuildActual(printer, snippets), LoadGolden("ForIn.golden"))); 1582 } 1583 1584 TEST(ForOf) { 1585 InitializedIgnitionHandleScope scope; 1586 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1587 ConstantPoolType::kMixed); 1588 const char* snippets[] = { 1589 "for (var p of [0, 1, 2]) {}\n", 1590 1591 "var x = 'potatoes';\n" 1592 "for (var p of x) { return p; }\n", 1593 1594 "for (var x of [10, 20, 30]) {\n" 1595 " if (x == 10) continue;\n" 1596 " if (x == 20) break;\n" 1597 "}\n", 1598 1599 "var x = { 'a': 1, 'b': 2 };\n" 1600 "for (x['a'] of [1,2,3]) { return x['a']; }\n", 1601 }; 1602 1603 CHECK( 1604 CompareTexts(BuildActual(printer, snippets), LoadGolden("ForOf.golden"))); 1605 } 1606 1607 TEST(Conditional) { 1608 InitializedIgnitionHandleScope scope; 1609 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1610 ConstantPoolType::kNumber); 1611 const char* snippets[] = { 1612 "return 1 ? 2 : 3;\n", 1613 1614 "return 1 ? 2 ? 3 : 4 : 5;\n", 1615 }; 1616 1617 CHECK(CompareTexts(BuildActual(printer, snippets), 1618 LoadGolden("Conditional.golden"))); 1619 } 1620 1621 TEST(Switch) { 1622 InitializedIgnitionHandleScope scope; 1623 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1624 ConstantPoolType::kNumber); 1625 const char* snippets[] = { 1626 "var a = 1;\n" 1627 "switch(a) {\n" 1628 " case 1: return 2;\n" 1629 " case 2: return 3;\n" 1630 "}\n", 1631 1632 "var a = 1;\n" 1633 "switch(a) {\n" 1634 " case 1: a = 2; break;\n" 1635 " case 2: a = 3; break;\n" 1636 "}\n", 1637 1638 "var a = 1;\n" 1639 "switch(a) {\n" 1640 " case 1: a = 2; // fall-through\n" 1641 " case 2: a = 3; break;\n" 1642 "}\n", 1643 1644 "var a = 1;\n" 1645 "switch(a) {\n" 1646 " case 2: break;\n" 1647 " case 3: break;\n" 1648 " default: a = 1; break;\n" 1649 "}\n", 1650 1651 "var a = 1;\n" 1652 "switch(typeof(a)) {\n" 1653 " case 2: a = 1; break;\n" 1654 " case 3: a = 2; break;\n" 1655 " default: a = 3; break;\n" 1656 "}\n", 1657 1658 "var a = 1;\n" 1659 "switch(a) {\n" 1660 " case typeof(a): a = 1; break;\n" 1661 " default: a = 2; break;\n" 1662 "}\n", 1663 1664 "var a = 1;\n" 1665 "switch(a) {\n" 1666 " case 1:\n" 1667 REPEAT_64(" a = 2;\n") 1668 " break;\n" 1669 " case 2:\n" 1670 " a = 3;\n" 1671 " break;\n" 1672 "}\n", 1673 1674 "var a = 1;\n" 1675 "switch(a) {\n" 1676 " case 1: \n" 1677 " switch(a + 1) {\n" 1678 " case 2 : a = 1; break;\n" 1679 " default : a = 2; break;\n" 1680 " } // fall-through\n" 1681 " case 2: a = 3;\n" 1682 "}\n", 1683 }; 1684 1685 CHECK(CompareTexts(BuildActual(printer, snippets), 1686 LoadGolden("Switch.golden"))); 1687 } 1688 1689 TEST(BasicBlockToBoolean) { 1690 InitializedIgnitionHandleScope scope; 1691 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1692 ConstantPoolType::kNumber); 1693 const char* snippets[] = { 1694 "var a = 1; if (a || a < 0) { return 1; }\n", 1695 1696 "var a = 1; if (a && a < 0) { return 1; }\n", 1697 1698 "var a = 1; a = (a || a < 0) ? 2 : 3;\n", 1699 }; 1700 1701 CHECK(CompareTexts(BuildActual(printer, snippets), 1702 LoadGolden("BasicBlockToBoolean.golden"))); 1703 } 1704 1705 TEST(DeadCodeRemoval) { 1706 InitializedIgnitionHandleScope scope; 1707 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1708 ConstantPoolType::kNumber); 1709 const char* snippets[] = { 1710 "return; var a = 1; a();\n", 1711 1712 "if (false) { return; }; var a = 1;\n", 1713 1714 "if (true) { return 1; } else { return 2; };\n", 1715 1716 "var a = 1; if (a) { return 1; }; return 2;\n", 1717 }; 1718 1719 CHECK(CompareTexts(BuildActual(printer, snippets), 1720 LoadGolden("DeadCodeRemoval.golden"))); 1721 } 1722 1723 TEST(ThisFunction) { 1724 InitializedIgnitionHandleScope scope; 1725 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1726 ConstantPoolType::kNumber); 1727 printer.set_wrap(false); 1728 printer.set_test_function_name("f"); 1729 1730 const char* snippets[] = { 1731 "var f;\n" 1732 "f = function f() {};", 1733 1734 "var f;\n" 1735 "f = function f() { return f; };", 1736 }; 1737 1738 CHECK(CompareTexts(BuildActual(printer, snippets, "", "\nf();"), 1739 LoadGolden("ThisFunction.golden"))); 1740 } 1741 1742 TEST(NewTarget) { 1743 InitializedIgnitionHandleScope scope; 1744 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1745 ConstantPoolType::kMixed); 1746 1747 const char* snippets[] = { 1748 "return new.target;\n", 1749 1750 "new.target;\n", 1751 }; 1752 1753 CHECK(CompareTexts(BuildActual(printer, snippets), 1754 LoadGolden("NewTarget.golden"))); 1755 } 1756 1757 TEST(RemoveRedundantLdar) { 1758 InitializedIgnitionHandleScope scope; 1759 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1760 ConstantPoolType::kNumber); 1761 const char* snippets[] = { 1762 "var ld_a = 1;\n" // This test is to check Ldar does not 1763 "while(true) {\n" // get removed if the preceding Star is 1764 " ld_a = ld_a + ld_a;\n" // in a different basicblock. 1765 " if (ld_a > 10) break;\n" 1766 "}\n" 1767 "return ld_a;\n", 1768 1769 "var ld_a = 1;\n" 1770 "do {\n" 1771 " ld_a = ld_a + ld_a;\n" 1772 " if (ld_a > 10) continue;\n" 1773 "} while(false);\n" 1774 "return ld_a;\n", 1775 1776 "var ld_a = 1;\n" 1777 " ld_a = ld_a + ld_a;\n" 1778 " return ld_a;\n", 1779 }; 1780 1781 CHECK(CompareTexts(BuildActual(printer, snippets), 1782 LoadGolden("RemoveRedundantLdar.golden"))); 1783 } 1784 1785 TEST(AssignmentsInBinaryExpression) { 1786 InitializedIgnitionHandleScope scope; 1787 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1788 ConstantPoolType::kString); 1789 const char* snippets[] = { 1790 "var x = 0, y = 1;\n" 1791 "return (x = 2, y = 3, x = 4, y = 5);\n", 1792 1793 "var x = 55;\n" 1794 "var y = (x = 100);\n" 1795 "return y;\n", 1796 1797 "var x = 55;\n" 1798 "x = x + (x = 100) + (x = 101);\n" 1799 "return x;\n", 1800 1801 "var x = 55;\n" 1802 "x = (x = 56) - x + (x = 57);\n" 1803 "x++;\n" 1804 "return x;\n", 1805 1806 "var x = 55;\n" 1807 "var y = x + (x = 1) + (x = 2) + (x = 3);\n" 1808 "return y;\n", 1809 1810 "var x = 55;\n" 1811 "var x = x + (x = 1) + (x = 2) + (x = 3);\n" 1812 "return x;\n", 1813 1814 "var x = 10, y = 20;\n" 1815 "return x + (x = 1) + (x + 1) * (y = 2) + (y = 3) + (x = 4) + (y = 5) + " 1816 "y;\n", 1817 1818 "var x = 17;\n" 1819 "return 1 + x + (x++) + (++x);\n", 1820 }; 1821 1822 CHECK(CompareTexts(BuildActual(printer, snippets), 1823 LoadGolden("AssignmentsInBinaryExpression.golden"))); 1824 } 1825 1826 TEST(Eval) { 1827 InitializedIgnitionHandleScope scope; 1828 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1829 ConstantPoolType::kString); 1830 const char* snippets[] = { 1831 "return eval('1;');\n", 1832 }; 1833 1834 CHECK( 1835 CompareTexts(BuildActual(printer, snippets), LoadGolden("Eval.golden"))); 1836 } 1837 1838 TEST(LookupSlot) { 1839 InitializedIgnitionHandleScope scope; 1840 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1841 ConstantPoolType::kString); 1842 1843 const char* snippets[] = { 1844 "eval('var x = 10;'); return x;\n", 1845 1846 "eval('var x = 10;'); return typeof x;\n", 1847 1848 "x = 20; return eval('');\n", 1849 }; 1850 1851 CHECK(CompareTexts(BuildActual(printer, snippets), 1852 LoadGolden("LookupSlot.golden"))); 1853 } 1854 1855 TEST(CallLookupSlot) { 1856 InitializedIgnitionHandleScope scope; 1857 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1858 ConstantPoolType::kMixed); 1859 const char* snippets[] = { 1860 "g = function(){}; eval(''); return g();\n", 1861 }; 1862 1863 CHECK(CompareTexts(BuildActual(printer, snippets), 1864 LoadGolden("CallLookupSlot.golden"))); 1865 } 1866 1867 // TODO(mythria): tests for variable/function declaration in lookup slots. 1868 1869 TEST(LookupSlotInEval) { 1870 InitializedIgnitionHandleScope scope; 1871 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1872 ConstantPoolType::kString); 1873 printer.set_wrap(false); 1874 printer.set_test_function_name("f"); 1875 1876 const char* snippets[] = { 1877 "return x;", 1878 1879 "x = 10;", 1880 1881 "'use strict'; x = 10;", 1882 1883 "return typeof x;", 1884 }; 1885 1886 std::string actual = BuildActual(printer, snippets, 1887 "var f;\n" 1888 "var x = 1;\n" 1889 "function f1() {\n" 1890 " eval(\"function t() { ", 1891 1892 " }; f = t; f();\");\n" 1893 "}\n" 1894 "f1();"); 1895 1896 CHECK(CompareTexts(actual, LoadGolden("LookupSlotInEval.golden"))); 1897 } 1898 1899 TEST(LookupSlotWideInEval) { 1900 InitializedIgnitionHandleScope scope; 1901 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1902 ConstantPoolType::kMixed); 1903 printer.set_wrap(false); 1904 printer.set_test_function_name("f"); 1905 1906 const char* snippets[] = { 1907 REPEAT_256(" \"var y = 2.3;\" +\n") // 1908 " \"return x;\" +\n", 1909 1910 REPEAT_256(" \"var y = 2.3;\" +\n") // 1911 " \"return typeof x;\" +\n", 1912 1913 REPEAT_256(" \"var y = 2.3;\" +\n") // 1914 " \"x = 10;\" +\n", 1915 1916 " \"'use strict';\" +\n" // 1917 REPEAT_256(" \"var y = 2.3;\" +\n") // 1918 " \"x = 10;\" +\n", 1919 }; 1920 1921 std::string actual = BuildActual(printer, snippets, 1922 "var f;\n" 1923 "var x = 1;\n" 1924 "function f1() {\n" 1925 " eval(\"function t() {\" +\n", 1926 1927 " \"};\" +\n" 1928 " \"f = t; f();\"\n);\n" 1929 "}\n" 1930 "f1();"); 1931 1932 CHECK(CompareTexts(actual, LoadGolden("LookupSlotWideInEval.golden"))); 1933 } 1934 1935 TEST(DeleteLookupSlotInEval) { 1936 InitializedIgnitionHandleScope scope; 1937 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1938 ConstantPoolType::kString); 1939 printer.set_wrap(false); 1940 printer.set_test_function_name("f"); 1941 1942 const char* snippets[] = { 1943 "delete x;", 1944 1945 "return delete y;", 1946 1947 "return delete z;", 1948 }; 1949 1950 std::string actual = BuildActual(printer, snippets, 1951 "var f;\n" 1952 "var x = 1;\n" 1953 "z = 10;\n" 1954 "function f1() {\n" 1955 " var y;\n" 1956 " eval(\"function t() { ", 1957 1958 " }; f = t; f();\");\n" 1959 "}\n" 1960 "f1();"); 1961 1962 CHECK(CompareTexts(actual, LoadGolden("DeleteLookupSlotInEval.golden"))); 1963 } 1964 1965 TEST(WideRegisters) { 1966 // Prepare prologue that creates frame for lots of registers. 1967 std::ostringstream os; 1968 for (size_t i = 0; i < 157; ++i) { 1969 os << "var x" << i << ";\n"; 1970 } 1971 std::string prologue(os.str()); 1972 1973 InitializedIgnitionHandleScope scope; 1974 BytecodeExpectationsPrinter printer(CcTest::isolate(), 1975 ConstantPoolType::kNumber); 1976 const char* snippets[] = { 1977 "x0 = x127;\n" 1978 "return x0;\n", 1979 1980 "x127 = x126;\n" 1981 "return x127;\n", 1982 1983 "if (x2 > 3) { return x129; }\n" 1984 "return x128;\n", 1985 1986 "var x0 = 0;\n" 1987 "if (x129 == 3) { var x129 = x0; }\n" 1988 "if (x2 > 3) { return x0; }\n" 1989 "return x129;\n", 1990 1991 "var x0 = 0;\n" 1992 "var x1 = 0;\n" 1993 "for (x128 = 0; x128 < 64; x128++) {" 1994 " x1 += x128;" 1995 "}" 1996 "return x128;\n", 1997 1998 "var x0 = 1234;\n" 1999 "var x1 = 0;\n" 2000 "for (x128 in x0) {" 2001 " x1 += x128;" 2002 "}" 2003 "return x1;\n", 2004 2005 "x0 = %Add(x64, x63);\n" 2006 "x1 = %Add(x27, x143);\n" 2007 "%TheHole();\n" 2008 "return x1;\n", 2009 }; 2010 2011 CHECK(CompareTexts(BuildActual(printer, snippets, prologue.c_str()), 2012 LoadGolden("WideRegisters.golden"))); 2013 } 2014 2015 TEST(ConstVariable) { 2016 InitializedIgnitionHandleScope scope; 2017 BytecodeExpectationsPrinter printer(CcTest::isolate(), 2018 ConstantPoolType::kString); 2019 const char* snippets[] = { 2020 "const x = 10;\n", 2021 2022 "const x = 10; return x;\n", 2023 2024 "const x = ( x = 20);\n", 2025 2026 "const x = 10; x = 20;\n", 2027 }; 2028 2029 CHECK(CompareTexts(BuildActual(printer, snippets), 2030 LoadGolden("ConstVariable.golden"))); 2031 } 2032 2033 TEST(LetVariable) { 2034 InitializedIgnitionHandleScope scope; 2035 BytecodeExpectationsPrinter printer(CcTest::isolate(), 2036 ConstantPoolType::kString); 2037 const char* snippets[] = { 2038 "let x = 10;\n", 2039 2040 "let x = 10; return x;\n", 2041 2042 "let x = (x = 20);\n", 2043 2044 "let x = 10; x = 20;\n", 2045 }; 2046 2047 CHECK(CompareTexts(BuildActual(printer, snippets), 2048 LoadGolden("LetVariable.golden"))); 2049 } 2050 2051 TEST(ConstVariableContextSlot) { 2052 // TODO(mythria): Add tests for initialization of this via super calls. 2053 // TODO(mythria): Add tests that walk the context chain. 2054 InitializedIgnitionHandleScope scope; 2055 BytecodeExpectationsPrinter printer(CcTest::isolate(), 2056 ConstantPoolType::kMixed); 2057 const char* snippets[] = { 2058 "const x = 10; function f1() {return x;}\n", 2059 2060 "const x = 10; function f1() {return x;} return x;\n", 2061 2062 "const x = (x = 20); function f1() {return x;}\n", 2063 2064 "const x = 10; x = 20; function f1() {return x;}\n", 2065 }; 2066 2067 CHECK(CompareTexts(BuildActual(printer, snippets), 2068 LoadGolden("ConstVariableContextSlot.golden"))); 2069 } 2070 2071 TEST(LetVariableContextSlot) { 2072 InitializedIgnitionHandleScope scope; 2073 BytecodeExpectationsPrinter printer(CcTest::isolate(), 2074 ConstantPoolType::kMixed); 2075 const char* snippets[] = { 2076 "let x = 10; function f1() {return x;}\n", 2077 2078 "let x = 10; function f1() {return x;} return x;\n", 2079 2080 "let x = (x = 20); function f1() {return x;}\n", 2081 2082 "let x = 10; x = 20; function f1() {return x;}\n", 2083 }; 2084 2085 CHECK(CompareTexts(BuildActual(printer, snippets), 2086 LoadGolden("LetVariableContextSlot.golden"))); 2087 } 2088 2089 TEST(DoExpression) { 2090 bool old_flag = FLAG_harmony_do_expressions; 2091 FLAG_harmony_do_expressions = true; 2092 2093 InitializedIgnitionHandleScope scope; 2094 BytecodeExpectationsPrinter printer(CcTest::isolate(), 2095 ConstantPoolType::kString); 2096 const char* snippets[] = { 2097 "var a = do { }; return a;\n", 2098 2099 "var a = do { var x = 100; }; return a;\n", 2100 2101 "while(true) { var a = 10; a = do { ++a; break; }; a = 20; }\n", 2102 }; 2103 2104 CHECK(CompareTexts(BuildActual(printer, snippets), 2105 LoadGolden("DoExpression.golden"))); 2106 2107 FLAG_harmony_do_expressions = old_flag; 2108 } 2109 2110 TEST(WithStatement) { 2111 InitializedIgnitionHandleScope scope; 2112 BytecodeExpectationsPrinter printer(CcTest::isolate(), 2113 ConstantPoolType::kMixed); 2114 const char* snippets[] = { 2115 "with ({x:42}) { return x; }\n", 2116 }; 2117 2118 CHECK(CompareTexts(BuildActual(printer, snippets), 2119 LoadGolden("WithStatement.golden"))); 2120 } 2121 2122 TEST(DoDebugger) { 2123 InitializedIgnitionHandleScope scope; 2124 BytecodeExpectationsPrinter printer(CcTest::isolate(), 2125 ConstantPoolType::kString); 2126 const char* snippets[] = { 2127 "debugger;\n", 2128 }; 2129 2130 CHECK(CompareTexts(BuildActual(printer, snippets), 2131 LoadGolden("DoDebugger.golden"))); 2132 } 2133 2134 TEST(ClassDeclarations) { 2135 InitializedIgnitionHandleScope scope; 2136 BytecodeExpectationsPrinter printer(CcTest::isolate(), 2137 ConstantPoolType::kMixed); 2138 const char* snippets[] = { 2139 "class Person {\n" 2140 " constructor(name) { this.name = name; }\n" 2141 " speak() { console.log(this.name + ' is speaking.'); }\n" 2142 "}\n", 2143 2144 "class person {\n" 2145 " constructor(name) { this.name = name; }\n" 2146 " speak() { console.log(this.name + ' is speaking.'); }\n" 2147 "}\n", 2148 2149 "var n0 = 'a';\n" 2150 "var n1 = 'b';\n" 2151 "class N {\n" 2152 " [n0]() { return n0; }\n" 2153 " static [n1]() { return n1; }\n" 2154 "}\n", 2155 2156 "var count = 0;\n" 2157 "class C { constructor() { count++; }}\n" 2158 "return new C();\n", 2159 }; 2160 2161 CHECK(CompareTexts(BuildActual(printer, snippets), 2162 LoadGolden("ClassDeclarations.golden"))); 2163 } 2164 2165 TEST(ClassAndSuperClass) { 2166 InitializedIgnitionHandleScope scope; 2167 BytecodeExpectationsPrinter printer(CcTest::isolate(), 2168 ConstantPoolType::kMixed); 2169 printer.set_wrap(false); 2170 printer.set_test_function_name("test"); 2171 const char* snippets[] = { 2172 "var test;\n" 2173 "(function() {\n" 2174 " class A {\n" 2175 " method() { return 2; }\n" 2176 " }\n" 2177 " class B extends A {\n" 2178 " method() { return super.method() + 1; }\n" 2179 " }\n" 2180 " test = new B().method;\n" 2181 " test();\n" 2182 "})();\n", 2183 2184 "var test;\n" 2185 "(function() {\n" 2186 " class A {\n" 2187 " get x() { return 1; }\n" 2188 " set x(val) { return; }\n" 2189 " }\n" 2190 " class B extends A {\n" 2191 " method() { super.x = 2; return super.x; }\n" 2192 " }\n" 2193 " test = new B().method;\n" 2194 " test();\n" 2195 "})();\n", 2196 2197 "var test;\n" 2198 "(function() {\n" 2199 " class A {\n" 2200 " constructor(x) { this.x_ = x; }\n" 2201 " }\n" 2202 " class B extends A {\n" 2203 " constructor() { super(1); this.y_ = 2; }\n" 2204 " }\n" 2205 " test = new B().constructor;\n" 2206 "})();\n", 2207 2208 "var test;\n" 2209 "(function() {\n" 2210 " class A {\n" 2211 " constructor() { this.x_ = 1; }\n" 2212 " }\n" 2213 " class B extends A {\n" 2214 " constructor() { super(); this.y_ = 2; }\n" 2215 " }\n" 2216 " test = new B().constructor;\n" 2217 "})();\n", 2218 }; 2219 2220 CHECK(CompareTexts(BuildActual(printer, snippets), 2221 LoadGolden("ClassAndSuperClass.golden"))); 2222 } 2223 2224 TEST(Generators) { 2225 bool old_flag = FLAG_ignition_generators; 2226 FLAG_ignition_generators = true; 2227 2228 InitializedIgnitionHandleScope scope; 2229 BytecodeExpectationsPrinter printer(CcTest::isolate(), 2230 ConstantPoolType::kMixed); 2231 printer.set_wrap(false); 2232 printer.set_test_function_name("f"); 2233 2234 const char* snippets[] = { 2235 "function* f() { }\n" 2236 "f();\n", 2237 2238 "function* f() { yield 42 }\n" 2239 "f();\n", 2240 2241 "function* f() { for (let x of [42]) yield x }\n" 2242 "f();\n", 2243 }; 2244 2245 CHECK(CompareTexts(BuildActual(printer, snippets), 2246 LoadGolden("Generators.golden"))); 2247 2248 FLAG_ignition_generators = old_flag; 2249 } 2250 2251 } // namespace interpreter 2252 } // namespace internal 2253 } // namespace v8 2254