Home | History | Annotate | Download | only in interpreter
      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