LCOV - code coverage report
Current view: top level - test/cctest/interpreter - test-bytecode-generator.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 524 535 97.9 %
Date: 2019-01-20 Functions: 109 109 100.0 %

          Line data    Source code
       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/interpreter/bytecode-array-iterator.h"
      10             : #include "src/interpreter/bytecode-generator.h"
      11             : #include "src/interpreter/interpreter.h"
      12             : #include "src/objects-inl.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 LOAD_UNIQUE_PROPERTY() "  b.name" STR(__COUNTER__) ";\n"
      27             : 
      28             : #define REPEAT_2(...) __VA_ARGS__ __VA_ARGS__
      29             : #define REPEAT_4(...) REPEAT_2(__VA_ARGS__) REPEAT_2(__VA_ARGS__)
      30             : #define REPEAT_8(...) REPEAT_4(__VA_ARGS__) REPEAT_4(__VA_ARGS__)
      31             : #define REPEAT_16(...) REPEAT_8(__VA_ARGS__) REPEAT_8(__VA_ARGS__)
      32             : #define REPEAT_32(...) REPEAT_16(__VA_ARGS__) REPEAT_16(__VA_ARGS__)
      33             : #define REPEAT_64(...) REPEAT_32(__VA_ARGS__) REPEAT_32(__VA_ARGS__)
      34             : #define REPEAT_128(...) REPEAT_64(__VA_ARGS__) REPEAT_64(__VA_ARGS__)
      35             : #define REPEAT_256(...) REPEAT_128(__VA_ARGS__) REPEAT_128(__VA_ARGS__)
      36             : 
      37             : #define REPEAT_127(...)  \
      38             :   REPEAT_64(__VA_ARGS__) \
      39             :   REPEAT_32(__VA_ARGS__) \
      40             :   REPEAT_16(__VA_ARGS__) \
      41             :   REPEAT_8(__VA_ARGS__)  \
      42             :   REPEAT_4(__VA_ARGS__)  \
      43             :   REPEAT_2(__VA_ARGS__)  \
      44             :   __VA_ARGS__
      45             : 
      46             : #define REPEAT_249(...)   \
      47             :   REPEAT_127(__VA_ARGS__) \
      48             :   REPEAT_64(__VA_ARGS__)  \
      49             :   REPEAT_32(__VA_ARGS__)  \
      50             :   REPEAT_16(__VA_ARGS__)  \
      51             :   REPEAT_8(__VA_ARGS__)   \
      52             :   REPEAT_2(__VA_ARGS__)
      53             : 
      54             : #define REPEAT_2_UNIQUE_VARS() UNIQUE_VAR() UNIQUE_VAR()
      55             : #define REPEAT_4_UNIQUE_VARS() REPEAT_2_UNIQUE_VARS() REPEAT_2_UNIQUE_VARS()
      56             : #define REPEAT_8_UNIQUE_VARS() REPEAT_4_UNIQUE_VARS() REPEAT_4_UNIQUE_VARS()
      57             : #define REPEAT_16_UNIQUE_VARS() REPEAT_8_UNIQUE_VARS() REPEAT_8_UNIQUE_VARS()
      58             : #define REPEAT_32_UNIQUE_VARS() REPEAT_16_UNIQUE_VARS() REPEAT_16_UNIQUE_VARS()
      59             : #define REPEAT_64_UNIQUE_VARS() REPEAT_32_UNIQUE_VARS() REPEAT_32_UNIQUE_VARS()
      60             : #define REPEAT_128_UNIQUE_VARS() REPEAT_64_UNIQUE_VARS() REPEAT_64_UNIQUE_VARS()
      61             : 
      62             : #define REPEAT_250_UNIQUE_VARS() \
      63             :   REPEAT_128_UNIQUE_VARS()       \
      64             :   REPEAT_64_UNIQUE_VARS()        \
      65             :   REPEAT_32_UNIQUE_VARS()        \
      66             :   REPEAT_16_UNIQUE_VARS()        \
      67             :   REPEAT_8_UNIQUE_VARS()         \
      68             :   UNIQUE_VAR()                   \
      69             :   UNIQUE_VAR()
      70             : 
      71             : #define REPEAT_2_LOAD_UNIQUE_PROPERTY() \
      72             :   LOAD_UNIQUE_PROPERTY() LOAD_UNIQUE_PROPERTY()
      73             : #define REPEAT_4_LOAD_UNIQUE_PROPERTY() \
      74             :   REPEAT_2_LOAD_UNIQUE_PROPERTY() REPEAT_2_LOAD_UNIQUE_PROPERTY()
      75             : #define REPEAT_8_LOAD_UNIQUE_PROPERTY() \
      76             :   REPEAT_4_LOAD_UNIQUE_PROPERTY() REPEAT_4_LOAD_UNIQUE_PROPERTY()
      77             : #define REPEAT_16_LOAD_UNIQUE_PROPERTY() \
      78             :   REPEAT_8_LOAD_UNIQUE_PROPERTY() REPEAT_8_LOAD_UNIQUE_PROPERTY()
      79             : #define REPEAT_32_LOAD_UNIQUE_PROPERTY() \
      80             :   REPEAT_16_LOAD_UNIQUE_PROPERTY() REPEAT_16_LOAD_UNIQUE_PROPERTY()
      81             : #define REPEAT_64_LOAD_UNIQUE_PROPERTY() \
      82             :   REPEAT_32_LOAD_UNIQUE_PROPERTY() REPEAT_32_LOAD_UNIQUE_PROPERTY()
      83             : #define REPEAT_128_LOAD_UNIQUE_PROPERTY() \
      84             :   REPEAT_64_LOAD_UNIQUE_PROPERTY() REPEAT_64_LOAD_UNIQUE_PROPERTY()
      85             : 
      86             : static const char* kGoldenFileDirectory =
      87             :     "test/cctest/interpreter/bytecode_expectations/";
      88             : 
      89         430 : class InitializedIgnitionHandleScope : public InitializedHandleScope {
      90             :  public:
      91         430 :   InitializedIgnitionHandleScope() {
      92         430 :     i::FLAG_always_opt = false;
      93         430 :     i::FLAG_allow_natives_syntax = true;
      94             :   }
      95             : };
      96             : 
      97         430 : void SkipGoldenFileHeader(std::istream& stream) {  // NOLINT
      98             :   std::string line;
      99             :   int separators_seen = 0;
     100        7780 :   while (std::getline(stream, line)) {
     101        3675 :     if (line == "---") separators_seen += 1;
     102        4105 :     if (separators_seen == 2) return;
     103             :   }
     104             : }
     105             : 
     106         430 : std::string LoadGolden(const std::string& golden_filename) {
     107        1290 :   std::ifstream expected_file((kGoldenFileDirectory + golden_filename).c_str());
     108         430 :   CHECK(expected_file.is_open());
     109         430 :   SkipGoldenFileHeader(expected_file);
     110         860 :   std::ostringstream expected_stream;
     111             :   // Restore the first separator, which was consumed by SkipGoldenFileHeader
     112         430 :   expected_stream << "---\n" << expected_file.rdbuf();
     113         430 :   return expected_stream.str();
     114             : }
     115             : 
     116             : template <size_t N>
     117         430 : std::string BuildActual(const BytecodeExpectationsPrinter& printer,
     118             :                         const char* (&snippet_list)[N],
     119             :                         const char* prologue = nullptr,
     120             :                         const char* epilogue = nullptr) {
     121         430 :   std::ostringstream actual_stream;
     122        2750 :   for (const char* snippet : snippet_list) {
     123             :     std::string source_code;
     124        2320 :     if (prologue) source_code += prologue;
     125             :     source_code += snippet;
     126        2320 :     if (epilogue) source_code += epilogue;
     127        2320 :     printer.PrintExpectation(actual_stream, source_code);
     128             :   }
     129         430 :   return actual_stream.str();
     130             : }
     131             : 
     132             : // inplace left trim
     133      242140 : static inline void ltrim(std::string& str) {
     134             :   str.erase(str.begin(),
     135             :             std::find_if(str.begin(), str.end(),
     136     2060635 :                          [](unsigned char ch) { return !std::isspace(ch); }));
     137      242140 : }
     138             : 
     139             : // inplace right trim
     140      242140 : static inline void rtrim(std::string& str) {
     141             :   str.erase(std::find_if(str.rbegin(), str.rend(),
     142      238020 :                          [](unsigned char ch) { return !std::isspace(ch); })
     143             :                 .base(),
     144      484280 :             str.end());
     145      242140 : }
     146             : 
     147      242140 : static inline std::string trim(std::string& str) {
     148      242140 :   ltrim(str);
     149      242140 :   rtrim(str);
     150      242140 :   return str;
     151             : }
     152             : 
     153         430 : bool CompareTexts(const std::string& generated, const std::string& expected) {
     154         430 :   std::istringstream generated_stream(generated);
     155         860 :   std::istringstream expected_stream(expected);
     156             :   std::string generated_line;
     157             :   std::string expected_line;
     158             :   // Line number does not include golden file header.
     159             :   int line_number = 0;
     160             :   bool strings_match = true;
     161             : 
     162             :   do {
     163      121500 :     std::getline(generated_stream, generated_line);
     164      121500 :     std::getline(expected_stream, expected_line);
     165             : 
     166      121930 :     if (!generated_stream.good() && !expected_stream.good()) {
     167             :       return strings_match;
     168             :     }
     169             : 
     170      121070 :     if (!generated_stream.good()) {
     171           0 :       std::cerr << "Expected has extra lines after line " << line_number
     172           0 :                 << "\n";
     173           0 :       std::cerr << "  Expected: '" << expected_line << "'\n";
     174           0 :       return false;
     175      121070 :     } else if (!expected_stream.good()) {
     176           0 :       std::cerr << "Generated has extra lines after line " << line_number
     177           0 :                 << "\n";
     178           0 :       std::cerr << "  Generated: '" << generated_line << "'\n";
     179           0 :       return false;
     180             :     }
     181             : 
     182      363210 :     if (trim(generated_line) != trim(expected_line)) {
     183           0 :       std::cerr << "Inputs differ at line " << line_number << "\n";
     184           0 :       std::cerr << "  Generated: '" << generated_line << "'\n";
     185           0 :       std::cerr << "  Expected:  '" << expected_line << "'\n";
     186             :       strings_match = false;
     187             :     }
     188      121070 :     line_number++;
     189         430 :   } while (true);
     190             : }
     191             : 
     192       28342 : TEST(PrimitiveReturnStatements) {
     193             :   InitializedIgnitionHandleScope scope;
     194           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
     195             :   const char* snippets[] = {
     196             :       "",
     197             : 
     198             :       "return;\n",
     199             : 
     200             :       "return null;\n",
     201             : 
     202             :       "return true;\n",
     203             : 
     204             :       "return false;\n",
     205             : 
     206             :       "return 0;\n",
     207             : 
     208             :       "return +1;\n",
     209             : 
     210             :       "return -1;\n",
     211             : 
     212             :       "return +127;\n",
     213             : 
     214             :       "return -128;\n",
     215             : 
     216             :       "return 2.0;\n",
     217           5 :   };
     218             : 
     219          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
     220             :                      LoadGolden("PrimitiveReturnStatements.golden")));
     221           5 : }
     222             : 
     223       28342 : TEST(PrimitiveExpressions) {
     224             :   InitializedIgnitionHandleScope scope;
     225           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
     226             :   const char* snippets[] = {
     227             :       "var x = 0; return x;\n",
     228             : 
     229             :       "var x = 0; return x + 3;\n",
     230             : 
     231             :       "var x = 0; return 3 + x;\n",
     232             : 
     233             :       "var x = 0; return x - 3;\n",
     234             : 
     235             :       "var x = 0; return 3 - x;\n",
     236             : 
     237             :       "var x = 4; return x * 3;\n",
     238             : 
     239             :       "var x = 4; return 3 * x;\n",
     240             : 
     241             :       "var x = 4; return x / 3;\n",
     242             : 
     243             :       "var x = 4; return 3 / x;\n",
     244             : 
     245             :       "var x = 4; return x % 3;\n",
     246             : 
     247             :       "var x = 4; return 3 % x;\n",
     248             : 
     249             :       "var x = 1; return x | 2;\n",
     250             : 
     251             :       "var x = 1; return 2 | x;\n",
     252             : 
     253             :       "var x = 1; return x ^ 2;\n",
     254             : 
     255             :       "var x = 1; return 2 ^ x;\n",
     256             : 
     257             :       "var x = 1; return x & 2;\n",
     258             : 
     259             :       "var x = 1; return 2 & x;\n",
     260             : 
     261             :       "var x = 10; return x << 3;\n",
     262             : 
     263             :       "var x = 10; return 3 << x;\n",
     264             : 
     265             :       "var x = 10; return x >> 3;\n",
     266             : 
     267             :       "var x = 10; return 3 >> x;\n",
     268             : 
     269             :       "var x = 10; return x >>> 3;\n",
     270             : 
     271             :       "var x = 10; return 3 >>> x;\n",
     272             : 
     273             :       "var x = 0; return (x, 3);\n",
     274           5 :   };
     275             : 
     276          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
     277             :                      LoadGolden("PrimitiveExpressions.golden")));
     278           5 : }
     279             : 
     280       28342 : TEST(LogicalExpressions) {
     281             :   InitializedIgnitionHandleScope scope;
     282           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
     283             :   const char* snippets[] = {
     284             :       "var x = 0; return x || 3;\n",
     285             : 
     286             :       "var x = 0; return (x == 1) || 3;\n",
     287             : 
     288             :       "var x = 0; return x && 3;\n",
     289             : 
     290             :       "var x = 0; return (x == 0) && 3;\n",
     291             : 
     292             :       "var x = 0; return x || (1, 2, 3);\n",
     293             : 
     294             :       "var a = 2, b = 3, c = 4; return a || (a, b, a, b, c = 5, 3);\n",
     295             : 
     296             :       "var x = 1; var a = 2, b = 3; return x || ("  //
     297             :       REPEAT_32("\n  a = 1, b = 2, ")               //
     298             :       "3);\n",
     299             : 
     300             :       "var x = 0; var a = 2, b = 3; return x && ("  //
     301             :       REPEAT_32("\n  a = 1, b = 2, ")               //
     302             :       "3);\n",
     303             : 
     304             :       "var x = 1; var a = 2, b = 3; return (x > 3) || ("  //
     305             :       REPEAT_32("\n  a = 1, b = 2, ")                     //
     306             :       "3);\n",
     307             : 
     308             :       "var x = 0; var a = 2, b = 3; return (x < 5) && ("  //
     309             :       REPEAT_32("\n  a = 1, b = 2, ")                     //
     310             :       "3);\n",
     311             : 
     312             :       "return 0 && 3;\n",
     313             : 
     314             :       "return 1 || 3;\n",
     315             : 
     316             :       "var x = 1; return x && 3 || 0, 1;\n",
     317           5 :   };
     318             : 
     319          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
     320             :                      LoadGolden("LogicalExpressions.golden")));
     321           5 : }
     322             : 
     323       28342 : TEST(Parameters) {
     324             :   InitializedIgnitionHandleScope scope;
     325           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
     326             :   printer.set_wrap(false);
     327          10 :   printer.set_test_function_name("f");
     328             : 
     329             :   const char* snippets[] = {
     330             :       "function f() { return this; }",
     331             : 
     332             :       "function f(arg1) { return arg1; }",
     333             : 
     334             :       "function f(arg1) { return this; }",
     335             : 
     336             :       "function f(arg1, arg2, arg3, arg4, arg5, arg6, arg7) { return arg4; }",
     337             : 
     338             :       "function f(arg1, arg2, arg3, arg4, arg5, arg6, arg7) { return this; }",
     339             : 
     340             :       "function f(arg1) { arg1 = 1; }",
     341             : 
     342             :       "function f(arg1, arg2, arg3, arg4) { arg2 = 1; }",
     343           5 :   };
     344             : 
     345          20 :   CHECK(CompareTexts(BuildActual(printer, snippets, "", "\nf();"),
     346             :                      LoadGolden("Parameters.golden")));
     347           5 : }
     348             : 
     349       28342 : TEST(IntegerConstants) {
     350             :   InitializedIgnitionHandleScope scope;
     351           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
     352             :   const char* snippets[] = {
     353             :       "return 12345678;\n",
     354             : 
     355             :       "var a = 1234; return 5678;\n",
     356             : 
     357             :       "var a = 1234; return 1234;\n",
     358           5 :   };
     359             : 
     360          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
     361             :                      LoadGolden("IntegerConstants.golden")));
     362           5 : }
     363             : 
     364       28342 : TEST(HeapNumberConstants) {
     365             :   InitializedIgnitionHandleScope scope;
     366           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
     367             :   const char* snippets[] = {
     368             :       "return 1.2;\n",
     369             : 
     370             :       "var a = 1.2; return 2.6;\n",
     371             : 
     372             :       "var a = 3.14; return 3.14;\n",
     373           5 :   };
     374             : 
     375          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
     376             :                      LoadGolden("HeapNumberConstants.golden")));
     377           5 : }
     378             : 
     379       28342 : TEST(StringConstants) {
     380             :   InitializedIgnitionHandleScope scope;
     381           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
     382             :   const char* snippets[] = {
     383             :       "return \"This is a string\";\n",
     384             : 
     385             :       "var a = \"First string\"; return \"Second string\";\n",
     386             : 
     387             :       "var a = \"Same string\"; return \"Same string\";\n",
     388           5 :   };
     389             : 
     390          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
     391             :                      LoadGolden("StringConstants.golden")));
     392           5 : }
     393             : 
     394       28342 : TEST(PropertyLoads) {
     395             :   InitializedIgnitionHandleScope scope;
     396           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
     397             :   printer.set_wrap(false);
     398          10 :   printer.set_test_function_name("f");
     399             : 
     400             :   const char* snippets[] = {
     401             :     "function f(a) { return a.name; }\n"
     402             :     "f({name : \"test\"});\n",
     403             : 
     404             :     "function f(a) { return a[\"key\"]; }\n"
     405             :     "f({key : \"test\"});\n",
     406             : 
     407             :     "function f(a) { return a[100]; }\n"
     408             :     "f({100 : \"test\"});\n",
     409             : 
     410             :     "function f(a, b) { return a[b]; }\n"
     411             :     "f({arg : \"test\"}, \"arg\");\n",
     412             : 
     413             :     "function f(a) { var b = a.name; return a[-124]; }\n"
     414             :     "f({\"-124\" : \"test\", name : 123 })",
     415             : 
     416             :     "function f(a) {\n"
     417             :     "  var b = {};\n"
     418             :     REPEAT_128_LOAD_UNIQUE_PROPERTY()
     419             :     "  return a.name;\n"
     420             :     "}\n"
     421             :     "f({name : \"test\"})\n",
     422             : 
     423             :     "function f(a, b) {\n"
     424             :     "  var c;\n"
     425             :     "  c = a[b];\n"
     426             :     REPEAT_127("  c = a[b];\n")
     427             :     "  return a[b];\n"
     428             :     "}\n"
     429             :     "f({name : \"test\"}, \"name\")\n",
     430           5 :   };
     431             : 
     432          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
     433             :                      LoadGolden("PropertyLoads.golden")));
     434           5 : }
     435             : 
     436       28342 : TEST(PropertyLoadStoreOneShot) {
     437             :   InitializedIgnitionHandleScope scope;
     438           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
     439             :   printer.set_wrap(false);
     440             :   printer.set_top_level(true);
     441             :   printer.set_oneshot_opt(true);
     442             : 
     443             :   const char* snippets[] = {
     444             :       R"(
     445             :       l = {
     446             :         'a': 1,
     447             :         'b': 2
     448             :       };
     449             : 
     450             :       v = l['a'] + l['b'];
     451             :       l['b'] = 7;
     452             :       l['a'] = l['b'];
     453             :       )",
     454             : 
     455             :       R"(
     456             :       l = {
     457             :         'a': 1.1,
     458             :         'b': 2.2
     459             :       };
     460             :       for (i = 0; i < 5; ++i) {
     461             :         l['a'] = l['a'] + l['b'];
     462             :         l['b'] = l['a'] + l['b'];
     463             :       }
     464             :       )",
     465             : 
     466             :       R"(
     467             :       l = {
     468             :         'a': 1.1,
     469             :         'b': 2.2
     470             :       };
     471             :       while (s > 0) {
     472             :         l['a']  = l['a'] - l['b'];
     473             :         l['b']  = l['b'] - l['a'];
     474             :       }
     475             :       )",
     476             : 
     477             :       R"(
     478             :       l = {
     479             :         'a': 1.1,
     480             :         'b': 2.2
     481             :       };
     482             :       s = 10;
     483             :       do {
     484             :         l['a'] = l['b'] - l['a'];
     485             :       } while (s < 10);
     486             :       )",
     487             : 
     488             :       R"(
     489             :       l = {
     490             :         'c': 1.1,
     491             :         'd': 2.2
     492             :       };
     493             :       if (l['c'] < 3) {
     494             :         l['c'] = 3;
     495             :       } else {
     496             :         l['d'] = 3;
     497             :       }
     498             :       )",
     499             : 
     500             :       R"(
     501             :       a = [1.1, [2.2, 4.5]];
     502             :       )",
     503             : 
     504             :       R"(
     505             :       b = [];
     506             :       )",
     507           5 :   };
     508          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
     509             :                      LoadGolden("PropertyLoadStoreOneShot.golden")));
     510           5 : }
     511             : 
     512       28342 : TEST(PropertyLoadStoreWithoutOneShot) {
     513             :   InitializedIgnitionHandleScope scope;
     514           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
     515             :   printer.set_wrap(false);
     516             :   printer.set_top_level(true);
     517             : 
     518             :   const char* snippets[] = {
     519             :       R"(
     520             :       l = {
     521             :         'aa': 1.1,
     522             :         'bb': 2.2
     523             :       };
     524             : 
     525             :       v = l['aa'] + l['bb'];
     526             :       l['bb'] = 7;
     527             :       l['aa'] = l['bb'];
     528             :       )",
     529             : 
     530             :       R"(
     531             :       l = {
     532             :         'cc': 3.1,
     533             :         'dd': 4.2
     534             :       };
     535             :       if (l['cc'] < 3) {
     536             :         l['cc'] = 3;
     537             :       } else {
     538             :         l['dd'] = 3;
     539             :       }
     540             :       )",
     541           5 :   };
     542          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
     543             :                      LoadGolden("PropertyLoadStoreWithoutOneShot.golden")));
     544           5 : }
     545             : 
     546       28342 : TEST(IIFEWithOneshotOpt) {
     547             :   InitializedIgnitionHandleScope scope;
     548           5 :   v8::Isolate* isolate = CcTest::isolate();
     549             :   BytecodeExpectationsPrinter printer(isolate);
     550             :   printer.set_wrap(false);
     551             :   printer.set_top_level(true);
     552             :   printer.set_print_callee(true);
     553             :   printer.set_oneshot_opt(true);
     554             : 
     555             :   const char* snippets[] = {
     556             :       // No feedback vectors for top-level loads/store named property in an IIFE
     557             :       R"(
     558             :       (function() {
     559             :         l = {};
     560             :         l.aa = 2;
     561             :         l.bb = l.aa;
     562             :         return arguments.callee;
     563             :       })();
     564             :     )",
     565             :       // Normal load/store within loops of an IIFE
     566             :       R"(
     567             :       (function() {
     568             :         l = {};
     569             :         for (i = 0; i < 5; ++i) {
     570             :           l.aa = 2;
     571             :           l.bb = l.aa;
     572             :         }
     573             :         return arguments.callee;
     574             :       })();
     575             :     )",
     576             : 
     577             :       R"(
     578             :       (function() {
     579             :         l = {};
     580             :         c = 4;
     581             :         while(c > 4) {
     582             :           l.aa = 2;
     583             :           l.bb = l.aa;
     584             :           c--;
     585             :         }
     586             :         return arguments.callee;
     587             :       })();
     588             :     )",
     589             : 
     590             :       R"(
     591             :       (function() {
     592             :         l = {};
     593             :         c = 4;
     594             :         do {
     595             :           l.aa = 2;
     596             :           l.bb = l.aa;
     597             :           c--;
     598             :         } while(c > 4)
     599             :         return arguments.callee;
     600             :       })();
     601             :     )",
     602             :       // No feedback vectors for loads/stores in conditionals
     603             :       R"(
     604             :       (function() {
     605             :         l = {
     606             :           'aa': 3.3,
     607             :           'bb': 4.4
     608             :         };
     609             :         if (l.aa < 3) {
     610             :           l.aa = 3;
     611             :         } else {
     612             :           l.aa = l.bb;
     613             :         }
     614             :         return arguments.callee;
     615             :       })();
     616             :     )",
     617             : 
     618             :       R"(
     619             :       (function() {
     620             :         a = [0, [1, 1,2,], 3];
     621             :         return arguments.callee;
     622             :       })();
     623             :     )",
     624             : 
     625             :       R"(
     626             :       (function() {
     627             :         a = [];
     628             :         return arguments.callee;
     629             :       })();
     630             :     )",
     631             :       // CallNoFeedback instead of CallProperty
     632             :       R"(
     633             :       this.f0 = function() {};
     634             :       this.f1 = function(a) {};
     635             :       this.f2 = function(a, b) {};
     636             :       this.f3 = function(a, b, c) {};
     637             :       this.f4 = function(a, b, c, d) {};
     638             :       this.f5 = function(a, b, c, d, e) {};
     639             :       (function() {
     640             :         this.f0();
     641             :         this.f1(1);
     642             :         this.f2(1, 2);
     643             :         this.f3(1, 2, 3);
     644             :         this.f4(1, 2, 3, 4);
     645             :         this.f5(1, 2, 3, 4, 5);
     646             :         return arguments.callee;
     647             :       })();
     648             :     )",
     649             :       // CallNoFeedback instead of CallUndefinedReceiver
     650             :       R"(
     651             :       function f0() {}
     652             :       function f1(a) {}
     653             :       function f2(a, b) {}
     654             :       function f3(a, b, c) {}
     655             :       function f4(a, b, c, d) {}
     656             :       function f5(a, b, c, d, e) {}
     657             :       (function() {
     658             :         f0();
     659             :         f1(1);
     660             :         f2(1, 2);
     661             :         f3(1, 2, 3);
     662             :         f4(1, 2, 3, 4);
     663             :         f5(1, 2, 3, 4, 5);
     664             :         return arguments.callee;
     665             :       })();
     666             :     )",
     667             :       R"(
     668             :       var t = 0;
     669             :       function f2() {};
     670             :       if (t == 0) {
     671             :         (function(){
     672             :           l = {};
     673             :           l.a = 3;
     674             :           l.b = 4;
     675             :           f2();
     676             :           return arguments.callee;
     677             :         })();
     678             :       }
     679             :     )",
     680             :       // No one-shot opt for IIFE`s within a function
     681             :       R"(
     682             :         function f2() {};
     683             :         function f() {
     684             :           return (function(){
     685             :             l = {};
     686             :             l.a = 3;
     687             :             l.b = 4;
     688             :             f2();
     689             :             return arguments.callee;
     690             :           })();
     691             :         }
     692             :         f();
     693             :     )",
     694             :       R"(
     695             :         var f = function(l) {  l.a = 3; return l; };
     696             :         f({});
     697             :         f;
     698             :     )",
     699             :       // No one-shot opt for top-level functions enclosed in parentheses
     700             :       R"(
     701             :         var f = (function(l) {  l.a = 3; return l; });
     702             :         f;
     703             :     )",
     704             :       R"(
     705             :         var f = (function foo(l) {  l.a = 3; return l; });
     706             :         f;
     707             :     )",
     708             :       R"(
     709             :         var f = function foo(l) {  l.a = 3; return l; };
     710             :         f({});
     711             :         f;
     712             :     )",
     713             :       R"(
     714             :         l = {};
     715             :         var f = (function foo(l) {  l.a = 3; return arguments.callee; })(l);
     716             :         f;
     717             :     )",
     718             :       R"(
     719             :         var f = (function foo(l) {  l.a = 3; return arguments.callee; })({});
     720             :         f;
     721             :     )",
     722           5 :   };
     723          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
     724             :                      LoadGolden("IIFEWithOneshotOpt.golden")));
     725           5 : }
     726             : 
     727       28342 : TEST(IIFEWithoutOneshotOpt) {
     728             :   InitializedIgnitionHandleScope scope;
     729           5 :   v8::Isolate* isolate = CcTest::isolate();
     730             :   BytecodeExpectationsPrinter printer(isolate);
     731             :   printer.set_wrap(false);
     732             :   printer.set_top_level(true);
     733             :   printer.set_print_callee(true);
     734             : 
     735             :   const char* snippets[] = {
     736             :       R"(
     737             :       (function() {
     738             :         l = {};
     739             :         l.a = 2;
     740             :         l.b = l.a;
     741             :         return arguments.callee;
     742             :       })();
     743             :     )",
     744             :       R"(
     745             :       (function() {
     746             :         l = {
     747             :           'a': 4.3,
     748             :           'b': 3.4
     749             :         };
     750             :         if (l.a < 3) {
     751             :           l.a = 3;
     752             :         } else {
     753             :           l.a = l.b;
     754             :         }
     755             :         return arguments.callee;
     756             :       })();
     757             :     )",
     758             :       R"(
     759             :       this.f0 = function() {};
     760             :       this.f1 = function(a) {};
     761             :       this.f2 = function(a, b) {};
     762             :       this.f3 = function(a, b, c) {};
     763             :       this.f4 = function(a, b, c, d) {};
     764             :       this.f5 = function(a, b, c, d, e) {};
     765             :       (function() {
     766             :         this.f0();
     767             :         this.f1(1);
     768             :         this.f2(1, 2);
     769             :         this.f3(1, 2, 3);
     770             :         this.f4(1, 2, 3, 4);
     771             :         this.f5(1, 2, 3, 4, 5);
     772             :         return arguments.callee;
     773             :       })();
     774             :     )",
     775             :       R"(
     776             :       function f0() {}
     777             :       function f1(a) {}
     778             :       function f2(a, b) {}
     779             :       function f3(a, b, c) {}
     780             :       function f4(a, b, c, d) {}
     781             :       function f5(a, b, c, d, e) {}
     782             :       (function() {
     783             :         f0();
     784             :         f1(1);
     785             :         f2(1, 2);
     786             :         f3(1, 2, 3);
     787             :         f4(1, 2, 3, 4);
     788             :         f5(1, 2, 3, 4, 5);
     789             :         return arguments.callee;
     790             :       })();
     791             :     )",
     792           5 :   };
     793          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
     794             :                      LoadGolden("IIFEWithoutOneshotOpt.golden")));
     795           5 : }
     796             : 
     797       28342 : TEST(PropertyStores) {
     798             :   InitializedIgnitionHandleScope scope;
     799           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
     800             :   printer.set_wrap(false);
     801          10 :   printer.set_test_function_name("f");
     802             : 
     803             :   const char* snippets[] = {
     804             :     "function f(a) { a.name = \"val\"; }\n"
     805             :     "f({name : \"test\"})",
     806             : 
     807             :     "function f(a) { a[\"key\"] = \"val\"; }\n"
     808             :     "f({key : \"test\"})",
     809             : 
     810             :     "function f(a) { a[100] = \"val\"; }\n"
     811             :     "f({100 : \"test\"})",
     812             : 
     813             :     "function f(a, b) { a[b] = \"val\"; }\n"
     814             :     "f({arg : \"test\"}, \"arg\")",
     815             : 
     816             :     "function f(a) { a.name = a[-124]; }\n"
     817             :     "f({\"-124\" : \"test\", name : 123 })",
     818             : 
     819             :     "function f(a) { \"use strict\"; a.name = \"val\"; }\n"
     820             :     "f({name : \"test\"})",
     821             : 
     822             :     "function f(a, b) { \"use strict\"; a[b] = \"val\"; }\n"
     823             :     "f({arg : \"test\"}, \"arg\")",
     824             : 
     825             :     "function f(a) {\n"
     826             :     "  a.name = 1;\n"
     827             :     "  var b = {};\n"
     828             :     REPEAT_128_LOAD_UNIQUE_PROPERTY()
     829             :     "  a.name = 2;\n"
     830             :     "}\n"
     831             :     "f({name : \"test\"})\n",
     832             : 
     833             :     "function f(a) {\n"
     834             :     " 'use strict';\n"
     835             :     "  a.name = 1;\n"
     836             :     "  var b = {};\n"
     837             :     REPEAT_128_LOAD_UNIQUE_PROPERTY()
     838             :     "  a.name = 2;\n"
     839             :     "}\n"
     840             :     "f({name : \"test\"})\n",
     841             : 
     842             :     "function f(a, b) {\n"
     843             :     "  a[b] = 1;\n"
     844             :     REPEAT_127("  a[b] = 1;\n")
     845             :     "  a[b] = 2;\n"
     846             :     "}\n"
     847             :     "f({name : \"test\"})\n",
     848             : 
     849             :     "function f(a, b) {\n"
     850             :     "  'use strict';\n"
     851             :     "  a[b] = 1;\n"
     852             :     REPEAT_127("  a[b] = 1;\n")
     853             :     "  a[b] = 2;\n"
     854             :     "}\n"
     855             :     "f({name : \"test\"})\n",
     856           5 :   };
     857             : 
     858          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
     859             :                      LoadGolden("PropertyStores.golden")));
     860           5 : }
     861             : 
     862             : #define FUNC_ARG "new (function Obj() { this.func = function() { return; }})()"
     863             : 
     864       28342 : TEST(PropertyCall) {
     865             :   InitializedIgnitionHandleScope scope;
     866           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
     867             :   printer.set_wrap(false);
     868          10 :   printer.set_test_function_name("f");
     869             : 
     870             :   const char* snippets[] = {
     871             :       "function f(a) { return a.func(); }\n"
     872             :       "f(" FUNC_ARG ")",
     873             : 
     874             :       "function f(a, b, c) { return a.func(b, c); }\n"
     875             :       "f(" FUNC_ARG ", 1, 2)",
     876             : 
     877             :       "function f(a, b) { return a.func(b + b, b); }\n"
     878             :       "f(" FUNC_ARG ", 1)",
     879             : 
     880             :       "function f(a) {\n"
     881             :       "  var b = {};\n"
     882             :       REPEAT_128_LOAD_UNIQUE_PROPERTY()
     883             :       "  a.func;\n"              //
     884             :       "  return a.func(); }\n"
     885             :       "f(" FUNC_ARG ")",
     886             : 
     887             :       "function f(a) { return a.func(1).func(2).func(3); }\n"
     888             :       "f(new (function Obj() { this.func = function(a) { return this; }})())",
     889           5 :   };
     890             : 
     891          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
     892             :                      LoadGolden("PropertyCall.golden")));
     893           5 : }
     894             : 
     895       28342 : TEST(LoadGlobal) {
     896             :   InitializedIgnitionHandleScope scope;
     897           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
     898             :   printer.set_wrap(false);
     899          10 :   printer.set_test_function_name("f");
     900             : 
     901             :   const char* snippets[] = {
     902             :     "var a = 1;\n"
     903             :     "function f() { return a; }\n"
     904             :     "f()",
     905             : 
     906             :     "function t() { }\n"
     907             :     "function f() { return t; }\n"
     908             :     "f()",
     909             : 
     910             :     "a = 1;\n"
     911             :     "function f() { return a; }\n"
     912             :     "f()",
     913             : 
     914             :     "a = 1;\n"
     915             :     "function f(c) {\n"
     916             :     "  var b = {};\n"
     917             :     REPEAT_128_LOAD_UNIQUE_PROPERTY()
     918             :     "  return a;\n"
     919             :     "}\n"
     920             :     "f({name: 1});\n",
     921           5 :   };
     922             : 
     923          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
     924             :                      LoadGolden("LoadGlobal.golden")));
     925           5 : }
     926             : 
     927       28342 : TEST(StoreGlobal) {
     928             :   InitializedIgnitionHandleScope scope;
     929           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
     930             :   printer.set_wrap(false);
     931          10 :   printer.set_test_function_name("f");
     932             : 
     933             :   const char* snippets[] = {
     934             :     "var a = 1;\n"
     935             :     "function f() { a = 2; }\n"
     936             :     "f();\n",
     937             : 
     938             :     "var a = \"test\"; function f(b) { a = b; }\n"
     939             :     "f(\"global\");\n",
     940             : 
     941             :     "'use strict'; var a = 1;\n"
     942             :     "function f() { a = 2; }\n"
     943             :     "f();\n",
     944             : 
     945             :     "a = 1;\n"
     946             :     "function f() { a = 2; }\n"
     947             :     "f();\n",
     948             : 
     949             :     "a = 1;\n"
     950             :     "function f(c) {\n"
     951             :     "  var b = {};\n"
     952             :     REPEAT_128_LOAD_UNIQUE_PROPERTY()
     953             :     "  a = 2;\n"
     954             :     "}\n"
     955             :     "f({name: 1});\n",
     956             : 
     957             :     "a = 1;\n"
     958             :     "function f(c) {\n"
     959             :     "  'use strict';\n"
     960             :     "  var b = {};\n"
     961             :     REPEAT_128_LOAD_UNIQUE_PROPERTY()
     962             :     "  a = 2;\n"
     963             :     "}\n"
     964             :     "f({name: 1});\n",
     965           5 :   };
     966             : 
     967          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
     968             :                      LoadGolden("StoreGlobal.golden")));
     969           5 : }
     970             : 
     971       28342 : TEST(CallGlobal) {
     972             :   InitializedIgnitionHandleScope scope;
     973           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
     974             :   printer.set_wrap(false);
     975          10 :   printer.set_test_function_name("f");
     976             : 
     977             :   const char* snippets[] = {
     978             :       "function t() { }\n"
     979             :       "function f() { return t(); }\n"
     980             :       "f();\n",
     981             : 
     982             :       "function t(a, b, c) { }\n"
     983             :       "function f() { return t(1, 2, 3); }\n"
     984             :       "f();\n",
     985           5 :   };
     986             : 
     987          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
     988             :                      LoadGolden("CallGlobal.golden")));
     989           5 : }
     990             : 
     991       28342 : TEST(CallRuntime) {
     992             :   InitializedIgnitionHandleScope scope;
     993           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
     994             :   printer.set_wrap(false);
     995          10 :   printer.set_test_function_name("f");
     996             : 
     997             :   const char* snippets[] = {
     998             :       "function f() { %TheHole() }\n"
     999             :       "f();\n",
    1000             : 
    1001             :       "function f(a) { return %IsArray(a) }\n"
    1002             :       "f(undefined);\n",
    1003             : 
    1004             :       "function f() { return %Add(1, 2) }\n"
    1005             :       "f();\n",
    1006           5 :   };
    1007             : 
    1008          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    1009             :                      LoadGolden("CallRuntime.golden")));
    1010           5 : }
    1011             : 
    1012       28342 : TEST(IfConditions) {
    1013             :   InitializedIgnitionHandleScope scope;
    1014           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    1015             :   printer.set_wrap(false);
    1016          10 :   printer.set_test_function_name("f");
    1017             : 
    1018             :   const char* snippets[] = {
    1019             :     "function f() {\n"
    1020             :     "  if (0) {\n"
    1021             :     "    return 1;\n"
    1022             :     "  } else {\n"
    1023             :     "    return -1;\n"
    1024             :     "  }\n"
    1025             :     "};\n"
    1026             :     "f();\n",
    1027             : 
    1028             :     "function f() {\n"
    1029             :     "  if ('lucky') {\n"
    1030             :     "    return 1;\n"
    1031             :     "  } else {\n"
    1032             :     "    return -1;\n"
    1033             :     "  }\n"
    1034             :     "};\n"
    1035             :     "f();\n",
    1036             : 
    1037             :     "function f() {\n"
    1038             :     "  if (false) {\n"
    1039             :     "    return 1;\n"
    1040             :     "  } else {\n"
    1041             :     "    return -1;\n"
    1042             :     "  }\n"
    1043             :     "};\n"
    1044             :     "f();\n",
    1045             : 
    1046             :     "function f() {\n"
    1047             :     "  if (false) {\n"
    1048             :     "    return 1;\n"
    1049             :     "  }\n"
    1050             :     "};\n"
    1051             :     "f();\n",
    1052             : 
    1053             :     "function f() {\n"
    1054             :     "  var a = 1;\n"
    1055             :     "  if (a) {\n"
    1056             :     "    a += 1;\n"
    1057             :     "  } else {\n"
    1058             :     "    return 2;\n"
    1059             :     "  }\n"
    1060             :     "};\n"
    1061             :     "f();\n",
    1062             : 
    1063             :     "function f(a) {\n"
    1064             :     "  if (a <= 0) {\n"
    1065             :     "    return 200;\n"
    1066             :     "  } else {\n"
    1067             :     "    return -200;\n"
    1068             :     "  }\n"
    1069             :     "};\n"
    1070             :     "f(99);\n",
    1071             : 
    1072             :     "function f(a, b) { if (a in b) { return 200; } }"
    1073             :     "f('prop', { prop: 'yes'});\n",
    1074             : 
    1075             :     "function f(z) { var a = 0; var b = 0; if (a === 0.01) {\n"
    1076             :     REPEAT_64("  b = a; a = b;\n")
    1077             :     " return 200; } else { return -200; } } f(0.001);\n",
    1078             : 
    1079             :     "function f() {\n"
    1080             :     "  var a = 0; var b = 0;\n"
    1081             :     "  if (a) {\n"
    1082             :     REPEAT_64("  b = a; a = b;\n")
    1083             :     "  return 200; } else { return -200; }\n"
    1084             :     "};\n"
    1085             :     "f();\n",
    1086             : 
    1087             :     "function f(a, b) {\n"
    1088             :     "  if (a == b) { return 1; }\n"
    1089             :     "  if (a === b) { return 1; }\n"
    1090             :     "  if (a < b) { return 1; }\n"
    1091             :     "  if (a > b) { return 1; }\n"
    1092             :     "  if (a <= b) { return 1; }\n"
    1093             :     "  if (a >= b) { return 1; }\n"
    1094             :     "  if (a in b) { return 1; }\n"
    1095             :     "  if (a instanceof b) { return 1; }\n"
    1096             :     "  return 0;\n"
    1097             :     "}\n"
    1098             :     "f(1, 1);\n",
    1099             : 
    1100             :     "function f() {\n"
    1101             :     "  var a = 0;\n"
    1102             :     "  if (a) {\n"
    1103             :     "    return 20;\n"
    1104             :     "  } else {\n"
    1105             :     "    return -20;\n"
    1106             :     "  }\n"
    1107             :     "};\n"
    1108             :     "f();\n",
    1109             : 
    1110             :     "function f(a, b) {\n"
    1111             :     "  if (a == b || a < 0) {\n"
    1112             :     "    return 1;\n"
    1113             :     "  } else if (a > 0 && b > 0) {\n"
    1114             :     "    return 0;\n"
    1115             :     "  } else {\n"
    1116             :     "    return -1;\n"
    1117             :     "  }\n"
    1118             :     "};\n"
    1119             :     "f(-1, 1);\n",
    1120           5 :   };
    1121             : 
    1122          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    1123             :                      LoadGolden("IfConditions.golden")));
    1124           5 : }
    1125             : 
    1126       28342 : TEST(DeclareGlobals) {
    1127             :   InitializedIgnitionHandleScope scope;
    1128           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    1129             :   printer.set_wrap(false);
    1130          10 :   printer.set_test_function_name("f");
    1131             :   printer.set_top_level(true);
    1132             : 
    1133             :   const char* snippets[] = {
    1134             :       "var a = 1;\n",
    1135             : 
    1136             :       "function f() {}\n",
    1137             : 
    1138             :       "var a = 1;\n"
    1139             :       "a=2;\n",
    1140             : 
    1141             :       "function f() {}\n"
    1142             :       "f();\n",
    1143           5 :   };
    1144             : 
    1145          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    1146             :                      LoadGolden("DeclareGlobals.golden")));
    1147           5 : }
    1148             : 
    1149       28342 : TEST(BreakableBlocks) {
    1150             :   InitializedIgnitionHandleScope scope;
    1151           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    1152             : 
    1153             :   const char* snippets[] = {
    1154             :       "var x = 0;\n"
    1155             :       "label: {\n"
    1156             :       "  x = x + 1;\n"
    1157             :       "  break label;\n"
    1158             :       "  x = x + 1;\n"
    1159             :       "}\n"
    1160             :       "return x;\n",
    1161             : 
    1162             :       "var sum = 0;\n"
    1163             :       "outer: {\n"
    1164             :       "  for (var x = 0; x < 10; ++x) {\n"
    1165             :       "    for (var y = 0; y < 3; ++y) {\n"
    1166             :       "      ++sum;\n"
    1167             :       "      if (x + y == 12) { break outer; }\n"
    1168             :       "    }\n"
    1169             :       "  }\n"
    1170             :       "}\n"
    1171             :       "return sum;\n",
    1172             : 
    1173             :       "outer: {\n"
    1174             :       "  let y = 10;\n"
    1175             :       "  function f() { return y; }\n"
    1176             :       "  break outer;\n"
    1177             :       "}\n",
    1178             : 
    1179             :       "let x = 1;\n"
    1180             :       "outer: {\n"
    1181             :       "  inner: {\n"
    1182             :       "   let y = 2;\n"
    1183             :       "    function f() { return x + y; }\n"
    1184             :       "    if (y) break outer;\n"
    1185             :       "    y = 3;\n"
    1186             :       "  }\n"
    1187             :       "}\n"
    1188             :       "x = 4;\n",
    1189           5 :   };
    1190             : 
    1191          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    1192             :                      LoadGolden("BreakableBlocks.golden")));
    1193           5 : }
    1194             : 
    1195       28342 : TEST(BasicLoops) {
    1196             :   InitializedIgnitionHandleScope scope;
    1197           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    1198             :   const char* snippets[] = {
    1199             :       "var x = 0;\n"
    1200             :       "while (false) { x = 99; break; continue; }\n"
    1201             :       "return x;\n",
    1202             : 
    1203             :       "var x = 0;\n"
    1204             :       "while (false) {\n"
    1205             :       "  x = x + 1;\n"
    1206             :       "};\n"
    1207             :       "return x;\n",
    1208             : 
    1209             :       "var x = 0;\n"
    1210             :       "var y = 1;\n"
    1211             :       "while (x < 10) {\n"
    1212             :       "  y = y * 12;\n"
    1213             :       "  x = x + 1;\n"
    1214             :       "  if (x == 3) continue;\n"
    1215             :       "  if (x == 4) break;\n"
    1216             :       "}\n"
    1217             :       "return y;\n",
    1218             : 
    1219             :       "var i = 0;\n"
    1220             :       "while (true) {\n"
    1221             :       "  if (i < 0) continue;\n"
    1222             :       "  if (i == 3) break;\n"
    1223             :       "  if (i == 4) break;\n"
    1224             :       "  if (i == 10) continue;\n"
    1225             :       "  if (i == 5) break;\n"
    1226             :       "  i = i + 1;\n"
    1227             :       "}\n"
    1228             :       "return i;\n",
    1229             : 
    1230             :       "var i = 0;\n"
    1231             :       "while (true) {\n"
    1232             :       "  while (i < 3) {\n"
    1233             :       "    if (i == 2) break;\n"
    1234             :       "    i = i + 1;\n"
    1235             :       "  }\n"
    1236             :       "  i = i + 1;\n"
    1237             :       "  break;\n"
    1238             :       "}\n"
    1239             :       "return i;\n",
    1240             : 
    1241             :       "var x = 10;\n"
    1242             :       "var y = 1;\n"
    1243             :       "while (x) {\n"
    1244             :       "  y = y * 12;\n"
    1245             :       "  x = x - 1;\n"
    1246             :       "}\n"
    1247             :       "return y;\n",
    1248             : 
    1249             :       "var x = 0; var y = 1;\n"
    1250             :       "do {\n"
    1251             :       "  y = y * 10;\n"
    1252             :       "  if (x == 5) break;\n"
    1253             :       "  if (x == 6) continue;\n"
    1254             :       "  x = x + 1;\n"
    1255             :       "} while (x < 10);\n"
    1256             :       "return y;\n",
    1257             : 
    1258             :       "var x = 10;\n"
    1259             :       "var y = 1;\n"
    1260             :       "do {\n"
    1261             :       "  y = y * 12;\n"
    1262             :       "  x = x - 1;\n"
    1263             :       "} while (x);\n"
    1264             :       "return y;\n",
    1265             : 
    1266             :       "var x = 0; var y = 1;\n"
    1267             :       "do {\n"
    1268             :       "  y = y * 10;\n"
    1269             :       "  if (x == 5) break;\n"
    1270             :       "  x = x + 1;\n"
    1271             :       "  if (x == 6) continue;\n"
    1272             :       "} while (false);\n"
    1273             :       "return y;\n",
    1274             : 
    1275             :       "var x = 0; var y = 1;\n"
    1276             :       "do {\n"
    1277             :       "  y = y * 10;\n"
    1278             :       "  if (x == 5) break;\n"
    1279             :       "  x = x + 1;\n"
    1280             :       "  if (x == 6) continue;\n"
    1281             :       "} while (true);\n"
    1282             :       "return y;\n",
    1283             : 
    1284             :       "var x = 0;\n"
    1285             :       "for (;;) {\n"
    1286             :       "  if (x == 1) break;\n"
    1287             :       "  if (x == 2) continue;\n"
    1288             :       "  x = x + 1;\n"
    1289             :       "}\n",
    1290             : 
    1291             :       "for (var x = 0;;) {\n"
    1292             :       "  if (x == 1) break;\n"
    1293             :       "  if (x == 2) continue;\n"
    1294             :       "  x = x + 1;\n"
    1295             :       "}\n",
    1296             : 
    1297             :       "var x = 0;\n"
    1298             :       "for (;; x = x + 1) {\n"
    1299             :       "  if (x == 1) break;\n"
    1300             :       "  if (x == 2) continue;\n"
    1301             :       "}\n",
    1302             : 
    1303             :       "for (var x = 0;; x = x + 1) {\n"
    1304             :       "  if (x == 1) break;\n"
    1305             :       "  if (x == 2) continue;\n"
    1306             :       "}\n",
    1307             : 
    1308             :       "var u = 0;\n"
    1309             :       "for (var i = 0; i < 100; i = i + 1) {\n"
    1310             :       "  u = u + 1;\n"
    1311             :       "  continue;\n"
    1312             :       "}\n",
    1313             : 
    1314             :       "var y = 1;\n"
    1315             :       "for (var x = 10; x; --x) {\n"
    1316             :       "  y = y * 12;\n"
    1317             :       "}\n"
    1318             :       "return y;\n",
    1319             : 
    1320             :       "var x = 0;\n"
    1321             :       "for (var i = 0; false; i++) {\n"
    1322             :       "  x = x + 1;\n"
    1323             :       "};\n"
    1324             :       "return x;\n",
    1325             : 
    1326             :       "var x = 0;\n"
    1327             :       "for (var i = 0; true; ++i) {\n"
    1328             :       "  x = x + 1;\n"
    1329             :       "  if (x == 20) break;\n"
    1330             :       "};\n"
    1331             :       "return x;\n",
    1332             : 
    1333             :       "var a = 0;\n"
    1334             :       "while (a) {\n"
    1335             :       "  { \n"
    1336             :       "   let z = 1;\n"
    1337             :       "   function f() { z = 2; }\n"
    1338             :       "   if (z) continue;\n"
    1339             :       "   z++;\n"
    1340             :       "  }\n"
    1341             :       "}\n",
    1342           5 :   };
    1343             : 
    1344          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    1345             :                      LoadGolden("BasicLoops.golden")));
    1346           5 : }
    1347             : 
    1348       28342 : TEST(UnaryOperators) {
    1349             :   InitializedIgnitionHandleScope scope;
    1350           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    1351             :   const char* snippets[] = {
    1352             :       "var x = 0;\n"
    1353             :       "while (x != 10) {\n"
    1354             :       "  x = x + 10;\n"
    1355             :       "}\n"
    1356             :       "return x;\n",
    1357             : 
    1358             :       "var x = false;\n"
    1359             :       "do {\n"
    1360             :       "  x = !x;\n"
    1361             :       "} while(x == false);\n"
    1362             :       "return x;\n",
    1363             : 
    1364             :       "var x = 101;\n"
    1365             :       "return void(x * 3);\n",
    1366             : 
    1367             :       "var x = 1234;\n"
    1368             :       "var y = void (x * x - 1);\n"
    1369             :       "return y;\n",
    1370             : 
    1371             :       "var x = 13;\n"
    1372             :       "return ~x;\n",
    1373             : 
    1374             :       "var x = 13;\n"
    1375             :       "return +x;\n",
    1376             : 
    1377             :       "var x = 13;\n"
    1378             :       "return -x;\n",
    1379           5 :   };
    1380             : 
    1381          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    1382             :                      LoadGolden("UnaryOperators.golden")));
    1383           5 : }
    1384             : 
    1385       28342 : TEST(Typeof) {
    1386             :   InitializedIgnitionHandleScope scope;
    1387           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    1388             :   printer.set_wrap(false);
    1389          10 :   printer.set_test_function_name("f");
    1390             : 
    1391             :   const char* snippets[] = {
    1392             :       "function f() {\n"
    1393             :       " var x = 13;\n"
    1394             :       " return typeof(x);\n"
    1395             :       "};",
    1396             : 
    1397             :       "var x = 13;\n"
    1398             :       "function f() {\n"
    1399             :       " return typeof(x);\n"
    1400             :       "};",
    1401           5 :   };
    1402             : 
    1403          20 :   CHECK(CompareTexts(BuildActual(printer, snippets, "", "\nf();"),
    1404             :                      LoadGolden("Typeof.golden")));
    1405           5 : }
    1406             : 
    1407       28342 : TEST(CompareTypeOf) {
    1408             :   InitializedIgnitionHandleScope scope;
    1409           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    1410             : 
    1411             :   const char* snippets[] = {
    1412             :       "return typeof(1) === 'number';\n",
    1413             : 
    1414             :       "return 'string' === typeof('foo');\n",
    1415             : 
    1416             :       "return typeof(true) == 'boolean';\n",
    1417             : 
    1418             :       "return 'string' === typeof(undefined);\n",
    1419             : 
    1420             :       "return 'unknown' === typeof(undefined);\n",
    1421           5 :   };
    1422             : 
    1423          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    1424             :                      LoadGolden("CompareTypeOf.golden")));
    1425           5 : }
    1426             : 
    1427       28342 : TEST(CompareNil) {
    1428             :   InitializedIgnitionHandleScope scope;
    1429           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    1430             : 
    1431             :   const char* snippets[] = {
    1432             :       "var a = 1;\n"
    1433             :       "return a === null;\n",
    1434             : 
    1435             :       "var a = undefined;\n"
    1436             :       "return undefined === a;\n",
    1437             : 
    1438             :       "var a = undefined;\n"
    1439             :       "return undefined !== a;\n",
    1440             : 
    1441             :       "var a = 2;\n"
    1442             :       "return a != null;\n",
    1443             : 
    1444             :       "var a = undefined;\n"
    1445             :       "return undefined == a;\n",
    1446             : 
    1447             :       "var a = undefined;\n"
    1448             :       "return undefined === a ? 1 : 2;\n",
    1449             : 
    1450             :       "var a = 0;\n"
    1451             :       "return null == a ? 1 : 2;\n",
    1452             : 
    1453             :       "var a = 0;\n"
    1454             :       "return undefined !== a ? 1 : 2;\n",
    1455             : 
    1456             :       "var a = 0;\n"
    1457             :       "return a === null ? 1 : 2;\n",
    1458             : 
    1459             :       "var a = 0;\n"
    1460             :       "if (a === null) {\n"
    1461             :       "  return 1;\n"
    1462             :       "} else {\n"
    1463             :       "  return 2;\n"
    1464             :       "}\n",
    1465             : 
    1466             :       "var a = 0;\n"
    1467             :       "if (a != undefined) {\n"
    1468             :       "  return 1;\n"
    1469             :       "}\n",
    1470             : 
    1471             :       "var a = undefined;\n"
    1472             :       "var b = 0;\n"
    1473             :       "while (a !== undefined) {\n"
    1474             :       "  b++;\n"
    1475             :       "}\n",
    1476           5 :   };
    1477             : 
    1478          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    1479             :                      LoadGolden("CompareNil.golden")));
    1480           5 : }
    1481             : 
    1482       28342 : TEST(Delete) {
    1483             :   InitializedIgnitionHandleScope scope;
    1484           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    1485             : 
    1486             :   const char* snippets[] = {
    1487             :       "var a = {x:13, y:14}; return delete a.x;\n",
    1488             : 
    1489             :       "'use strict'; var a = {x:13, y:14}; return delete a.x;\n",
    1490             : 
    1491             :       "var a = {1:13, 2:14}; return delete a[2];\n",
    1492             : 
    1493             :       "var a = 10; return delete a;\n",
    1494             : 
    1495             :       "'use strict';\n"
    1496             :       "var a = {1:10};\n"
    1497             :       "(function f1() {return a;});\n"
    1498             :       "return delete a[1];\n",
    1499             : 
    1500             :       "return delete 'test';\n",
    1501           5 :   };
    1502             : 
    1503          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    1504             :                      LoadGolden("Delete.golden")));
    1505           5 : }
    1506             : 
    1507       28342 : TEST(GlobalDelete) {
    1508             :   InitializedIgnitionHandleScope scope;
    1509           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    1510             :   printer.set_wrap(false);
    1511          10 :   printer.set_test_function_name("f");
    1512             : 
    1513             :   const char* snippets[] = {
    1514             :       "var a = {x:13, y:14};\n"
    1515             :       "function f() {\n"
    1516             :       "  return delete a.x;\n"
    1517             :       "};\n"
    1518             :       "f();\n",
    1519             : 
    1520             :       "a = {1:13, 2:14};\n"
    1521             :       "function f() {\n"
    1522             :       "  'use strict';\n"
    1523             :       "  return delete a[1];\n"
    1524             :       "};\n"
    1525             :       "f();\n",
    1526             : 
    1527             :       "var a = {x:13, y:14};\n"
    1528             :       "function f() {\n"
    1529             :       "  return delete a;\n"
    1530             :       "};\n"
    1531             :       "f();\n",
    1532             : 
    1533             :       "b = 30;\n"
    1534             :       "function f() {\n"
    1535             :       "  return delete b;\n"
    1536             :       "};\n"
    1537             :       "f();\n",
    1538           5 :   };
    1539             : 
    1540          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    1541             :                      LoadGolden("GlobalDelete.golden")));
    1542           5 : }
    1543             : 
    1544       28342 : TEST(FunctionLiterals) {
    1545             :   InitializedIgnitionHandleScope scope;
    1546           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    1547             : 
    1548             :   const char* snippets[] = {
    1549             :       "return function(){ }\n",
    1550             : 
    1551             :       "return (function(){ })()\n",
    1552             : 
    1553             :       "return (function(x){ return x; })(1)\n",
    1554           5 :   };
    1555             : 
    1556          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    1557             :                      LoadGolden("FunctionLiterals.golden")));
    1558           5 : }
    1559             : 
    1560       28342 : TEST(RegExpLiterals) {
    1561             :   InitializedIgnitionHandleScope scope;
    1562           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    1563             : 
    1564             :   const char* snippets[] = {
    1565             :       "return /ab+d/;\n",
    1566             : 
    1567             :       "return /(\\w+)\\s(\\w+)/i;\n",
    1568             : 
    1569             :       "return /ab+d/.exec('abdd');\n",
    1570           5 :   };
    1571             : 
    1572          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    1573             :                      LoadGolden("RegExpLiterals.golden")));
    1574           5 : }
    1575             : 
    1576       28342 : TEST(ArrayLiterals) {
    1577             :   InitializedIgnitionHandleScope scope;
    1578           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    1579             : 
    1580             :   const char* snippets[] = {
    1581             :       "return [ 1, 2 ];\n",
    1582             : 
    1583             :       "var a = 1; return [ a, a + 1 ];\n",
    1584             : 
    1585             :       "return [ [ 1, 2 ], [ 3 ] ];\n",
    1586             : 
    1587             :       "var a = 1; return [ [ a, 2 ], [ a + 2 ] ];\n",
    1588             : 
    1589             :       "var a = [ 1, 2 ]; return [ ...a ];\n",
    1590             : 
    1591             :       "var a = [ 1, 2 ]; return [ 0, ...a ];\n",
    1592             : 
    1593             :       "var a = [ 1, 2 ]; return [ ...a, 3 ];\n",
    1594           5 :   };
    1595             : 
    1596          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    1597             :                      LoadGolden("ArrayLiterals.golden")));
    1598           5 : }
    1599             : 
    1600       28342 : TEST(ObjectLiterals) {
    1601             :   InitializedIgnitionHandleScope scope;
    1602           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    1603             : 
    1604             :   const char* snippets[] = {
    1605             :       "return { };\n",
    1606             : 
    1607             :       "return { name: 'string', val: 9.2 };\n",
    1608             : 
    1609             :       "var a = 1; return { name: 'string', val: a };\n",
    1610             : 
    1611             :       "var a = 1; return { val: a, val: a + 1 };\n",
    1612             : 
    1613             :       "return { func: function() { } };\n",
    1614             : 
    1615             :       "return { func(a) { return a; } };\n",
    1616             : 
    1617             :       "return { get a() { return 2; } };\n",
    1618             : 
    1619             :       "return { get a() { return this.x; }, set a(val) { this.x = val } };\n",
    1620             : 
    1621             :       "return { set b(val) { this.y = val } };\n",
    1622             : 
    1623             :       "var a = 1; return { 1: a };\n",
    1624             : 
    1625             :       "return { __proto__: null };\n",
    1626             : 
    1627             :       "var a = 'test'; return { [a]: 1 };\n",
    1628             : 
    1629             :       "var a = 'test'; return { val: a, [a]: 1 };\n",
    1630             : 
    1631             :       "var a = 'test'; return { [a]: 1, __proto__: {} };\n",
    1632             : 
    1633             :       "var n = 'name'; return { [n]: 'val', get a() { }, set a(b) {} };\n",
    1634           5 :   };
    1635             : 
    1636          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    1637             :                      LoadGolden("ObjectLiterals.golden")));
    1638           5 : }
    1639             : 
    1640       28342 : TEST(TopLevelObjectLiterals) {
    1641             :   InitializedIgnitionHandleScope scope;
    1642           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    1643             :   printer.set_wrap(false);
    1644          10 :   printer.set_test_function_name("f");
    1645             :   printer.set_top_level(true);
    1646             : 
    1647             :   const char* snippets[] = {
    1648             :       "var a = { func: function() { } };\n",
    1649           5 :   };
    1650             : 
    1651          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    1652             :                      LoadGolden("TopLevelObjectLiterals.golden")));
    1653           5 : }
    1654             : 
    1655       28342 : TEST(TryCatch) {
    1656             :   InitializedIgnitionHandleScope scope;
    1657           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    1658             : 
    1659             :   const char* snippets[] = {
    1660             :       "try { return 1; } catch(e) { return 2; }\n",
    1661             : 
    1662             :       "var a;\n"
    1663             :       "try { a = 1 } catch(e1) {};\n"
    1664             :       "try { a = 2 } catch(e2) { a = 3 }\n",
    1665           5 :   };
    1666             : 
    1667          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    1668             :                      LoadGolden("TryCatch.golden")));
    1669           5 : }
    1670             : 
    1671       28342 : TEST(TryFinally) {
    1672             :   InitializedIgnitionHandleScope scope;
    1673           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    1674             :   const char* snippets[] = {
    1675             :       "var a = 1;\n"
    1676             :       "try { a = 2; } finally { a = 3; }\n",
    1677             : 
    1678             :       "var a = 1;\n"
    1679             :       "try { a = 2; } catch(e) { a = 20 } finally { a = 3; }\n",
    1680             : 
    1681             :       "var a; try {\n"
    1682             :       "  try { a = 1 } catch(e) { a = 2 }\n"
    1683             :       "} catch(e) { a = 20 } finally { a = 3; }\n",
    1684           5 :   };
    1685             : 
    1686          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    1687             :                      LoadGolden("TryFinally.golden")));
    1688           5 : }
    1689             : 
    1690       28342 : TEST(Throw) {
    1691             :   InitializedIgnitionHandleScope scope;
    1692           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    1693             :   const char* snippets[] = {
    1694             :       "throw 1;\n",
    1695             : 
    1696             :       "throw 'Error';\n",
    1697             : 
    1698             :       "var a = 1; if (a) { throw 'Error'; };\n",
    1699           5 :   };
    1700             : 
    1701          20 :   CHECK(
    1702             :       CompareTexts(BuildActual(printer, snippets), LoadGolden("Throw.golden")));
    1703           5 : }
    1704             : 
    1705       28342 : TEST(CallNew) {
    1706             :   InitializedIgnitionHandleScope scope;
    1707           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    1708             :   printer.set_wrap(false);
    1709          10 :   printer.set_test_function_name("f");
    1710             : 
    1711             :   const char* snippets[] = {
    1712             :       "function bar() { this.value = 0; }\n"
    1713             :       "function f() { return new bar(); }\n"
    1714             :       "f();\n",
    1715             : 
    1716             :       "function bar(x) { this.value = 18; this.x = x;}\n"
    1717             :       "function f() { return new bar(3); }\n"
    1718             :       "f();\n",
    1719             : 
    1720             :       "function bar(w, x, y, z) {\n"
    1721             :       "  this.value = 18;\n"
    1722             :       "  this.x = x;\n"
    1723             :       "  this.y = y;\n"
    1724             :       "  this.z = z;\n"
    1725             :       "}\n"
    1726             :       "function f() { return new bar(3, 4, 5); }\n"
    1727             :       "f();\n",
    1728           5 :   };
    1729             : 
    1730          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    1731             :                      LoadGolden("CallNew.golden")));
    1732           5 : }
    1733             : 
    1734       28342 : TEST(ContextVariables) {
    1735             :   // The wide check below relies on MIN_CONTEXT_SLOTS + 3 + 249 == 256, if this
    1736             :   // ever changes, the REPEAT_XXX should be changed to output the correct number
    1737             :   // of unique variables to trigger the wide slot load / store.
    1738             :   STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS + 3 + 249 == 256);
    1739             : 
    1740             :   InitializedIgnitionHandleScope scope;
    1741           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    1742             :   const char* snippets[] = {
    1743             :     "var a; return function() { a = 1; };\n",
    1744             : 
    1745             :     "var a = 1; return function() { a = 2; };\n",
    1746             : 
    1747             :     "var a = 1; var b = 2; return function() { a = 2; b = 3 };\n",
    1748             : 
    1749             :     "var a; (function() { a = 2; })(); return a;\n",
    1750             : 
    1751             :     "'use strict';\n"
    1752             :     "let a = 1;\n"
    1753             :     "{ let b = 2; return function() { a + b; }; }\n",
    1754             : 
    1755             :     "'use strict';\n"
    1756             :     REPEAT_250_UNIQUE_VARS()
    1757             :     "eval();\n"
    1758             :     "var b = 100;\n"
    1759             :     "return b\n",
    1760           5 :   };
    1761             : 
    1762          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    1763             :                      LoadGolden("ContextVariables.golden")));
    1764           5 : }
    1765             : 
    1766       28342 : TEST(ContextParameters) {
    1767             :   InitializedIgnitionHandleScope scope;
    1768           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    1769             :   printer.set_wrap(false);
    1770          10 :   printer.set_test_function_name("f");
    1771             : 
    1772             :   const char* snippets[] = {
    1773             :       "function f(arg1) { return function() { arg1 = 2; }; }",
    1774             : 
    1775             :       "function f(arg1) { var a = function() { arg1 = 2; }; return arg1; }",
    1776             : 
    1777             :       "function f(a1, a2, a3, a4) { return function() { a1 = a3; }; }",
    1778             : 
    1779             :       "function f() { var self = this; return function() { self = 2; }; }",
    1780           5 :   };
    1781             : 
    1782          20 :   CHECK(CompareTexts(BuildActual(printer, snippets, "", "\nf();"),
    1783             :                      LoadGolden("ContextParameters.golden")));
    1784           5 : }
    1785             : 
    1786       28342 : TEST(OuterContextVariables) {
    1787             :   InitializedIgnitionHandleScope scope;
    1788           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    1789             :   printer.set_wrap(false);
    1790          10 :   printer.set_test_function_name("f");
    1791             : 
    1792             :   const char* snippets[] = {
    1793             :       "function Outer() {\n"
    1794             :       "  var outerVar = 1;\n"
    1795             :       "  function Inner(innerArg) {\n"
    1796             :       "    this.innerFunc = function() { return outerVar * innerArg; }\n"
    1797             :       "  }\n"
    1798             :       "  this.getInnerFunc = function() { return new Inner(1).innerFunc; }\n"
    1799             :       "}\n"
    1800             :       "var f = new Outer().getInnerFunc();",
    1801             : 
    1802             :       "function Outer() {\n"
    1803             :       "  var outerVar = 1;\n"
    1804             :       "  function Inner(innerArg) {\n"
    1805             :       "    this.innerFunc = function() { outerVar = innerArg; }\n"
    1806             :       "  }\n"
    1807             :       "  this.getInnerFunc = function() { return new Inner(1).innerFunc; }\n"
    1808             :       "}\n"
    1809             :       "var f = new Outer().getInnerFunc();",
    1810           5 :   };
    1811             : 
    1812          20 :   CHECK(CompareTexts(BuildActual(printer, snippets, "", "\nf();"),
    1813             :                      LoadGolden("OuterContextVariables.golden")));
    1814           5 : }
    1815             : 
    1816       28342 : TEST(CountOperators) {
    1817             :   InitializedIgnitionHandleScope scope;
    1818           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    1819             :   const char* snippets[] = {
    1820             :       "var a = 1; return ++a;\n",
    1821             : 
    1822             :       "var a = 1; return a++;\n",
    1823             : 
    1824             :       "var a = 1; return --a;\n",
    1825             : 
    1826             :       "var a = 1; return a--;\n",
    1827             : 
    1828             :       "var a = { val: 1 }; return a.val++;\n",
    1829             : 
    1830             :       "var a = { val: 1 }; return --a.val;\n",
    1831             : 
    1832             :       "var name = 'var'; var a = { val: 1 }; return a[name]--;\n",
    1833             : 
    1834             :       "var name = 'var'; var a = { val: 1 }; return ++a[name];\n",
    1835             : 
    1836             :       "var a = 1; var b = function() { return a }; return ++a;\n",
    1837             : 
    1838             :       "var a = 1; var b = function() { return a }; return a--;\n",
    1839             : 
    1840             :       "var idx = 1; var a = [1, 2]; return a[idx++] = 2;\n",
    1841           5 :   };
    1842             : 
    1843          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    1844             :                      LoadGolden("CountOperators.golden")));
    1845           5 : }
    1846             : 
    1847       28342 : TEST(GlobalCountOperators) {
    1848             :   InitializedIgnitionHandleScope scope;
    1849           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    1850             :   printer.set_wrap(false);
    1851          10 :   printer.set_test_function_name("f");
    1852             : 
    1853             :   const char* snippets[] = {
    1854             :       "var global = 1;\n"
    1855             :       "function f() { return ++global; }\n"
    1856             :       "f();\n",
    1857             : 
    1858             :       "var global = 1;\n"
    1859             :       "function f() { return global--; }\n"
    1860             :       "f();\n",
    1861             : 
    1862             :       "unallocated = 1;\n"
    1863             :       "function f() { 'use strict'; return --unallocated; }\n"
    1864             :       "f();\n",
    1865             : 
    1866             :       "unallocated = 1;\n"
    1867             :       "function f() { return unallocated++; }\n"
    1868             :       "f();\n",
    1869           5 :   };
    1870             : 
    1871          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    1872             :                      LoadGolden("GlobalCountOperators.golden")));
    1873           5 : }
    1874             : 
    1875       28342 : TEST(CompoundExpressions) {
    1876             :   InitializedIgnitionHandleScope scope;
    1877           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    1878             :   const char* snippets[] = {
    1879             :       "var a = 1; a += 2;\n",
    1880             : 
    1881             :       "var a = 1; a /= 2;\n",
    1882             : 
    1883             :       "var a = { val: 2 }; a.name *= 2;\n",
    1884             : 
    1885             :       "var a = { 1: 2 }; a[1] ^= 2;\n",
    1886             : 
    1887             :       "var a = 1; (function f() { return a; }); a |= 24;\n",
    1888           5 :   };
    1889             : 
    1890          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    1891             :                      LoadGolden("CompoundExpressions.golden")));
    1892           5 : }
    1893             : 
    1894       28342 : TEST(GlobalCompoundExpressions) {
    1895             :   InitializedIgnitionHandleScope scope;
    1896           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    1897             :   printer.set_wrap(false);
    1898          10 :   printer.set_test_function_name("f");
    1899             : 
    1900             :   const char* snippets[] = {
    1901             :       "var global = 1;\n"
    1902             :       "function f() { return global &= 1; }\n"
    1903             :       "f();\n",
    1904             : 
    1905             :       "unallocated = 1;\n"
    1906             :       "function f() { return unallocated += 1; }\n"
    1907             :       "f();\n",
    1908           5 :   };
    1909             : 
    1910          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    1911             :                      LoadGolden("GlobalCompoundExpressions.golden")));
    1912           5 : }
    1913             : 
    1914       28342 : TEST(CreateArguments) {
    1915             :   InitializedIgnitionHandleScope scope;
    1916           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    1917             :   printer.set_wrap(false);
    1918          10 :   printer.set_test_function_name("f");
    1919             : 
    1920             :   const char* snippets[] = {
    1921             :       "function f() { return arguments; }",
    1922             : 
    1923             :       "function f() { return arguments[0]; }",
    1924             : 
    1925             :       "function f() { 'use strict'; return arguments; }",
    1926             : 
    1927             :       "function f(a) { return arguments[0]; }",
    1928             : 
    1929             :       "function f(a, b, c) { return arguments; }",
    1930             : 
    1931             :       "function f(a, b, c) { 'use strict'; return arguments; }",
    1932           5 :   };
    1933             : 
    1934          20 :   CHECK(CompareTexts(BuildActual(printer, snippets, "", "\nf();"),
    1935             :                      LoadGolden("CreateArguments.golden")));
    1936           5 : }
    1937             : 
    1938       28342 : TEST(CreateRestParameter) {
    1939             :   InitializedIgnitionHandleScope scope;
    1940           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    1941             :   printer.set_wrap(false);
    1942          10 :   printer.set_test_function_name("f");
    1943             : 
    1944             :   const char* snippets[] = {
    1945             :       "function f(...restArgs) { return restArgs; }",
    1946             : 
    1947             :       "function f(a, ...restArgs) { return restArgs; }",
    1948             : 
    1949             :       "function f(a, ...restArgs) { return restArgs[0]; }",
    1950             : 
    1951             :       "function f(a, ...restArgs) { return restArgs[0] + arguments[0]; }",
    1952           5 :   };
    1953             : 
    1954          20 :   CHECK(CompareTexts(BuildActual(printer, snippets, "", "\nf();"),
    1955             :                      LoadGolden("CreateRestParameter.golden")));
    1956           5 : }
    1957             : 
    1958       28342 : TEST(ForIn) {
    1959             :   InitializedIgnitionHandleScope scope;
    1960           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    1961             :   const char* snippets[] = {
    1962             :       "for (var p in null) {}\n",
    1963             : 
    1964             :       "for (var p in undefined) {}\n",
    1965             : 
    1966             :       "for (var p in undefined) {}\n",
    1967             : 
    1968             :       "var x = 'potatoes';\n"
    1969             :       "for (var p in x) { return p; }\n",
    1970             : 
    1971             :       "var x = 0;\n"
    1972             :       "for (var p in [1,2,3]) { x += p; }\n",
    1973             : 
    1974             :       "var x = { 'a': 1, 'b': 2 };\n"
    1975             :       "for (x['a'] in [10, 20, 30]) {\n"
    1976             :       "  if (x['a'] == 10) continue;\n"
    1977             :       "  if (x['a'] == 20) break;\n"
    1978             :       "}\n",
    1979             : 
    1980             :       "var x = [ 10, 11, 12 ] ;\n"
    1981             :       "for (x[0] in [1,2,3]) { return x[3]; }\n",
    1982           5 :   };
    1983             : 
    1984          20 :   CHECK(
    1985             :       CompareTexts(BuildActual(printer, snippets), LoadGolden("ForIn.golden")));
    1986           5 : }
    1987             : 
    1988       28342 : TEST(ForOf) {
    1989             :   InitializedIgnitionHandleScope scope;
    1990           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    1991             :   const char* snippets[] = {
    1992             :       "for (var p of [0, 1, 2]) {}\n",
    1993             : 
    1994             :       "var x = 'potatoes';\n"
    1995             :       "for (var p of x) { return p; }\n",
    1996             : 
    1997             :       "for (var x of [10, 20, 30]) {\n"
    1998             :       "  if (x == 10) continue;\n"
    1999             :       "  if (x == 20) break;\n"
    2000             :       "}\n",
    2001             : 
    2002             :       "var x = { 'a': 1, 'b': 2 };\n"
    2003             :       "for (x['a'] of [1,2,3]) { return x['a']; }\n",
    2004           5 :   };
    2005             : 
    2006          20 :   CHECK(
    2007             :       CompareTexts(BuildActual(printer, snippets), LoadGolden("ForOf.golden")));
    2008           5 : }
    2009             : 
    2010       28342 : TEST(Conditional) {
    2011             :   InitializedIgnitionHandleScope scope;
    2012           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    2013             :   const char* snippets[] = {
    2014             :       "return 1 ? 2 : 3;\n",
    2015             : 
    2016             :       "return 1 ? 2 ? 3 : 4 : 5;\n",
    2017             : 
    2018             :       "return 0 < 1 ? 2 : 3;\n",
    2019             : 
    2020             :       "var x = 0;\n"
    2021             :       "return x ? 2 : 3;\n",
    2022           5 :   };
    2023             : 
    2024          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    2025             :                      LoadGolden("Conditional.golden")));
    2026           5 : }
    2027             : 
    2028       28342 : TEST(Switch) {
    2029             :   InitializedIgnitionHandleScope scope;
    2030           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    2031             :   const char* snippets[] = {
    2032             :     "var a = 1;\n"
    2033             :     "switch(a) {\n"
    2034             :     " case 1: return 2;\n"
    2035             :     " case 2: return 3;\n"
    2036             :     "}\n",
    2037             : 
    2038             :     "var a = 1;\n"
    2039             :     "switch(a) {\n"
    2040             :     " case 1: a = 2; break;\n"
    2041             :     " case 2: a = 3; break;\n"
    2042             :     "}\n",
    2043             : 
    2044             :     "var a = 1;\n"
    2045             :     "switch(a) {\n"
    2046             :     " case 1: a = 2; // fall-through\n"
    2047             :     " case 2: a = 3; break;\n"
    2048             :     "}\n",
    2049             : 
    2050             :     "var a = 1;\n"
    2051             :     "switch(a) {\n"
    2052             :     " case 2: break;\n"
    2053             :     " case 3: break;\n"
    2054             :     " default: a = 1; break;\n"
    2055             :     "}\n",
    2056             : 
    2057             :     "var a = 1;\n"
    2058             :     "switch(typeof(a)) {\n"
    2059             :     " case 2: a = 1; break;\n"
    2060             :     " case 3: a = 2; break;\n"
    2061             :     " default: a = 3; break;\n"
    2062             :     "}\n",
    2063             : 
    2064             :     "var a = 1;\n"
    2065             :     "switch(a) {\n"
    2066             :     " case typeof(a): a = 1; break;\n"
    2067             :     " default: a = 2; break;\n"
    2068             :     "}\n",
    2069             : 
    2070             :     "var a = 1;\n"
    2071             :     "switch(a) {\n"
    2072             :     " case 1:\n"
    2073             :     REPEAT_64("  a = 2;\n")
    2074             :     "  break;\n"
    2075             :     " case 2:\n"
    2076             :     "  a = 3;\n"
    2077             :     "  break;\n"
    2078             :     "}\n",
    2079             : 
    2080             :     "var a = 1;\n"
    2081             :     "switch(a) {\n"
    2082             :     " case 1: \n"
    2083             :     "   switch(a + 1) {\n"
    2084             :     "      case 2 : a = 1; break;\n"
    2085             :     "      default : a = 2; break;\n"
    2086             :     "   }  // fall-through\n"
    2087             :     " case 2: a = 3;\n"
    2088             :     "}\n",
    2089           5 :   };
    2090             : 
    2091          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    2092             :                      LoadGolden("Switch.golden")));
    2093           5 : }
    2094             : 
    2095       28342 : TEST(BasicBlockToBoolean) {
    2096             :   InitializedIgnitionHandleScope scope;
    2097           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    2098             :   const char* snippets[] = {
    2099             :       "var a = 1; if (a || a < 0) { return 1; }\n",
    2100             : 
    2101             :       "var a = 1; if (a && a < 0) { return 1; }\n",
    2102             : 
    2103             :       "var a = 1; a = (a || a < 0) ? 2 : 3;\n",
    2104           5 :   };
    2105             : 
    2106          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    2107             :                      LoadGolden("BasicBlockToBoolean.golden")));
    2108           5 : }
    2109             : 
    2110       28342 : TEST(DeadCodeRemoval) {
    2111             :   InitializedIgnitionHandleScope scope;
    2112           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    2113             :   const char* snippets[] = {
    2114             :       "return; var a = 1; a();\n",
    2115             : 
    2116             :       "if (false) { return; }; var a = 1;\n",
    2117             : 
    2118             :       "if (true) { return 1; } else { return 2; };\n",
    2119             : 
    2120             :       "var a = 1; if (a) { return 1; }; return 2;\n",
    2121           5 :   };
    2122             : 
    2123          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    2124             :                      LoadGolden("DeadCodeRemoval.golden")));
    2125           5 : }
    2126             : 
    2127       28342 : TEST(ThisFunction) {
    2128             :   InitializedIgnitionHandleScope scope;
    2129           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    2130             :   printer.set_wrap(false);
    2131          10 :   printer.set_test_function_name("f");
    2132             : 
    2133             :   const char* snippets[] = {
    2134             :       "var f;\n"
    2135             :       "f = function f() {};",
    2136             : 
    2137             :       "var f;\n"
    2138             :       "f = function f() { return f; };",
    2139           5 :   };
    2140             : 
    2141          20 :   CHECK(CompareTexts(BuildActual(printer, snippets, "", "\nf();"),
    2142             :                      LoadGolden("ThisFunction.golden")));
    2143           5 : }
    2144             : 
    2145       28342 : TEST(NewTarget) {
    2146             :   InitializedIgnitionHandleScope scope;
    2147           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    2148             : 
    2149             :   const char* snippets[] = {
    2150             :       "return new.target;\n",
    2151             : 
    2152             :       "new.target;\n",
    2153           5 :   };
    2154             : 
    2155          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    2156             :                      LoadGolden("NewTarget.golden")));
    2157           5 : }
    2158             : 
    2159       28342 : TEST(RemoveRedundantLdar) {
    2160             :   InitializedIgnitionHandleScope scope;
    2161           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    2162             :   const char* snippets[] = {
    2163             :       "var ld_a = 1;\n"          // This test is to check Ldar does not
    2164             :       "while(true) {\n"          // get removed if the preceding Star is
    2165             :       "  ld_a = ld_a + ld_a;\n"  // in a different basicblock.
    2166             :       "  if (ld_a > 10) break;\n"
    2167             :       "}\n"
    2168             :       "return ld_a;\n",
    2169             : 
    2170             :       "var ld_a = 1;\n"
    2171             :       "do {\n"
    2172             :       "  ld_a = ld_a + ld_a;\n"
    2173             :       "  if (ld_a > 10) continue;\n"
    2174             :       "} while(false);\n"
    2175             :       "return ld_a;\n",
    2176             : 
    2177             :       "var ld_a = 1;\n"
    2178             :       "  ld_a = ld_a + ld_a;\n"
    2179             :       "  return ld_a;\n",
    2180           5 :   };
    2181             : 
    2182          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    2183             :                      LoadGolden("RemoveRedundantLdar.golden")));
    2184           5 : }
    2185             : 
    2186       28342 : TEST(GenerateTestUndetectable) {
    2187             :   InitializedIgnitionHandleScope scope;
    2188           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    2189             :   const char* snippets[] = {
    2190             :       "var obj_a = {val:1};\n"
    2191             :       "var b = 10;\n"
    2192             :       "if (obj_a == null) { b = 20;}\n"
    2193             :       "return b;\n",
    2194             : 
    2195             :       "var obj_a = {val:1};\n"
    2196             :       "var b = 10;\n"
    2197             :       "if (obj_a == undefined) { b = 20;}\n"
    2198             :       "return b;\n",
    2199             : 
    2200             :       "var obj_a = {val:1};\n"
    2201             :       "var b = 10;\n"
    2202             :       "if (obj_a != null) { b = 20;}\n"
    2203             :       "return b;\n",
    2204             : 
    2205             :       "var obj_a = {val:1};\n"
    2206             :       "var b = 10;\n"
    2207             :       "if (obj_a != undefined) { b = 20;}\n"
    2208             :       "return b;\n",
    2209             : 
    2210             :       "var obj_a = {val:1};\n"
    2211             :       "var b = 10;\n"
    2212             :       "if (obj_a === null) { b = 20;}\n"
    2213             :       "return b;\n",
    2214             : 
    2215             :       "var obj_a = {val:1};\n"
    2216             :       "var b = 10;\n"
    2217             :       "if (obj_a === undefined) { b = 20;}\n"
    2218             :       "return b;\n",
    2219             : 
    2220             :       "var obj_a = {val:1};\n"
    2221             :       "var b = 10;\n"
    2222             :       "if (obj_a !== null) { b = 20;}\n"
    2223             :       "return b;\n",
    2224             : 
    2225             :       "var obj_a = {val:1};\n"
    2226             :       "var b = 10;\n"
    2227             :       "if (obj_a !== undefined) { b = 20;}\n"
    2228           5 :       "return b;\n"};
    2229             : 
    2230          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    2231             :                      LoadGolden("GenerateTestUndetectable.golden")));
    2232           5 : }
    2233             : 
    2234       28342 : TEST(AssignmentsInBinaryExpression) {
    2235             :   InitializedIgnitionHandleScope scope;
    2236           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    2237             :   const char* snippets[] = {
    2238             :       "var x = 0, y = 1;\n"
    2239             :       "return (x = 2, y = 3, x = 4, y = 5);\n",
    2240             : 
    2241             :       "var x = 55;\n"
    2242             :       "var y = (x = 100);\n"
    2243             :       "return y;\n",
    2244             : 
    2245             :       "var x = 55;\n"
    2246             :       "x = x + (x = 100) + (x = 101);\n"
    2247             :       "return x;\n",
    2248             : 
    2249             :       "var x = 55;\n"
    2250             :       "x = (x = 56) - x + (x = 57);\n"
    2251             :       "x++;\n"
    2252             :       "return x;\n",
    2253             : 
    2254             :       "var x = 55;\n"
    2255             :       "var y = x + (x = 1) + (x = 2) + (x = 3);\n"
    2256             :       "return y;\n",
    2257             : 
    2258             :       "var x = 55;\n"
    2259             :       "var x = x + (x = 1) + (x = 2) + (x = 3);\n"
    2260             :       "return x;\n",
    2261             : 
    2262             :       "var x = 10, y = 20;\n"
    2263             :       "return x + (x = 1) + (x + 1) * (y = 2) + (y = 3) + (x = 4) + (y = 5) + "
    2264             :       "y;\n",
    2265             : 
    2266             :       "var x = 17;\n"
    2267             :       "return 1 + x + (x++) + (++x);\n",
    2268           5 :   };
    2269             : 
    2270          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    2271             :                      LoadGolden("AssignmentsInBinaryExpression.golden")));
    2272           5 : }
    2273             : 
    2274       28342 : TEST(DestructuringAssignment) {
    2275             :   InitializedIgnitionHandleScope scope;
    2276           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    2277             :   const char* snippets[] = {
    2278             :       "var x, a = [0,1,2,3];\n"
    2279             :       "[x] = a;\n",
    2280             : 
    2281             :       "var x, y, a = [0,1,2,3];\n"
    2282             :       "[,x,...y] = a;\n",
    2283             : 
    2284             :       "var x={}, y, a = [0];\n"
    2285             :       "[x.foo,y=4] = a;\n",
    2286             : 
    2287             :       "var x, a = {x:1};\n"
    2288             :       "({x} = a);\n",
    2289             : 
    2290             :       "var x={}, a = {y:1};\n"
    2291             :       "({y:x.foo} = a);\n",
    2292             : 
    2293             :       "var x, a = {y:1, w:2, v:3};\n"
    2294             :       "({x=0,...y} = a);\n",
    2295           5 :   };
    2296             : 
    2297          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    2298             :                      LoadGolden("DestructuringAssignment.golden")));
    2299           5 : }
    2300             : 
    2301       28342 : TEST(Eval) {
    2302             :   InitializedIgnitionHandleScope scope;
    2303           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    2304             :   const char* snippets[] = {
    2305             :       "return eval('1;');\n",
    2306           5 :   };
    2307             : 
    2308          20 :   CHECK(
    2309             :       CompareTexts(BuildActual(printer, snippets), LoadGolden("Eval.golden")));
    2310           5 : }
    2311             : 
    2312       28342 : TEST(LookupSlot) {
    2313             :   InitializedIgnitionHandleScope scope;
    2314           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    2315          10 :   printer.set_test_function_name("f");
    2316             : 
    2317             :   // clang-format off
    2318             :   const char* snippets[] = {
    2319             :       "eval('var x = 10;'); return x;\n",
    2320             : 
    2321             :       "eval('var x = 10;'); return typeof x;\n",
    2322             : 
    2323             :       "x = 20; return eval('');\n",
    2324             : 
    2325             :       "var x = 20;\n"
    2326             :       "f = function(){\n"
    2327             :       "  eval('var x = 10');\n"
    2328             :       "  return x;\n"
    2329             :       "}\n"
    2330             :       "f();\n",
    2331             : 
    2332             :       "x = 20;\n"
    2333             :       "f = function(){\n"
    2334             :       "  eval('var x = 10');\n"
    2335             :       "  return x;\n"
    2336             :       "}\n"
    2337             :       "f();\n"
    2338           5 :   };
    2339             :   // clang-format on
    2340             : 
    2341          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    2342             :                      LoadGolden("LookupSlot.golden")));
    2343           5 : }
    2344             : 
    2345       28342 : TEST(CallLookupSlot) {
    2346             :   InitializedIgnitionHandleScope scope;
    2347           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    2348             :   const char* snippets[] = {
    2349             :       "g = function(){}; eval(''); return g();\n",
    2350           5 :   };
    2351             : 
    2352          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    2353             :                      LoadGolden("CallLookupSlot.golden")));
    2354           5 : }
    2355             : 
    2356             : // TODO(mythria): tests for variable/function declaration in lookup slots.
    2357             : 
    2358       28342 : TEST(LookupSlotInEval) {
    2359             :   InitializedIgnitionHandleScope scope;
    2360           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    2361             :   printer.set_wrap(false);
    2362          10 :   printer.set_test_function_name("f");
    2363             : 
    2364             :   const char* snippets[] = {
    2365             :       "return x;",
    2366             : 
    2367             :       "x = 10;",
    2368             : 
    2369             :       "'use strict'; x = 10;",
    2370             : 
    2371             :       "return typeof x;",
    2372           5 :   };
    2373             : 
    2374             :   std::string actual = BuildActual(printer, snippets,
    2375             :                                    "var f;\n"
    2376             :                                    "var x = 1;\n"
    2377             :                                    "function f1() {\n"
    2378             :                                    "  eval(\"function t() { ",
    2379             : 
    2380             :                                    " }; f = t; f();\");\n"
    2381             :                                    "}\n"
    2382           5 :                                    "f1();");
    2383             : 
    2384          15 :   CHECK(CompareTexts(actual, LoadGolden("LookupSlotInEval.golden")));
    2385           5 : }
    2386             : 
    2387       28342 : TEST(DeleteLookupSlotInEval) {
    2388             :   InitializedIgnitionHandleScope scope;
    2389           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    2390             :   printer.set_wrap(false);
    2391          10 :   printer.set_test_function_name("f");
    2392             : 
    2393             :   const char* snippets[] = {
    2394             :       "delete x;",
    2395             : 
    2396             :       "return delete y;",
    2397             : 
    2398             :       "return delete z;",
    2399           5 :   };
    2400             : 
    2401             :   std::string actual = BuildActual(printer, snippets,
    2402             :                                    "var f;\n"
    2403             :                                    "var x = 1;\n"
    2404             :                                    "z = 10;\n"
    2405             :                                    "function f1() {\n"
    2406             :                                    "  var y;\n"
    2407             :                                    "  eval(\"function t() { ",
    2408             : 
    2409             :                                    " }; f = t; f();\");\n"
    2410             :                                    "}\n"
    2411           5 :                                    "f1();");
    2412             : 
    2413          15 :   CHECK(CompareTexts(actual, LoadGolden("DeleteLookupSlotInEval.golden")));
    2414           5 : }
    2415             : 
    2416       28342 : TEST(WideRegisters) {
    2417             :   // Prepare prologue that creates frame for lots of registers.
    2418           5 :   std::ostringstream os;
    2419         790 :   for (size_t i = 0; i < 157; ++i) {
    2420        1570 :     os << "var x" << i << ";\n";
    2421             :   }
    2422             :   std::string prologue(os.str());
    2423             : 
    2424             :   InitializedIgnitionHandleScope scope;
    2425           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    2426             :   const char* snippets[] = {
    2427             :       "x0 = x127;\n"
    2428             :       "return x0;\n",
    2429             : 
    2430             :       "x127 = x126;\n"
    2431             :       "return x127;\n",
    2432             : 
    2433             :       "if (x2 > 3) { return x129; }\n"
    2434             :       "return x128;\n",
    2435             : 
    2436             :       "var x0 = 0;\n"
    2437             :       "if (x129 == 3) { var x129 = x0; }\n"
    2438             :       "if (x2 > 3) { return x0; }\n"
    2439             :       "return x129;\n",
    2440             : 
    2441             :       "var x0 = 0;\n"
    2442             :       "var x1 = 0;\n"
    2443             :       "for (x128 = 0; x128 < 64; x128++) {"
    2444             :       "  x1 += x128;"
    2445             :       "}"
    2446             :       "return x128;\n",
    2447             : 
    2448             :       "var x0 = 1234;\n"
    2449             :       "var x1 = 0;\n"
    2450             :       "for (x128 in x0) {"
    2451             :       "  x1 += x128;"
    2452             :       "}"
    2453             :       "return x1;\n",
    2454             : 
    2455             :       "x0 = %Add(x64, x63);\n"
    2456             :       "x1 = %Add(x27, x143);\n"
    2457             :       "%TheHole();\n"
    2458             :       "return x1;\n",
    2459           5 :   };
    2460             : 
    2461          25 :   CHECK(CompareTexts(BuildActual(printer, snippets, prologue.c_str()),
    2462           5 :                      LoadGolden("WideRegisters.golden")));
    2463           5 : }
    2464             : 
    2465       28342 : TEST(ConstVariable) {
    2466             :   InitializedIgnitionHandleScope scope;
    2467           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    2468             :   const char* snippets[] = {
    2469             :       "const x = 10;\n",
    2470             : 
    2471             :       "const x = 10; return x;\n",
    2472             : 
    2473             :       "const x = ( x = 20);\n",
    2474             : 
    2475             :       "const x = 10; x = 20;\n",
    2476           5 :   };
    2477             : 
    2478          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    2479             :                      LoadGolden("ConstVariable.golden")));
    2480           5 : }
    2481             : 
    2482       28342 : TEST(LetVariable) {
    2483             :   InitializedIgnitionHandleScope scope;
    2484           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    2485             :   const char* snippets[] = {
    2486             :       "let x = 10;\n",
    2487             : 
    2488             :       "let x = 10; return x;\n",
    2489             : 
    2490             :       "let x = (x = 20);\n",
    2491             : 
    2492             :       "let x = 10; x = 20;\n",
    2493           5 :   };
    2494             : 
    2495          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    2496             :                      LoadGolden("LetVariable.golden")));
    2497           5 : }
    2498             : 
    2499       28342 : TEST(ConstVariableContextSlot) {
    2500             :   // TODO(mythria): Add tests for initialization of this via super calls.
    2501             :   // TODO(mythria): Add tests that walk the context chain.
    2502             :   InitializedIgnitionHandleScope scope;
    2503           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    2504             :   const char* snippets[] = {
    2505             :       "const x = 10; function f1() {return x;}\n",
    2506             : 
    2507             :       "const x = 10; function f1() {return x;} return x;\n",
    2508             : 
    2509             :       "const x = (x = 20); function f1() {return x;}\n",
    2510             : 
    2511             :       "const x = 10; x = 20; function f1() {return x;}\n",
    2512           5 :   };
    2513             : 
    2514          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    2515             :                      LoadGolden("ConstVariableContextSlot.golden")));
    2516           5 : }
    2517             : 
    2518       28342 : TEST(LetVariableContextSlot) {
    2519             :   InitializedIgnitionHandleScope scope;
    2520           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    2521             :   const char* snippets[] = {
    2522             :       "let x = 10; function f1() {return x;}\n",
    2523             : 
    2524             :       "let x = 10; function f1() {return x;} return x;\n",
    2525             : 
    2526             :       "let x = (x = 20); function f1() {return x;}\n",
    2527             : 
    2528             :       "let x = 10; x = 20; function f1() {return x;}\n",
    2529           5 :   };
    2530             : 
    2531          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    2532             :                      LoadGolden("LetVariableContextSlot.golden")));
    2533           5 : }
    2534             : 
    2535       28342 : TEST(WithStatement) {
    2536             :   InitializedIgnitionHandleScope scope;
    2537           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    2538             :   const char* snippets[] = {
    2539             :       "with ({x:42}) { return x; }\n",
    2540           5 :   };
    2541             : 
    2542          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    2543             :                      LoadGolden("WithStatement.golden")));
    2544           5 : }
    2545             : 
    2546       28342 : TEST(DoDebugger) {
    2547             :   InitializedIgnitionHandleScope scope;
    2548           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    2549             :   const char* snippets[] = {
    2550             :       "debugger;\n",
    2551           5 :   };
    2552             : 
    2553          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    2554             :                      LoadGolden("DoDebugger.golden")));
    2555           5 : }
    2556             : 
    2557       28342 : TEST(ClassDeclarations) {
    2558             :   InitializedIgnitionHandleScope scope;
    2559           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    2560             :   const char* snippets[] = {
    2561             :       "class Person {\n"
    2562             :       "  constructor(name) { this.name = name; }\n"
    2563             :       "  speak() { console.log(this.name + ' is speaking.'); }\n"
    2564             :       "}\n",
    2565             : 
    2566             :       "class person {\n"
    2567             :       "  constructor(name) { this.name = name; }\n"
    2568             :       "  speak() { console.log(this.name + ' is speaking.'); }\n"
    2569             :       "}\n",
    2570             : 
    2571             :       "var n0 = 'a';\n"
    2572             :       "var n1 = 'b';\n"
    2573             :       "class N {\n"
    2574             :       "  [n0]() { return n0; }\n"
    2575             :       "  static [n1]() { return n1; }\n"
    2576             :       "}\n",
    2577             : 
    2578             :       "var count = 0;\n"
    2579             :       "class C { constructor() { count++; }}\n"
    2580             :       "return new C();\n",
    2581             : 
    2582             :       "(class {})\n"
    2583             :       "class E { static name () {}}\n",
    2584           5 :   };
    2585             : 
    2586          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    2587             :                      LoadGolden("ClassDeclarations.golden")));
    2588           5 : }
    2589             : 
    2590       28342 : TEST(ClassAndSuperClass) {
    2591             :   InitializedIgnitionHandleScope scope;
    2592           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    2593             :   printer.set_wrap(false);
    2594          10 :   printer.set_test_function_name("test");
    2595             :   const char* snippets[] = {
    2596             :       "var test;\n"
    2597             :       "(function() {\n"
    2598             :       "  class A {\n"
    2599             :       "    method() { return 2; }\n"
    2600             :       "  }\n"
    2601             :       "  class B extends A {\n"
    2602             :       "    method() { return super.method() + 1; }\n"
    2603             :       "  }\n"
    2604             :       "  test = new B().method;\n"
    2605             :       "  test();\n"
    2606             :       "})();\n",
    2607             : 
    2608             :       "var test;\n"
    2609             :       "(function() {\n"
    2610             :       "  class A {\n"
    2611             :       "    get x() { return 1; }\n"
    2612             :       "    set x(val) { return; }\n"
    2613             :       "  }\n"
    2614             :       "  class B extends A {\n"
    2615             :       "    method() { super.x = 2; return super.x; }\n"
    2616             :       "  }\n"
    2617             :       "  test = new B().method;\n"
    2618             :       "  test();\n"
    2619             :       "})();\n",
    2620             : 
    2621             :       "var test;\n"
    2622             :       "(function() {\n"
    2623             :       "  class A {\n"
    2624             :       "    constructor(x) { this.x_ = x; }\n"
    2625             :       "  }\n"
    2626             :       "  class B extends A {\n"
    2627             :       "    constructor() { super(1); this.y_ = 2; }\n"
    2628             :       "  }\n"
    2629             :       "  test = new B().constructor;\n"
    2630             :       "})();\n",
    2631             : 
    2632             :       "var test;\n"
    2633             :       "(function() {\n"
    2634             :       "  class A {\n"
    2635             :       "    constructor() { this.x_ = 1; }\n"
    2636             :       "  }\n"
    2637             :       "  class B extends A {\n"
    2638             :       "    constructor() { super(); this.y_ = 2; }\n"
    2639             :       "  }\n"
    2640             :       "  test = new B().constructor;\n"
    2641             :       "})();\n",
    2642           5 :   };
    2643             : 
    2644          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    2645             :                      LoadGolden("ClassAndSuperClass.golden")));
    2646           5 : }
    2647             : 
    2648       28342 : TEST(PublicClassFields) {
    2649           5 :   bool old_flag = i::FLAG_harmony_public_fields;
    2650           5 :   i::FLAG_harmony_public_fields = true;
    2651             :   InitializedIgnitionHandleScope scope;
    2652           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    2653             : 
    2654             :   const char* snippets[] = {
    2655             :       "{\n"
    2656             :       "  class A {\n"
    2657             :       "    a;\n"
    2658             :       "    ['b'];\n"
    2659             :       "  }\n"
    2660             :       "\n"
    2661             :       "  class B {\n"
    2662             :       "    a = 1;\n"
    2663             :       "    ['b'] = this.a;\n"
    2664             :       "  }\n"
    2665             :       "  new A;\n"
    2666             :       "  new B;\n"
    2667             :       "}\n",
    2668             : 
    2669             :       "{\n"
    2670             :       "  class A extends class {} {\n"
    2671             :       "    a;\n"
    2672             :       "    ['b'];\n"
    2673             :       "  }\n"
    2674             :       "\n"
    2675             :       "  class B extends class {} {\n"
    2676             :       "    a = 1;\n"
    2677             :       "    ['b'] = this.a;\n"
    2678             :       "    foo() { return 1; }\n"
    2679             :       "    constructor() {\n"
    2680             :       "      super();\n"
    2681             :       "    }\n"
    2682             :       "  }\n"
    2683             :       "\n"
    2684             :       "  class C extends B {\n"
    2685             :       "    a = 1;\n"
    2686             :       "    ['b'] = this.a;\n"
    2687             :       "    constructor() {\n"
    2688             :       "      (() => super())();\n"
    2689             :       "    }\n"
    2690             :       "  }\n"
    2691             :       "\n"
    2692             :       "  new A;\n"
    2693             :       "  new B;\n"
    2694             :       "  new C;\n"
    2695           5 :       "}\n"};
    2696             : 
    2697          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    2698             :                      LoadGolden("PublicClassFields.golden")));
    2699           5 :   i::FLAG_harmony_public_fields = old_flag;
    2700           5 : }
    2701             : 
    2702       28342 : TEST(PrivateClassFields) {
    2703           5 :   bool old_flag = i::FLAG_harmony_private_fields;
    2704           5 :   i::FLAG_harmony_private_fields = true;
    2705             :   InitializedIgnitionHandleScope scope;
    2706           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    2707             : 
    2708             :   const char* snippets[] = {
    2709             :       "{\n"
    2710             :       "  class A {\n"
    2711             :       "    #a;\n"
    2712             :       "    constructor() {\n"
    2713             :       "      this.#a = 1;\n"
    2714             :       "    }\n"
    2715             :       "  }\n"
    2716             :       "\n"
    2717             :       "  class B {\n"
    2718             :       "    #a = 1;\n"
    2719             :       "  }\n"
    2720             :       "  new A;\n"
    2721             :       "  new B;\n"
    2722             :       "}\n",
    2723             : 
    2724             :       "{\n"
    2725             :       "  class A extends class {} {\n"
    2726             :       "    #a;\n"
    2727             :       "    constructor() {\n"
    2728             :       "      super();\n"
    2729             :       "      this.#a = 1;\n"
    2730             :       "    }\n"
    2731             :       "  }\n"
    2732             :       "\n"
    2733             :       "  class B extends class {} {\n"
    2734             :       "    #a = 1;\n"
    2735             :       "    #b = this.#a;\n"
    2736             :       "    foo() { return this.#a; }\n"
    2737             :       "    bar(v) { this.#b = v; }\n"
    2738             :       "    constructor() {\n"
    2739             :       "      super();\n"
    2740             :       "      this.foo();\n"
    2741             :       "      this.bar(3);\n"
    2742             :       "    }\n"
    2743             :       "  }\n"
    2744             :       "\n"
    2745             :       "  class C extends B {\n"
    2746             :       "    #a = 2;\n"
    2747             :       "    constructor() {\n"
    2748             :       "      (() => super())();\n"
    2749             :       "    }\n"
    2750             :       "  }\n"
    2751             :       "\n"
    2752             :       "  new A;\n"
    2753             :       "  new B;\n"
    2754             :       "  new C;\n"
    2755           5 :       "};\n"};
    2756             : 
    2757          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    2758             :                      LoadGolden("PrivateClassFields.golden")));
    2759           5 :   i::FLAG_harmony_private_fields = old_flag;
    2760           5 : }
    2761             : 
    2762       28342 : TEST(StaticClassFields) {
    2763           5 :   bool old_flag = i::FLAG_harmony_public_fields;
    2764           5 :   bool old_static_flag = i::FLAG_harmony_static_fields;
    2765           5 :   i::FLAG_harmony_public_fields = true;
    2766           5 :   i::FLAG_harmony_static_fields = true;
    2767             :   InitializedIgnitionHandleScope scope;
    2768           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    2769             : 
    2770             :   const char* snippets[] = {
    2771             :       "{\n"
    2772             :       "  class A {\n"
    2773             :       "    a;\n"
    2774             :       "    ['b'];\n"
    2775             :       "    static c;\n"
    2776             :       "    static ['d'];\n"
    2777             :       "  }\n"
    2778             :       "\n"
    2779             :       "  class B {\n"
    2780             :       "    a = 1;\n"
    2781             :       "    ['b'] = this.a;\n"
    2782             :       "    static c = 3;\n"
    2783             :       "    static ['d'] = this.c;\n"
    2784             :       "  }\n"
    2785             :       "  new A;\n"
    2786             :       "  new B;\n"
    2787             :       "}\n",
    2788             : 
    2789             :       "{\n"
    2790             :       "  class A extends class {} {\n"
    2791             :       "    a;\n"
    2792             :       "    ['b'];\n"
    2793             :       "    static c;\n"
    2794             :       "    static ['d'];\n"
    2795             :       "  }\n"
    2796             :       "\n"
    2797             :       "  class B extends class {} {\n"
    2798             :       "    a = 1;\n"
    2799             :       "    ['b'] = this.a;\n"
    2800             :       "    static c = 3;\n"
    2801             :       "    static ['d'] = this.c;\n"
    2802             :       "    foo() { return 1; }\n"
    2803             :       "    constructor() {\n"
    2804             :       "      super();\n"
    2805             :       "    }\n"
    2806             :       "  }\n"
    2807             :       "\n"
    2808             :       "  class C extends B {\n"
    2809             :       "    a = 1;\n"
    2810             :       "    ['b'] = this.a;\n"
    2811             :       "    static c = 3;\n"
    2812             :       "    static ['d'] = super.foo();\n"
    2813             :       "    constructor() {\n"
    2814             :       "      (() => super())();\n"
    2815             :       "    }\n"
    2816             :       "  }\n"
    2817             :       "\n"
    2818             :       "  new A;\n"
    2819             :       "  new B;\n"
    2820             :       "  new C;\n"
    2821           5 :       "}\n"};
    2822             : 
    2823          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    2824             :                      LoadGolden("StaticClassFields.golden")));
    2825           5 :   i::FLAG_harmony_public_fields = old_flag;
    2826           5 :   i::FLAG_harmony_static_fields = old_static_flag;
    2827           5 : }
    2828             : 
    2829       28342 : TEST(Generators) {
    2830             :   InitializedIgnitionHandleScope scope;
    2831           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    2832             :   printer.set_wrap(false);
    2833          10 :   printer.set_test_function_name("f");
    2834             : 
    2835             :   const char* snippets[] = {
    2836             :       "function* f() { }\n"
    2837             :       "f();\n",
    2838             : 
    2839             :       "function* f() { yield 42 }\n"
    2840             :       "f();\n",
    2841             : 
    2842             :       "function* f() { for (let x of [42]) yield x }\n"
    2843             :       "f();\n",
    2844             : 
    2845             :       "function* g() { yield 42 }\n"
    2846             :       "function* f() { yield* g() }\n"
    2847             :       "f();\n",
    2848           5 :   };
    2849             : 
    2850          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    2851             :                      LoadGolden("Generators.golden")));
    2852           5 : }
    2853             : 
    2854       28342 : TEST(AsyncGenerators) {
    2855             :   InitializedIgnitionHandleScope scope;
    2856           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    2857             :   printer.set_wrap(false);
    2858          10 :   printer.set_test_function_name("f");
    2859             : 
    2860             :   const char* snippets[] = {
    2861             :       "async function* f() { }\n"
    2862             :       "f();\n",
    2863             : 
    2864             :       "async function* f() { yield 42 }\n"
    2865             :       "f();\n",
    2866             : 
    2867             :       "async function* f() { for (let x of [42]) yield x }\n"
    2868             :       "f();\n",
    2869             : 
    2870             :       "function* g() { yield 42 }\n"
    2871             :       "async function* f() { yield* g() }\n"
    2872             :       "f();\n",
    2873           5 :   };
    2874             : 
    2875          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    2876             :                      LoadGolden("AsyncGenerators.golden")));
    2877           5 : }
    2878             : 
    2879       28342 : TEST(Modules) {
    2880             :   InitializedIgnitionHandleScope scope;
    2881           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    2882             :   printer.set_wrap(false);
    2883             :   printer.set_module(true);
    2884             :   printer.set_top_level(true);
    2885             : 
    2886             :   const char* snippets[] = {
    2887             :       "import \"bar\";\n",
    2888             : 
    2889             :       "import {foo} from \"bar\";\n",
    2890             : 
    2891             :       "import {foo as goo} from \"bar\";\n"
    2892             :       "goo(42);\n"
    2893             :       "{ let x; { goo(42) } };\n",
    2894             : 
    2895             :       "export var foo = 42;\n"
    2896             :       "foo++;\n"
    2897             :       "{ let x; { foo++ } };\n",
    2898             : 
    2899             :       "export let foo = 42;\n"
    2900             :       "foo++;\n"
    2901             :       "{ let x; { foo++ } };\n",
    2902             : 
    2903             :       "export const foo = 42;\n"
    2904             :       "foo++;\n"
    2905             :       "{ let x; { foo++ } };\n",
    2906             : 
    2907             :       "export default (function () {});\n",
    2908             : 
    2909             :       "export default (class {});\n",
    2910             : 
    2911             :       "export {foo as goo} from \"bar\"\n",
    2912             : 
    2913             :       "export * from \"bar\"\n",
    2914             : 
    2915             :       "import * as foo from \"bar\"\n"
    2916             :       "foo.f(foo, foo.x);\n",
    2917           5 :   };
    2918             : 
    2919          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    2920             :                      LoadGolden("Modules.golden")));
    2921           5 : }
    2922             : 
    2923       28342 : TEST(SuperCallAndSpread) {
    2924             :   InitializedIgnitionHandleScope scope;
    2925           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    2926             :   printer.set_wrap(false);
    2927          10 :   printer.set_test_function_name("test");
    2928             :   const char* snippets[] = {
    2929             :       "var test;\n"
    2930             :       "(function() {\n"
    2931             :       "  class A {\n"
    2932             :       "    constructor(...args) { this.baseArgs = args; }\n"
    2933             :       "  }\n"
    2934             :       "  class B extends A {}\n"
    2935             :       "  test = new B(1, 2, 3).constructor;\n"
    2936             :       "})();\n",
    2937             : 
    2938             :       "var test;\n"
    2939             :       "(function() {\n"
    2940             :       "  class A {\n"
    2941             :       "    constructor(...args) { this.baseArgs = args; }\n"
    2942             :       "  }\n"
    2943             :       "  class B extends A {\n"
    2944             :       "    constructor(...args) { super(1, ...args); }\n"
    2945             :       "  }\n"
    2946             :       "  test = new B(1, 2, 3).constructor;\n"
    2947             :       "})();\n",
    2948             : 
    2949             :       "var test;\n"
    2950             :       "(function() {\n"
    2951             :       "  class A {\n"
    2952             :       "    constructor(...args) { this.baseArgs = args; }\n"
    2953             :       "  }\n"
    2954             :       "  class B extends A {\n"
    2955             :       "    constructor(...args) { super(1, ...args, 1); }\n"
    2956             :       "  }\n"
    2957             :       "  test = new B(1, 2, 3).constructor;\n"
    2958             :       "})();\n",
    2959           5 :   };
    2960             : 
    2961          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    2962             :                      LoadGolden("SuperCallAndSpread.golden")));
    2963           5 : }
    2964             : 
    2965       28342 : TEST(CallAndSpread) {
    2966             :   InitializedIgnitionHandleScope scope;
    2967           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    2968             :   const char* snippets[] = {"Math.max(...[1, 2, 3]);\n",
    2969             :                             "Math.max(0, ...[1, 2, 3]);\n",
    2970           5 :                             "Math.max(0, ...[1, 2, 3], 4);\n"};
    2971             : 
    2972          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    2973             :                      LoadGolden("CallAndSpread.golden")));
    2974           5 : }
    2975             : 
    2976       28342 : TEST(NewAndSpread) {
    2977             :   InitializedIgnitionHandleScope scope;
    2978           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    2979             :   const char* snippets[] = {
    2980             :       "class A { constructor(...args) { this.args = args; } }\n"
    2981             :       "new A(...[1, 2, 3]);\n",
    2982             : 
    2983             :       "class A { constructor(...args) { this.args = args; } }\n"
    2984             :       "new A(0, ...[1, 2, 3]);\n",
    2985             : 
    2986             :       "class A { constructor(...args) { this.args = args; } }\n"
    2987           5 :       "new A(0, ...[1, 2, 3], 4);\n"};
    2988             : 
    2989          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    2990             :                      LoadGolden("NewAndSpread.golden")));
    2991           5 : }
    2992             : 
    2993       28342 : TEST(ForAwaitOf) {
    2994             :   InitializedIgnitionHandleScope scope;
    2995           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    2996             :   printer.set_wrap(false);
    2997          10 :   printer.set_test_function_name("f");
    2998             : 
    2999             :   const char* snippets[] = {
    3000             :       "async function f() {\n"
    3001             :       "  for await (let x of [1, 2, 3]) {}\n"
    3002             :       "}\n"
    3003             :       "f();\n",
    3004             : 
    3005             :       "async function f() {\n"
    3006             :       "  for await (let x of [1, 2, 3]) { return x; }\n"
    3007             :       "}\n"
    3008             :       "f();\n",
    3009             : 
    3010             :       "async function f() {\n"
    3011             :       "  for await (let x of [10, 20, 30]) {\n"
    3012             :       "    if (x == 10) continue;\n"
    3013             :       "    if (x == 20) break;\n"
    3014             :       "  }\n"
    3015             :       "}\n"
    3016             :       "f();\n",
    3017             : 
    3018             :       "async function f() {\n"
    3019             :       "  var x = { 'a': 1, 'b': 2 };\n"
    3020             :       "  for (x['a'] of [1,2,3]) { return x['a']; }\n"
    3021             :       "}\n"
    3022           5 :       "f();\n"};
    3023             : 
    3024          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    3025             :                      LoadGolden("ForAwaitOf.golden")));
    3026           5 : }
    3027             : 
    3028       28342 : TEST(StandardForLoop) {
    3029             :   InitializedIgnitionHandleScope scope;
    3030           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    3031             :   printer.set_wrap(false);
    3032          10 :   printer.set_test_function_name("f");
    3033             : 
    3034             :   const char* snippets[] = {
    3035             :       "function f() {\n"
    3036             :       "  for (let x = 0; x < 10; ++x) { let y = x; }\n"
    3037             :       "}\n"
    3038             :       "f();\n",
    3039             : 
    3040             :       "function f() {\n"
    3041             :       "  for (let x = 0; x < 10; ++x) { eval('1'); }\n"
    3042             :       "}\n"
    3043             :       "f();\n",
    3044             : 
    3045             :       "function f() {\n"
    3046             :       "  for (let x = 0; x < 10; ++x) { (function() { return x; })(); }\n"
    3047             :       "}\n"
    3048             :       "f();\n",
    3049             : 
    3050             :       "function f() {\n"
    3051             :       "  for (let { x, y } = { x: 0, y: 3 }; y > 0; --y) { let z = x + y; }\n"
    3052             :       "}\n"
    3053             :       "f();\n",
    3054             : 
    3055             :       "function* f() {\n"
    3056             :       "  for (let x = 0; x < 10; ++x) { let y = x; }\n"
    3057             :       "}\n"
    3058             :       "f();\n",
    3059             : 
    3060             :       "function* f() {\n"
    3061             :       "  for (let x = 0; x < 10; ++x) yield x;\n"
    3062             :       "}\n"
    3063             :       "f();\n",
    3064             : 
    3065             :       "async function f() {\n"
    3066             :       "  for (let x = 0; x < 10; ++x) { let y = x; }\n"
    3067             :       "}\n"
    3068             :       "f();\n",
    3069             : 
    3070             :       "async function f() {\n"
    3071             :       "  for (let x = 0; x < 10; ++x) await x;\n"
    3072             :       "}\n"
    3073           5 :       "f();\n"};
    3074             : 
    3075          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    3076             :                      LoadGolden("StandardForLoop.golden")));
    3077           5 : }
    3078             : 
    3079       28342 : TEST(ForOfLoop) {
    3080             :   InitializedIgnitionHandleScope scope;
    3081           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    3082             :   printer.set_wrap(false);
    3083          10 :   printer.set_test_function_name("f");
    3084             : 
    3085             :   const char* snippets[] = {
    3086             :       "function f(arr) {\n"
    3087             :       "  for (let x of arr) { let y = x; }\n"
    3088             :       "}\n"
    3089             :       "f([1, 2, 3]);\n",
    3090             : 
    3091             :       "function f(arr) {\n"
    3092             :       "  for (let x of arr) { eval('1'); }\n"
    3093             :       "}\n"
    3094             :       "f([1, 2, 3]);\n",
    3095             : 
    3096             :       "function f(arr) {\n"
    3097             :       "  for (let x of arr) { (function() { return x; })(); }\n"
    3098             :       "}\n"
    3099             :       "f([1, 2, 3]);\n",
    3100             : 
    3101             :       "function f(arr) {\n"
    3102             :       "  for (let { x, y } of arr) { let z = x + y; }\n"
    3103             :       "}\n"
    3104             :       "f([{ x: 0, y: 3 }, { x: 1, y: 9 }, { x: -12, y: 17 }]);\n",
    3105             : 
    3106             :       "function* f(arr) {\n"
    3107             :       "  for (let x of arr) { let y = x; }\n"
    3108             :       "}\n"
    3109             :       "f([1, 2, 3]);\n",
    3110             : 
    3111             :       "function* f(arr) {\n"
    3112             :       "  for (let x of arr) yield x;\n"
    3113             :       "}\n"
    3114             :       "f([1, 2, 3]);\n",
    3115             : 
    3116             :       "async function f(arr) {\n"
    3117             :       "  for (let x of arr) { let y = x; }\n"
    3118             :       "}\n"
    3119             :       "f([1, 2, 3]);\n",
    3120             : 
    3121             :       "async function f(arr) {\n"
    3122             :       "  for (let x of arr) await x;\n"
    3123             :       "}\n"
    3124           5 :       "f([1, 2, 3]);\n"};
    3125             : 
    3126          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    3127             :                      LoadGolden("ForOfLoop.golden")));
    3128           5 : }
    3129             : 
    3130       28342 : TEST(StringConcat) {
    3131             :   InitializedIgnitionHandleScope scope;
    3132           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    3133             : 
    3134             :   const char* snippets[] = {
    3135             :       "var a = 1;\n"
    3136             :       "var b = 2;\n"
    3137             :       "return a + b + 'string';\n",
    3138             : 
    3139             :       "var a = 1;\n"
    3140             :       "var b = 2;\n"
    3141             :       "return 'string' + a + b;\n",
    3142             : 
    3143             :       "var a = 1;\n"
    3144             :       "var b = 2;\n"
    3145             :       "return a + 'string' + b;\n",
    3146             : 
    3147             :       "var a = 1;\n"
    3148             :       "var b = 2;\n"
    3149             :       "return 'foo' + a + 'bar' + b + 'baz' + 1;\n",
    3150             : 
    3151             :       "var a = 1;\n"
    3152             :       "var b = 2;\n"
    3153             :       "return (a + 'string') + ('string' + b);\n",
    3154             : 
    3155             :       "var a = 1;\n"
    3156             :       "var b = 2;\n"
    3157             :       "function foo(a, b) { };\n"
    3158             :       "return 'string' + foo(a, b) + a + b;\n",
    3159           5 :   };
    3160             : 
    3161          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    3162             :                      LoadGolden("StringConcat.golden")));
    3163           5 : }
    3164             : 
    3165       28342 : TEST(TemplateLiterals) {
    3166             :   InitializedIgnitionHandleScope scope;
    3167           5 :   BytecodeExpectationsPrinter printer(CcTest::isolate());
    3168             : 
    3169             :   const char* snippets[] = {
    3170             :       "var a = 1;\n"
    3171             :       "var b = 2;\n"
    3172             :       "return `${a}${b}string`;\n",
    3173             : 
    3174             :       "var a = 1;\n"
    3175             :       "var b = 2;\n"
    3176             :       "return `string${a}${b}`;\n",
    3177             : 
    3178             :       "var a = 1;\n"
    3179             :       "var b = 2;\n"
    3180             :       "return `${a}string${b}`;\n",
    3181             : 
    3182             :       "var a = 1;\n"
    3183             :       "var b = 2;\n"
    3184             :       "return `foo${a}bar${b}baz${1}`;\n",
    3185             : 
    3186             :       "var a = 1;\n"
    3187             :       "var b = 2;\n"
    3188             :       "return `${a}string` + `string${b}`;\n",
    3189             : 
    3190             :       "var a = 1;\n"
    3191             :       "var b = 2;\n"
    3192             :       "function foo(a, b) { };\n"
    3193             :       "return `string${foo(a, b)}${a}${b}`;\n",
    3194           5 :   };
    3195             : 
    3196          20 :   CHECK(CompareTexts(BuildActual(printer, snippets),
    3197             :                      LoadGolden("TemplateLiterals.golden")));
    3198           5 : }
    3199             : 
    3200             : #undef XSTR
    3201             : #undef STR
    3202             : #undef UNIQUE_VAR
    3203             : #undef REPEAT_2
    3204             : #undef REPEAT_4
    3205             : #undef REPEAT_8
    3206             : #undef REPEAT_16
    3207             : #undef REPEAT_32
    3208             : #undef REPEAT_64
    3209             : #undef REPEAT_128
    3210             : #undef REPEAT_256
    3211             : #undef REPEAT_127
    3212             : #undef REPEAT_249
    3213             : #undef REPEAT_2_UNIQUE_VARS
    3214             : #undef REPEAT_4_UNIQUE_VARS
    3215             : #undef REPEAT_8_UNIQUE_VARS
    3216             : #undef REPEAT_16_UNIQUE_VARS
    3217             : #undef REPEAT_32_UNIQUE_VARS
    3218             : #undef REPEAT_64_UNIQUE_VARS
    3219             : #undef REPEAT_128_UNIQUE_VARS
    3220             : #undef REPEAT_250_UNIQUE_VARS
    3221             : #undef LOAD_UNIQUE_PROPERTY
    3222             : #undef REPEAT_2_LOAD_UNIQUE_PROPERTY
    3223             : #undef REPEAT_4_LOAD_UNIQUE_PROPERTY
    3224             : #undef REPEAT_8_LOAD_UNIQUE_PROPERTY
    3225             : #undef REPEAT_16_LOAD_UNIQUE_PROPERTY
    3226             : #undef REPEAT_32_LOAD_UNIQUE_PROPERTY
    3227             : #undef REPEAT_64_LOAD_UNIQUE_PROPERTY
    3228             : #undef REPEAT_128_LOAD_UNIQUE_PROPERTY
    3229             : #undef FUNC_ARG
    3230             : 
    3231             : }  // namespace interpreter
    3232             : }  // namespace internal
    3233       85011 : }  // namespace v8

Generated by: LCOV version 1.10