Home | History | Annotate | Download | only in interpreter
      1 // Copyright 2015 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "src/v8.h"
      6 
      7 #include "src/compiler.h"
      8 #include "src/interpreter/bytecode-array-iterator.h"
      9 #include "src/interpreter/bytecode-generator.h"
     10 #include "src/interpreter/interpreter.h"
     11 #include "test/cctest/cctest.h"
     12 #include "test/cctest/test-feedback-vector.h"
     13 
     14 namespace v8 {
     15 namespace internal {
     16 namespace interpreter {
     17 
     18 class BytecodeGeneratorHelper {
     19  public:
     20   const char* kFunctionName = "f";
     21 
     22   static const int kLastParamIndex =
     23       -InterpreterFrameConstants::kLastParamFromRegisterPointer / kPointerSize;
     24 
     25   BytecodeGeneratorHelper() {
     26     i::FLAG_ignition = true;
     27     i::FLAG_ignition_fake_try_catch = true;
     28     i::FLAG_ignition_fallback_on_eval_and_catch = false;
     29     i::FLAG_ignition_filter = StrDup(kFunctionName);
     30     i::FLAG_always_opt = false;
     31     i::FLAG_allow_natives_syntax = true;
     32     i::FLAG_legacy_const = true;
     33     CcTest::i_isolate()->interpreter()->Initialize();
     34   }
     35 
     36   Isolate* isolate() { return CcTest::i_isolate(); }
     37   Factory* factory() { return CcTest::i_isolate()->factory(); }
     38 
     39   Handle<BytecodeArray> MakeTopLevelBytecode(const char* source) {
     40     const char* old_ignition_filter = i::FLAG_ignition_filter;
     41     i::FLAG_ignition_filter = "*";
     42     Local<v8::Script> script = v8_compile(source);
     43     i::FLAG_ignition_filter = old_ignition_filter;
     44     i::Handle<i::JSFunction> js_function = v8::Utils::OpenHandle(*script);
     45     return handle(js_function->shared()->bytecode_array(), CcTest::i_isolate());
     46   }
     47 
     48   Handle<BytecodeArray> MakeBytecode(const char* script,
     49                                      const char* function_name) {
     50     CompileRun(script);
     51     v8::Local<v8::Context> context =
     52         v8::Isolate::GetCurrent()->GetCurrentContext();
     53     Local<Function> function = Local<Function>::Cast(
     54         CcTest::global()->Get(context, v8_str(function_name)).ToLocalChecked());
     55     i::Handle<i::JSFunction> js_function =
     56         i::Handle<i::JSFunction>::cast(v8::Utils::OpenHandle(*function));
     57     return handle(js_function->shared()->bytecode_array(), CcTest::i_isolate());
     58   }
     59 
     60   Handle<BytecodeArray> MakeBytecode(const char* script, const char* filter,
     61                                      const char* function_name) {
     62     const char* old_ignition_filter = i::FLAG_ignition_filter;
     63     i::FLAG_ignition_filter = filter;
     64     Handle<BytecodeArray> return_val = MakeBytecode(script, function_name);
     65     i::FLAG_ignition_filter = old_ignition_filter;
     66     return return_val;
     67   }
     68 
     69   Handle<BytecodeArray> MakeBytecodeForFunctionBody(const char* body) {
     70     static const char kFormat[] = "function %s() { %s }\n%s();";
     71     static const int kFormatLength = arraysize(kFormat);
     72     int length = kFormatLength + 2 * StrLength(kFunctionName) + StrLength(body);
     73     ScopedVector<char> program(length);
     74     length = SNPrintF(program, kFormat, kFunctionName, body, kFunctionName);
     75     CHECK_GT(length, 0);
     76     return MakeBytecode(program.start(), kFunctionName);
     77   }
     78 
     79   Handle<BytecodeArray> MakeBytecodeForFunction(const char* function) {
     80     ScopedVector<char> program(3072);
     81     SNPrintF(program, "%s\n%s();", function, kFunctionName);
     82     return MakeBytecode(program.start(), kFunctionName);
     83   }
     84 
     85   Handle<BytecodeArray> MakeBytecodeForFunctionNoFilter(const char* function) {
     86     ScopedVector<char> program(3072);
     87     SNPrintF(program, "%s\n%s();", function, kFunctionName);
     88     return MakeBytecode(program.start(), "*", kFunctionName);
     89   }
     90 };
     91 
     92 
     93 // Helper macros for handcrafting bytecode sequences.
     94 #define B(x) static_cast<uint8_t>(Bytecode::k##x)
     95 #define U8(x) static_cast<uint8_t>((x) & 0xff)
     96 #define R(x) static_cast<uint8_t>(-(x) & 0xff)
     97 #define A(x, n) R(helper.kLastParamIndex - (n) + 1 + (x))
     98 #define THIS(n) A(0, n)
     99 #if defined(V8_TARGET_LITTLE_ENDIAN)
    100 #define U16(x) static_cast<uint8_t>((x) & 0xff),                    \
    101                static_cast<uint8_t>(((x) >> kBitsPerByte) & 0xff)
    102 #define U16I(x) static_cast<uint8_t>((x) & 0xff),                   \
    103                 static_cast<uint8_t>(((x++) >> kBitsPerByte) & 0xff)
    104 #elif defined(V8_TARGET_BIG_ENDIAN)
    105 #define U16(x) static_cast<uint8_t>(((x) >> kBitsPerByte) & 0xff),   \
    106                static_cast<uint8_t>((x) & 0xff)
    107 #define U16I(x) static_cast<uint8_t>(((x) >> kBitsPerByte) & 0xff),  \
    108                 static_cast<uint8_t>((x++) & 0xff)
    109 #else
    110 #error Unknown byte ordering
    111 #endif
    112 
    113 #define XSTR(A) #A
    114 #define STR(A) XSTR(A)
    115 
    116 #define COMMA() ,
    117 #define SPACE()
    118 #define UNIQUE_VAR() "var a" STR(__COUNTER__) " = 0;\n"
    119 
    120 #define REPEAT_2(SEP, ...)                      \
    121   __VA_ARGS__ SEP() __VA_ARGS__
    122 #define REPEAT_4(SEP, ...)  \
    123   REPEAT_2(SEP, __VA_ARGS__) SEP() REPEAT_2(SEP, __VA_ARGS__)
    124 #define REPEAT_8(SEP, ...)  \
    125   REPEAT_4(SEP, __VA_ARGS__) SEP() REPEAT_4(SEP, __VA_ARGS__)
    126 #define REPEAT_16(SEP, ...)  \
    127   REPEAT_8(SEP, __VA_ARGS__) SEP() REPEAT_8(SEP, __VA_ARGS__)
    128 #define REPEAT_32(SEP, ...)  \
    129   REPEAT_16(SEP, __VA_ARGS__) SEP() REPEAT_16(SEP, __VA_ARGS__)
    130 #define REPEAT_64(SEP, ...)  \
    131   REPEAT_32(SEP, __VA_ARGS__) SEP() REPEAT_32(SEP, __VA_ARGS__)
    132 #define REPEAT_128(SEP, ...)  \
    133   REPEAT_64(SEP, __VA_ARGS__) SEP() REPEAT_64(SEP, __VA_ARGS__)
    134 #define REPEAT_256(SEP, ...)  \
    135   REPEAT_128(SEP, __VA_ARGS__) SEP() REPEAT_128(SEP, __VA_ARGS__)
    136 
    137 #define REPEAT_127(SEP, ...)                                           \
    138   REPEAT_64(SEP, __VA_ARGS__) SEP() REPEAT_32(SEP, __VA_ARGS__) SEP()  \
    139   REPEAT_16(SEP, __VA_ARGS__) SEP() REPEAT_8(SEP, __VA_ARGS__) SEP()   \
    140   REPEAT_4(SEP, __VA_ARGS__) SEP() REPEAT_2(SEP, __VA_ARGS__) SEP()    \
    141   __VA_ARGS__
    142 
    143 #define REPEAT_249(SEP, ...)                                            \
    144   REPEAT_127(SEP, __VA_ARGS__) SEP() REPEAT_64(SEP, __VA_ARGS__) SEP()  \
    145   REPEAT_32(SEP, __VA_ARGS__) SEP() REPEAT_16(SEP, __VA_ARGS__) SEP()   \
    146   REPEAT_8(SEP, __VA_ARGS__) SEP() REPEAT_2(SEP, __VA_ARGS__)
    147 
    148 #define REPEAT_249_UNIQUE_VARS()                                        \
    149 UNIQUE_VAR() REPEAT_127(UNIQUE_VAR) UNIQUE_VAR() REPEAT_64(UNIQUE_VAR)  \
    150 UNIQUE_VAR() REPEAT_32(UNIQUE_VAR) UNIQUE_VAR() REPEAT_16(UNIQUE_VAR)   \
    151 UNIQUE_VAR() REPEAT_8(UNIQUE_VAR) UNIQUE_VAR() REPEAT_2(UNIQUE_VAR)
    152 
    153 // Structure for containing expected bytecode snippets.
    154 template<typename T, int C = 6>
    155 struct ExpectedSnippet {
    156   const char* code_snippet;
    157   int frame_size;
    158   int parameter_count;
    159   int bytecode_length;
    160   const uint8_t bytecode[2048];
    161   int constant_count;
    162   T constants[C];
    163 };
    164 
    165 
    166 static void CheckConstant(int expected, Object* actual) {
    167   CHECK_EQ(expected, Smi::cast(actual)->value());
    168 }
    169 
    170 
    171 static void CheckConstant(double expected, Object* actual) {
    172   CHECK_EQ(expected, HeapNumber::cast(actual)->value());
    173 }
    174 
    175 
    176 static void CheckConstant(const char* expected, Object* actual) {
    177   Handle<String> expected_string =
    178       CcTest::i_isolate()->factory()->NewStringFromAsciiChecked(expected);
    179   CHECK(String::cast(actual)->Equals(*expected_string));
    180 }
    181 
    182 
    183 static void CheckConstant(Handle<Object> expected, Object* actual) {
    184   CHECK(actual == *expected || expected->StrictEquals(actual));
    185 }
    186 
    187 
    188 static void CheckConstant(InstanceType expected, Object* actual) {
    189   CHECK_EQ(expected, HeapObject::cast(actual)->map()->instance_type());
    190 }
    191 
    192 
    193 template <typename T, int C>
    194 static void CheckBytecodeArrayEqual(const ExpectedSnippet<T, C>& expected,
    195                                     Handle<BytecodeArray> actual) {
    196   CHECK_EQ(expected.frame_size, actual->frame_size());
    197   CHECK_EQ(expected.parameter_count, actual->parameter_count());
    198   CHECK_EQ(expected.bytecode_length, actual->length());
    199   if (expected.constant_count == 0) {
    200     CHECK_EQ(CcTest::heap()->empty_fixed_array(), actual->constant_pool());
    201   } else {
    202     CHECK_EQ(expected.constant_count, actual->constant_pool()->length());
    203     for (int i = 0; i < expected.constant_count; i++) {
    204       CheckConstant(expected.constants[i], actual->constant_pool()->get(i));
    205     }
    206   }
    207 
    208   BytecodeArrayIterator iterator(actual);
    209   int i = 0;
    210   while (!iterator.done()) {
    211     int bytecode_index = i++;
    212     Bytecode bytecode = iterator.current_bytecode();
    213     if (Bytecodes::ToByte(bytecode) != expected.bytecode[bytecode_index]) {
    214       std::ostringstream stream;
    215       stream << "Check failed: expected bytecode [" << bytecode_index
    216              << "] to be " << Bytecodes::ToString(static_cast<Bytecode>(
    217                                   expected.bytecode[bytecode_index]))
    218              << " but got " << Bytecodes::ToString(bytecode);
    219       FATAL(stream.str().c_str());
    220     }
    221     for (int j = 0; j < Bytecodes::NumberOfOperands(bytecode); ++j) {
    222       OperandType operand_type = Bytecodes::GetOperandType(bytecode, j);
    223       int operand_index = i;
    224       i += static_cast<int>(Bytecodes::SizeOfOperand(operand_type));
    225       uint32_t raw_operand = iterator.GetRawOperand(j, operand_type);
    226       uint32_t expected_operand;
    227       switch (Bytecodes::SizeOfOperand(operand_type)) {
    228         case OperandSize::kNone:
    229           UNREACHABLE();
    230           return;
    231         case OperandSize::kByte:
    232           expected_operand =
    233               static_cast<uint32_t>(expected.bytecode[operand_index]);
    234           break;
    235         case OperandSize::kShort:
    236           expected_operand =
    237               ReadUnalignedUInt16(&expected.bytecode[operand_index]);
    238           break;
    239         default:
    240           UNREACHABLE();
    241           return;
    242       }
    243       if (raw_operand != expected_operand) {
    244         std::ostringstream stream;
    245         stream << "Check failed: expected operand [" << j << "] for bytecode ["
    246                << bytecode_index << "] to be "
    247                << static_cast<unsigned int>(expected_operand) << " but got "
    248                << static_cast<unsigned int>(raw_operand);
    249         FATAL(stream.str().c_str());
    250       }
    251     }
    252     iterator.Advance();
    253   }
    254 }
    255 
    256 
    257 TEST(PrimitiveReturnStatements) {
    258   InitializedHandleScope handle_scope;
    259   BytecodeGeneratorHelper helper;
    260 
    261   ExpectedSnippet<int> snippets[] = {
    262       {"", 0, 1, 2, {B(LdaUndefined), B(Return)}, 0},
    263       {"return;", 0, 1, 2, {B(LdaUndefined), B(Return)}, 0},
    264       {"return null;", 0, 1, 2, {B(LdaNull), B(Return)}, 0},
    265       {"return true;", 0, 1, 2, {B(LdaTrue), B(Return)}, 0},
    266       {"return false;", 0, 1, 2, {B(LdaFalse), B(Return)}, 0},
    267       {"return 0;", 0, 1, 2, {B(LdaZero), B(Return)}, 0},
    268       {"return +1;", 0, 1, 3, {B(LdaSmi8), U8(1), B(Return)}, 0},
    269       {"return -1;", 0, 1, 3, {B(LdaSmi8), U8(-1), B(Return)}, 0},
    270       {"return +127;", 0, 1, 3, {B(LdaSmi8), U8(127), B(Return)}, 0},
    271       {"return -128;", 0, 1, 3, {B(LdaSmi8), U8(-128), B(Return)}, 0},
    272   };
    273 
    274   for (size_t i = 0; i < arraysize(snippets); i++) {
    275     Handle<BytecodeArray> bytecode_array =
    276         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
    277     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
    278   }
    279 }
    280 
    281 
    282 TEST(PrimitiveExpressions) {
    283   InitializedHandleScope handle_scope;
    284   BytecodeGeneratorHelper helper;
    285 
    286   ExpectedSnippet<int> snippets[] = {
    287       {"var x = 0; return x;",
    288        kPointerSize,
    289        1,
    290        4,
    291        {B(LdaZero),     //
    292         B(Star), R(0),  //
    293         B(Return)},
    294        0},
    295       {"var x = 0; return x + 3;",
    296        2 * kPointerSize,
    297        1,
    298        10,
    299        {B(LdaZero),         //
    300         B(Star), R(0),      //
    301         B(Star), R(1),      //
    302         B(LdaSmi8), U8(3),  //
    303         B(Add), R(1),       //
    304         B(Return)},
    305        0},
    306       {"var x = 0; return x - 3;",
    307        2 * kPointerSize,
    308        1,
    309        10,
    310        {B(LdaZero),         //
    311         B(Star), R(0),      //
    312         B(Star), R(1),      //
    313         B(LdaSmi8), U8(3),  //
    314         B(Sub), R(1),       //
    315         B(Return)},
    316        0},
    317       {"var x = 4; return x * 3;",
    318        2 * kPointerSize,
    319        1,
    320        11,
    321        {B(LdaSmi8), U8(4),  //
    322         B(Star), R(0),      //
    323         B(Star), R(1),      //
    324         B(LdaSmi8), U8(3),  //
    325         B(Mul), R(1),       //
    326         B(Return)},
    327        0},
    328       {"var x = 4; return x / 3;",
    329        2 * kPointerSize,
    330        1,
    331        11,
    332        {B(LdaSmi8), U8(4),  //
    333         B(Star), R(0),      //
    334         B(Star), R(1),      //
    335         B(LdaSmi8), U8(3),  //
    336         B(Div), R(1),       //
    337         B(Return)},
    338        0},
    339       {"var x = 4; return x % 3;",
    340        2 * kPointerSize,
    341        1,
    342        11,
    343        {B(LdaSmi8), U8(4),  //
    344         B(Star), R(0),      //
    345         B(Star), R(1),      //
    346         B(LdaSmi8), U8(3),  //
    347         B(Mod), R(1),       //
    348         B(Return)},
    349        0},
    350       {"var x = 1; return x | 2;",
    351        2 * kPointerSize,
    352        1,
    353        11,
    354        {B(LdaSmi8), U8(1),   //
    355         B(Star), R(0),       //
    356         B(Star), R(1),       //
    357         B(LdaSmi8), U8(2),   //
    358         B(BitwiseOr), R(1),  //
    359         B(Return)},
    360        0},
    361       {"var x = 1; return x ^ 2;",
    362        2 * kPointerSize,
    363        1,
    364        11,
    365        {B(LdaSmi8), U8(1),    //
    366         B(Star), R(0),        //
    367         B(Star), R(1),        //
    368         B(LdaSmi8), U8(2),    //
    369         B(BitwiseXor), R(1),  //
    370         B(Return)},
    371        0},
    372       {"var x = 1; return x & 2;",
    373        2 * kPointerSize,
    374        1,
    375        11,
    376        {B(LdaSmi8), U8(1),    //
    377         B(Star), R(0),        //
    378         B(Star), R(1),        //
    379         B(LdaSmi8), U8(2),    //
    380         B(BitwiseAnd), R(1),  //
    381         B(Return)},
    382        0},
    383       {"var x = 10; return x << 3;",
    384        2 * kPointerSize,
    385        1,
    386        11,
    387        {B(LdaSmi8), U8(10),  //
    388         B(Star), R(0),       //
    389         B(Star), R(1),       //
    390         B(LdaSmi8), U8(3),   //
    391         B(ShiftLeft), R(1),  //
    392         B(Return)},
    393        0},
    394       {"var x = 10; return x >> 3;",
    395        2 * kPointerSize,
    396        1,
    397        11,
    398        {B(LdaSmi8), U8(10),   //
    399         B(Star), R(0),        //
    400         B(Star), R(1),        //
    401         B(LdaSmi8), U8(3),    //
    402         B(ShiftRight), R(1),  //
    403         B(Return)},
    404        0},
    405       {"var x = 10; return x >>> 3;",
    406        2 * kPointerSize,
    407        1,
    408        11,
    409        {B(LdaSmi8), U8(10),          //
    410         B(Star), R(0),               //
    411         B(Star), R(1),               //
    412         B(LdaSmi8), U8(3),           //
    413         B(ShiftRightLogical), R(1),  //
    414         B(Return)},
    415        0},
    416       {"var x = 0; return (x, 3);",
    417        1 * kPointerSize,
    418        1,
    419        6,
    420        {B(LdaZero),         //
    421         B(Star), R(0),      //
    422         B(LdaSmi8), U8(3),  //
    423         B(Return)},
    424        0}};
    425 
    426   for (size_t i = 0; i < arraysize(snippets); i++) {
    427     Handle<BytecodeArray> bytecode_array =
    428         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
    429     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
    430   }
    431 }
    432 
    433 
    434 TEST(LogicalExpressions) {
    435   InitializedHandleScope handle_scope;
    436   BytecodeGeneratorHelper helper;
    437 
    438   ExpectedSnippet<int> snippets[] = {
    439       {"var x = 0; return x || 3;",
    440        1 * kPointerSize,
    441        1,
    442        8,
    443        {B(LdaZero),                     //
    444         B(Star), R(0),                  //
    445         B(JumpIfToBooleanTrue), U8(4),  //
    446         B(LdaSmi8), U8(3),              //
    447         B(Return)},
    448        0},
    449       {"var x = 0; return (x == 1) || 3;",
    450        2 * kPointerSize,
    451        1,
    452        14,
    453        {B(LdaZero),            //
    454         B(Star), R(0),         //
    455         B(Star), R(1),         //
    456         B(LdaSmi8), U8(1),     //
    457         B(TestEqual), R(1),    //
    458         B(JumpIfTrue), U8(4),  //
    459         B(LdaSmi8), U8(3),     //
    460         B(Return)},
    461        0},
    462       {"var x = 0; return x && 3;",
    463        1 * kPointerSize,
    464        1,
    465        8,
    466        {B(LdaZero),                      //
    467         B(Star), R(0),                   //
    468         B(JumpIfToBooleanFalse), U8(4),  //
    469         B(LdaSmi8), U8(3),               //
    470         B(Return)},
    471        0},
    472       {"var x = 0; return (x == 0) && 3;",
    473        2 * kPointerSize,
    474        1,
    475        13,
    476        {B(LdaZero),             //
    477         B(Star), R(0),          //
    478         B(Star), R(1),          //
    479         B(LdaZero),             //
    480         B(TestEqual), R(1),     //
    481         B(JumpIfFalse), U8(4),  //
    482         B(LdaSmi8), U8(3),      //
    483         B(Return)},
    484        0},
    485       {"var x = 0; return x || (1, 2, 3);",
    486        1 * kPointerSize,
    487        1,
    488        8,
    489        {B(LdaZero),                     //
    490         B(Star), R(0),                  //
    491         B(JumpIfToBooleanTrue), U8(4),  //
    492         B(LdaSmi8), U8(3),              //
    493         B(Return)},
    494        0},
    495       {"var a = 2, b = 3, c = 4; return a || (a, b, a, b, c = 5, 3);",
    496        3 * kPointerSize,
    497        1,
    498        31,
    499        {B(LdaSmi8), U8(2),               //
    500         B(Star), R(0),                   //
    501         B(LdaSmi8), U8(3),               //
    502         B(Star), R(1),                   //
    503         B(LdaSmi8), U8(4),               //
    504         B(Star), R(2),                   //
    505         B(Ldar), R(0),                   //
    506         B(JumpIfToBooleanTrue), U8(16),  //
    507         B(Ldar), R(0),                   //
    508         B(Ldar), R(1),                   //
    509         B(Ldar), R(0),                   //
    510         B(Ldar), R(1),                   //
    511         B(LdaSmi8), U8(5),               //
    512         B(Star), R(2),                   //
    513         B(LdaSmi8), U8(3),               //
    514         B(Return)},
    515        0},
    516       {"var x = 1; var a = 2, b = 3; return x || ("
    517        REPEAT_32(SPACE, "a = 1, b = 2, ")
    518        "3);",
    519        3 * kPointerSize,
    520        1,
    521        275,
    522        {B(LdaSmi8), U8(1),                      //
    523         B(Star), R(0),                          //
    524         B(LdaSmi8), U8(2),                      //
    525         B(Star), R(1),                          //
    526         B(LdaSmi8), U8(3),                      //
    527         B(Star), R(2),                          //
    528         B(Ldar), R(0),                          //
    529         B(JumpIfToBooleanTrueConstant), U8(0),  //
    530         REPEAT_32(COMMA,                        //
    531                   B(LdaSmi8), U8(1),            //
    532                   B(Star), R(1),                //
    533                   B(LdaSmi8), U8(2),            //
    534                   B(Star), R(2)),               //
    535         B(LdaSmi8), U8(3),                      //
    536         B(Return)},
    537        1,
    538        {260, 0, 0, 0}},
    539       {"var x = 0; var a = 2, b = 3; return x && ("
    540        REPEAT_32(SPACE, "a = 1, b = 2, ")
    541        "3);",
    542        3 * kPointerSize,
    543        1,
    544        274,
    545        {B(LdaZero),                              //
    546         B(Star), R(0),                           //
    547         B(LdaSmi8), U8(2),                       //
    548         B(Star), R(1),                           //
    549         B(LdaSmi8), U8(3),                       //
    550         B(Star), R(2),                           //
    551         B(Ldar), R(0),                           //
    552         B(JumpIfToBooleanFalseConstant), U8(0),  //
    553         REPEAT_32(COMMA,                         //
    554                   B(LdaSmi8), U8(1),             //
    555                   B(Star), R(1),                 //
    556                   B(LdaSmi8), U8(2),             //
    557                   B(Star), R(2)),                //
    558         B(LdaSmi8), U8(3),                       //
    559         B(Return)},                              //
    560        1,
    561        {260, 0, 0, 0}},
    562       {"var x = 1; var a = 2, b = 3; return (x > 3) || ("
    563         REPEAT_32(SPACE, "a = 1, b = 2, ")
    564        "3);",
    565        4 * kPointerSize,
    566        1,
    567        281,
    568        {B(LdaSmi8), U8(1),             //
    569         B(Star), R(0),                 //
    570         B(LdaSmi8), U8(2),             //
    571         B(Star), R(1),                 //
    572         B(LdaSmi8), U8(3),             //
    573         B(Star), R(2),                 //
    574         B(Ldar), R(0),                 //
    575         B(Star), R(3),                 //
    576         B(LdaSmi8), U8(3),             //
    577         B(TestGreaterThan), R(3),      //
    578         B(JumpIfTrueConstant), U8(0),  //
    579         REPEAT_32(COMMA,               //
    580                   B(LdaSmi8), U8(1),   //
    581                   B(Star), R(1),       //
    582                   B(LdaSmi8), U8(2),   //
    583                   B(Star), R(2)),      //
    584         B(LdaSmi8), U8(3),             //
    585         B(Return)},
    586        1,
    587        {260, 0, 0, 0}},
    588       {"var x = 0; var a = 2, b = 3; return (x < 5) && ("
    589         REPEAT_32(SPACE, "a = 1, b = 2, ")
    590        "3);",
    591        4 * kPointerSize,
    592        1,
    593        280,
    594        {B(LdaZero),                     //
    595         B(Star), R(0),                  //
    596         B(LdaSmi8), U8(2),              //
    597         B(Star), R(1),                  //
    598         B(LdaSmi8), U8(3),              //
    599         B(Star), R(2),                  //
    600         B(Ldar), R(0),                  //
    601         B(Star), R(3),                  //
    602         B(LdaSmi8), U8(5),              //
    603         B(TestLessThan), R(3),          //
    604         B(JumpIfFalseConstant), U8(0),  //
    605         REPEAT_32(COMMA,                //
    606                   B(LdaSmi8), U8(1),    //
    607                   B(Star), R(1),        //
    608                   B(LdaSmi8), U8(2),    //
    609                   B(Star), R(2)),       //
    610         B(LdaSmi8), U8(3),              //
    611         B(Return)},
    612        1,
    613        {260, 0, 0, 0}},
    614       {"return 0 && 3;",
    615        0 * kPointerSize,
    616        1,
    617        2,
    618        {B(LdaZero),  //
    619         B(Return)},
    620        0},
    621       {"return 1 || 3;",
    622        0 * kPointerSize,
    623        1,
    624        3,
    625        {B(LdaSmi8), U8(1),  //
    626         B(Return)},
    627        0},
    628       {"var x = 1; return x && 3 || 0, 1;",
    629        1 * kPointerSize,
    630        1,
    631        14,
    632        {B(LdaSmi8), U8(1),               //
    633         B(Star), R(0),                   //
    634         B(JumpIfToBooleanFalse), U8(4),  //
    635         B(LdaSmi8), U8(3),               //
    636         B(JumpIfToBooleanTrue), U8(3),   //
    637         B(LdaZero),                      //
    638         B(LdaSmi8), U8(1),               //
    639         B(Return)},
    640        0}};
    641 
    642   for (size_t i = 0; i < arraysize(snippets); i++) {
    643     Handle<BytecodeArray> bytecode_array =
    644         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
    645     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
    646   }
    647 }
    648 
    649 
    650 TEST(Parameters) {
    651   InitializedHandleScope handle_scope;
    652   BytecodeGeneratorHelper helper;
    653 
    654   ExpectedSnippet<int> snippets[] = {
    655       {"function f() { return this; }",
    656        0,
    657        1,
    658        3,
    659        {B(Ldar), THIS(1), B(Return)},
    660        0},
    661       {"function f(arg1) { return arg1; }",
    662        0,
    663        2,
    664        3,
    665        {B(Ldar), A(1, 2), B(Return)},
    666        0},
    667       {"function f(arg1) { return this; }",
    668        0,
    669        2,
    670        3,
    671        {B(Ldar), THIS(2), B(Return)},
    672        0},
    673       {"function f(arg1, arg2, arg3, arg4, arg5, arg6, arg7) { return arg4; }",
    674        0,
    675        8,
    676        3,
    677        {B(Ldar), A(4, 8), B(Return)},
    678        0},
    679       {"function f(arg1, arg2, arg3, arg4, arg5, arg6, arg7) { return this; }",
    680        0,
    681        8,
    682        3,
    683        {B(Ldar), THIS(8), B(Return)},
    684        0},
    685       {"function f(arg1) { arg1 = 1; }",
    686        0,
    687        2,
    688        6,
    689        {B(LdaSmi8), U8(1),  //
    690         B(Star), A(1, 2),   //
    691         B(LdaUndefined),    //
    692         B(Return)},
    693        0},
    694       {"function f(arg1, arg2, arg3, arg4) { arg2 = 1; }",
    695        0,
    696        5,
    697        6,
    698        {B(LdaSmi8), U8(1),  //
    699         B(Star), A(2, 5),   //
    700         B(LdaUndefined),    //
    701         B(Return)},
    702        0},
    703   };
    704 
    705   for (size_t i = 0; i < arraysize(snippets); i++) {
    706     Handle<BytecodeArray> bytecode_array =
    707         helper.MakeBytecodeForFunction(snippets[i].code_snippet);
    708     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
    709   }
    710 }
    711 
    712 
    713 TEST(IntegerConstants) {
    714   InitializedHandleScope handle_scope;
    715   BytecodeGeneratorHelper helper;
    716 
    717   ExpectedSnippet<int> snippets[] = {
    718     {"return 12345678;",
    719      0,
    720      1,
    721      3,
    722      {
    723        B(LdaConstant), U8(0),  //
    724        B(Return)               //
    725      },
    726      1,
    727      {12345678}},
    728     {"var a = 1234; return 5678;",
    729      1 * kPointerSize,
    730      1,
    731      7,
    732      {
    733        B(LdaConstant), U8(0),  //
    734        B(Star), R(0),          //
    735        B(LdaConstant), U8(1),  //
    736        B(Return)               //
    737      },
    738      2,
    739      {1234, 5678}},
    740     {"var a = 1234; return 1234;",
    741      1 * kPointerSize,
    742      1,
    743      7,
    744      {
    745        B(LdaConstant), U8(0),  //
    746        B(Star), R(0),          //
    747        B(LdaConstant), U8(0),  //
    748        B(Return)               //
    749      },
    750      1,
    751      {1234}}};
    752 
    753   for (size_t i = 0; i < arraysize(snippets); i++) {
    754     Handle<BytecodeArray> bytecode_array =
    755         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
    756     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
    757   }
    758 }
    759 
    760 
    761 TEST(HeapNumberConstants) {
    762   InitializedHandleScope handle_scope;
    763   BytecodeGeneratorHelper helper;
    764 
    765   int wide_idx = 0;
    766 
    767   ExpectedSnippet<double, 257> snippets[] = {
    768     {"return 1.2;",
    769      0,
    770      1,
    771      3,
    772      {
    773        B(LdaConstant), U8(0),  //
    774        B(Return)               //
    775      },
    776      1,
    777      {1.2}},
    778     {"var a = 1.2; return 2.6;",
    779      1 * kPointerSize,
    780      1,
    781      7,
    782      {
    783        B(LdaConstant), U8(0),  //
    784        B(Star), R(0),          //
    785        B(LdaConstant), U8(1),  //
    786        B(Return)               //
    787      },
    788      2,
    789      {1.2, 2.6}},
    790     {"var a = 3.14; return 3.14;",
    791      1 * kPointerSize,
    792      1,
    793      7,
    794      {
    795        B(LdaConstant), U8(0),  //
    796        B(Star), R(0),          //
    797        B(LdaConstant), U8(1),  //
    798        B(Return)               //
    799      },
    800      2,
    801      {3.14, 3.14}},
    802     {"var a;"
    803      REPEAT_256(SPACE, " a = 1.414;")
    804      " a = 3.14;",
    805      1 * kPointerSize,
    806      1,
    807      1031,
    808      {
    809          REPEAT_256(COMMA,                     //
    810            B(LdaConstant), U8(wide_idx++),     //
    811            B(Star), R(0)),                     //
    812          B(LdaConstantWide), U16(wide_idx),    //
    813          B(Star), R(0),                        //
    814          B(LdaUndefined),                      //
    815          B(Return),                            //
    816      },
    817      257,
    818      {REPEAT_256(COMMA, 1.414),
    819       3.14}}
    820   };
    821   for (size_t i = 0; i < arraysize(snippets); i++) {
    822     Handle<BytecodeArray> bytecode_array =
    823         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
    824     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
    825   }
    826 }
    827 
    828 
    829 TEST(StringConstants) {
    830   InitializedHandleScope handle_scope;
    831   BytecodeGeneratorHelper helper;
    832 
    833   ExpectedSnippet<const char*> snippets[] = {
    834       {"return \"This is a string\";",
    835        0,
    836        1,
    837        3,
    838        {
    839            B(LdaConstant), U8(0),  //
    840            B(Return)               //
    841        },
    842        1,
    843        {"This is a string"}},
    844       {"var a = \"First string\"; return \"Second string\";",
    845        1 * kPointerSize,
    846        1,
    847        7,
    848        {
    849            B(LdaConstant), U8(0),  //
    850            B(Star), R(0),          //
    851            B(LdaConstant), U8(1),  //
    852            B(Return)               //
    853        },
    854        2,
    855        {"First string", "Second string"}},
    856       {"var a = \"Same string\"; return \"Same string\";",
    857        1 * kPointerSize,
    858        1,
    859        7,
    860        {
    861            B(LdaConstant), U8(0),  //
    862            B(Star), R(0),          //
    863            B(LdaConstant), U8(0),  //
    864            B(Return)               //
    865        },
    866        1,
    867        {"Same string"}}};
    868 
    869   for (size_t i = 0; i < arraysize(snippets); i++) {
    870     Handle<BytecodeArray> bytecode_array =
    871         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
    872     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
    873   }
    874 }
    875 
    876 
    877 TEST(PropertyLoads) {
    878   InitializedHandleScope handle_scope;
    879   BytecodeGeneratorHelper helper;
    880   Zone zone;
    881 
    882   FeedbackVectorSpec feedback_spec(&zone);
    883   FeedbackVectorSlot slot1 = feedback_spec.AddLoadICSlot();
    884   FeedbackVectorSlot slot2 = feedback_spec.AddLoadICSlot();
    885 
    886   Handle<i::TypeFeedbackVector> vector =
    887       i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec);
    888 
    889   // These are a hack used by the LoadICXXXWide tests below.
    890   int wide_idx_1 = vector->GetIndex(slot1) - 2;
    891   int wide_idx_2 = vector->GetIndex(slot1) - 2;
    892   int wide_idx_3 = vector->GetIndex(slot1) - 2;
    893   int wide_idx_4 = vector->GetIndex(slot1) - 2;
    894 
    895   ExpectedSnippet<const char*> snippets[] = {
    896       {"function f(a) { return a.name; }\nf({name : \"test\"})",
    897        1 * kPointerSize,
    898        2,
    899        9,
    900        {
    901            B(Ldar), A(1, 2),                                           //
    902            B(Star), R(0),                                              //
    903            B(LoadICSloppy), R(0), U8(0), U8(vector->GetIndex(slot1)),  //
    904            B(Return),                                                  //
    905        },
    906        1,
    907        {"name"}},
    908       {"function f(a) { return a[\"key\"]; }\nf({key : \"test\"})",
    909        1 * kPointerSize,
    910        2,
    911        9,
    912        {
    913            B(Ldar), A(1, 2),                                           //
    914            B(Star), R(0),                                              //
    915            B(LoadICSloppy), R(0), U8(0), U8(vector->GetIndex(slot1)),  //
    916            B(Return)                                                   //
    917        },
    918        1,
    919        {"key"}},
    920       {"function f(a) { return a[100]; }\nf({100 : \"test\"})",
    921        1 * kPointerSize,
    922        2,
    923        10,
    924        {
    925            B(Ldar), A(1, 2),                                         //
    926            B(Star), R(0),                                            //
    927            B(LdaSmi8), U8(100),                                      //
    928            B(KeyedLoadICSloppy), R(0), U8(vector->GetIndex(slot1)),  //
    929            B(Return)                                                 //
    930        },
    931        0},
    932       {"function f(a, b) { return a[b]; }\nf({arg : \"test\"}, \"arg\")",
    933        1 * kPointerSize,
    934        3,
    935        10,
    936        {
    937            B(Ldar), A(1, 3),                                         //
    938            B(Star), R(0),                                            //
    939            B(Ldar), A(1, 2),                                         //
    940            B(KeyedLoadICSloppy), R(0), U8(vector->GetIndex(slot1)),  //
    941            B(Return)                                                 //
    942        },
    943        0},
    944       {"function f(a) { var b = a.name; return a[-124]; }\n"
    945        "f({\"-124\" : \"test\", name : 123 })",
    946        2 * kPointerSize,
    947        2,
    948        20,
    949        {
    950            B(Ldar), A(1, 2),                                           //
    951            B(Star), R(1),                                              //
    952            B(LoadICSloppy), R(1), U8(0), U8(vector->GetIndex(slot1)),  //
    953            B(Star), R(0),                                              //
    954            B(Ldar), A(1, 2),                                           //
    955            B(Star), R(1),                                              //
    956            B(LdaSmi8), U8(-124),                                       //
    957            B(KeyedLoadICSloppy), R(1), U8(vector->GetIndex(slot2)),    //
    958            B(Return),                                                  //
    959        },
    960        1,
    961        {"name"}},
    962       {"function f(a) { \"use strict\"; return a.name; }\nf({name : \"test\"})",
    963        1 * kPointerSize,
    964        2,
    965        9,
    966        {
    967            B(Ldar), A(1, 2),                                           //
    968            B(Star), R(0),                                              //
    969            B(LoadICStrict), R(0), U8(0), U8(vector->GetIndex(slot1)),  //
    970            B(Return),                                                  //
    971        },
    972        1,
    973        {"name"}},
    974       {"function f(a, b) { \"use strict\"; return a[b]; }\n"
    975        "f({arg : \"test\"}, \"arg\")",
    976        1 * kPointerSize,
    977        3,
    978        10,
    979        {
    980            B(Ldar), A(1, 3),                                         //
    981            B(Star), R(0),                                            //
    982            B(Ldar), A(2, 3),                                         //
    983            B(KeyedLoadICStrict), R(0), U8(vector->GetIndex(slot1)),  //
    984            B(Return),                                                //
    985        },
    986        0},
    987       {"function f(a) {\n"
    988        " var b;\n"
    989        "b = a.name;"
    990        REPEAT_127(SPACE, " b = a.name; ")
    991        " return a.name; }\n"
    992        "f({name : \"test\"})\n",
    993        2 * kPointerSize,
    994        2,
    995        1291,
    996        {
    997            B(Ldar), A(1, 2),                                        //
    998            B(Star), R(1),                                           //
    999            B(LoadICSloppy), R(1), U8(0), U8(wide_idx_1 += 2),       //
   1000            B(Star), R(0),                                           //
   1001            REPEAT_127(COMMA,                                        //
   1002                       B(Ldar), A(1, 2),                             //
   1003                       B(Star), R(1),                                //
   1004                       B(LoadICSloppy), R(1), U8(0),                 //
   1005                                        U8((wide_idx_1 += 2)),       //
   1006                       B(Star), R(0)),                               //
   1007            B(Ldar), A(1, 2),                                        //
   1008            B(Star), R(1),                                           //
   1009            B(LoadICSloppyWide), R(1), U16(0), U16(wide_idx_1 + 2),  //
   1010            B(Return),                                               //
   1011        },
   1012        1,
   1013        {"name"}},
   1014       {"function f(a) {\n"
   1015        " 'use strict'; var b;\n"
   1016        "  b = a.name;\n"
   1017        REPEAT_127(SPACE, " b = a.name; ")
   1018        " return a.name; }\n"
   1019        "f({name : \"test\"})\n",
   1020        2 * kPointerSize,
   1021        2,
   1022        1291,
   1023        {
   1024            B(Ldar), A(1, 2),                                        //
   1025            B(Star), R(1),                                           //
   1026            B(LoadICStrict), R(1), U8(0), U8((wide_idx_2 += 2)),     //
   1027            B(Star), R(0),                                           //
   1028            REPEAT_127(COMMA,                                        //
   1029                       B(Ldar), A(1, 2),                             //
   1030                       B(Star), R(1),                                //
   1031                       B(LoadICStrict), R(1), U8(0),                 //
   1032                                        U8((wide_idx_2 += 2)),       //
   1033                       B(Star), R(0)),                               //
   1034            B(Ldar), A(1, 2),                                        //
   1035            B(Star), R(1),                                           //
   1036            B(LoadICStrictWide), R(1), U16(0), U16(wide_idx_2 + 2),  //
   1037            B(Return),                                               //
   1038        },
   1039        1,
   1040        {"name"}},
   1041       {"function f(a, b) {\n"
   1042        " var c;\n"
   1043        " c = a[b];"
   1044        REPEAT_127(SPACE, " c = a[b]; ")
   1045        " return a[b]; }\n"
   1046        "f({name : \"test\"}, \"name\")\n",
   1047        2 * kPointerSize,
   1048        3,
   1049        1419,
   1050        {
   1051            B(Ldar), A(1, 3),                                              //
   1052            B(Star), R(1),                                                 //
   1053            B(Ldar), A(2, 3),                                              //
   1054            B(KeyedLoadICSloppy), R(1), U8((wide_idx_3 += 2)),             //
   1055            B(Star), R(0),                                                 //
   1056            REPEAT_127(COMMA,                                              //
   1057                       B(Ldar), A(1, 3),                                   //
   1058                       B(Star), R(1),                                      //
   1059                       B(Ldar), A(2, 3),                                   //
   1060                       B(KeyedLoadICSloppy), R(1), U8((wide_idx_3 += 2)),  //
   1061                       B(Star), R(0)),                                     //
   1062            B(Ldar), A(1, 3),                                              //
   1063            B(Star), R(1),                                                 //
   1064            B(Ldar), A(2, 3),                                              //
   1065            B(KeyedLoadICSloppyWide), R(1), U16(wide_idx_3 + 2),           //
   1066            B(Return),                                                     //
   1067        }},
   1068       {"function f(a, b) {\n"
   1069        " 'use strict'; var c;\n"
   1070        "  c = a[b];"
   1071        REPEAT_127(SPACE, " c = a[b]; ")
   1072        " return a[b]; }\n"
   1073        "f({name : \"test\"}, \"name\")\n",
   1074        2 * kPointerSize,
   1075        3,
   1076        1419,
   1077        {
   1078            B(Ldar), A(1, 3),                                              //
   1079            B(Star), R(1),                                                 //
   1080            B(Ldar), A(2, 3),                                              //
   1081            B(KeyedLoadICStrict), R(1), U8((wide_idx_4 += 2)),             //
   1082            B(Star), R(0),                                                 //
   1083            REPEAT_127(COMMA,                                              //
   1084                       B(Ldar), A(1, 3),                                   //
   1085                       B(Star), R(1),                                      //
   1086                       B(Ldar), A(2, 3),                                   //
   1087                       B(KeyedLoadICStrict), R(1), U8((wide_idx_4 += 2)),  //
   1088                       B(Star), R(0)),                                     //
   1089            B(Ldar), A(1, 3),                                              //
   1090            B(Star), R(1),                                                 //
   1091            B(Ldar), A(2, 3),                                              //
   1092            B(KeyedLoadICStrictWide), R(1), U16(wide_idx_4 + 2),           //
   1093            B(Return),                                                     //
   1094        }},
   1095   };
   1096   for (size_t i = 0; i < arraysize(snippets); i++) {
   1097     Handle<BytecodeArray> bytecode_array =
   1098         helper.MakeBytecode(snippets[i].code_snippet, helper.kFunctionName);
   1099     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   1100   }
   1101 }
   1102 
   1103 
   1104 TEST(PropertyStores) {
   1105   InitializedHandleScope handle_scope;
   1106   BytecodeGeneratorHelper helper;
   1107   Zone zone;
   1108 
   1109   FeedbackVectorSpec feedback_spec(&zone);
   1110   FeedbackVectorSlot slot1 = feedback_spec.AddStoreICSlot();
   1111   FeedbackVectorSlot slot2 = feedback_spec.AddStoreICSlot();
   1112 
   1113   Handle<i::TypeFeedbackVector> vector =
   1114       i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec);
   1115 
   1116   // These are a hack used by the StoreICXXXWide tests below.
   1117   int wide_idx_1 = vector->GetIndex(slot1) - 2;
   1118   int wide_idx_2 = vector->GetIndex(slot1) - 2;
   1119   int wide_idx_3 = vector->GetIndex(slot1) - 2;
   1120   int wide_idx_4 = vector->GetIndex(slot1) - 2;
   1121 
   1122   ExpectedSnippet<const char*> snippets[] = {
   1123       {"function f(a) { a.name = \"val\"; }\nf({name : \"test\"})",
   1124        kPointerSize,
   1125        2,
   1126        12,
   1127        {
   1128            B(Ldar), A(1, 2),                                            //
   1129            B(Star), R(0),                                               //
   1130            B(LdaConstant), U8(0),                                       //
   1131            B(StoreICSloppy), R(0), U8(1), U8(vector->GetIndex(slot1)),  //
   1132            B(LdaUndefined),                                             //
   1133            B(Return),                                                   //
   1134        },
   1135        2,
   1136        {"val", "name"}},
   1137       {"function f(a) { a[\"key\"] = \"val\"; }\nf({key : \"test\"})",
   1138        kPointerSize,
   1139        2,
   1140        12,
   1141        {
   1142            B(Ldar), A(1, 2),                                            //
   1143            B(Star), R(0),                                               //
   1144            B(LdaConstant), U8(0),                                       //
   1145            B(StoreICSloppy), R(0), U8(1), U8(vector->GetIndex(slot1)),  //
   1146            B(LdaUndefined),                                             //
   1147            B(Return),                                                   //
   1148        },
   1149        2,
   1150        {"val", "key"}},
   1151       {"function f(a) { a[100] = \"val\"; }\nf({100 : \"test\"})",
   1152        2 * kPointerSize,
   1153        2,
   1154        16,
   1155        {
   1156            B(Ldar), A(1, 2),                   //
   1157            B(Star), R(0),                      //
   1158            B(LdaSmi8), U8(100),                //
   1159            B(Star), R(1),                      //
   1160            B(LdaConstant), U8(0),              //
   1161            B(KeyedStoreICSloppy), R(0), R(1),  //
   1162            U8(vector->GetIndex(slot1)),        //
   1163            B(LdaUndefined),                    //
   1164            B(Return),                          //
   1165        },
   1166        1,
   1167        {"val"}},
   1168       {"function f(a, b) { a[b] = \"val\"; }\nf({arg : \"test\"}, \"arg\")",
   1169        2 * kPointerSize,
   1170        3,
   1171        16,
   1172        {
   1173            B(Ldar), A(1, 3),                   //
   1174            B(Star), R(0),                      //
   1175            B(Ldar), A(2, 3),                   //
   1176            B(Star), R(1),                      //
   1177            B(LdaConstant), U8(0),              //
   1178            B(KeyedStoreICSloppy), R(0), R(1),  //
   1179            U8(vector->GetIndex(slot1)),        //
   1180            B(LdaUndefined),                    //
   1181            B(Return),                          //
   1182        },
   1183        1,
   1184        {"val"}},
   1185       {"function f(a) { a.name = a[-124]; }\n"
   1186        "f({\"-124\" : \"test\", name : 123 })",
   1187        2 * kPointerSize,
   1188        2,
   1189        19,
   1190        {
   1191            B(Ldar), A(1, 2),                                            //
   1192            B(Star), R(0),                                               //
   1193            B(Ldar), A(1, 2),                                            //
   1194            B(Star), R(1),                                               //
   1195            B(LdaSmi8), U8(-124),                                        //
   1196            B(KeyedLoadICSloppy), R(1), U8(vector->GetIndex(slot1)),     //
   1197            B(StoreICSloppy), R(0), U8(0), U8(vector->GetIndex(slot2)),  //
   1198            B(LdaUndefined),                                             //
   1199            B(Return),                                                   //
   1200        },
   1201        1,
   1202        {"name"}},
   1203       {"function f(a) { \"use strict\"; a.name = \"val\"; }\n"
   1204        "f({name : \"test\"})",
   1205        kPointerSize,
   1206        2,
   1207        12,
   1208        {
   1209            B(Ldar), A(1, 2),                                            //
   1210            B(Star), R(0),                                               //
   1211            B(LdaConstant), U8(0),                                       //
   1212            B(StoreICStrict), R(0), U8(1), U8(vector->GetIndex(slot1)),  //
   1213            B(LdaUndefined),                                             //
   1214            B(Return),                                                   //
   1215        },
   1216        2,
   1217        {"val", "name"}},
   1218       {"function f(a, b) { \"use strict\"; a[b] = \"val\"; }\n"
   1219        "f({arg : \"test\"}, \"arg\")",
   1220        2 * kPointerSize,
   1221        3,
   1222        16,
   1223        {
   1224            B(Ldar), A(1, 3),                                                //
   1225            B(Star), R(0),                                                   //
   1226            B(Ldar), A(2, 3),                                                //
   1227            B(Star), R(1),                                                   //
   1228            B(LdaConstant), U8(0),                                           //
   1229            B(KeyedStoreICStrict), R(0), R(1), U8(vector->GetIndex(slot1)),  //
   1230            B(LdaUndefined),                                                 //
   1231            B(Return),                                                       //
   1232        },
   1233        1,
   1234        {"val"}},
   1235       {"function f(a) {\n"
   1236        "a.name = 1;"
   1237        REPEAT_127(SPACE, " a.name = 1; ")
   1238        " a.name = 2; }\n"
   1239        "f({name : \"test\"})\n",
   1240        kPointerSize,
   1241        2,
   1242        1294,
   1243        {
   1244            B(Ldar), A(1, 2),                                         //
   1245            B(Star), R(0),                                            //
   1246            B(LdaSmi8), U8(1),                                        //
   1247            B(StoreICSloppy), R(0), U8(0), U8((wide_idx_1 += 2)),     //
   1248            REPEAT_127(COMMA,                                         //
   1249                       B(Ldar), A(1, 2),                              //
   1250                       B(Star), R(0),                                 //
   1251                       B(LdaSmi8), U8(1),                             //
   1252                       B(StoreICSloppy), R(0), U8(0),                 //
   1253                                         U8((wide_idx_1 += 2))),      //
   1254            B(Ldar), A(1, 2),                                         //
   1255            B(Star), R(0),                                            //
   1256            B(LdaSmi8), U8(2),                                        //
   1257            B(StoreICSloppyWide), R(0), U16(0), U16(wide_idx_1 + 2),  //
   1258            B(LdaUndefined),                                          //
   1259            B(Return),                                                //
   1260        },
   1261        1,
   1262        {"name"}},
   1263       {"function f(a) {\n"
   1264        " 'use strict';\n"
   1265        "  a.name = 1;"
   1266        REPEAT_127(SPACE, " a.name = 1; ")
   1267        " a.name = 2; }\n"
   1268        "f({name : \"test\"})\n",
   1269        kPointerSize,
   1270        2,
   1271        1294,
   1272        {
   1273            B(Ldar), A(1, 2),                                         //
   1274            B(Star), R(0),                                            //
   1275            B(LdaSmi8), U8(1),                                        //
   1276            B(StoreICStrict), R(0), U8(0), U8(wide_idx_2 += 2),       //
   1277            REPEAT_127(COMMA,                                         //
   1278                       B(Ldar), A(1, 2),                              //
   1279                       B(Star), R(0),                                 //
   1280                       B(LdaSmi8), U8(1),                             //
   1281                       B(StoreICStrict), R(0), U8(0),                 //
   1282                                         U8((wide_idx_2 += 2))),      //
   1283            B(Ldar), A(1, 2),                                         //
   1284            B(Star), R(0),                                            //
   1285            B(LdaSmi8), U8(2),                                        //
   1286            B(StoreICStrictWide), R(0), U16(0), U16(wide_idx_2 + 2),  //
   1287            B(LdaUndefined),                                          //
   1288            B(Return),                                                //
   1289        },
   1290        1,
   1291        {"name"}},
   1292       {"function f(a, b) {\n"
   1293        " a[b] = 1;"
   1294         REPEAT_127(SPACE, " a[b] = 1; ")
   1295        " a[b] = 2; }\n"
   1296        "f({name : \"test\"})\n",
   1297        2 * kPointerSize,
   1298        3,
   1299        1809,
   1300        {
   1301            B(Ldar), A(1, 3),                                            //
   1302            B(Star), R(0),                                               //
   1303            B(Ldar), A(2, 3),                                            //
   1304            B(Star), R(1),                                               //
   1305            B(LdaSmi8), U8(1),                                           //
   1306            B(KeyedStoreICSloppy), R(0), R(1), U8(wide_idx_3 += 2),      //
   1307            REPEAT_127(COMMA,                                            //
   1308                       B(Ldar), A(1, 3),                                 //
   1309                       B(Star), R(0),                                    //
   1310                       B(Ldar), A(2, 3),                                 //
   1311                       B(Star), R(1),                                    //
   1312                       B(LdaSmi8), U8(1),                                //
   1313                       B(KeyedStoreICSloppy), R(0), R(1),                //
   1314                                              U8((wide_idx_3 += 2))),    //
   1315            B(Ldar), A(1, 3),                                            //
   1316            B(Star), R(0),                                               //
   1317            B(Ldar), A(2, 3),                                            //
   1318            B(Star), R(1),                                               //
   1319            B(LdaSmi8), U8(2),                                           //
   1320            B(KeyedStoreICSloppyWide), R(0), R(1), U16(wide_idx_3 + 2),  //
   1321            B(LdaUndefined),                                             //
   1322            B(Return),                                                   //
   1323        }},
   1324       {"function f(a, b) {\n"
   1325        " 'use strict';\n"
   1326        "  a[b] = 1;"
   1327         REPEAT_127(SPACE, " a[b] = 1; ")
   1328        " a[b] = 2; }\n"
   1329        "f({name : \"test\"})\n",
   1330        2 * kPointerSize,
   1331        3,
   1332        1809,
   1333        {
   1334            B(Ldar), A(1, 3),                                            //
   1335            B(Star), R(0),                                               //
   1336            B(Ldar), A(2, 3),                                            //
   1337            B(Star), R(1),                                               //
   1338            B(LdaSmi8), U8(1),                                           //
   1339            B(KeyedStoreICStrict), R(0), R(1), U8(wide_idx_4 += 2),      //
   1340            REPEAT_127(COMMA,                                            //
   1341                       B(Ldar), A(1, 3),                                 //
   1342                       B(Star), R(0),                                    //
   1343                       B(Ldar), A(2, 3),                                 //
   1344                       B(Star), R(1),                                    //
   1345                       B(LdaSmi8), U8(1),                                //
   1346                       B(KeyedStoreICStrict), R(0), R(1),                //
   1347                                              U8((wide_idx_4 += 2))),    //
   1348            B(Ldar), A(1, 3),                                            //
   1349            B(Star), R(0),                                               //
   1350            B(Ldar), A(2, 3),                                            //
   1351            B(Star), R(1),                                               //
   1352            B(LdaSmi8), U8(2),                                           //
   1353            B(KeyedStoreICStrictWide), R(0), R(1), U16(wide_idx_4 + 2),  //
   1354            B(LdaUndefined),                                             //
   1355            B(Return),                                                   //
   1356        }}};
   1357   for (size_t i = 0; i < arraysize(snippets); i++) {
   1358     Handle<BytecodeArray> bytecode_array =
   1359         helper.MakeBytecode(snippets[i].code_snippet, helper.kFunctionName);
   1360     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   1361   }
   1362 }
   1363 
   1364 
   1365 #define FUNC_ARG "new (function Obj() { this.func = function() { return; }})()"
   1366 
   1367 
   1368 TEST(PropertyCall) {
   1369   InitializedHandleScope handle_scope;
   1370   BytecodeGeneratorHelper helper;
   1371   Zone zone;
   1372 
   1373   FeedbackVectorSpec feedback_spec(&zone);
   1374   FeedbackVectorSlot slot1 = feedback_spec.AddCallICSlot();
   1375   FeedbackVectorSlot slot2 = feedback_spec.AddLoadICSlot();
   1376 
   1377   Handle<i::TypeFeedbackVector> vector =
   1378       i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec);
   1379 
   1380   // These are a hack used by the CallWide test below.
   1381   int wide_idx = vector->GetIndex(slot1) - 2;
   1382 
   1383   ExpectedSnippet<const char*> snippets[] = {
   1384       {"function f(a) { return a.func(); }\nf(" FUNC_ARG ")",
   1385        2 * kPointerSize,
   1386        2,
   1387        16,
   1388        {
   1389            B(Ldar), A(1, 2),                                           //
   1390            B(Star), R(1),                                              //
   1391            B(LoadICSloppy), R(1), U8(0), U8(vector->GetIndex(slot2)),  //
   1392            B(Star), R(0),                                              //
   1393            B(Call), R(0), R(1), U8(0), U8(vector->GetIndex(slot1)),    //
   1394            B(Return),                                                  //
   1395        },
   1396        1,
   1397        {"func"}},
   1398       {"function f(a, b, c) { return a.func(b, c); }\nf(" FUNC_ARG ", 1, 2)",
   1399        4 * kPointerSize,
   1400        4,
   1401        24,
   1402        {
   1403            B(Ldar), A(1, 4),                                           //
   1404            B(Star), R(1),                                              //
   1405            B(LoadICSloppy), R(1), U8(0), U8(vector->GetIndex(slot2)),  //
   1406            B(Star), R(0),                                              //
   1407            B(Ldar), A(2, 4),                                           //
   1408            B(Star), R(2),                                              //
   1409            B(Ldar), A(3, 4),                                           //
   1410            B(Star), R(3),                                              //
   1411            B(Call), R(0), R(1), U8(2), U8(vector->GetIndex(slot1)),    //
   1412            B(Return)                                                   //
   1413        },
   1414        1,
   1415        {"func"}},
   1416       {"function f(a, b) { return a.func(b + b, b); }\nf(" FUNC_ARG ", 1)",
   1417        4 * kPointerSize,
   1418        3,
   1419        30,
   1420        {
   1421            B(Ldar), A(1, 3),                                           //
   1422            B(Star), R(1),                                              //
   1423            B(LoadICSloppy), R(1), U8(0), U8(vector->GetIndex(slot2)),  //
   1424            B(Star), R(0),                                              //
   1425            B(Ldar), A(2, 3),                                           //
   1426            B(Star), R(3),                                              //
   1427            B(Ldar), A(2, 3),                                           //
   1428            B(Add), R(3),                                               //
   1429            B(Star), R(2),                                              //
   1430            B(Ldar), A(2, 3),                                           //
   1431            B(Star), R(3),                                              //
   1432            B(Call), R(0), R(1), U8(2), U8(vector->GetIndex(slot1)),    //
   1433            B(Return),                                                  //
   1434        },
   1435        1,
   1436        {"func"}},
   1437       {"function f(a) {\n"
   1438        " a.func;\n"
   1439        REPEAT_127(SPACE, " a.func;\n")
   1440        " return a.func(); }\nf(" FUNC_ARG ")",
   1441        2 * kPointerSize,
   1442        2,
   1443        1044,
   1444        {
   1445            B(Ldar), A(1, 2),                                               //
   1446            B(Star), R(0),                                                  //
   1447            B(LoadICSloppy), R(0), U8(0), U8(wide_idx += 2),                //
   1448            REPEAT_127(COMMA,                                               //
   1449                       B(Ldar), A(1, 2),                                    //
   1450                       B(Star), R(0),                                       //
   1451                       B(LoadICSloppy), R(0), U8(0), U8((wide_idx += 2))),  //
   1452            B(Ldar), A(1, 2),                                               //
   1453            B(Star), R(1),                                                  //
   1454            B(LoadICSloppyWide), R(1), U16(0), U16(wide_idx + 4),           //
   1455            B(Star), R(0),                                                  //
   1456            B(CallWide), R(0), R(1), U16(0), U16(wide_idx + 2),             //
   1457            B(Return),                                                      //
   1458        },
   1459        1,
   1460        {"func"}},
   1461   };
   1462   for (size_t i = 0; i < arraysize(snippets); i++) {
   1463     Handle<BytecodeArray> bytecode_array =
   1464         helper.MakeBytecode(snippets[i].code_snippet, helper.kFunctionName);
   1465     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   1466   }
   1467 }
   1468 
   1469 
   1470 TEST(LoadGlobal) {
   1471   InitializedHandleScope handle_scope;
   1472   BytecodeGeneratorHelper helper;
   1473   Zone zone;
   1474 
   1475   FeedbackVectorSpec feedback_spec(&zone);
   1476   FeedbackVectorSlot slot = feedback_spec.AddLoadICSlot();
   1477 
   1478   Handle<i::TypeFeedbackVector> vector =
   1479       i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec);
   1480 
   1481   // These are a hack used by the LdaGlobalXXXWide tests below.
   1482   int wide_idx_1 = vector->GetIndex(slot) - 2;
   1483   int wide_idx_2 = vector->GetIndex(slot) - 2;
   1484 
   1485   ExpectedSnippet<const char*> snippets[] = {
   1486       {"var a = 1;\nfunction f() { return a; }\nf()",
   1487        0,
   1488        1,
   1489        4,
   1490        {
   1491            B(LdaGlobalSloppy), U8(0), U8(vector->GetIndex(slot)),  //
   1492            B(Return)                                               //
   1493        },
   1494        1,
   1495        {"a"}},
   1496       {"function t() { }\nfunction f() { return t; }\nf()",
   1497        0,
   1498        1,
   1499        4,
   1500        {
   1501            B(LdaGlobalSloppy), U8(0), U8(vector->GetIndex(slot)),  //
   1502            B(Return)                                               //
   1503        },
   1504        1,
   1505        {"t"}},
   1506       {"'use strict'; var a = 1;\nfunction f() { return a; }\nf()",
   1507        0,
   1508        1,
   1509        4,
   1510        {
   1511            B(LdaGlobalStrict), U8(0), U8(vector->GetIndex(slot)),  //
   1512            B(Return)                                               //
   1513        },
   1514        1,
   1515        {"a"}},
   1516       {"a = 1;\nfunction f() { return a; }\nf()",
   1517        0,
   1518        1,
   1519        4,
   1520        {
   1521            B(LdaGlobalSloppy), U8(0), U8(vector->GetIndex(slot)),  //
   1522            B(Return)                                               //
   1523        },
   1524        1,
   1525        {"a"}},
   1526       {"a = 1;"
   1527        "function f(b) {\n"
   1528        "   b.name;\n"
   1529         REPEAT_127(SPACE, "b.name; ")
   1530        " return a;"
   1531        "}\nf({name: 1});",
   1532        kPointerSize,
   1533        2,
   1534        1030,
   1535        {
   1536            B(Ldar), A(1, 2),                                               //
   1537            B(Star), R(0),                                                  //
   1538            B(LoadICSloppy), R(0), U8(0), U8(wide_idx_1 += 2),              //
   1539            REPEAT_127(COMMA,                                               //
   1540                       B(Ldar), A(1, 2),                                    //
   1541                       B(Star), R(0),                                       //
   1542                       B(LoadICSloppy), R(0), U8(0), U8(wide_idx_1 += 2)),  //
   1543            B(LdaGlobalSloppyWide), U16(1), U16(wide_idx_1 + 2),            //
   1544            B(Return),                                                      //
   1545        },
   1546        2,
   1547        {"name", "a"}},
   1548       {"a = 1;"
   1549        "function f(b) {\n"
   1550        " 'use strict';\n"
   1551        "  b.name\n"
   1552           REPEAT_127(SPACE, "b.name; ")
   1553        "  return a;"
   1554        "}\nf({name: 1});",
   1555        kPointerSize,
   1556        2,
   1557        1030,
   1558        {
   1559            B(Ldar), A(1, 2),                                               //
   1560            B(Star), R(0),                                                  //
   1561            B(LoadICStrict), R(0), U8(0), U8(wide_idx_2 += 2),              //
   1562            REPEAT_127(COMMA,                                               //
   1563                       B(Ldar), A(1, 2),                                    //
   1564                       B(Star), R(0),                                       //
   1565                       B(LoadICStrict), R(0), U8(0), U8(wide_idx_2 += 2)),  //
   1566            B(LdaGlobalStrictWide), U16(1), U16(wide_idx_2 + 2),            //
   1567            B(Return),                                                      //
   1568        },
   1569        2,
   1570        {"name", "a"}},
   1571   };
   1572 
   1573   for (size_t i = 0; i < arraysize(snippets); i++) {
   1574     Handle<BytecodeArray> bytecode_array =
   1575         helper.MakeBytecode(snippets[i].code_snippet, "f");
   1576     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   1577   }
   1578 }
   1579 
   1580 
   1581 TEST(StoreGlobal) {
   1582   InitializedHandleScope handle_scope;
   1583   BytecodeGeneratorHelper helper;
   1584   Zone zone;
   1585 
   1586   FeedbackVectorSpec feedback_spec(&zone);
   1587   FeedbackVectorSlot slot = feedback_spec.AddStoreICSlot();
   1588 
   1589   Handle<i::TypeFeedbackVector> vector =
   1590       i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec);
   1591 
   1592   // These are a hack used by the StaGlobalXXXWide tests below.
   1593   int wide_idx_1 = vector->GetIndex(slot) - 2;
   1594   int wide_idx_2 = vector->GetIndex(slot) - 2;
   1595 
   1596   ExpectedSnippet<const char*> snippets[] = {
   1597       {"var a = 1;\nfunction f() { a = 2; }\nf()",
   1598        0,
   1599        1,
   1600        7,
   1601        {
   1602            B(LdaSmi8), U8(2),                                      //
   1603            B(StaGlobalSloppy), U8(0), U8(vector->GetIndex(slot)),  //
   1604            B(LdaUndefined),                                        //
   1605            B(Return)                                               //
   1606        },
   1607        1,
   1608        {"a"}},
   1609       {"var a = \"test\"; function f(b) { a = b; }\nf(\"global\")",
   1610        0,
   1611        2,
   1612        7,
   1613        {
   1614            B(Ldar), R(helper.kLastParamIndex),                     //
   1615            B(StaGlobalSloppy), U8(0), U8(vector->GetIndex(slot)),  //
   1616            B(LdaUndefined),                                        //
   1617            B(Return)                                               //
   1618        },
   1619        1,
   1620        {"a"}},
   1621       {"'use strict'; var a = 1;\nfunction f() { a = 2; }\nf()",
   1622        0,
   1623        1,
   1624        7,
   1625        {
   1626            B(LdaSmi8), U8(2),                                      //
   1627            B(StaGlobalStrict), U8(0), U8(vector->GetIndex(slot)),  //
   1628            B(LdaUndefined),                                        //
   1629            B(Return)                                               //
   1630        },
   1631        1,
   1632        {"a"}},
   1633       {"a = 1;\nfunction f() { a = 2; }\nf()",
   1634        0,
   1635        1,
   1636        7,
   1637        {
   1638            B(LdaSmi8), U8(2),                                      //
   1639            B(StaGlobalSloppy), U8(0), U8(vector->GetIndex(slot)),  //
   1640            B(LdaUndefined),                                        //
   1641            B(Return)                                               //
   1642        },
   1643        1,
   1644        {"a"}},
   1645       {"a = 1;"
   1646        "function f(b) {"
   1647        " b.name;\n"
   1648        REPEAT_127(SPACE, "b.name; ")
   1649        " a = 2; }\n"
   1650        "f({name: 1});",
   1651        kPointerSize,
   1652        2,
   1653        1033,
   1654        {
   1655            B(Ldar), A(1, 2),                                               //
   1656            B(Star), R(0),                                                  //
   1657            B(LoadICSloppy), R(0), U8(0), U8(wide_idx_1 += 2),              //
   1658            REPEAT_127(COMMA,                                               //
   1659                       B(Ldar), A(1, 2),                                    //
   1660                       B(Star), R(0),                                       //
   1661                       B(LoadICSloppy), R(0), U8(0), U8(wide_idx_1 += 2)),  //
   1662            B(LdaSmi8), U8(2),                                              //
   1663            B(StaGlobalSloppyWide), U16(1), U16(wide_idx_1 + 2),            //
   1664            B(LdaUndefined),                                                //
   1665            B(Return),                                                      //
   1666        },
   1667        2,
   1668        {"name", "a"}},
   1669       {"a = 1;"
   1670        "function f(b) {\n"
   1671        " 'use strict';\n"
   1672        "  b.name;\n"
   1673        REPEAT_127(SPACE, "b.name; ")
   1674        " a = 2; }\n"
   1675        "f({name: 1});",
   1676        kPointerSize,
   1677        2,
   1678        1033,
   1679        {
   1680            B(Ldar), A(1, 2),                                               //
   1681            B(Star), R(0),                                                  //
   1682            B(LoadICStrict), R(0), U8(0), U8(wide_idx_2 += 2),              //
   1683            REPEAT_127(COMMA,                                               //
   1684                       B(Ldar), A(1, 2),                                    //
   1685                       B(Star), R(0),                                       //
   1686                       B(LoadICStrict), R(0), U8(0), U8(wide_idx_2 += 2)),  //
   1687            B(LdaSmi8), U8(2),                                              //
   1688            B(StaGlobalStrictWide), U16(1), U16(wide_idx_2 + 2),            //
   1689            B(LdaUndefined),                                                //
   1690            B(Return),                                                      //
   1691        },
   1692        2,
   1693        {"name", "a"}},
   1694   };
   1695 
   1696   for (size_t i = 0; i < arraysize(snippets); i++) {
   1697     Handle<BytecodeArray> bytecode_array =
   1698         helper.MakeBytecode(snippets[i].code_snippet, "f");
   1699     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   1700   }
   1701 }
   1702 
   1703 
   1704 TEST(CallGlobal) {
   1705   InitializedHandleScope handle_scope;
   1706   BytecodeGeneratorHelper helper;
   1707   Zone zone;
   1708 
   1709   FeedbackVectorSpec feedback_spec(&zone);
   1710   FeedbackVectorSlot slot1 = feedback_spec.AddCallICSlot();
   1711   FeedbackVectorSlot slot2 = feedback_spec.AddLoadICSlot();
   1712 
   1713   Handle<i::TypeFeedbackVector> vector =
   1714       i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec);
   1715 
   1716   ExpectedSnippet<const char*> snippets[] = {
   1717       {"function t() { }\nfunction f() { return t(); }\nf()",
   1718        2 * kPointerSize,
   1719        1,
   1720        14,
   1721        {
   1722            B(LdaUndefined),                                          //
   1723            B(Star), R(1),                                            //
   1724            B(LdaGlobalSloppy), U8(0), U8(vector->GetIndex(slot2)),   //
   1725            B(Star), R(0),                                            //
   1726            B(Call), R(0), R(1), U8(0), U8(vector->GetIndex(slot1)),  //
   1727            B(Return)                                                 //
   1728        },
   1729        1,
   1730        {"t"}},
   1731       {"function t(a, b, c) { }\nfunction f() { return t(1, 2, 3); }\nf()",
   1732        5 * kPointerSize,
   1733        1,
   1734        26,
   1735        {
   1736            B(LdaUndefined),                                          //
   1737            B(Star), R(1),                                            //
   1738            B(LdaGlobalSloppy), U8(0), U8(vector->GetIndex(slot2)),   //
   1739            B(Star), R(0),                                            //
   1740            B(LdaSmi8), U8(1),                                        //
   1741            B(Star), R(2),                                            //
   1742            B(LdaSmi8), U8(2),                                        //
   1743            B(Star), R(3),                                            //
   1744            B(LdaSmi8), U8(3),                                        //
   1745            B(Star), R(4),                                            //
   1746            B(Call), R(0), R(1), U8(3), U8(vector->GetIndex(slot1)),  //
   1747            B(Return)                                                 //
   1748        },
   1749        1,
   1750        {"t"}},
   1751   };
   1752 
   1753   size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
   1754   for (size_t i = 0; i < num_snippets; i++) {
   1755     Handle<BytecodeArray> bytecode_array =
   1756         helper.MakeBytecode(snippets[i].code_snippet, "f");
   1757     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   1758   }
   1759 }
   1760 
   1761 
   1762 TEST(CallRuntime) {
   1763   InitializedHandleScope handle_scope;
   1764   BytecodeGeneratorHelper helper;
   1765 
   1766   ExpectedSnippet<InstanceType> snippets[] = {
   1767       {
   1768           "function f() { %TheHole() }\nf()",
   1769           0,
   1770           1,
   1771           7,
   1772           {
   1773               B(CallRuntime), U16(Runtime::kTheHole), R(0), U8(0),  //
   1774               B(LdaUndefined),                                      //
   1775               B(Return)                                             //
   1776           },
   1777       },
   1778       {
   1779           "function f(a) { return %IsArray(a) }\nf(undefined)",
   1780           1 * kPointerSize,
   1781           2,
   1782           10,
   1783           {
   1784               B(Ldar), A(1, 2),                                     //
   1785               B(Star), R(0),                                        //
   1786               B(CallRuntime), U16(Runtime::kIsArray), R(0), U8(1),  //
   1787               B(Return)                                             //
   1788           },
   1789       },
   1790       {
   1791           "function f() { return %Add(1, 2) }\nf()",
   1792           2 * kPointerSize,
   1793           1,
   1794           14,
   1795           {
   1796               B(LdaSmi8), U8(1),                                //
   1797               B(Star), R(0),                                    //
   1798               B(LdaSmi8), U8(2),                                //
   1799               B(Star), R(1),                                    //
   1800               B(CallRuntime), U16(Runtime::kAdd), R(0), U8(2),  //
   1801               B(Return)                                         //
   1802           },
   1803       },
   1804       {
   1805           "function f() { return %spread_iterable([1]) }\nf()",
   1806           2 * kPointerSize,
   1807           1,
   1808           15,
   1809           {
   1810               B(LdaUndefined),                                              //
   1811               B(Star), R(0),                                                //
   1812               B(CreateArrayLiteral), U8(0), U8(0), U8(3),                   //
   1813               B(Star), R(1),                                                //
   1814               B(CallJSRuntime), U16(Context::SPREAD_ITERABLE_INDEX), R(0),  //
   1815               U8(1),                                                        //
   1816               B(Return),                                                    //
   1817           },
   1818           1,
   1819           {InstanceType::FIXED_ARRAY_TYPE},
   1820       },
   1821   };
   1822 
   1823   for (size_t i = 0; i < arraysize(snippets); i++) {
   1824     Handle<BytecodeArray> bytecode_array =
   1825         helper.MakeBytecode(snippets[i].code_snippet, "f");
   1826     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   1827   }
   1828 }
   1829 
   1830 
   1831 TEST(IfConditions) {
   1832   InitializedHandleScope handle_scope;
   1833   BytecodeGeneratorHelper helper;
   1834 
   1835   Handle<Object> unused = helper.factory()->undefined_value();
   1836 
   1837   ExpectedSnippet<Handle<Object>> snippets[] = {
   1838       {"function f() { if (0) { return 1; } else { return -1; } } f()",
   1839        0,
   1840        1,
   1841        3,
   1842        {
   1843            B(LdaSmi8), U8(-1),  //
   1844            B(Return),           //
   1845        },
   1846        0,
   1847        {unused, unused, unused, unused, unused, unused}},
   1848       {"function f() { if ('lucky') { return 1; } else { return -1; } } f();",
   1849        0,
   1850        1,
   1851        3,
   1852        {
   1853            B(LdaSmi8), U8(1),  //
   1854            B(Return),          //
   1855        },
   1856        0,
   1857        {unused, unused, unused, unused, unused, unused}},
   1858       {"function f() { if (false) { return 1; } else { return -1; } } f();",
   1859        0,
   1860        1,
   1861        3,
   1862        {
   1863            B(LdaSmi8), U8(-1),  //
   1864            B(Return),           //
   1865        },
   1866        0,
   1867        {unused, unused, unused, unused, unused, unused}},
   1868       {"function f() { if (false) { return 1; } } f();",
   1869        0,
   1870        1,
   1871        2,
   1872        {
   1873            B(LdaUndefined),  //
   1874            B(Return),        //
   1875        },
   1876        0,
   1877        {unused, unused, unused, unused, unused, unused}},
   1878       {"function f() { var a = 1; if (a) { a += 1; } else { return 2; } } f();",
   1879        2 * kPointerSize,
   1880        1,
   1881        23,
   1882        {
   1883            B(LdaSmi8), U8(1),                //
   1884            B(Star), R(0),                    //
   1885            B(JumpIfToBooleanFalse), U8(14),  //
   1886            B(Ldar), R(0),                    //
   1887            B(Star), R(1),                    //
   1888            B(LdaSmi8), U8(1),                //
   1889            B(Add), R(1),                     //
   1890            B(Star), R(0),                    //
   1891            B(Jump), U8(5),                   //
   1892            B(LdaSmi8), U8(2),                //
   1893            B(Return),                        //
   1894            B(LdaUndefined),                  //
   1895            B(Return),                        //
   1896        },
   1897        0,
   1898        {unused, unused, unused, unused, unused, unused}},
   1899       {"function f(a) { if (a <= 0) { return 200; } else { return -200; } }"
   1900        "f(99);",
   1901        kPointerSize,
   1902        2,
   1903        17,
   1904        {
   1905            B(Ldar), A(1, 2),              //
   1906            B(Star), R(0),                 //
   1907            B(LdaZero),                    //
   1908            B(TestLessThanOrEqual), R(0),  //
   1909            B(JumpIfFalse), U8(5),         //
   1910            B(LdaConstant), U8(0),         //
   1911            B(Return),                     //
   1912            B(LdaConstant), U8(1),         //
   1913            B(Return),                     //
   1914            B(LdaUndefined),               //
   1915            B(Return),                     //
   1916        },
   1917        2,
   1918        {helper.factory()->NewNumberFromInt(200),
   1919         helper.factory()->NewNumberFromInt(-200), unused, unused, unused,
   1920         unused}},
   1921       {"function f(a, b) { if (a in b) { return 200; } }"
   1922        "f('prop', { prop: 'yes'});",
   1923        kPointerSize,
   1924        3,
   1925        15,
   1926        {
   1927            B(Ldar), A(1, 3),       //
   1928            B(Star), R(0),          //
   1929            B(Ldar), A(2, 3),       //
   1930            B(TestIn), R(0),        //
   1931            B(JumpIfFalse), U8(5),  //
   1932            B(LdaConstant), U8(0),  //
   1933            B(Return),              //
   1934            B(LdaUndefined),        //
   1935            B(Return),              //
   1936        },
   1937        1,
   1938        {helper.factory()->NewNumberFromInt(200), unused, unused, unused, unused,
   1939         unused}},
   1940       {"function f(z) { var a = 0; var b = 0; if (a === 0.01) { "
   1941        REPEAT_64(SPACE, "b = a; a = b; ")
   1942        " return 200; } else { return -200; } } f(0.001)",
   1943        3 * kPointerSize,
   1944        2,
   1945        282,
   1946        {
   1947            B(LdaZero),                     //
   1948            B(Star), R(0),                  //
   1949            B(LdaZero),                     //
   1950            B(Star), R(1),                  //
   1951            B(Ldar), R(0),                  //
   1952            B(Star), R(2),                  //
   1953            B(LdaConstant), U8(0),          //
   1954            B(TestEqualStrict), R(2),       //
   1955            B(JumpIfFalseConstant), U8(2),  //
   1956            B(Ldar), R(0),                  //
   1957            REPEAT_64(COMMA,                //
   1958              B(Star), R(1),                //
   1959              B(Star), R(0)),               //
   1960            B(LdaConstant), U8(1),          //
   1961            B(Return),                      //
   1962            B(LdaConstant), U8(3),          //
   1963            B(Return),                      //
   1964            B(LdaUndefined),                //
   1965            B(Return)},                     //
   1966        4,
   1967        {helper.factory()->NewHeapNumber(0.01),
   1968         helper.factory()->NewNumberFromInt(200),
   1969         helper.factory()->NewNumberFromInt(263),
   1970         helper.factory()->NewNumberFromInt(-200), unused, unused}},
   1971       {"function f() { var a = 0; var b = 0; if (a) { "
   1972        REPEAT_64(SPACE, "b = a; a = b; ")
   1973        " return 200; } else { return -200; } } f()",
   1974        2 * kPointerSize,
   1975        1,
   1976        276,
   1977        {
   1978            B(LdaZero),                              //
   1979            B(Star), R(0),                           //
   1980            B(LdaZero),                              //
   1981            B(Star), R(1),                           //
   1982            B(Ldar), R(0),                           //
   1983            B(JumpIfToBooleanFalseConstant), U8(1),  //
   1984            B(Ldar), R(0),                           //
   1985            REPEAT_64(COMMA,                         //
   1986              B(Star), R(1),                         //
   1987              B(Star), R(0)),                        //
   1988            B(LdaConstant), U8(0),                   //
   1989            B(Return),                               //
   1990            B(LdaConstant), U8(2),                   //
   1991            B(Return),                               //
   1992            B(LdaUndefined),                         //
   1993            B(Return)},                              //
   1994        3,
   1995        {helper.factory()->NewNumberFromInt(200),
   1996         helper.factory()->NewNumberFromInt(263),
   1997         helper.factory()->NewNumberFromInt(-200), unused, unused, unused}},
   1998 
   1999       {"function f(a, b) {\n"
   2000        "  if (a == b) { return 1; }\n"
   2001        "  if (a === b) { return 1; }\n"
   2002        "  if (a < b) { return 1; }\n"
   2003        "  if (a > b) { return 1; }\n"
   2004        "  if (a <= b) { return 1; }\n"
   2005        "  if (a >= b) { return 1; }\n"
   2006        "  if (a in b) { return 1; }\n"
   2007        "  if (a instanceof b) { return 1; }\n"
   2008        "  return 0;\n"
   2009        "} f(1, 1);",
   2010        kPointerSize,
   2011        3,
   2012        106,
   2013        {
   2014 #define IF_CONDITION_RETURN(condition) \
   2015          B(Ldar), A(1, 3),             \
   2016          B(Star), R(0),                \
   2017          B(Ldar), A(2, 3),             \
   2018          B(condition), R(0),           \
   2019          B(JumpIfFalse), U8(5),        \
   2020          B(LdaSmi8), U8(1),            \
   2021          B(Return),
   2022            IF_CONDITION_RETURN(TestEqual)               //
   2023            IF_CONDITION_RETURN(TestEqualStrict)         //
   2024            IF_CONDITION_RETURN(TestLessThan)            //
   2025            IF_CONDITION_RETURN(TestGreaterThan)         //
   2026            IF_CONDITION_RETURN(TestLessThanOrEqual)     //
   2027            IF_CONDITION_RETURN(TestGreaterThanOrEqual)  //
   2028            IF_CONDITION_RETURN(TestIn)                  //
   2029            IF_CONDITION_RETURN(TestInstanceOf)          //
   2030            B(LdaZero),                                  //
   2031            B(Return)},                                  //
   2032 #undef IF_CONDITION_RETURN
   2033        0,
   2034        {unused, unused, unused, unused, unused, unused}},
   2035       {"function f() {"
   2036        " var a = 0;"
   2037        " if (a) {"
   2038        "  return 20;"
   2039        "} else {"
   2040        "  return -20;}"
   2041        "};"
   2042        "f();",
   2043        1 * kPointerSize,
   2044        1,
   2045        13,
   2046        {
   2047            B(LdaZero),                      //
   2048            B(Star), R(0),                   //
   2049            B(JumpIfToBooleanFalse), U8(5),  //
   2050            B(LdaSmi8), U8(20),              //
   2051            B(Return),                       //
   2052            B(LdaSmi8), U8(-20),             //
   2053            B(Return),                       //
   2054            B(LdaUndefined),                 //
   2055            B(Return)
   2056        },
   2057        0,
   2058        {unused, unused, unused, unused, unused, unused}}};
   2059 
   2060   for (size_t i = 0; i < arraysize(snippets); i++) {
   2061     Handle<BytecodeArray> bytecode_array =
   2062         helper.MakeBytecode(snippets[i].code_snippet, helper.kFunctionName);
   2063     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   2064   }
   2065 }
   2066 
   2067 
   2068 TEST(DeclareGlobals) {
   2069   InitializedHandleScope handle_scope;
   2070   BytecodeGeneratorHelper helper;
   2071   Zone zone;
   2072 
   2073   // Create different feedback vector specs to be precise on slot numbering.
   2074   FeedbackVectorSpec feedback_spec_stores(&zone);
   2075   FeedbackVectorSlot store_slot_1 = feedback_spec_stores.AddStoreICSlot();
   2076   FeedbackVectorSlot store_slot_2 = feedback_spec_stores.AddStoreICSlot();
   2077   USE(store_slot_1);
   2078 
   2079   Handle<i::TypeFeedbackVector> store_vector =
   2080       i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec_stores);
   2081 
   2082   FeedbackVectorSpec feedback_spec_loads(&zone);
   2083   FeedbackVectorSlot load_slot_1 = feedback_spec_loads.AddLoadICSlot();
   2084   FeedbackVectorSlot call_slot_1 = feedback_spec_loads.AddCallICSlot();
   2085 
   2086   Handle<i::TypeFeedbackVector> load_vector =
   2087       i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec_loads);
   2088 
   2089   ExpectedSnippet<InstanceType> snippets[] = {
   2090       {"var a = 1;",
   2091        4 * kPointerSize,
   2092        1,
   2093        30,
   2094        {
   2095            B(LdaConstant), U8(0),                                            //
   2096            B(Star), R(1),                                                    //
   2097            B(LdaZero),                                                       //
   2098            B(Star), R(2),                                                    //
   2099            B(CallRuntime), U16(Runtime::kDeclareGlobals), R(1), U8(2),       //
   2100            B(LdaConstant), U8(1),                                            //
   2101            B(Star), R(1),                                                    //
   2102            B(LdaZero),                                                       //
   2103            B(Star), R(2),                                                    //
   2104            B(LdaSmi8), U8(1),                                                //
   2105            B(Star), R(3),                                                    //
   2106            B(CallRuntime), U16(Runtime::kInitializeVarGlobal), R(1), U8(3),  //
   2107            B(LdaUndefined),                                                  //
   2108            B(Return)                                                         //
   2109        },
   2110        2,
   2111        {InstanceType::FIXED_ARRAY_TYPE,
   2112         InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
   2113       {"function f() {}",
   2114        2 * kPointerSize,
   2115        1,
   2116        14,
   2117        {
   2118            B(LdaConstant), U8(0),                                       //
   2119            B(Star), R(0),                                               //
   2120            B(LdaZero),                                                  //
   2121            B(Star), R(1),                                               //
   2122            B(CallRuntime), U16(Runtime::kDeclareGlobals), R(0), U8(2),  //
   2123            B(LdaUndefined),                                             //
   2124            B(Return)                                                    //
   2125        },
   2126        1,
   2127        {InstanceType::FIXED_ARRAY_TYPE}},
   2128       {"var a = 1;\na=2;",
   2129        4 * kPointerSize,
   2130        1,
   2131        36,
   2132        {
   2133            B(LdaConstant), U8(0),                                            //
   2134            B(Star), R(1),                                                    //
   2135            B(LdaZero),                                                       //
   2136            B(Star), R(2),                                                    //
   2137            B(CallRuntime), U16(Runtime::kDeclareGlobals), R(1), U8(2),       //
   2138            B(LdaConstant), U8(1),                                            //
   2139            B(Star), R(1),                                                    //
   2140            B(LdaZero),                                                       //
   2141            B(Star), R(2),                                                    //
   2142            B(LdaSmi8), U8(1),                                                //
   2143            B(Star), R(3),                                                    //
   2144            B(CallRuntime), U16(Runtime::kInitializeVarGlobal), R(1), U8(3),  //
   2145            B(LdaSmi8), U8(2),                                                //
   2146            B(StaGlobalSloppy), U8(1),                                        //
   2147                                U8(store_vector->GetIndex(store_slot_2)),     //
   2148            B(Star), R(0),                                                    //
   2149            B(Return)                                                         //
   2150        },
   2151        2,
   2152        {InstanceType::FIXED_ARRAY_TYPE,
   2153         InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
   2154       {"function f() {}\nf();",
   2155        3 * kPointerSize,
   2156        1,
   2157        28,
   2158        {
   2159            B(LdaConstant), U8(0),                                        //
   2160            B(Star), R(1),                                                //
   2161            B(LdaZero),                                                   //
   2162            B(Star), R(2),                                                //
   2163            B(CallRuntime), U16(Runtime::kDeclareGlobals), R(1), U8(2),   //
   2164            B(LdaUndefined),                                              //
   2165            B(Star), R(2),                                                //
   2166            B(LdaGlobalSloppy), U8(1),                                    //
   2167                                U8(load_vector->GetIndex(load_slot_1)),   //
   2168            B(Star), R(1),                                                //
   2169            B(Call), R(1), R(2), U8(0),                                   //
   2170                                 U8(load_vector->GetIndex(call_slot_1)),  //
   2171            B(Star), R(0),                                                //
   2172            B(Return)                                                     //
   2173        },
   2174        2,
   2175        {InstanceType::FIXED_ARRAY_TYPE,
   2176         InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
   2177   };
   2178 
   2179   for (size_t i = 0; i < arraysize(snippets); i++) {
   2180     Handle<BytecodeArray> bytecode_array =
   2181         helper.MakeTopLevelBytecode(snippets[i].code_snippet);
   2182     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   2183   }
   2184 }
   2185 
   2186 
   2187 TEST(BreakableBlocks) {
   2188   InitializedHandleScope handle_scope;
   2189   BytecodeGeneratorHelper helper;
   2190 
   2191   ExpectedSnippet<int> snippets[] = {
   2192       {"var x = 0;\n"
   2193        "label: {\n"
   2194        "  x = x + 1;\n"
   2195        "  break label;\n"
   2196        "  x = x + 1;\n"
   2197        "}\n"
   2198        "return x;",
   2199        2 * kPointerSize,
   2200        1,
   2201        16,
   2202        {
   2203            B(LdaZero),         //
   2204            B(Star), R(0),      //
   2205            B(Star), R(1),      //
   2206            B(LdaSmi8), U8(1),  //
   2207            B(Add), R(1),       //
   2208            B(Star), R(0),      //
   2209            B(Jump), U8(2),     //
   2210            B(Ldar), R(0),      //
   2211            B(Return)           //
   2212        }},
   2213       {"var sum = 0;\n"
   2214        "outer: {\n"
   2215        "  for (var x = 0; x < 10; ++x) {\n"
   2216        "    for (var y = 0; y < 3; ++y) {\n"
   2217        "      ++sum;\n"
   2218        "      if (x + y == 12) { break outer; }\n"
   2219        "    }\n"
   2220        "  }\n"
   2221        "}\n"
   2222        "return sum;",
   2223        5 * kPointerSize,
   2224        1,
   2225        72,
   2226        {
   2227            B(LdaZero),              //
   2228            B(Star), R(0),           //
   2229            B(LdaZero),              //
   2230            B(Star), R(1),           //
   2231            B(Ldar), R(1),           //
   2232            B(Star), R(3),           //
   2233            B(LdaSmi8), U8(10),      //
   2234            B(TestLessThan), R(3),   //
   2235            B(JumpIfFalse), U8(55),  //
   2236            B(LdaZero),              //
   2237            B(Star), R(2),           //
   2238            B(Ldar), R(2),           //
   2239            B(Star), R(3),           //
   2240            B(LdaSmi8), U8(3),       //
   2241            B(TestLessThan), R(3),   //
   2242            B(JumpIfFalse), U8(34),  //
   2243            B(Ldar), R(0),           //
   2244            B(ToNumber),             //
   2245            B(Inc),                  //
   2246            B(Star), R(0),           //
   2247            B(Ldar), R(1),           //
   2248            B(Star), R(3),           //
   2249            B(Ldar), R(2),           //
   2250            B(Add), R(3),            //
   2251            B(Star), R(4),           //
   2252            B(LdaSmi8), U8(12),      //
   2253            B(TestEqual), R(4),      //
   2254            B(JumpIfFalse), U8(4),   //
   2255            B(Jump), U8(18),         //
   2256            B(Ldar), R(2),           //
   2257            B(ToNumber),             //
   2258            B(Inc),                  //
   2259            B(Star), R(2),           //
   2260            B(Jump), U8(-40),        //
   2261            B(Ldar), R(1),           //
   2262            B(ToNumber),             //
   2263            B(Inc),                  //
   2264            B(Star), R(1),           //
   2265            B(Jump), U8(-61),        //
   2266            B(Ldar), R(0),           //
   2267            B(Return),               //
   2268        }},
   2269   };
   2270 
   2271   for (size_t i = 0; i < arraysize(snippets); i++) {
   2272     Handle<BytecodeArray> bytecode_array =
   2273         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
   2274     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   2275   }
   2276 }
   2277 
   2278 
   2279 TEST(BasicLoops) {
   2280   InitializedHandleScope handle_scope;
   2281   BytecodeGeneratorHelper helper;
   2282 
   2283   ExpectedSnippet<int> snippets[] = {
   2284       {"var x = 0;\n"
   2285        "while (false) { x = 99; break; continue; }\n"
   2286        "return x;",
   2287        1 * kPointerSize,
   2288        1,
   2289        4,
   2290        {
   2291            B(LdaZero),     //
   2292            B(Star), R(0),  //
   2293            B(Return)       //
   2294        }},
   2295       {"var x = 0;"
   2296        "while (false) {"
   2297        "  x = x + 1;"
   2298        "};"
   2299        "return x;",
   2300        1 * kPointerSize,
   2301        1,
   2302        4,
   2303        {
   2304            B(LdaZero),     //
   2305            B(Star), R(0),  //
   2306            B(Return),      //
   2307        },
   2308        0},
   2309       {"var x = 0;"
   2310        "var y = 1;"
   2311        "while (x < 10) {"
   2312        "  y = y * 12;"
   2313        "  x = x + 1;"
   2314        "  if (x == 3) continue;"
   2315        "  if (x == 4) break;"
   2316        "}"
   2317        "return y;",
   2318        3 * kPointerSize,
   2319        1,
   2320        64,
   2321        {
   2322            B(LdaZero),              //
   2323            B(Star), R(0),           //
   2324            B(LdaSmi8), U8(1),       //
   2325            B(Star), R(1),           //
   2326            B(Ldar), R(0),           //
   2327            B(Star), R(2),           //
   2328            B(LdaSmi8), U8(10),      //
   2329            B(TestLessThan), R(2),   //
   2330            B(JumpIfFalse), U8(46),  //
   2331            B(Ldar), R(1),           //
   2332            B(Star), R(2),           //
   2333            B(LdaSmi8), U8(12),      //
   2334            B(Mul), R(2),            //
   2335            B(Star), R(1),           //
   2336            B(Ldar), R(0),           //
   2337            B(Star), R(2),           //
   2338            B(LdaSmi8), U8(1),       //
   2339            B(Add), R(2),            //
   2340            B(Star), R(0),           //
   2341            B(Star), R(2),           //
   2342            B(LdaSmi8), U8(3),       //
   2343            B(TestEqual), R(2),      //
   2344            B(JumpIfFalse), U8(4),   //
   2345            B(Jump), U8(-38),        //
   2346            B(Ldar), R(0),           //
   2347            B(Star), R(2),           //
   2348            B(LdaSmi8), U8(4),       //
   2349            B(TestEqual), R(2),      //
   2350            B(JumpIfFalse), U8(4),   //
   2351            B(Jump), U8(4),          //
   2352            B(Jump), U8(-52),        //
   2353            B(Ldar), R(1),           //
   2354            B(Return),               //
   2355        },
   2356        0},
   2357       {"var i = 0;"
   2358        "while (true) {"
   2359        "  if (i < 0) continue;"
   2360        "  if (i == 3) break;"
   2361        "  if (i == 4) break;"
   2362        "  if (i == 10) continue;"
   2363        "  if (i == 5) break;"
   2364        "  i = i + 1;"
   2365        "}"
   2366        "return i;",
   2367        2 * kPointerSize,
   2368        1,
   2369        77,
   2370        {
   2371            B(LdaZero),             //
   2372            B(Star), R(0),          //
   2373            B(Ldar), R(0),          //
   2374            B(Star), R(1),          //
   2375            B(LdaZero),             //
   2376            B(TestLessThan), R(1),  //
   2377            B(JumpIfFalse), U8(4),  //
   2378            B(Jump), U8(-9),        //
   2379            B(Ldar), R(0),          //
   2380            B(Star), R(1),          //
   2381            B(LdaSmi8), U8(3),      //
   2382            B(TestEqual), R(1),     //
   2383            B(JumpIfFalse), U8(4),  //
   2384            B(Jump), U8(50),        //
   2385            B(Ldar), R(0),          //
   2386            B(Star), R(1),          //
   2387            B(LdaSmi8), U8(4),      //
   2388            B(TestEqual), R(1),     //
   2389            B(JumpIfFalse), U8(4),  //
   2390            B(Jump), U8(38),        //
   2391            B(Ldar), R(0),          //
   2392            B(Star), R(1),          //
   2393            B(LdaSmi8), U8(10),     //
   2394            B(TestEqual), R(1),     //
   2395            B(JumpIfFalse), U8(4),  //
   2396            B(Jump), U8(-45),       //
   2397            B(Ldar), R(0),          //
   2398            B(Star), R(1),          //
   2399            B(LdaSmi8), U8(5),      //
   2400            B(TestEqual), R(1),     //
   2401            B(JumpIfFalse), U8(4),  //
   2402            B(Jump), U8(14),        //
   2403            B(Ldar), R(0),          //
   2404            B(Star), R(1),          //
   2405            B(LdaSmi8), U8(1),      //
   2406            B(Add), R(1),           //
   2407            B(Star), R(0),          //
   2408            B(Jump), U8(-69),       //
   2409            B(Ldar), R(0),          //
   2410            B(Return),              //
   2411        },
   2412        0},
   2413       {"var i = 0;"
   2414        "while (true) {"
   2415        "  while (i < 3) {"
   2416        "    if (i == 2) break;"
   2417        "    i = i + 1;"
   2418        "  }"
   2419        "  i = i + 1;"
   2420        "  break;"
   2421        "}"
   2422        "return i;",
   2423        2 * kPointerSize,
   2424        1,
   2425        54,
   2426        {
   2427            B(LdaZero),              //
   2428            B(Star), R(0),           //
   2429            B(Ldar), R(0),           //
   2430            B(Star), R(1),           //
   2431            B(LdaSmi8), U8(3),       //
   2432            B(TestLessThan), R(1),   //
   2433            B(JumpIfFalse), U8(26),  //
   2434            B(Ldar), R(0),           //
   2435            B(Star), R(1),           //
   2436            B(LdaSmi8), U8(2),       //
   2437            B(TestEqual), R(1),      //
   2438            B(JumpIfFalse), U8(4),   //
   2439            B(Jump), U8(14),         //
   2440            B(Ldar), R(0),           //
   2441            B(Star), R(1),           //
   2442            B(LdaSmi8), U8(1),       //
   2443            B(Add), R(1),            //
   2444            B(Star), R(0),           //
   2445            B(Jump), U8(-32),        //
   2446            B(Ldar), R(0),           //
   2447            B(Star), R(1),           //
   2448            B(LdaSmi8), U8(1),       //
   2449            B(Add), R(1),            //
   2450            B(Star), R(0),           //
   2451            B(Jump), U8(4),          //
   2452            B(Jump), U8(-46),        //
   2453            B(Ldar), R(0),           //
   2454            B(Return),               //
   2455        },
   2456        0},
   2457       {"var x = 10;"
   2458        "var y = 1;"
   2459        "while (x) {"
   2460        "  y = y * 12;"
   2461        "  x = x - 1;"
   2462        "}"
   2463        "return y;",
   2464        3 * kPointerSize,
   2465        1,
   2466        37,
   2467        {
   2468            B(LdaSmi8), U8(10),               //
   2469            B(Star), R(0),                    //
   2470            B(LdaSmi8), U8(1),                //
   2471            B(Star), R(1),                    //
   2472            B(Ldar), R(0),                    //
   2473            B(JumpIfToBooleanFalse), U8(24),  //
   2474            B(Ldar), R(1),                    //
   2475            B(Star), R(2),                    //
   2476            B(LdaSmi8), U8(12),               //
   2477            B(Mul), R(2),                     //
   2478            B(Star), R(1),                    //
   2479            B(Ldar), R(0),                    //
   2480            B(Star), R(2),                    //
   2481            B(LdaSmi8), U8(1),                //
   2482            B(Sub), R(2),                     //
   2483            B(Star), R(0),                    //
   2484            B(Jump), U8(-24),                 //
   2485            B(Ldar), R(1),                    //
   2486            B(Return),                        //
   2487        },
   2488        0},
   2489       {"var x = 0; var y = 1;"
   2490        "do {"
   2491        "  y = y * 10;"
   2492        "  if (x == 5) break;"
   2493        "  if (x == 6) continue;"
   2494        "  x = x + 1;"
   2495        "} while (x < 10);"
   2496        "return y;",
   2497        3 * kPointerSize,
   2498        1,
   2499        64,
   2500        {
   2501            B(LdaZero),              //
   2502            B(Star), R(0),           //
   2503            B(LdaSmi8), U8(1),       //
   2504            B(Star), R(1),           //
   2505            B(Ldar), R(1),           //
   2506            B(Star), R(2),           //
   2507            B(LdaSmi8), U8(10),      //
   2508            B(Mul), R(2),            //
   2509            B(Star), R(1),           //
   2510            B(Ldar), R(0),           //
   2511            B(Star), R(2),           //
   2512            B(LdaSmi8), U8(5),       //
   2513            B(TestEqual), R(2),      //
   2514            B(JumpIfFalse), U8(4),   //
   2515            B(Jump), U8(34),         //
   2516            B(Ldar), R(0),           //
   2517            B(Star), R(2),           //
   2518            B(LdaSmi8), U8(6),       //
   2519            B(TestEqual), R(2),      //
   2520            B(JumpIfFalse), U8(4),   //
   2521            B(Jump), U8(12),         //
   2522            B(Ldar), R(0),           //
   2523            B(Star), R(2),           //
   2524            B(LdaSmi8), U8(1),       //
   2525            B(Add), R(2),            //
   2526            B(Star), R(0),           //
   2527            B(Ldar), R(0),           //
   2528            B(Star), R(2),           //
   2529            B(LdaSmi8), U8(10),      //
   2530            B(TestLessThan), R(2),   //
   2531            B(JumpIfTrue), U8(-52),  //
   2532            B(Ldar), R(1),           //
   2533            B(Return),               //
   2534        },
   2535        0},
   2536       {"var x = 10;"
   2537        "var y = 1;"
   2538        "do {"
   2539        "  y = y * 12;"
   2540        "  x = x - 1;"
   2541        "} while (x);"
   2542        "return y;",
   2543        3 * kPointerSize,
   2544        1,
   2545        35,
   2546        {
   2547            B(LdaSmi8), U8(10),               //
   2548            B(Star), R(0),                    //
   2549            B(LdaSmi8), U8(1),                //
   2550            B(Star), R(1),                    //
   2551            B(Ldar), R(1),                    //
   2552            B(Star), R(2),                    //
   2553            B(LdaSmi8), U8(12),               //
   2554            B(Mul), R(2),                     //
   2555            B(Star), R(1),                    //
   2556            B(Ldar), R(0),                    //
   2557            B(Star), R(2),                    //
   2558            B(LdaSmi8), U8(1),                //
   2559            B(Sub), R(2),                     //
   2560            B(Star), R(0),                    //
   2561            B(Ldar), R(0),                    //
   2562            B(JumpIfToBooleanTrue), U8(-22),  //
   2563            B(Ldar), R(1),                    //
   2564            B(Return),                        //
   2565        },
   2566        0},
   2567       {"var x = 0; var y = 1;"
   2568        "do {"
   2569        "  y = y * 10;"
   2570        "  if (x == 5) break;"
   2571        "  x = x + 1;"
   2572        "  if (x == 6) continue;"
   2573        "} while (false);"
   2574        "return y;",
   2575        3 * kPointerSize,
   2576        1,
   2577        52,
   2578        {
   2579            B(LdaZero),             //
   2580            B(Star), R(0),          //
   2581            B(LdaSmi8), U8(1),      //
   2582            B(Star), R(1),          //
   2583            B(Ldar), R(1),          //
   2584            B(Star), R(2),          //
   2585            B(LdaSmi8), U8(10),     //
   2586            B(Mul), R(2),           //
   2587            B(Star), R(1),          //
   2588            B(Ldar), R(0),          //
   2589            B(Star), R(2),          //
   2590            B(LdaSmi8), U8(5),      //
   2591            B(TestEqual), R(2),     //
   2592            B(JumpIfFalse), U8(4),  //
   2593            B(Jump), U8(22),        //
   2594            B(Ldar), R(0),          //
   2595            B(Star), R(2),          //
   2596            B(LdaSmi8), U8(1),      //
   2597            B(Add), R(2),           //
   2598            B(Star), R(0),          //
   2599            B(Star), R(2),          //
   2600            B(LdaSmi8), U8(6),      //
   2601            B(TestEqual), R(2),     //
   2602            B(JumpIfFalse), U8(4),  //
   2603            B(Jump), U8(2),         //
   2604            B(Ldar), R(1),          //
   2605            B(Return),              //
   2606        },
   2607        0},
   2608       {"var x = 0; var y = 1;"
   2609        "do {"
   2610        "  y = y * 10;"
   2611        "  if (x == 5) break;"
   2612        "  x = x + 1;"
   2613        "  if (x == 6) continue;"
   2614        "} while (true);"
   2615        "return y;",
   2616        3 * kPointerSize,
   2617        1,
   2618        54,
   2619        {
   2620            B(LdaZero),             //
   2621            B(Star), R(0),          //
   2622            B(LdaSmi8), U8(1),      //
   2623            B(Star), R(1),          //
   2624            B(Ldar), R(1),          //
   2625            B(Star), R(2),          //
   2626            B(LdaSmi8), U8(10),     //
   2627            B(Mul), R(2),           //
   2628            B(Star), R(1),          //
   2629            B(Ldar), R(0),          //
   2630            B(Star), R(2),          //
   2631            B(LdaSmi8), U8(5),      //
   2632            B(TestEqual), R(2),     //
   2633            B(JumpIfFalse), U8(4),  //
   2634            B(Jump), U8(24),        //
   2635            B(Ldar), R(0),          //
   2636            B(Star), R(2),          //
   2637            B(LdaSmi8), U8(1),      //
   2638            B(Add), R(2),           //
   2639            B(Star), R(0),          //
   2640            B(Star), R(2),          //
   2641            B(LdaSmi8), U8(6),      //
   2642            B(TestEqual), R(2),     //
   2643            B(JumpIfFalse), U8(4),  //
   2644            B(Jump), U8(-40),       //
   2645            B(Jump), U8(-42),       //
   2646            B(Ldar), R(1),          //
   2647            B(Return),              //
   2648        },
   2649        0},
   2650       {"var x = 0; "
   2651        "for (;;) {"
   2652        "  if (x == 1) break;"
   2653        "  if (x == 2) continue;"
   2654        "  x = x + 1;"
   2655        "}",
   2656        2 * kPointerSize,
   2657        1,
   2658        41,
   2659        {
   2660            B(LdaZero),             //
   2661            B(Star), R(0),          //
   2662            B(Ldar), R(0),          //
   2663            B(Star), R(1),          //
   2664            B(LdaSmi8), U8(1),      //
   2665            B(TestEqual), R(1),     //
   2666            B(JumpIfFalse), U8(4),  //
   2667            B(Jump), U8(26),        //
   2668            B(Ldar), R(0),          //
   2669            B(Star), R(1),          //
   2670            B(LdaSmi8), U8(2),      //
   2671            B(TestEqual), R(1),     //
   2672            B(JumpIfFalse), U8(4),  //
   2673            B(Jump), U8(-22),       //
   2674            B(Ldar), R(0),          //
   2675            B(Star), R(1),          //
   2676            B(LdaSmi8), U8(1),      //
   2677            B(Add), R(1),           //
   2678            B(Star), R(0),          //
   2679            B(Jump), U8(-34),       //
   2680            B(LdaUndefined),        //
   2681            B(Return),              //
   2682        },
   2683        0},
   2684       {"for (var x = 0;;) {"
   2685        "  if (x == 1) break;"
   2686        "  if (x == 2) continue;"
   2687        "  x = x + 1;"
   2688        "}",
   2689        2 * kPointerSize,
   2690        1,
   2691        41,
   2692        {
   2693            B(LdaZero),             //
   2694            B(Star), R(0),          //
   2695            B(Ldar), R(0),          //
   2696            B(Star), R(1),          //
   2697            B(LdaSmi8), U8(1),      //
   2698            B(TestEqual), R(1),     //
   2699            B(JumpIfFalse), U8(4),  //
   2700            B(Jump), U8(26),        //
   2701            B(Ldar), R(0),          //
   2702            B(Star), R(1),          //
   2703            B(LdaSmi8), U8(2),      //
   2704            B(TestEqual), R(1),     //
   2705            B(JumpIfFalse), U8(4),  //
   2706            B(Jump), U8(-22),       //
   2707            B(Ldar), R(0),          //
   2708            B(Star), R(1),          //
   2709            B(LdaSmi8), U8(1),      //
   2710            B(Add), R(1),           //
   2711            B(Star), R(0),          //
   2712            B(Jump), U8(-34),       //
   2713            B(LdaUndefined),        //
   2714            B(Return),              //
   2715        },
   2716        0},
   2717       {"var x = 0; "
   2718        "for (;; x = x + 1) {"
   2719        "  if (x == 1) break;"
   2720        "  if (x == 2) continue;"
   2721        "}",
   2722        2 * kPointerSize,
   2723        1,
   2724        41,
   2725        {
   2726            B(LdaZero),             //
   2727            B(Star), R(0),          //
   2728            B(Ldar), R(0),          //
   2729            B(Star), R(1),          //
   2730            B(LdaSmi8), U8(1),      //
   2731            B(TestEqual), R(1),     //
   2732            B(JumpIfFalse), U8(4),  //
   2733            B(Jump), U8(26),        //
   2734            B(Ldar), R(0),          //
   2735            B(Star), R(1),          //
   2736            B(LdaSmi8), U8(2),      //
   2737            B(TestEqual), R(1),     //
   2738            B(JumpIfFalse), U8(4),  //
   2739            B(Jump), U8(2),         //
   2740            B(Ldar), R(0),          //
   2741            B(Star), R(1),          //
   2742            B(LdaSmi8), U8(1),      //
   2743            B(Add), R(1),           //
   2744            B(Star), R(0),          //
   2745            B(Jump), U8(-34),       //
   2746            B(LdaUndefined),        //
   2747            B(Return),              //
   2748        },
   2749        0},
   2750       {"for (var x = 0;; x = x + 1) {"
   2751        "  if (x == 1) break;"
   2752        "  if (x == 2) continue;"
   2753        "}",
   2754        2 * kPointerSize,
   2755        1,
   2756        41,
   2757        {
   2758            B(LdaZero),             //
   2759            B(Star), R(0),          //
   2760            B(Ldar), R(0),          //
   2761            B(Star), R(1),          //
   2762            B(LdaSmi8), U8(1),      //
   2763            B(TestEqual), R(1),     //
   2764            B(JumpIfFalse), U8(4),  //
   2765            B(Jump), U8(26),        //
   2766            B(Ldar), R(0),          //
   2767            B(Star), R(1),          //
   2768            B(LdaSmi8), U8(2),      //
   2769            B(TestEqual), R(1),     //
   2770            B(JumpIfFalse), U8(4),  //
   2771            B(Jump), U8(2),         //
   2772            B(Ldar), R(0),          //
   2773            B(Star), R(1),          //
   2774            B(LdaSmi8), U8(1),      //
   2775            B(Add), R(1),           //
   2776            B(Star), R(0),          //
   2777            B(Jump), U8(-34),       //
   2778            B(LdaUndefined),        //
   2779            B(Return),              //
   2780        },
   2781        0},
   2782       {"var u = 0;"
   2783        "for (var i = 0; i < 100; i = i + 1) {"
   2784        "  u = u + 1;"
   2785        "  continue;"
   2786        "}",
   2787        3 * kPointerSize,
   2788        1,
   2789        42,
   2790        {
   2791            B(LdaZero),              //
   2792            B(Star), R(0),           //
   2793            B(LdaZero),              //
   2794            B(Star), R(1),           //
   2795            B(Ldar), R(1),           //
   2796            B(Star), R(2),           //
   2797            B(LdaSmi8), U8(100),     //
   2798            B(TestLessThan), R(2),   //
   2799            B(JumpIfFalse), U8(26),  //
   2800            B(Ldar), R(0),           //
   2801            B(Star), R(2),           //
   2802            B(LdaSmi8), U8(1),       //
   2803            B(Add), R(2),            //
   2804            B(Star), R(0),           //
   2805            B(Jump), U8(2),          //
   2806            B(Ldar), R(1),           //
   2807            B(Star), R(2),           //
   2808            B(LdaSmi8), U8(1),       //
   2809            B(Add), R(2),            //
   2810            B(Star), R(1),           //
   2811            B(Jump), U8(-32),        //
   2812            B(LdaUndefined),         //
   2813            B(Return),               //
   2814        },
   2815        0},
   2816       {"var y = 1;"
   2817        "for (var x = 10; x; --x) {"
   2818        "  y = y * 12;"
   2819        "}"
   2820        "return y;",
   2821        3 * kPointerSize,
   2822        1,
   2823        33,
   2824        {
   2825            B(LdaSmi8), U8(1),                //
   2826            B(Star), R(0),                    //
   2827            B(LdaSmi8), U8(10),               //
   2828            B(Star), R(1),                    //
   2829            B(Ldar), R(1),                    //
   2830            B(JumpIfToBooleanFalse), U8(20),  //
   2831            B(Ldar), R(0),                    //
   2832            B(Star), R(2),                    //
   2833            B(LdaSmi8), U8(12),               //
   2834            B(Mul), R(2),                     //
   2835            B(Star), R(0),                    //
   2836            B(Ldar), R(1),                    //
   2837            B(ToNumber),                      //
   2838            B(Dec),                           //
   2839            B(Star), R(1),                    //
   2840            B(Jump), U8(-20),                 //
   2841            B(Ldar), R(0),                    //
   2842            B(Return),                        //
   2843        },
   2844        0},
   2845       {"var x = 0;"
   2846        "for (var i = 0; false; i++) {"
   2847        "  x = x + 1;"
   2848        "};"
   2849        "return x;",
   2850        2 * kPointerSize,
   2851        1,
   2852        9,
   2853        {
   2854            B(LdaZero),     //
   2855            B(Star), R(0),  //
   2856            B(LdaZero),     //
   2857            B(Star), R(1),  //
   2858            B(Ldar), R(0),  //
   2859            B(Return),      //
   2860        },
   2861        0},
   2862       {"var x = 0;"
   2863        "for (var i = 0; true; ++i) {"
   2864        "  x = x + 1;"
   2865        "  if (x == 20) break;"
   2866        "};"
   2867        "return x;",
   2868        3 * kPointerSize,
   2869        1,
   2870        37,
   2871        {
   2872            B(LdaZero),             //
   2873            B(Star), R(0),          //
   2874            B(LdaZero),             //
   2875            B(Star), R(1),          //
   2876            B(Ldar), R(0),          //
   2877            B(Star), R(2),          //
   2878            B(LdaSmi8), U8(1),      //
   2879            B(Add), R(2),           //
   2880            B(Star), R(0),          //
   2881            B(Star), R(2),          //
   2882            B(LdaSmi8), U8(20),     //
   2883            B(TestEqual), R(2),     //
   2884            B(JumpIfFalse), U8(4),  //
   2885            B(Jump), U8(10),        //
   2886            B(Ldar), R(1),          //
   2887            B(ToNumber),            //
   2888            B(Inc),                 //
   2889            B(Star), R(1),          //
   2890            B(Jump), U8(-26),       //
   2891            B(Ldar), R(0),          //
   2892            B(Return),              //
   2893        },
   2894        0},
   2895   };
   2896 
   2897   for (size_t i = 0; i < arraysize(snippets); i++) {
   2898     Handle<BytecodeArray> bytecode_array =
   2899         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
   2900     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   2901   }
   2902 }
   2903 
   2904 
   2905 TEST(JumpsRequiringConstantWideOperands) {
   2906   InitializedHandleScope handle_scope;
   2907   BytecodeGeneratorHelper helper;
   2908 
   2909   int constant_count = 0;
   2910   ExpectedSnippet<Handle<Object>, 316> snippets[] = {
   2911       {
   2912        REPEAT_256(SPACE, "var x = 0.1;")
   2913        REPEAT_32(SPACE, "var x = 0.2;")
   2914        REPEAT_16(SPACE, "var x = 0.3;")
   2915        REPEAT_8(SPACE, "var x = 0.4;")
   2916        "for (var i = 0; i < 3; i++) {\n"
   2917        "  if (i == 1) continue;\n"
   2918        "  if (i == 2) break;\n"
   2919        "}\n"
   2920        "return 3;",
   2921        kPointerSize * 3,
   2922        1,
   2923        1359,
   2924        {
   2925 #define L(c) B(LdaConstant), U8(c), B(Star), R(0)
   2926            REPEAT_256(COMMA, L(constant_count++)),
   2927 #undef L
   2928 #define LW(c) B(LdaConstantWide), U16I(c), B(Star), R(0)
   2929            REPEAT_32(COMMA, LW(constant_count)),
   2930            REPEAT_16(COMMA, LW(constant_count)),
   2931            REPEAT_8(COMMA, LW(constant_count)),
   2932 #undef LW
   2933            B(LdaZero),                            //
   2934            B(Star), R(1),                         //
   2935            B(Ldar), R(1),                         //
   2936            B(Star), R(2),                         //
   2937            B(LdaSmi8), U8(3),                     //
   2938            B(TestLessThan), R(2),                 //
   2939            B(JumpIfFalseConstantWide), U16(313),  //
   2940            B(Ldar), R(1),                         //
   2941            B(Star), R(2),                         //
   2942            B(LdaSmi8), U8(1),                     //
   2943            B(TestEqual), R(2),                    //
   2944            B(JumpIfFalseConstantWide), U16(312),  //
   2945            B(JumpConstantWide), U16(315),         //
   2946            B(Ldar), R(1),                         //
   2947            B(Star), R(2),                         //
   2948            B(LdaSmi8), U8(2),                     //
   2949            B(TestEqual), R(2),                    //
   2950            B(JumpIfFalseConstantWide), U16(312),  //
   2951            B(JumpConstantWide), U16(314),         //
   2952            B(Ldar), R(1),                         //
   2953            B(ToNumber),                           //
   2954            B(Star), R(2),                         //
   2955            B(Inc),                                //
   2956            B(Star), R(1),                         //
   2957            B(Jump), U8(-47),                      //
   2958            B(LdaSmi8), U8(3),                     //
   2959            B(Return)                              //
   2960        },
   2961        316,
   2962        {
   2963 #define S(x) CcTest::i_isolate()->factory()->NewNumber(x)
   2964         REPEAT_256(COMMA, S(0.1)),
   2965         REPEAT_32(COMMA, S(0.2)),
   2966         REPEAT_16(COMMA, S(0.3)),
   2967         REPEAT_8(COMMA, S(0.4)),
   2968 #undef S
   2969 #define N(x) CcTest::i_isolate()->factory()->NewNumberFromInt(x)
   2970            N(6), N(41), N(13), N(17)
   2971 #undef N
   2972        }}};
   2973 
   2974   for (size_t i = 0; i < arraysize(snippets); i++) {
   2975     Handle<BytecodeArray> bytecode_array =
   2976         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
   2977     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   2978   }
   2979 }
   2980 
   2981 
   2982 TEST(UnaryOperators) {
   2983   InitializedHandleScope handle_scope;
   2984   BytecodeGeneratorHelper helper;
   2985 
   2986   ExpectedSnippet<int> snippets[] = {
   2987       {"var x = 0;"
   2988        "while (x != 10) {"
   2989        "  x = x + 10;"
   2990        "}"
   2991        "return x;",
   2992        2 * kPointerSize,
   2993        1,
   2994        29,
   2995        {
   2996            B(LdaZero),              //
   2997            B(Star), R(0),           //
   2998            B(Ldar), R(0),           //
   2999            B(Star), R(1),           //
   3000            B(LdaSmi8), U8(10),      //
   3001            B(TestEqual), R(1),      //
   3002            B(LogicalNot),           //
   3003            B(JumpIfFalse), U8(14),  //
   3004            B(Ldar), R(0),           //
   3005            B(Star), R(1),           //
   3006            B(LdaSmi8), U8(10),      //
   3007            B(Add), R(1),            //
   3008            B(Star), R(0),           //
   3009            B(Jump), U8(-21),        //
   3010            B(Ldar), R(0),           //
   3011            B(Return),               //
   3012        },
   3013        0},
   3014       {"var x = false;"
   3015        "do {"
   3016        "  x = !x;"
   3017        "} while(x == false);"
   3018        "return x;",
   3019        2 * kPointerSize,
   3020        1,
   3021        20,
   3022        {
   3023            B(LdaFalse),            //
   3024            B(Star), R(0),          //
   3025            B(Ldar), R(0),          //
   3026            B(LogicalNot),          //
   3027            B(Star), R(0),          //
   3028            B(Ldar), R(0),          //
   3029            B(Star), R(1),          //
   3030            B(LdaFalse),            //
   3031            B(TestEqual), R(1),     //
   3032            B(JumpIfTrue), U8(-12),  //
   3033            B(Ldar), R(0),          //
   3034            B(Return),              //
   3035        },
   3036        0},
   3037       {"var x = 101;"
   3038        "return void(x * 3);",
   3039        2 * kPointerSize,
   3040        1,
   3041        12,
   3042        {
   3043            B(LdaSmi8), U8(101),  //
   3044            B(Star), R(0),        //
   3045            B(Star), R(1),        //
   3046            B(LdaSmi8), U8(3),    //
   3047            B(Mul), R(1),         //
   3048            B(LdaUndefined),      //
   3049            B(Return),            //
   3050        },
   3051        0},
   3052       {"var x = 1234;"
   3053        "var y = void (x * x - 1);"
   3054        "return y;",
   3055        4 * kPointerSize,
   3056        1,
   3057        20,
   3058        {
   3059            B(LdaConstant), U8(0),  //
   3060            B(Star), R(0),          //
   3061            B(Star), R(2),          //
   3062            B(Ldar), R(0),          //
   3063            B(Mul), R(2),           //
   3064            B(Star), R(3),          //
   3065            B(LdaSmi8), U8(1),      //
   3066            B(Sub), R(3),           //
   3067            B(LdaUndefined),        //
   3068            B(Star), R(1),          //
   3069            B(Return),              //
   3070        },
   3071        1,
   3072        {1234}},
   3073       {"var x = 13;"
   3074        "return ~x;",
   3075        2 * kPointerSize,
   3076        1,
   3077        11,
   3078        {
   3079            B(LdaSmi8), U8(13),   //
   3080            B(Star), R(0),        //
   3081            B(Star), R(1),        //
   3082            B(LdaSmi8), U8(-1),   //
   3083            B(BitwiseXor), R(1),  //
   3084            B(Return),            //
   3085        },
   3086        0},
   3087       {"var x = 13;"
   3088        "return +x;",
   3089        2 * kPointerSize,
   3090        1,
   3091        11,
   3092        {
   3093            B(LdaSmi8), U8(13),  //
   3094            B(Star), R(0),       //
   3095            B(Star), R(1),       //
   3096            B(LdaSmi8), U8(1),   //
   3097            B(Mul), R(1),        //
   3098            B(Return),           //
   3099        },
   3100        0},
   3101       {"var x = 13;"
   3102        "return -x;",
   3103        2 * kPointerSize,
   3104        1,
   3105        11,
   3106        {
   3107            B(LdaSmi8), U8(13),  //
   3108            B(Star), R(0),       //
   3109            B(Star), R(1),       //
   3110            B(LdaSmi8), U8(-1),  //
   3111            B(Mul), R(1),        //
   3112            B(Return),           //
   3113        },
   3114        0}};
   3115 
   3116   for (size_t i = 0; i < arraysize(snippets); i++) {
   3117     Handle<BytecodeArray> bytecode_array =
   3118         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
   3119     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   3120   }
   3121 }
   3122 
   3123 
   3124 TEST(Typeof) {
   3125   InitializedHandleScope handle_scope;
   3126   BytecodeGeneratorHelper helper;
   3127   Zone zone;
   3128 
   3129   FeedbackVectorSpec feedback_spec(&zone);
   3130   FeedbackVectorSlot slot = feedback_spec.AddLoadICSlot();
   3131 
   3132   Handle<i::TypeFeedbackVector> vector =
   3133       i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec);
   3134 
   3135   ExpectedSnippet<const char*> snippets[] = {
   3136       {"function f() {\n"
   3137        " var x = 13;\n"
   3138        " return typeof(x);\n"
   3139        "}; f();",
   3140        kPointerSize,
   3141        1,
   3142        6,
   3143        {
   3144            B(LdaSmi8), U8(13),  //
   3145            B(Star), R(0),       //
   3146            B(TypeOf),           //
   3147            B(Return),           //
   3148        }},
   3149       {"var x = 13;\n"
   3150        "function f() {\n"
   3151        " return typeof(x);\n"
   3152        "}; f();",
   3153        0,
   3154        1,
   3155        5,
   3156        {
   3157            B(LdaGlobalInsideTypeofSloppy), U8(0),                       //
   3158                                            U8(vector->GetIndex(slot)),  //
   3159            B(TypeOf),                                                   //
   3160            B(Return),                                                   //
   3161        },
   3162        1,
   3163        {"x"}},
   3164       {"var x = 13;\n"
   3165        "function f() {\n"
   3166        " 'use strict';\n"
   3167        " return typeof(x);\n"
   3168        "}; f();",
   3169        0,
   3170        1,
   3171        5,
   3172        {
   3173            B(LdaGlobalInsideTypeofStrict), U8(0),                       //
   3174                                            U8(vector->GetIndex(slot)),  //
   3175            B(TypeOf),                                                   //
   3176            B(Return),                                                   //
   3177        },
   3178        1,
   3179        {"x"}},
   3180   };
   3181 
   3182   for (size_t i = 0; i < arraysize(snippets); i++) {
   3183     Handle<BytecodeArray> bytecode_array =
   3184         helper.MakeBytecodeForFunction(snippets[i].code_snippet);
   3185     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   3186   }
   3187 }
   3188 
   3189 
   3190 TEST(Delete) {
   3191   InitializedHandleScope handle_scope;
   3192   BytecodeGeneratorHelper helper;
   3193 
   3194   int deep_elements_flags =
   3195       ObjectLiteral::kFastElements | ObjectLiteral::kDisableMementos;
   3196   int closure = Register::function_closure().index();
   3197   int first_context_slot = Context::MIN_CONTEXT_SLOTS;
   3198 
   3199   ExpectedSnippet<InstanceType> snippets[] = {
   3200       {"var a = {x:13, y:14}; return delete a.x;",
   3201        2 * kPointerSize,
   3202        1,
   3203        13,
   3204        {
   3205            B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags),  //
   3206            B(Star), R(0),                                                  //
   3207            B(Star), R(1),                                                  //
   3208            B(LdaConstant), U8(1),                                          //
   3209            B(DeletePropertySloppy), R(1),                                  //
   3210            B(Return)
   3211        },
   3212        2,
   3213        {InstanceType::FIXED_ARRAY_TYPE,
   3214         InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
   3215       {"'use strict'; var a = {x:13, y:14}; return delete a.x;",
   3216        2 * kPointerSize,
   3217        1,
   3218        13,
   3219        {
   3220            B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags),  //
   3221            B(Star), R(0),                                                  //
   3222            B(Star), R(1),                                                  //
   3223            B(LdaConstant), U8(1),                                          //
   3224            B(DeletePropertyStrict), R(1),                                  //
   3225            B(Return)
   3226        },
   3227        2,
   3228        {InstanceType::FIXED_ARRAY_TYPE,
   3229         InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
   3230       {"var a = {1:13, 2:14}; return delete a[2];",
   3231        2 * kPointerSize,
   3232        1,
   3233        13,
   3234        {
   3235            B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags),  //
   3236            B(Star), R(0),                                                  //
   3237            B(Star), R(1),                                                  //
   3238            B(LdaSmi8), U8(2),                                              //
   3239            B(DeletePropertySloppy), R(1),                                  //
   3240            B(Return)
   3241        },
   3242        1,
   3243        {InstanceType::FIXED_ARRAY_TYPE}},
   3244       {"var a = 10; return delete a;",
   3245        1 * kPointerSize,
   3246        1,
   3247        6,
   3248        {
   3249            B(LdaSmi8), U8(10),  //
   3250            B(Star), R(0),       //
   3251            B(LdaFalse),         //
   3252            B(Return)
   3253         },
   3254        0},
   3255       {"'use strict';"
   3256        "var a = {1:10};"
   3257        "(function f1() {return a;});"
   3258        "return delete a[1];",
   3259        2 * kPointerSize,
   3260        1,
   3261        27,
   3262        {
   3263            B(CallRuntime), U16(Runtime::kNewFunctionContext),              //
   3264                             R(closure), U8(1),                             //
   3265            B(PushContext), R(0),                                           //
   3266            B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags),  //
   3267            B(StaContextSlot), R(0), U8(first_context_slot),                //
   3268            B(CreateClosure), U8(1), U8(0),                                 //
   3269            B(LdaContextSlot), R(0), U8(first_context_slot),                //
   3270            B(Star), R(1),                                                  //
   3271            B(LdaSmi8), U8(1),                                              //
   3272            B(DeletePropertyStrict), R(1),                                  //
   3273            B(Return)
   3274        },
   3275        2,
   3276        {InstanceType::FIXED_ARRAY_TYPE,
   3277         InstanceType::SHARED_FUNCTION_INFO_TYPE}},
   3278       {"return delete 'test';",
   3279        0 * kPointerSize,
   3280        1,
   3281        2,
   3282        {
   3283            B(LdaTrue),  //
   3284            B(Return)
   3285        },
   3286        0},
   3287   };
   3288 
   3289   for (size_t i = 0; i < arraysize(snippets); i++) {
   3290     Handle<BytecodeArray> bytecode_array =
   3291         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
   3292     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   3293   }
   3294 }
   3295 
   3296 
   3297 TEST(GlobalDelete) {
   3298   InitializedHandleScope handle_scope;
   3299   BytecodeGeneratorHelper helper;
   3300   Zone zone;
   3301 
   3302   int context = Register::function_context().index();
   3303   int native_context_index = Context::NATIVE_CONTEXT_INDEX;
   3304   int global_context_index = Context::EXTENSION_INDEX;
   3305   FeedbackVectorSpec feedback_spec(&zone);
   3306   FeedbackVectorSlot slot = feedback_spec.AddLoadICSlot();
   3307 
   3308   Handle<i::TypeFeedbackVector> vector =
   3309       i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec);
   3310 
   3311   ExpectedSnippet<InstanceType> snippets[] = {
   3312       {"var a = {x:13, y:14};\n function f() { return delete a.x; };\n f();",
   3313        1 * kPointerSize,
   3314        1,
   3315        10,
   3316        {B(LdaGlobalSloppy), U8(0), U8(vector->GetIndex(slot)),  //
   3317         B(Star), R(0),                                          //
   3318         B(LdaConstant), U8(1),                                  //
   3319         B(DeletePropertySloppy), R(0),                          //
   3320         B(Return)},
   3321        2,
   3322        {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
   3323         InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
   3324       {"a = {1:13, 2:14};\n"
   3325        "function f() {'use strict'; return delete a[1];};\n f();",
   3326        1 * kPointerSize,
   3327        1,
   3328        10,
   3329        {B(LdaGlobalStrict), U8(0), U8(vector->GetIndex(slot)),  //
   3330         B(Star), R(0),                                          //
   3331         B(LdaSmi8), U8(1),                                      //
   3332         B(DeletePropertyStrict), R(0),                          //
   3333         B(Return)},
   3334        1,
   3335        {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
   3336       {"var a = {x:13, y:14};\n function f() { return delete a; };\n f();",
   3337        2 * kPointerSize,
   3338        1,
   3339        15,
   3340        {B(LdaContextSlot), R(context), U8(native_context_index),  //
   3341         B(Star), R(0),                                            //
   3342         B(LdaContextSlot), R(0), U8(global_context_index),        //
   3343         B(Star), R(1),                                            //
   3344         B(LdaConstant), U8(0),                                    //
   3345         B(DeletePropertySloppy), R(1),                            //
   3346         B(Return)},
   3347        1,
   3348        {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
   3349       {"b = 30;\n function f() { return delete b; };\n f();",
   3350        2 * kPointerSize,
   3351        1,
   3352        15,
   3353        {B(LdaContextSlot), R(context), U8(native_context_index),  //
   3354         B(Star), R(0),                                            //
   3355         B(LdaContextSlot), R(0), U8(global_context_index),        //
   3356         B(Star), R(1),                                            //
   3357         B(LdaConstant), U8(0),                                    //
   3358         B(DeletePropertySloppy), R(1),                            //
   3359         B(Return)},
   3360        1,
   3361        {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}};
   3362 
   3363   for (size_t i = 0; i < arraysize(snippets); i++) {
   3364     Handle<BytecodeArray> bytecode_array =
   3365         helper.MakeBytecode(snippets[i].code_snippet, "f");
   3366     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   3367   }
   3368 }
   3369 
   3370 
   3371 TEST(FunctionLiterals) {
   3372   InitializedHandleScope handle_scope;
   3373   BytecodeGeneratorHelper helper;
   3374   Zone zone;
   3375 
   3376   FeedbackVectorSpec feedback_spec(&zone);
   3377   FeedbackVectorSlot slot = feedback_spec.AddCallICSlot();
   3378 
   3379   Handle<i::TypeFeedbackVector> vector =
   3380       i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec);
   3381 
   3382   ExpectedSnippet<InstanceType> snippets[] = {
   3383       {"return function(){ }",
   3384        0,
   3385        1,
   3386        4,
   3387        {
   3388            B(CreateClosure), U8(0), U8(0),  //
   3389            B(Return)                        //
   3390        },
   3391        1,
   3392        {InstanceType::SHARED_FUNCTION_INFO_TYPE}},
   3393       {"return (function(){ })()",
   3394        2 * kPointerSize,
   3395        1,
   3396        14,
   3397        {
   3398            B(LdaUndefined),                                         //
   3399            B(Star), R(1),                                           //
   3400            B(CreateClosure), U8(0), U8(0),                          //
   3401            B(Star), R(0),                                           //
   3402            B(Call), R(0), R(1), U8(0), U8(vector->GetIndex(slot)),  //
   3403            B(Return)                                                //
   3404        },
   3405        1,
   3406        {InstanceType::SHARED_FUNCTION_INFO_TYPE}},
   3407       {"return (function(x){ return x; })(1)",
   3408        3 * kPointerSize,
   3409        1,
   3410        18,
   3411        {
   3412            B(LdaUndefined),                                         //
   3413            B(Star), R(1),                                           //
   3414            B(CreateClosure), U8(0), U8(0),                          //
   3415            B(Star), R(0),                                           //
   3416            B(LdaSmi8), U8(1),                                       //
   3417            B(Star), R(2),                                           //
   3418            B(Call), R(0), R(1), U8(1), U8(vector->GetIndex(slot)),  //
   3419            B(Return)                                                //
   3420        },
   3421        1,
   3422        {InstanceType::SHARED_FUNCTION_INFO_TYPE}},
   3423   };
   3424 
   3425   for (size_t i = 0; i < arraysize(snippets); i++) {
   3426     Handle<BytecodeArray> bytecode_array =
   3427         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
   3428     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   3429   }
   3430 }
   3431 
   3432 
   3433 TEST(RegExpLiterals) {
   3434   InitializedHandleScope handle_scope;
   3435   BytecodeGeneratorHelper helper;
   3436   Zone zone;
   3437 
   3438   FeedbackVectorSpec feedback_spec(&zone);
   3439   FeedbackVectorSlot slot1 = feedback_spec.AddCallICSlot();
   3440   FeedbackVectorSlot slot2 = feedback_spec.AddLoadICSlot();
   3441   uint8_t i_flags = JSRegExp::kIgnoreCase;
   3442 
   3443   Handle<i::TypeFeedbackVector> vector =
   3444       i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec);
   3445 
   3446   ExpectedSnippet<const char*> snippets[] = {
   3447       {"return /ab+d/;",
   3448        0 * kPointerSize,
   3449        1,
   3450        5,
   3451        {
   3452            B(CreateRegExpLiteral), U8(0), U8(0), U8(0),  //
   3453            B(Return),                                    //
   3454        },
   3455        1,
   3456        {"ab+d"}},
   3457       {"return /(\\w+)\\s(\\w+)/i;",
   3458        0 * kPointerSize,
   3459        1,
   3460        5,
   3461        {
   3462            B(CreateRegExpLiteral), U8(0), U8(0), U8(i_flags),  //
   3463            B(Return),                                          //
   3464        },
   3465        1,
   3466        {"(\\w+)\\s(\\w+)"}},
   3467       {"return /ab+d/.exec('abdd');",
   3468        3 * kPointerSize,
   3469        1,
   3470        22,
   3471        {
   3472            B(CreateRegExpLiteral), U8(0), U8(0), U8(0),                //
   3473            B(Star), R(1),                                              //
   3474            B(LoadICSloppy), R(1), U8(1), U8(vector->GetIndex(slot2)),  //
   3475            B(Star), R(0),                                              //
   3476            B(LdaConstant), U8(2),                                      //
   3477            B(Star), R(2),                                              //
   3478            B(Call), R(0), R(1), U8(1), U8(vector->GetIndex(slot1)),    //
   3479            B(Return),                                                  //
   3480        },
   3481        3,
   3482        {"ab+d", "exec", "abdd"}},
   3483   };
   3484 
   3485   for (size_t i = 0; i < arraysize(snippets); i++) {
   3486     Handle<BytecodeArray> bytecode_array =
   3487         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
   3488     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   3489   }
   3490 }
   3491 
   3492 
   3493 TEST(RegExpLiteralsWide) {
   3494   InitializedHandleScope handle_scope;
   3495   BytecodeGeneratorHelper helper;
   3496   Zone zone;
   3497 
   3498   int wide_idx = 0;
   3499 
   3500   ExpectedSnippet<InstanceType, 257> snippets[] = {
   3501       {"var a;" REPEAT_256(SPACE, "a = 1.23;") "return /ab+d/;",
   3502        1 * kPointerSize,
   3503        1,
   3504        1031,
   3505        {
   3506            REPEAT_256(COMMA,                                     //
   3507              B(LdaConstant), U8(wide_idx++),                     //
   3508              B(Star), R(0)),                                     //
   3509            B(CreateRegExpLiteralWide), U16(256), U16(0), U8(0),  //
   3510            B(Return)                                             //
   3511        },
   3512        257,
   3513        {REPEAT_256(COMMA, InstanceType::HEAP_NUMBER_TYPE),
   3514         InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
   3515   };
   3516 
   3517   for (size_t i = 0; i < arraysize(snippets); i++) {
   3518     Handle<BytecodeArray> bytecode_array =
   3519         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
   3520     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   3521   }
   3522 }
   3523 
   3524 
   3525 TEST(ArrayLiterals) {
   3526   InitializedHandleScope handle_scope;
   3527   BytecodeGeneratorHelper helper;
   3528   Zone zone;
   3529 
   3530   FeedbackVectorSpec feedback_spec(&zone);
   3531   FeedbackVectorSlot slot1 = feedback_spec.AddKeyedStoreICSlot();
   3532   FeedbackVectorSlot slot2 = feedback_spec.AddKeyedStoreICSlot();
   3533   FeedbackVectorSlot slot3 = feedback_spec.AddKeyedStoreICSlot();
   3534 
   3535   Handle<i::TypeFeedbackVector> vector =
   3536       i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec);
   3537 
   3538   int simple_flags =
   3539       ArrayLiteral::kDisableMementos | ArrayLiteral::kShallowElements;
   3540   int deep_elements_flags = ArrayLiteral::kDisableMementos;
   3541   ExpectedSnippet<InstanceType> snippets[] = {
   3542       {"return [ 1, 2 ];",
   3543        0,
   3544        1,
   3545        5,
   3546        {
   3547            B(CreateArrayLiteral), U8(0), U8(0), U8(simple_flags),  //
   3548            B(Return)                                               //
   3549        },
   3550        1,
   3551        {InstanceType::FIXED_ARRAY_TYPE}},
   3552       {"var a = 1; return [ a, a + 1 ];",
   3553        4 * kPointerSize,
   3554        1,
   3555        38,
   3556        {
   3557            B(LdaSmi8), U8(1),                                               //
   3558            B(Star), R(0),                                                   //
   3559            B(CreateArrayLiteral), U8(0), U8(0), U8(3),                      //
   3560            B(Star), R(2),                                                   //
   3561            B(LdaZero),                                                      //
   3562            B(Star), R(1),                                                   //
   3563            B(Ldar), R(0),                                                   //
   3564            B(KeyedStoreICSloppy), R(2), R(1), U8(vector->GetIndex(slot1)),  //
   3565            B(LdaSmi8), U8(1),                                               //
   3566            B(Star), R(1),                                                   //
   3567            B(Ldar), R(0),                                                   //
   3568            B(Star), R(3),                                                   //
   3569            B(LdaSmi8), U8(1),                                               //
   3570            B(Add), R(3),                                                    //
   3571            B(KeyedStoreICSloppy), R(2), R(1), U8(vector->GetIndex(slot1)),  //
   3572            B(Ldar), R(2),                                                   //
   3573            B(Return),                                                       //
   3574        },
   3575        1,
   3576        {InstanceType::FIXED_ARRAY_TYPE}},
   3577       {"return [ [ 1, 2 ], [ 3 ] ];",
   3578        0,
   3579        1,
   3580        5,
   3581        {
   3582            B(CreateArrayLiteral), U8(0), U8(2), U8(deep_elements_flags),  //
   3583            B(Return)                                                      //
   3584        },
   3585        1,
   3586        {InstanceType::FIXED_ARRAY_TYPE}},
   3587       {"var a = 1; return [ [ a, 2 ], [ a + 2 ] ];",
   3588        6 * kPointerSize,
   3589        1,
   3590        68,
   3591        {
   3592            B(LdaSmi8), U8(1),                                               //
   3593            B(Star), R(0),                                                   //
   3594            B(CreateArrayLiteral), U8(0), U8(2), U8(deep_elements_flags),    //
   3595            B(Star), R(2),                                                   //
   3596            B(LdaZero),                                                      //
   3597            B(Star), R(1),                                                   //
   3598            B(CreateArrayLiteral), U8(1), U8(0), U8(simple_flags),           //
   3599            B(Star), R(4),                                                   //
   3600            B(LdaZero),                                                      //
   3601            B(Star), R(3),                                                   //
   3602            B(Ldar), R(0),                                                   //
   3603            B(KeyedStoreICSloppy), R(4), R(3), U8(vector->GetIndex(slot1)),  //
   3604            B(Ldar), R(4),                                                   //
   3605            B(KeyedStoreICSloppy), R(2), R(1), U8(vector->GetIndex(slot3)),  //
   3606            B(LdaSmi8), U8(1),                                               //
   3607            B(Star), R(1),                                                   //
   3608            B(CreateArrayLiteral), U8(2), U8(1), U8(simple_flags),           //
   3609            B(Star), R(4),                                                   //
   3610            B(LdaZero),                                                      //
   3611            B(Star), R(3),                                                   //
   3612            B(Ldar), R(0),                                                   //
   3613            B(Star), R(5),                                                   //
   3614            B(LdaSmi8), U8(2),                                               //
   3615            B(Add), R(5),                                                    //
   3616            B(KeyedStoreICSloppy), R(4), R(3), U8(vector->GetIndex(slot2)),  //
   3617            B(Ldar), R(4),                                                   //
   3618            B(KeyedStoreICSloppy), R(2), R(1), U8(vector->GetIndex(slot3)),  //
   3619            B(Ldar), R(2),                                                   //
   3620            B(Return),                                                       //
   3621        },
   3622        3,
   3623        {InstanceType::FIXED_ARRAY_TYPE, InstanceType::FIXED_ARRAY_TYPE,
   3624         InstanceType::FIXED_ARRAY_TYPE}},
   3625   };
   3626 
   3627   for (size_t i = 0; i < arraysize(snippets); i++) {
   3628     Handle<BytecodeArray> bytecode_array =
   3629         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
   3630     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   3631   }
   3632 }
   3633 
   3634 
   3635 TEST(ArrayLiteralsWide) {
   3636   InitializedHandleScope handle_scope;
   3637   BytecodeGeneratorHelper helper;
   3638   Zone zone;
   3639 
   3640   int wide_idx = 0;
   3641   int simple_flags =
   3642       ArrayLiteral::kDisableMementos | ArrayLiteral::kShallowElements;
   3643 
   3644   ExpectedSnippet<InstanceType, 257> snippets[] = {
   3645       {"var a;" REPEAT_256(SPACE, "a = 1.23;") "return [ 1 , 2 ];",
   3646        1 * kPointerSize,
   3647        1,
   3648        1031,
   3649        {
   3650            REPEAT_256(COMMA,                                               //
   3651              B(LdaConstant), U8(wide_idx++),                               //
   3652              B(Star), R(0)),                                               //
   3653            B(CreateArrayLiteralWide), U16(256), U16(0), U8(simple_flags),  //
   3654            B(Return)                                                       //
   3655        },
   3656        257,
   3657        {REPEAT_256(COMMA, InstanceType::HEAP_NUMBER_TYPE),
   3658         InstanceType::FIXED_ARRAY_TYPE}},
   3659   };
   3660 
   3661   for (size_t i = 0; i < arraysize(snippets); i++) {
   3662     Handle<BytecodeArray> bytecode_array =
   3663         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
   3664     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   3665   }
   3666 }
   3667 
   3668 
   3669 TEST(ObjectLiterals) {
   3670   InitializedHandleScope handle_scope;
   3671   BytecodeGeneratorHelper helper;
   3672   Zone zone;
   3673 
   3674   FeedbackVectorSpec feedback_spec(&zone);
   3675   FeedbackVectorSlot slot1 = feedback_spec.AddStoreICSlot();
   3676 
   3677   Handle<i::TypeFeedbackVector> vector =
   3678       i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec);
   3679 
   3680   int simple_flags = ObjectLiteral::kFastElements |
   3681                      ObjectLiteral::kShallowProperties |
   3682                      ObjectLiteral::kDisableMementos;
   3683   int deep_elements_flags =
   3684       ObjectLiteral::kFastElements | ObjectLiteral::kDisableMementos;
   3685   ExpectedSnippet<InstanceType> snippets[] = {
   3686       {"return { };",
   3687        0,
   3688        1,
   3689        5,
   3690        {
   3691            B(CreateObjectLiteral), U8(0), U8(0), U8(simple_flags),  //
   3692            B(Return)                                                //
   3693        },
   3694        1,
   3695        {InstanceType::FIXED_ARRAY_TYPE}},
   3696       {"return { name: 'string', val: 9.2 };",
   3697        0,
   3698        1,
   3699        5,
   3700        {
   3701            B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags),  //
   3702            B(Return)                                                       //
   3703        },
   3704        1,
   3705        {InstanceType::FIXED_ARRAY_TYPE}},
   3706       {"var a = 1; return { name: 'string', val: a };",
   3707        2 * kPointerSize,
   3708        1,
   3709        19,
   3710        {
   3711            B(LdaSmi8), U8(1),                                              //
   3712            B(Star), R(0),                                                  //
   3713            B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags),  //
   3714            B(Star), R(1),                                                  //
   3715            B(Ldar), R(0),                                                  //
   3716            B(StoreICSloppy), R(1), U8(1), U8(vector->GetIndex(slot1)),     //
   3717            B(Ldar), R(1),                                                  //
   3718            B(Return),                                                      //
   3719        },
   3720        2,
   3721        {InstanceType::FIXED_ARRAY_TYPE,
   3722         InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
   3723       {"var a = 1; return { val: a, val: a + 1 };",
   3724        3 * kPointerSize,
   3725        1,
   3726        25,
   3727        {
   3728            B(LdaSmi8), U8(1),                                              //
   3729            B(Star), R(0),                                                  //
   3730            B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags),  //
   3731            B(Star), R(1),                                                  //
   3732            B(Ldar), R(0),                                                  //
   3733            B(Star), R(2),                                                  //
   3734            B(LdaSmi8), U8(1),                                              //
   3735            B(Add), R(2),                                                   //
   3736            B(StoreICSloppy), R(1), U8(1), U8(vector->GetIndex(slot1)),     //
   3737            B(Ldar), R(1),                                                  //
   3738            B(Return),                                                      //
   3739        },
   3740        2,
   3741        {InstanceType::FIXED_ARRAY_TYPE,
   3742         InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
   3743       {"return { func: function() { } };",
   3744        1 * kPointerSize,
   3745        1,
   3746        16,
   3747        {
   3748            B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags),  //
   3749            B(Star), R(0),                                                  //
   3750            B(CreateClosure), U8(1), U8(0),                                 //
   3751            B(StoreICSloppy), R(0), U8(2), U8(vector->GetIndex(slot1)),     //
   3752            B(Ldar), R(0),                                                  //
   3753            B(Return),                                                      //
   3754        },
   3755        3,
   3756        {InstanceType::FIXED_ARRAY_TYPE,
   3757         InstanceType::SHARED_FUNCTION_INFO_TYPE,
   3758         InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
   3759       {"return { func(a) { return a; } };",
   3760        1 * kPointerSize,
   3761        1,
   3762        16,
   3763        {
   3764            B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags),  //
   3765            B(Star), R(0),                                                  //
   3766            B(CreateClosure), U8(1), U8(0),                                 //
   3767            B(StoreICSloppy), R(0), U8(2), U8(vector->GetIndex(slot1)),     //
   3768            B(Ldar), R(0),                                                  //
   3769            B(Return),                                                      //
   3770        },
   3771        3,
   3772        {InstanceType::FIXED_ARRAY_TYPE,
   3773         InstanceType::SHARED_FUNCTION_INFO_TYPE,
   3774         InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
   3775       {"return { get a() { return 2; } };",
   3776        5 * kPointerSize,
   3777        1,
   3778        29,
   3779        {
   3780            B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags),   //
   3781            B(Star), R(0),                                                   //
   3782            B(LdaConstant), U8(1),                                           //
   3783            B(Star), R(1),                                                   //
   3784            B(CreateClosure), U8(2), U8(0),                                  //
   3785            B(Star), R(2),                                                   //
   3786            B(LdaNull),                                                      //
   3787            B(Star), R(3),                                                   //
   3788            B(LdaZero),                                                      //
   3789            B(Star), R(4),                                                   //
   3790            B(CallRuntime), U16(Runtime::kDefineAccessorPropertyUnchecked),  //
   3791                            R(0), U8(5),                                     //
   3792            B(Ldar), R(0),                                                   //
   3793            B(Return),                                                       //
   3794        },
   3795        3,
   3796        {InstanceType::FIXED_ARRAY_TYPE,
   3797         InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
   3798         InstanceType::SHARED_FUNCTION_INFO_TYPE}},
   3799       {"return { get a() { return this.x; }, set a(val) { this.x = val } };",
   3800        5 * kPointerSize,
   3801        1,
   3802        31,
   3803        {
   3804            B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags),   //
   3805            B(Star), R(0),                                                   //
   3806            B(LdaConstant), U8(1),                                           //
   3807            B(Star), R(1),                                                   //
   3808            B(CreateClosure), U8(2), U8(0),                                  //
   3809            B(Star), R(2),                                                   //
   3810            B(CreateClosure), U8(3), U8(0),                                  //
   3811            B(Star), R(3),                                                   //
   3812            B(LdaZero),                                                      //
   3813            B(Star), R(4),                                                   //
   3814            B(CallRuntime), U16(Runtime::kDefineAccessorPropertyUnchecked),  //
   3815                            R(0), U8(5),                                     //
   3816            B(Ldar), R(0),                                                   //
   3817            B(Return),                                                       //
   3818        },
   3819        4,
   3820        {InstanceType::FIXED_ARRAY_TYPE,
   3821         InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
   3822         InstanceType::SHARED_FUNCTION_INFO_TYPE,
   3823         InstanceType::SHARED_FUNCTION_INFO_TYPE}},
   3824       {"return { set b(val) { this.y = val } };",
   3825        5 * kPointerSize,
   3826        1,
   3827        29,
   3828        {
   3829            B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags),   //
   3830            B(Star), R(0),                                                   //
   3831            B(LdaConstant), U8(1),                                           //
   3832            B(Star), R(1),                                                   //
   3833            B(LdaNull),                                                      //
   3834            B(Star), R(2),                                                   //
   3835            B(CreateClosure), U8(2), U8(0),                                  //
   3836            B(Star), R(3),                                                   //
   3837            B(LdaZero),                                                      //
   3838            B(Star), R(4),                                                   //
   3839            B(CallRuntime), U16(Runtime::kDefineAccessorPropertyUnchecked),  //
   3840                            R(0), U8(5),                                     //
   3841            B(Ldar), R(0),                                                   //
   3842            B(Return),                                                       //
   3843        },
   3844        3,
   3845        {InstanceType::FIXED_ARRAY_TYPE,
   3846         InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
   3847         InstanceType::SHARED_FUNCTION_INFO_TYPE}},
   3848       {"var a = 1; return { 1: a };",
   3849        5 * kPointerSize,
   3850        1,
   3851        29,
   3852        {
   3853            B(LdaSmi8), U8(1),                                              //
   3854            B(Star), R(0),                                                  //
   3855            B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags),  //
   3856            B(Star), R(1),                                                  //
   3857            B(LdaSmi8), U8(1),                                              //
   3858            B(Star), R(2),                                                  //
   3859            B(Ldar), R(0),                                                  //
   3860            B(Star), R(3),                                                  //
   3861            B(LdaZero),                                                     //
   3862            B(Star), R(4),                                                  //
   3863            B(CallRuntime), U16(Runtime::kSetProperty), R(1), U8(4),        //
   3864            B(Ldar), R(1),                                                  //
   3865            B(Return),                                                      //
   3866        },
   3867        1,
   3868        {InstanceType::FIXED_ARRAY_TYPE}},
   3869       {"return { __proto__: null }",
   3870        2 * kPointerSize,
   3871        1,
   3872        17,
   3873        {
   3874            B(CreateObjectLiteral), U8(0), U8(0), U8(simple_flags),            //
   3875            B(Star), R(0),                                                     //
   3876            B(LdaNull), B(Star), R(1),                                         //
   3877            B(CallRuntime), U16(Runtime::kInternalSetPrototype), R(0), U8(2),  //
   3878            B(Ldar), R(0),                                                     //
   3879            B(Return),                                                         //
   3880        },
   3881        1,
   3882        {InstanceType::FIXED_ARRAY_TYPE}},
   3883       {"var a = 'test'; return { [a]: 1 }",
   3884        5 * kPointerSize,
   3885        1,
   3886        30,
   3887        {
   3888            B(LdaConstant), U8(0),                                             //
   3889            B(Star), R(0),                                                     //
   3890            B(CreateObjectLiteral), U8(1), U8(0), U8(simple_flags),            //
   3891            B(Star), R(1),                                                     //
   3892            B(Ldar), R(0),                                                     //
   3893            B(ToName),                                                         //
   3894            B(Star), R(2),                                                     //
   3895            B(LdaSmi8), U8(1),                                                 //
   3896            B(Star), R(3),                                                     //
   3897            B(LdaZero),                                                        //
   3898            B(Star), R(4),                                                     //
   3899            B(CallRuntime), U16(Runtime::kDefineDataPropertyUnchecked), R(1),  //
   3900                            U8(4),                                             //
   3901            B(Ldar), R(1),                                                     //
   3902            B(Return),                                                         //
   3903        },
   3904        2,
   3905        {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
   3906         InstanceType::FIXED_ARRAY_TYPE}},
   3907       {"var a = 'test'; return { val: a, [a]: 1 }",
   3908        5 * kPointerSize,
   3909        1,
   3910        36,
   3911        {
   3912            B(LdaConstant), U8(0),                                             //
   3913            B(Star), R(0),                                                     //
   3914            B(CreateObjectLiteral), U8(1), U8(0), U8(deep_elements_flags),     //
   3915            B(Star), R(1),                                                     //
   3916            B(Ldar), R(0),                                                     //
   3917            B(StoreICSloppy), R(1), U8(2), U8(vector->GetIndex(slot1)),        //
   3918            B(Ldar), R(0),                                                     //
   3919            B(ToName),                                                         //
   3920            B(Star), R(2),                                                     //
   3921            B(LdaSmi8), U8(1),                                                 //
   3922            B(Star), R(3),                                                     //
   3923            B(LdaZero),                                                        //
   3924            B(Star), R(4),                                                     //
   3925            B(CallRuntime), U16(Runtime::kDefineDataPropertyUnchecked), R(1),  //
   3926                            U8(4),                                             //
   3927            B(Ldar), R(1),                                                     //
   3928            B(Return),                                                         //
   3929        },
   3930        3,
   3931        {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
   3932         InstanceType::FIXED_ARRAY_TYPE,
   3933         InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
   3934       {"var a = 'test'; return { [a]: 1, __proto__: {} }",
   3935        5 * kPointerSize,
   3936        1,
   3937        41,
   3938        {
   3939            B(LdaConstant), U8(0),                                             //
   3940            B(Star), R(0),                                                     //
   3941            B(CreateObjectLiteral), U8(1), U8(1), U8(simple_flags),            //
   3942            B(Star), R(1),                                                     //
   3943            B(Ldar), R(0),                                                     //
   3944            B(ToName),                                                         //
   3945            B(Star), R(2),                                                     //
   3946            B(LdaSmi8), U8(1),                                                 //
   3947            B(Star), R(3),                                                     //
   3948            B(LdaZero),                                                        //
   3949            B(Star), R(4),                                                     //
   3950            B(CallRuntime), U16(Runtime::kDefineDataPropertyUnchecked), R(1),  //
   3951                            U8(4),                                             //
   3952            B(CreateObjectLiteral), U8(1), U8(0), U8(13),                      //
   3953            B(Star), R(2),                                                     //
   3954            B(CallRuntime), U16(Runtime::kInternalSetPrototype), R(1), U8(2),  //
   3955            B(Ldar), R(1),                                                     //
   3956            B(Return),                                                         //
   3957        },
   3958        2,
   3959        {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
   3960         InstanceType::FIXED_ARRAY_TYPE}},
   3961       {"var n = 'name'; return { [n]: 'val', get a() { }, set a(b) {} };",
   3962        5 * kPointerSize,
   3963        1,
   3964        64,
   3965        {
   3966            B(LdaConstant), U8(0),                                             //
   3967            B(Star), R(0),                                                     //
   3968            B(CreateObjectLiteral), U8(1), U8(0), U8(simple_flags),            //
   3969            B(Star), R(1),                                                     //
   3970            B(Ldar), R(0),                                                     //
   3971            B(ToName),                                                         //
   3972            B(Star), R(2),                                                     //
   3973            B(LdaConstant), U8(2),                                             //
   3974            B(Star), R(3),                                                     //
   3975            B(LdaZero),                                                        //
   3976            B(Star), R(4),                                                     //
   3977            B(CallRuntime), U16(Runtime::kDefineDataPropertyUnchecked), R(1),  //
   3978                            U8(4),                                             //
   3979            B(LdaConstant), U8(3),                                             //
   3980            B(Star), R(2),                                                     //
   3981            B(CreateClosure), U8(4), U8(0),                                    //
   3982            B(Star), R(3),                                                     //
   3983            B(LdaZero),                                                        //
   3984            B(Star), R(4),                                                     //
   3985            B(CallRuntime), U16(Runtime::kDefineGetterPropertyUnchecked),      //
   3986                            R(1), U8(4),                                       //
   3987            B(LdaConstant), U8(3),                                             //
   3988            B(Star), R(2),                                                     //
   3989            B(CreateClosure), U8(5), U8(0),                                    //
   3990            B(Star), R(3),                                                     //
   3991            B(LdaZero),                                                        //
   3992            B(Star), R(4),                                                     //
   3993            B(CallRuntime), U16(Runtime::kDefineSetterPropertyUnchecked),      //
   3994                            R(1), U8(4),                                       //
   3995            B(Ldar), R(1),                                                     //
   3996            B(Return),                                                         //
   3997        },
   3998        6,
   3999        {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
   4000         InstanceType::FIXED_ARRAY_TYPE,
   4001         InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
   4002         InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
   4003         InstanceType::SHARED_FUNCTION_INFO_TYPE,
   4004         InstanceType::SHARED_FUNCTION_INFO_TYPE}},
   4005   };
   4006 
   4007   for (size_t i = 0; i < arraysize(snippets); i++) {
   4008     Handle<BytecodeArray> bytecode_array =
   4009         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
   4010     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   4011   }
   4012 }
   4013 
   4014 
   4015 TEST(ObjectLiteralsWide) {
   4016   InitializedHandleScope handle_scope;
   4017   BytecodeGeneratorHelper helper;
   4018   Zone zone;
   4019 
   4020   int deep_elements_flags =
   4021       ObjectLiteral::kFastElements | ObjectLiteral::kDisableMementos;
   4022   int wide_idx = 0;
   4023 
   4024   ExpectedSnippet<InstanceType, 257> snippets[] = {
   4025       {"var a;" REPEAT_256(SPACE,
   4026                            "a = 1.23;") "return { name: 'string', val: 9.2 };",
   4027        1 * kPointerSize,
   4028        1,
   4029        1031,
   4030        {
   4031            REPEAT_256(COMMA,                                     //
   4032              B(LdaConstant), U8(wide_idx++),                     //
   4033              B(Star), R(0)),                                     //
   4034            B(CreateObjectLiteralWide), U16(256), U16(0),         //
   4035                                        U8(deep_elements_flags),  //
   4036            B(Return)                                             //
   4037        },
   4038        257,
   4039        {REPEAT_256(COMMA, InstanceType::HEAP_NUMBER_TYPE),
   4040         InstanceType::FIXED_ARRAY_TYPE}},
   4041   };
   4042 
   4043   for (size_t i = 0; i < arraysize(snippets); i++) {
   4044     Handle<BytecodeArray> bytecode_array =
   4045         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
   4046     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   4047   }
   4048 }
   4049 
   4050 
   4051 TEST(TopLevelObjectLiterals) {
   4052   InitializedHandleScope handle_scope;
   4053   BytecodeGeneratorHelper helper;
   4054 
   4055   int has_function_flags = ObjectLiteral::kFastElements |
   4056                            ObjectLiteral::kHasFunction |
   4057                            ObjectLiteral::kDisableMementos;
   4058   ExpectedSnippet<InstanceType> snippets[] = {
   4059       {"var a = { func: function() { } };",
   4060        5 * kPointerSize,
   4061        1,
   4062        48,
   4063        {
   4064            B(LdaConstant), U8(0),                                            //
   4065            B(Star), R(1),                                                    //
   4066            B(LdaZero),                                                       //
   4067            B(Star), R(2),                                                    //
   4068            B(CallRuntime), U16(Runtime::kDeclareGlobals), R(1), U8(2),       //
   4069            B(LdaConstant), U8(1),                                            //
   4070            B(Star), R(1),                                                    //
   4071            B(LdaZero),                                                       //
   4072            B(Star), R(2),                                                    //
   4073            B(CreateObjectLiteral), U8(2), U8(0), U8(has_function_flags),     //
   4074            B(Star), R(4),                                                    //
   4075            B(CreateClosure), U8(3), U8(1),                                   //
   4076            B(StoreICSloppy), R(4), U8(4), U8(3),                             //
   4077            B(CallRuntime), U16(Runtime::kToFastProperties), R(4), U8(1),     //
   4078            B(Ldar), R(4),                                                    //
   4079            B(Star), R(3),                                                    //
   4080            B(CallRuntime), U16(Runtime::kInitializeVarGlobal), R(1), U8(3),  //
   4081            B(LdaUndefined),                                                  //
   4082            B(Return),                                                        //
   4083        },
   4084        5,
   4085        {InstanceType::FIXED_ARRAY_TYPE,
   4086         InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
   4087         InstanceType::FIXED_ARRAY_TYPE,
   4088         InstanceType::SHARED_FUNCTION_INFO_TYPE,
   4089         InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
   4090   };
   4091 
   4092   for (size_t i = 0; i < arraysize(snippets); i++) {
   4093     Handle<BytecodeArray> bytecode_array =
   4094         helper.MakeTopLevelBytecode(snippets[i].code_snippet);
   4095     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   4096   }
   4097 }
   4098 
   4099 
   4100 TEST(TryCatch) {
   4101   InitializedHandleScope handle_scope;
   4102   BytecodeGeneratorHelper helper;
   4103 
   4104   // TODO(rmcilroy): modify tests when we have real try catch support.
   4105   ExpectedSnippet<int> snippets[] = {
   4106       {"try { return 1; } catch(e) { return 2; }",
   4107        kPointerSize,
   4108        1,
   4109        3,
   4110        {
   4111            B(LdaSmi8), U8(1),  //
   4112            B(Return),          //
   4113        },
   4114        0},
   4115   };
   4116 
   4117   for (size_t i = 0; i < arraysize(snippets); i++) {
   4118     Handle<BytecodeArray> bytecode_array =
   4119         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
   4120     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   4121   }
   4122 }
   4123 
   4124 
   4125 TEST(TryFinally) {
   4126   InitializedHandleScope handle_scope;
   4127   BytecodeGeneratorHelper helper;
   4128 
   4129   // TODO(rmcilroy): modify tests when we have real try finally support.
   4130   ExpectedSnippet<int> snippets[] = {
   4131       {"var a = 1; try { a = 2; } finally { a = 3; }",
   4132        kPointerSize,
   4133        1,
   4134        14,
   4135        {
   4136            B(LdaSmi8), U8(1),  //
   4137            B(Star), R(0),      //
   4138            B(LdaSmi8), U8(2),  //
   4139            B(Star), R(0),      //
   4140            B(LdaSmi8), U8(3),  //
   4141            B(Star), R(0),      //
   4142            B(LdaUndefined),    //
   4143            B(Return),          //
   4144        },
   4145        0},
   4146       {"var a = 1; try { a = 2; } catch(e) { a = 20 } finally { a = 3; }",
   4147        2 * kPointerSize,
   4148        1,
   4149        14,
   4150        {
   4151            B(LdaSmi8), U8(1),  //
   4152            B(Star), R(0),      //
   4153            B(LdaSmi8), U8(2),  //
   4154            B(Star), R(0),      //
   4155            B(LdaSmi8), U8(3),  //
   4156            B(Star), R(0),      //
   4157            B(LdaUndefined),    //
   4158            B(Return),          //
   4159        },
   4160        0},
   4161   };
   4162 
   4163   for (size_t i = 0; i < arraysize(snippets); i++) {
   4164     Handle<BytecodeArray> bytecode_array =
   4165         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
   4166     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   4167   }
   4168 }
   4169 
   4170 
   4171 TEST(Throw) {
   4172   InitializedHandleScope handle_scope;
   4173   BytecodeGeneratorHelper helper;
   4174 
   4175   // TODO(rmcilroy): modify tests when we have real try catch support.
   4176   ExpectedSnippet<const char*> snippets[] = {
   4177       {"throw 1;",
   4178        0,
   4179        1,
   4180        3,
   4181        {
   4182            B(LdaSmi8), U8(1),  //
   4183            B(Throw),           //
   4184        },
   4185        0},
   4186       {"throw 'Error';",
   4187        0,
   4188        1,
   4189        3,
   4190        {
   4191            B(LdaConstant), U8(0),  //
   4192            B(Throw),               //
   4193        },
   4194        1,
   4195        {"Error"}},
   4196       {"var a = 1; if (a) { throw 'Error'; };",
   4197        1 * kPointerSize,
   4198        1,
   4199        11,
   4200        {
   4201            B(LdaSmi8), U8(1),               //
   4202            B(Star), R(0),                   //
   4203            B(JumpIfToBooleanFalse), U8(5),  //
   4204            B(LdaConstant), U8(0),           //
   4205            B(Throw),                        //
   4206            B(LdaUndefined),                 //
   4207            B(Return),                       //
   4208        },
   4209        1,
   4210        {"Error"}},
   4211   };
   4212 
   4213   for (size_t i = 0; i < arraysize(snippets); i++) {
   4214     Handle<BytecodeArray> bytecode_array =
   4215         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
   4216     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   4217   }
   4218 }
   4219 
   4220 
   4221 TEST(CallNew) {
   4222   InitializedHandleScope handle_scope;
   4223   BytecodeGeneratorHelper helper;
   4224   Zone zone;
   4225 
   4226   FeedbackVectorSpec feedback_spec(&zone);
   4227   FeedbackVectorSlot slot1 = feedback_spec.AddGeneralSlot();
   4228   FeedbackVectorSlot slot2 = feedback_spec.AddLoadICSlot();
   4229   USE(slot1);
   4230 
   4231   Handle<i::TypeFeedbackVector> vector =
   4232       i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec);
   4233 
   4234   ExpectedSnippet<InstanceType> snippets[] = {
   4235       {"function bar() { this.value = 0; }\n"
   4236        "function f() { return new bar(); }\n"
   4237        "f()",
   4238        1 * kPointerSize,
   4239        1,
   4240        10,
   4241        {
   4242            B(LdaGlobalSloppy), U8(0), U8(vector->GetIndex(slot2)),  //
   4243            B(Star), R(0),                                           //
   4244            B(New), R(0), R(0), U8(0),                               //
   4245            B(Return),                                               //
   4246        },
   4247        1,
   4248        {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
   4249       {"function bar(x) { this.value = 18; this.x = x;}\n"
   4250        "function f() { return new bar(3); }\n"
   4251        "f()",
   4252        2 * kPointerSize,
   4253        1,
   4254        14,
   4255        {
   4256            B(LdaGlobalSloppy), U8(0), U8(vector->GetIndex(slot2)),  //
   4257            B(Star), R(0),                                           //
   4258            B(LdaSmi8), U8(3),                                       //
   4259            B(Star), R(1),                                           //
   4260            B(New), R(0), R(1), U8(1),                               //
   4261            B(Return),                                               //
   4262        },
   4263        1,
   4264        {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
   4265       {"function bar(w, x, y, z) {\n"
   4266        "  this.value = 18;\n"
   4267        "  this.x = x;\n"
   4268        "  this.y = y;\n"
   4269        "  this.z = z;\n"
   4270        "}\n"
   4271        "function f() { return new bar(3, 4, 5); }\n"
   4272        "f()",
   4273        4 * kPointerSize,
   4274        1,
   4275        22,
   4276        {
   4277            B(LdaGlobalSloppy), U8(0), U8(vector->GetIndex(slot2)),  //
   4278            B(Star), R(0),                                           //
   4279            B(LdaSmi8), U8(3),                                       //
   4280            B(Star), R(1),                                           //
   4281            B(LdaSmi8), U8(4),                                       //
   4282            B(Star), R(2),                                           //
   4283            B(LdaSmi8), U8(5),                                       //
   4284            B(Star), R(3),                                           //
   4285            B(New), R(0), R(1), U8(3),                               //
   4286            B(Return),                                               //
   4287        },
   4288        1,
   4289        {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
   4290   };
   4291 
   4292   for (size_t i = 0; i < arraysize(snippets); i++) {
   4293     Handle<BytecodeArray> bytecode_array =
   4294         helper.MakeBytecode(snippets[i].code_snippet, "f");
   4295     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   4296   }
   4297 }
   4298 
   4299 
   4300 TEST(ContextVariables) {
   4301   InitializedHandleScope handle_scope;
   4302   BytecodeGeneratorHelper helper;
   4303   Zone zone;
   4304 
   4305   FeedbackVectorSpec feedback_spec(&zone);
   4306   FeedbackVectorSlot slot = feedback_spec.AddCallICSlot();
   4307 
   4308   Handle<i::TypeFeedbackVector> vector =
   4309       i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec);
   4310 
   4311   int closure = Register::function_closure().index();
   4312   int new_target = Register::new_target().index();
   4313   int first_context_slot = Context::MIN_CONTEXT_SLOTS;
   4314 
   4315   // The wide check below relies on MIN_CONTEXT_SLOTS + 3 + 249 == 256, if this
   4316   // ever changes, the REPEAT_XXX should be changed to output the correct number
   4317   // of unique variables to trigger the wide slot load / store.
   4318   STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS + 3 + 249 == 256);
   4319   int wide_slot = first_context_slot + 3;
   4320 
   4321   ExpectedSnippet<InstanceType> snippets[] = {
   4322       {"var a; return function() { a = 1; };",
   4323        1 * kPointerSize,
   4324        1,
   4325        11,
   4326        {
   4327            B(CallRuntime), U16(Runtime::kNewFunctionContext),  //
   4328                            R(closure), U8(1),                  //
   4329            B(PushContext), R(0),                               //
   4330            B(CreateClosure), U8(0), U8(0),                     //
   4331            B(Return),                                          //
   4332        },
   4333        1,
   4334        {InstanceType::SHARED_FUNCTION_INFO_TYPE}},
   4335       {"var a = 1; return function() { a = 2; };",
   4336        1 * kPointerSize,
   4337        1,
   4338        16,
   4339        {
   4340            B(CallRuntime), U16(Runtime::kNewFunctionContext),  //
   4341                            R(closure), U8(1),                  //
   4342            B(PushContext), R(0),                               //
   4343            B(LdaSmi8), U8(1),                                  //
   4344            B(StaContextSlot), R(0), U8(first_context_slot),    //
   4345            B(CreateClosure), U8(0), U8(0),                     //
   4346            B(Return),                                          //
   4347        },
   4348        1,
   4349        {InstanceType::SHARED_FUNCTION_INFO_TYPE}},
   4350       {"var a = 1; var b = 2; return function() { a = 2; b = 3 };",
   4351        1 * kPointerSize,
   4352        1,
   4353        21,
   4354        {
   4355            B(CallRuntime), U16(Runtime::kNewFunctionContext),    //
   4356                            R(closure), U8(1),                    //
   4357            B(PushContext), R(0),                                 //
   4358            B(LdaSmi8), U8(1),                                    //
   4359            B(StaContextSlot), R(0), U8(first_context_slot),      //
   4360            B(LdaSmi8), U8(2),                                    //
   4361            B(StaContextSlot), R(0), U8(first_context_slot + 1),  //
   4362            B(CreateClosure), U8(0), U8(0),                       //
   4363            B(Return),                                            //
   4364        },
   4365        1,
   4366        {InstanceType::SHARED_FUNCTION_INFO_TYPE}},
   4367       {"var a; (function() { a = 2; })(); return a;",
   4368        3 * kPointerSize,
   4369        1,
   4370        24,
   4371        {
   4372            B(CallRuntime), U16(Runtime::kNewFunctionContext),       //
   4373                            R(closure), U8(1),                       //
   4374            B(PushContext), R(0),                                    //
   4375            B(LdaUndefined),                                         //
   4376            B(Star), R(2),                                           //
   4377            B(CreateClosure), U8(0), U8(0),                          //
   4378            B(Star), R(1),                                           //
   4379            B(Call), R(1), R(2), U8(0), U8(vector->GetIndex(slot)),  //
   4380            B(LdaContextSlot), R(0), U8(first_context_slot),         //
   4381            B(Return),                                               //
   4382        },
   4383        1,
   4384        {InstanceType::SHARED_FUNCTION_INFO_TYPE}},
   4385       {"'use strict'; let a = 1; { let b = 2; return function() { a + b; }; }",
   4386        4 * kPointerSize,
   4387        1,
   4388        44,
   4389        {
   4390            B(CallRuntime), U16(Runtime::kNewFunctionContext),             //
   4391                            R(closure), U8(1),                             //
   4392            B(PushContext), R(0),                                          //
   4393            B(LdaTheHole),                                                 //
   4394            B(StaContextSlot), R(0), U8(first_context_slot),               //
   4395            B(LdaSmi8), U8(1),                                             //
   4396            B(StaContextSlot), R(0), U8(first_context_slot),               //
   4397            B(LdaConstant), U8(0),                                         //
   4398            B(Star), R(2),                                                 //
   4399            B(Ldar), R(closure),                                           //
   4400            B(Star), R(3),                                                 //
   4401            B(CallRuntime), U16(Runtime::kPushBlockContext), R(2), U8(2),  //
   4402            B(PushContext), R(1),                                          //
   4403            B(LdaTheHole),                                                 //
   4404            B(StaContextSlot), R(1), U8(first_context_slot),               //
   4405            B(LdaSmi8), U8(2),                                             //
   4406            B(StaContextSlot), R(1), U8(first_context_slot),               //
   4407            B(CreateClosure), U8(1), U8(0),                                //
   4408            B(Return),                                                     //
   4409        },
   4410        2,
   4411        {InstanceType::FIXED_ARRAY_TYPE,
   4412         InstanceType::SHARED_FUNCTION_INFO_TYPE}},
   4413       {"'use strict';\n"
   4414        REPEAT_249_UNIQUE_VARS()
   4415        "eval();"
   4416        "var b = 100;"
   4417        "return b",
   4418        3 * kPointerSize,
   4419        1,
   4420        1041,
   4421        {
   4422            B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure),  //
   4423                            U8(1),                                          //
   4424            B(PushContext), R(0),                                           //
   4425            B(Ldar), THIS(1),                                               //
   4426            B(StaContextSlot), R(0), U8(first_context_slot),                //
   4427            B(CreateUnmappedArguments),                                     //
   4428            B(StaContextSlot), R(0), U8(first_context_slot + 1),            //
   4429            B(Ldar), R(new_target),                                         //
   4430            B(StaContextSlot), R(0), U8(first_context_slot + 2),            //
   4431            REPEAT_249(COMMA,                                               //
   4432                       B(LdaZero),                                          //
   4433                       B(StaContextSlot), R(0), U8(wide_slot++)),           //
   4434            B(LdaUndefined),                                                //
   4435            B(Star), R(2),                                                  //
   4436            B(LdaGlobalStrict), U8(0), U8(1),                               //
   4437            B(Star), R(1),                                                  //
   4438            B(Call), R(1), R(2), U8(0), U8(0),                              //
   4439            B(LdaSmi8), U8(100),                                            //
   4440            B(StaContextSlotWide), R(0), U16(256),                          //
   4441            B(LdaContextSlotWide), R(0), U16(256),                          //
   4442            B(Return),                                                      //
   4443        },
   4444        1,
   4445        {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
   4446   };
   4447 
   4448   for (size_t i = 0; i < arraysize(snippets); i++) {
   4449     Handle<BytecodeArray> bytecode_array =
   4450         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
   4451     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   4452   }
   4453 }
   4454 
   4455 
   4456 TEST(ContextParameters) {
   4457   InitializedHandleScope handle_scope;
   4458   BytecodeGeneratorHelper helper;
   4459 
   4460   int closure = Register::function_closure().index();
   4461   int first_context_slot = Context::MIN_CONTEXT_SLOTS;
   4462 
   4463   ExpectedSnippet<InstanceType> snippets[] = {
   4464       {"function f(arg1) { return function() { arg1 = 2; }; }",
   4465        1 * kPointerSize,
   4466        2,
   4467        16,
   4468        {
   4469            B(CallRuntime), U16(Runtime::kNewFunctionContext),  //
   4470                            R(closure), U8(1),                  //
   4471            B(PushContext), R(0),                               //
   4472            B(Ldar), R(helper.kLastParamIndex),                 //
   4473            B(StaContextSlot), R(0), U8(first_context_slot),    //
   4474            B(CreateClosure), U8(0), U8(0),                     //
   4475            B(Return),                                          //
   4476        },
   4477        1,
   4478        {InstanceType::SHARED_FUNCTION_INFO_TYPE}},
   4479       {"function f(arg1) { var a = function() { arg1 = 2; }; return arg1; }",
   4480        2 * kPointerSize,
   4481        2,
   4482        21,
   4483        {
   4484            B(CallRuntime), U16(Runtime::kNewFunctionContext),  //
   4485                            R(closure), U8(1),                  //
   4486            B(PushContext), R(1),                               //
   4487            B(Ldar), R(helper.kLastParamIndex),                 //
   4488            B(StaContextSlot), R(1), U8(first_context_slot),    //
   4489            B(CreateClosure), U8(0), U8(0),                     //
   4490            B(Star), R(0),                                      //
   4491            B(LdaContextSlot), R(1), U8(first_context_slot),    //
   4492            B(Return),                                          //
   4493        },
   4494        1,
   4495        {InstanceType::SHARED_FUNCTION_INFO_TYPE}},
   4496       {"function f(a1, a2, a3, a4) { return function() { a1 = a3; }; }",
   4497        1 * kPointerSize,
   4498        5,
   4499        21,
   4500        {
   4501            B(CallRuntime), U16(Runtime::kNewFunctionContext),    //
   4502                            R(closure), U8(1),                    //
   4503            B(PushContext), R(0),                                 //
   4504            B(Ldar), R(helper.kLastParamIndex - 3),               //
   4505            B(StaContextSlot), R(0), U8(first_context_slot + 1),  //
   4506            B(Ldar), R(helper.kLastParamIndex -1),                //
   4507            B(StaContextSlot), R(0), U8(first_context_slot),      //
   4508            B(CreateClosure), U8(0), U8(0),                       //
   4509            B(Return),                                            //
   4510        },
   4511        1,
   4512        {InstanceType::SHARED_FUNCTION_INFO_TYPE}},
   4513       {"function f() { var self = this; return function() { self = 2; }; }",
   4514        1 * kPointerSize,
   4515        1,
   4516        16,
   4517        {
   4518            B(CallRuntime), U16(Runtime::kNewFunctionContext),  //
   4519                            R(closure), U8(1),                  //
   4520            B(PushContext), R(0),                               //
   4521            B(Ldar), R(helper.kLastParamIndex),                 //
   4522            B(StaContextSlot), R(0), U8(first_context_slot),    //
   4523            B(CreateClosure), U8(0), U8(0),                     //
   4524            B(Return),                                          //
   4525        },
   4526        1,
   4527        {InstanceType::SHARED_FUNCTION_INFO_TYPE}},
   4528   };
   4529 
   4530   for (size_t i = 0; i < arraysize(snippets); i++) {
   4531     Handle<BytecodeArray> bytecode_array =
   4532         helper.MakeBytecodeForFunction(snippets[i].code_snippet);
   4533     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   4534   }
   4535 }
   4536 
   4537 
   4538 TEST(OuterContextVariables) {
   4539   InitializedHandleScope handle_scope;
   4540   BytecodeGeneratorHelper helper;
   4541 
   4542   int context = Register::function_context().index();
   4543   int first_context_slot = Context::MIN_CONTEXT_SLOTS;
   4544 
   4545   ExpectedSnippet<InstanceType> snippets[] = {
   4546       {"function Outer() {"
   4547        "  var outerVar = 1;"
   4548        "  function Inner(innerArg) {"
   4549        "    this.innerFunc = function() { return outerVar * innerArg; }"
   4550        "  }"
   4551        "  this.getInnerFunc = function() { return new Inner(1).innerFunc; }"
   4552        "}"
   4553        "var f = new Outer().getInnerFunc();",
   4554        2 * kPointerSize,
   4555        1,
   4556        20,
   4557        {
   4558            B(Ldar), R(context),                                    //
   4559            B(Star), R(0),                                          //
   4560            B(LdaContextSlot), R(0), U8(Context::PREVIOUS_INDEX),   //
   4561            B(Star), R(0),                                          //
   4562            B(LdaContextSlot), R(0), U8(first_context_slot),        //
   4563            B(Star), R(1),                                          //
   4564            B(LdaContextSlot), R(context), U8(first_context_slot),  //
   4565            B(Mul), R(1),                                           //
   4566            B(Return),                                              //
   4567        }},
   4568       {"function Outer() {"
   4569        "  var outerVar = 1;"
   4570        "  function Inner(innerArg) {"
   4571        "    this.innerFunc = function() { outerVar = innerArg; }"
   4572        "  }"
   4573        "  this.getInnerFunc = function() { return new Inner(1).innerFunc; }"
   4574        "}"
   4575        "var f = new Outer().getInnerFunc();",
   4576        2 * kPointerSize,
   4577        1,
   4578        21,
   4579        {
   4580            B(LdaContextSlot), R(context), U8(first_context_slot),  //
   4581            B(Star), R(0),                                          //
   4582            B(Ldar), R(context),                                    //
   4583            B(Star), R(1),                                          //
   4584            B(LdaContextSlot), R(1), U8(Context::PREVIOUS_INDEX),   //
   4585            B(Star), R(1),                                          //
   4586            B(Ldar), R(0),                                          //
   4587            B(StaContextSlot), R(1), U8(first_context_slot),        //
   4588            B(LdaUndefined),                                        //
   4589            B(Return),                                              //
   4590        }},
   4591   };
   4592 
   4593   for (size_t i = 0; i < arraysize(snippets); i++) {
   4594     Handle<BytecodeArray> bytecode_array =
   4595         helper.MakeBytecodeForFunctionNoFilter(snippets[i].code_snippet);
   4596     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   4597   }
   4598 }
   4599 
   4600 
   4601 TEST(CountOperators) {
   4602   InitializedHandleScope handle_scope;
   4603   BytecodeGeneratorHelper helper;
   4604   Zone zone;
   4605 
   4606   FeedbackVectorSpec feedback_spec(&zone);
   4607   FeedbackVectorSlot slot1 = feedback_spec.AddLoadICSlot();
   4608   FeedbackVectorSlot slot2 = feedback_spec.AddStoreICSlot();
   4609   Handle<i::TypeFeedbackVector> vector =
   4610       i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec);
   4611 
   4612   FeedbackVectorSpec store_feedback_spec(&zone);
   4613   FeedbackVectorSlot store_slot = store_feedback_spec.AddStoreICSlot();
   4614   Handle<i::TypeFeedbackVector> store_vector =
   4615       i::NewTypeFeedbackVector(helper.isolate(), &store_feedback_spec);
   4616 
   4617   int closure = Register::function_closure().index();
   4618   int first_context_slot = Context::MIN_CONTEXT_SLOTS;
   4619 
   4620   int object_literal_flags =
   4621       ObjectLiteral::kFastElements | ObjectLiteral::kDisableMementos;
   4622   int array_literal_flags =
   4623       ArrayLiteral::kDisableMementos | ArrayLiteral::kShallowElements;
   4624 
   4625   ExpectedSnippet<InstanceType> snippets[] = {
   4626       {"var a = 1; return ++a;",
   4627        1 * kPointerSize,
   4628        1,
   4629        9,
   4630        {
   4631            B(LdaSmi8), U8(1),  //
   4632            B(Star), R(0),      //
   4633            B(ToNumber),        //
   4634            B(Inc),             //
   4635            B(Star), R(0),      //
   4636            B(Return),          //
   4637        }},
   4638       {"var a = 1; return a++;",
   4639        2 * kPointerSize,
   4640        1,
   4641        13,
   4642        {
   4643            B(LdaSmi8), U8(1),  //
   4644            B(Star), R(0),      //
   4645            B(ToNumber),        //
   4646            B(Star), R(1),      //
   4647            B(Inc),             //
   4648            B(Star), R(0),      //
   4649            B(Ldar), R(1),      //
   4650            B(Return),          //
   4651        }},
   4652       {"var a = 1; return --a;",
   4653        1 * kPointerSize,
   4654        1,
   4655        9,
   4656        {
   4657            B(LdaSmi8), U8(1),  //
   4658            B(Star), R(0),      //
   4659            B(ToNumber),        //
   4660            B(Dec),             //
   4661            B(Star), R(0),      //
   4662            B(Return),          //
   4663        }},
   4664       {"var a = 1; return a--;",
   4665        2 * kPointerSize,
   4666        1,
   4667        13,
   4668        {
   4669            B(LdaSmi8), U8(1),  //
   4670            B(Star), R(0),      //
   4671            B(ToNumber),        //
   4672            B(Star), R(1),      //
   4673            B(Dec),             //
   4674            B(Star), R(0),      //
   4675            B(Ldar), R(1),      //
   4676            B(Return),          //
   4677        }},
   4678       {"var a = { val: 1 }; return a.val++;",
   4679        3 * kPointerSize,
   4680        1,
   4681        23,
   4682        {
   4683            B(CreateObjectLiteral), U8(0), U8(0), U8(object_literal_flags),  //
   4684            B(Star), R(0),                                                   //
   4685            B(Star), R(1),                                                   //
   4686            B(LoadICSloppy), R(1), U8(1), U8(vector->GetIndex(slot1)),       //
   4687            B(ToNumber),                                                     //
   4688            B(Star), R(2),                                                   //
   4689            B(Inc),                                                          //
   4690            B(StoreICSloppy), R(1), U8(1), U8(vector->GetIndex(slot2)),      //
   4691            B(Ldar), R(2),                                                   //
   4692            B(Return),                                                       //
   4693        },
   4694        2,
   4695        {InstanceType::FIXED_ARRAY_TYPE,
   4696         InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
   4697       {"var a = { val: 1 }; return --a.val;",
   4698        2 * kPointerSize,
   4699        1,
   4700        19,
   4701        {
   4702            B(CreateObjectLiteral), U8(0), U8(0), U8(object_literal_flags),  //
   4703            B(Star), R(0),                                                   //
   4704            B(Star), R(1),                                                   //
   4705            B(LoadICSloppy), R(1), U8(1), U8(vector->GetIndex(slot1)),       //
   4706            B(ToNumber),                                                     //
   4707            B(Dec),                                                          //
   4708            B(StoreICSloppy), R(1), U8(1), U8(vector->GetIndex(slot2)),      //
   4709            B(Return),                                                       //
   4710        },
   4711        2,
   4712        {InstanceType::FIXED_ARRAY_TYPE,
   4713         InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
   4714       {"var name = 'var'; var a = { val: 1 }; return a[name]--;",
   4715        5 * kPointerSize,
   4716        1,
   4717        30,
   4718        {
   4719            B(LdaConstant), U8(0),                                           //
   4720            B(Star), R(0),                                                   //
   4721            B(CreateObjectLiteral), U8(1), U8(0), U8(object_literal_flags),  //
   4722            B(Star), R(1),                                                   //
   4723            B(Star), R(2),                                                   //
   4724            B(Ldar), R(0),                                                   //
   4725            B(Star), R(3),                                                   //
   4726            B(KeyedLoadICSloppy), R(2), U8(vector->GetIndex(slot1)),         //
   4727            B(ToNumber),                                                     //
   4728            B(Star), R(4),                                                   //
   4729            B(Dec),                                                          //
   4730            B(KeyedStoreICSloppy), R(2), R(3), U8(vector->GetIndex(slot2)),  //
   4731            B(Ldar), R(4),                                                   //
   4732            B(Return),                                                       //
   4733        },
   4734        2,
   4735        {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
   4736         InstanceType::FIXED_ARRAY_TYPE}},
   4737       {"var name = 'var'; var a = { val: 1 }; return ++a[name];",
   4738        4 * kPointerSize,
   4739        1,
   4740        26,
   4741        {
   4742            B(LdaConstant), U8(0),                                           //
   4743            B(Star), R(0),                                                   //
   4744            B(CreateObjectLiteral), U8(1), U8(0), U8(object_literal_flags),  //
   4745            B(Star), R(1),                                                   //
   4746            B(Star), R(2),                                                   //
   4747            B(Ldar), R(0),                                                   //
   4748            B(Star), R(3),                                                   //
   4749            B(KeyedLoadICSloppy), R(2), U8(vector->GetIndex(slot1)),         //
   4750            B(ToNumber),                                                     //
   4751            B(Inc),                                                          //
   4752            B(KeyedStoreICSloppy), R(2), R(3), U8(vector->GetIndex(slot2)),  //
   4753            B(Return),                                                       //
   4754        },
   4755        2,
   4756        {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
   4757         InstanceType::FIXED_ARRAY_TYPE}},
   4758       {"var a = 1; var b = function() { return a }; return ++a;",
   4759        2 * kPointerSize,
   4760        1,
   4761        26,
   4762        {
   4763            B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure),  //
   4764                            U8(1),                                          //
   4765            B(PushContext), R(1),                                           //
   4766            B(LdaSmi8), U8(1),                                              //
   4767            B(StaContextSlot), R(1), U8(first_context_slot),                //
   4768            B(CreateClosure), U8(0), U8(0),                                 //
   4769            B(Star), R(0),                                                  //
   4770            B(LdaContextSlot), R(1), U8(first_context_slot),                //
   4771            B(ToNumber),                                                    //
   4772            B(Inc),                                                         //
   4773            B(StaContextSlot), R(1), U8(first_context_slot),                //
   4774            B(Return),                                                      //
   4775        },
   4776        1,
   4777        {InstanceType::SHARED_FUNCTION_INFO_TYPE}},
   4778       {"var a = 1; var b = function() { return a }; return a--;",
   4779        3 * kPointerSize,
   4780        1,
   4781        30,
   4782        {
   4783            B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure),  //
   4784                            U8(1),                                          //
   4785            B(PushContext), R(1),                                           //
   4786            B(LdaSmi8), U8(1),                                              //
   4787            B(StaContextSlot), R(1), U8(first_context_slot),                //
   4788            B(CreateClosure), U8(0), U8(0),                                 //
   4789            B(Star), R(0),                                                  //
   4790            B(LdaContextSlot), R(1), U8(first_context_slot),                //
   4791            B(ToNumber),                                                    //
   4792            B(Star), R(2),                                                  //
   4793            B(Dec),                                                         //
   4794            B(StaContextSlot), R(1), U8(first_context_slot),                //
   4795            B(Ldar), R(2),                                                  //
   4796            B(Return),                                                      //
   4797        },
   4798        1,
   4799        {InstanceType::SHARED_FUNCTION_INFO_TYPE}},
   4800       {"var idx = 1; var a = [1, 2]; return a[idx++] = 2;",
   4801        4 * kPointerSize,
   4802        1,
   4803        27,
   4804        {
   4805            B(LdaSmi8), U8(1),                                              //
   4806            B(Star), R(0),                                                  //
   4807            B(CreateArrayLiteral), U8(0), U8(0), U8(array_literal_flags),   //
   4808            B(Star), R(1),                                                  //
   4809            B(Star), R(2),                                                  //
   4810            B(Ldar), R(0),                                                  //
   4811            B(ToNumber),                                                    //
   4812            B(Star), R(3),                                                  //
   4813            B(Inc),                                                         //
   4814            B(Star), R(0),                                                  //
   4815            B(LdaSmi8), U8(2),                                              //
   4816            B(KeyedStoreICSloppy), R(2), R(3),                              //
   4817                                   U8(store_vector->GetIndex(store_slot)),  //
   4818            B(Return),                                                      //
   4819        },
   4820        1,
   4821        {InstanceType::FIXED_ARRAY_TYPE}},
   4822   };
   4823 
   4824   for (size_t i = 0; i < arraysize(snippets); i++) {
   4825     Handle<BytecodeArray> bytecode_array =
   4826         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
   4827     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   4828   }
   4829 }
   4830 
   4831 
   4832 TEST(GlobalCountOperators) {
   4833   InitializedHandleScope handle_scope;
   4834   BytecodeGeneratorHelper helper;
   4835   Zone zone;
   4836 
   4837   FeedbackVectorSpec feedback_spec(&zone);
   4838   FeedbackVectorSlot slot1 = feedback_spec.AddLoadICSlot();
   4839   FeedbackVectorSlot slot2 = feedback_spec.AddStoreICSlot();
   4840 
   4841   Handle<i::TypeFeedbackVector> vector =
   4842       i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec);
   4843 
   4844   ExpectedSnippet<const char*> snippets[] = {
   4845       {"var global = 1;\nfunction f() { return ++global; }\nf()",
   4846        0,
   4847        1,
   4848        9,
   4849        {
   4850            B(LdaGlobalSloppy), U8(0), U8(vector->GetIndex(slot1)),  //
   4851            B(ToNumber),                                             //
   4852            B(Inc),                                                  //
   4853            B(StaGlobalSloppy), U8(0), U8(vector->GetIndex(slot2)),  //
   4854            B(Return),                                               //
   4855        },
   4856        1,
   4857        {"global"}},
   4858       {"var global = 1;\nfunction f() { return global--; }\nf()",
   4859        1 * kPointerSize,
   4860        1,
   4861        13,
   4862        {
   4863            B(LdaGlobalSloppy), U8(0), U8(vector->GetIndex(slot1)),  //
   4864            B(ToNumber),                                             //
   4865            B(Star), R(0),                                           //
   4866            B(Dec),                                                  //
   4867            B(StaGlobalSloppy), U8(0), U8(vector->GetIndex(slot2)),  //
   4868            B(Ldar), R(0),                                           //
   4869            B(Return),
   4870        },
   4871        1,
   4872        {"global"}},
   4873       {"unallocated = 1;\nfunction f() { 'use strict'; return --unallocated; }"
   4874        "f()",
   4875        0,
   4876        1,
   4877        9,
   4878        {
   4879            B(LdaGlobalStrict), U8(0), U8(vector->GetIndex(slot1)),  //
   4880            B(ToNumber),                                             //
   4881            B(Dec),                                                  //
   4882            B(StaGlobalStrict), U8(0), U8(vector->GetIndex(slot2)),  //
   4883            B(Return),                                               //
   4884        },
   4885        1,
   4886        {"unallocated"}},
   4887       {"unallocated = 1;\nfunction f() { return unallocated++; }\nf()",
   4888        1 * kPointerSize,
   4889        1,
   4890        13,
   4891        {
   4892            B(LdaGlobalSloppy), U8(0), U8(vector->GetIndex(slot1)),  //
   4893            B(ToNumber),                                             //
   4894            B(Star), R(0),                                           //
   4895            B(Inc),                                                  //
   4896            B(StaGlobalSloppy), U8(0), U8(vector->GetIndex(slot2)),  //
   4897            B(Ldar), R(0),                                           //
   4898            B(Return),
   4899        },
   4900        1,
   4901        {"unallocated"}},
   4902   };
   4903 
   4904   for (size_t i = 0; i < arraysize(snippets); i++) {
   4905     Handle<BytecodeArray> bytecode_array =
   4906         helper.MakeBytecode(snippets[i].code_snippet, "f");
   4907     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   4908   }
   4909 }
   4910 
   4911 
   4912 TEST(CompoundExpressions) {
   4913   InitializedHandleScope handle_scope;
   4914   BytecodeGeneratorHelper helper;
   4915   Zone zone;
   4916 
   4917   int closure = Register::function_closure().index();
   4918   int first_context_slot = Context::MIN_CONTEXT_SLOTS;
   4919 
   4920   FeedbackVectorSpec feedback_spec(&zone);
   4921   FeedbackVectorSlot slot1 = feedback_spec.AddLoadICSlot();
   4922   FeedbackVectorSlot slot2 = feedback_spec.AddStoreICSlot();
   4923 
   4924   Handle<i::TypeFeedbackVector> vector =
   4925       i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec);
   4926 
   4927   int object_literal_flags =
   4928       ObjectLiteral::kFastElements | ObjectLiteral::kDisableMementos;
   4929   ExpectedSnippet<InstanceType> snippets[] = {
   4930       {"var a = 1; a += 2;",
   4931        2 * kPointerSize,
   4932        1,
   4933        14,
   4934        {
   4935            B(LdaSmi8), U8(1),  //
   4936            B(Star), R(0),      //
   4937            B(Star), R(1),      //
   4938            B(LdaSmi8), U8(2),  //
   4939            B(Add), R(1),       //
   4940            B(Star), R(0),      //
   4941            B(LdaUndefined),    //
   4942            B(Return),          //
   4943        }},
   4944       {"var a = 1; a /= 2;",
   4945        2 * kPointerSize,
   4946        1,
   4947        14,
   4948        {
   4949            B(LdaSmi8), U8(1),  //
   4950            B(Star), R(0),      //
   4951            B(Star), R(1),      //
   4952            B(LdaSmi8), U8(2),  //
   4953            B(Div), R(1),       //
   4954            B(Star), R(0),      //
   4955            B(LdaUndefined),    //
   4956            B(Return),          //
   4957        }},
   4958       {"var a = { val: 2 }; a.name *= 2;",
   4959        3 * kPointerSize,
   4960        1,
   4961        24,
   4962        {
   4963            B(CreateObjectLiteral), U8(0), U8(0), U8(object_literal_flags),  //
   4964            B(Star), R(0),                                                   //
   4965            B(Star), R(1),                                                   //
   4966            B(LoadICSloppy), R(1), U8(1), U8(vector->GetIndex(slot1)),       //
   4967            B(Star), R(2),                                                   //
   4968            B(LdaSmi8), U8(2),                                               //
   4969            B(Mul), R(2),                                                    //
   4970            B(StoreICSloppy), R(1), U8(1), U8(vector->GetIndex(slot2)),      //
   4971            B(LdaUndefined),                                                 //
   4972            B(Return),                                                       //
   4973        },
   4974        2,
   4975        {InstanceType::FIXED_ARRAY_TYPE,
   4976         InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
   4977       {"var a = { 1: 2 }; a[1] ^= 2;",
   4978        4 * kPointerSize,
   4979        1,
   4980        27,
   4981        {
   4982            B(CreateObjectLiteral), U8(0), U8(0), U8(object_literal_flags),  //
   4983            B(Star), R(0),                                                   //
   4984            B(Star), R(1),                                                   //
   4985            B(LdaSmi8), U8(1),                                               //
   4986            B(Star), R(2),                                                   //
   4987            B(KeyedLoadICSloppy), R(1), U8(vector->GetIndex(slot1)),         //
   4988            B(Star), R(3),                                                   //
   4989            B(LdaSmi8), U8(2),                                               //
   4990            B(BitwiseXor), R(3),                                             //
   4991            B(KeyedStoreICSloppy), R(1), R(2), U8(vector->GetIndex(slot2)),  //
   4992            B(LdaUndefined),                                                 //
   4993            B(Return),                                                       //
   4994        },
   4995        1,
   4996        {InstanceType::FIXED_ARRAY_TYPE}},
   4997       {"var a = 1; (function f() { return a; }); a |= 24;",
   4998        2 * kPointerSize,
   4999        1,
   5000        29,
   5001        {
   5002            B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure),  //
   5003                            U8(1),                                          //
   5004            B(PushContext), R(0),                                           //
   5005            B(LdaSmi8), U8(1),                                              //
   5006            B(StaContextSlot), R(0), U8(first_context_slot),                //
   5007            B(CreateClosure), U8(0), U8(0),                                 //
   5008            B(LdaContextSlot), R(0), U8(first_context_slot),                //
   5009            B(Star), R(1),                                                  //
   5010            B(LdaSmi8), U8(24),                                             //
   5011            B(BitwiseOr), R(1),                                             //
   5012            B(StaContextSlot), R(0), U8(first_context_slot),                //
   5013            B(LdaUndefined),                                                //
   5014            B(Return),                                                      //
   5015        },
   5016        1,
   5017        {InstanceType::SHARED_FUNCTION_INFO_TYPE}},
   5018   };
   5019 
   5020   for (size_t i = 0; i < arraysize(snippets); i++) {
   5021     Handle<BytecodeArray> bytecode_array =
   5022         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
   5023     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   5024   }
   5025 }
   5026 
   5027 
   5028 TEST(GlobalCompoundExpressions) {
   5029   InitializedHandleScope handle_scope;
   5030   BytecodeGeneratorHelper helper;
   5031   Zone zone;
   5032 
   5033   FeedbackVectorSpec feedback_spec(&zone);
   5034   FeedbackVectorSlot slot1 = feedback_spec.AddLoadICSlot();
   5035   FeedbackVectorSlot slot2 = feedback_spec.AddStoreICSlot();
   5036 
   5037   Handle<i::TypeFeedbackVector> vector =
   5038       i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec);
   5039 
   5040   ExpectedSnippet<const char*> snippets[] = {
   5041       {"var global = 1;\nfunction f() { return global &= 1; }\nf()",
   5042        1 * kPointerSize,
   5043        1,
   5044        13,
   5045        {
   5046            B(LdaGlobalSloppy), U8(0), U8(vector->GetIndex(slot1)),  //
   5047            B(Star), R(0),                                           //
   5048            B(LdaSmi8), U8(1),                                       //
   5049            B(BitwiseAnd), R(0),                                     //
   5050            B(StaGlobalSloppy), U8(0), U8(vector->GetIndex(slot2)),  //
   5051            B(Return),                                               //
   5052        },
   5053        1,
   5054        {"global"}},
   5055       {"unallocated = 1;\nfunction f() { return unallocated += 1; }\nf()",
   5056        1 * kPointerSize,
   5057        1,
   5058        13,
   5059        {
   5060            B(LdaGlobalSloppy), U8(0), U8(vector->GetIndex(slot1)),  //
   5061            B(Star), R(0),                                           //
   5062            B(LdaSmi8), U8(1),                                       //
   5063            B(Add), R(0),                                            //
   5064            B(StaGlobalSloppy), U8(0), U8(vector->GetIndex(slot2)),  //
   5065            B(Return),                                               //
   5066        },
   5067        1,
   5068        {"unallocated"}},
   5069   };
   5070 
   5071   for (size_t i = 0; i < arraysize(snippets); i++) {
   5072     Handle<BytecodeArray> bytecode_array =
   5073         helper.MakeBytecode(snippets[i].code_snippet, "f");
   5074     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   5075   }
   5076 }
   5077 
   5078 
   5079 TEST(CreateArguments) {
   5080   InitializedHandleScope handle_scope;
   5081   BytecodeGeneratorHelper helper;
   5082   Zone zone;
   5083 
   5084   int closure = Register::function_closure().index();
   5085   int first_context_slot = Context::MIN_CONTEXT_SLOTS;
   5086 
   5087   FeedbackVectorSpec feedback_spec(&zone);
   5088   FeedbackVectorSlot slot = feedback_spec.AddKeyedLoadICSlot();
   5089 
   5090   Handle<i::TypeFeedbackVector> vector =
   5091       i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec);
   5092 
   5093   ExpectedSnippet<const char*> snippets[] = {
   5094       {"function f() { return arguments; }",
   5095        1 * kPointerSize,
   5096        1,
   5097        4,
   5098        {
   5099            B(CreateMappedArguments),  //
   5100            B(Star), R(0),             //
   5101            B(Return),                 //
   5102        }},
   5103       {"function f() { return arguments[0]; }",
   5104        2 * kPointerSize,
   5105        1,
   5106        10,
   5107        {
   5108            B(CreateMappedArguments),                                //
   5109            B(Star), R(0),                                           //
   5110            B(Star), R(1),                                           //
   5111            B(LdaZero),                                              //
   5112            B(KeyedLoadICSloppy), R(1), U8(vector->GetIndex(slot)),  //
   5113            B(Return),                                               //
   5114        }},
   5115       {"function f() { 'use strict'; return arguments; }",
   5116        1 * kPointerSize,
   5117        1,
   5118        4,
   5119        {
   5120            B(CreateUnmappedArguments),  //
   5121            B(Star), R(0),               //
   5122            B(Return),                   //
   5123        }},
   5124       {"function f(a) { return arguments[0]; }",
   5125        3 * kPointerSize,
   5126        2,
   5127        22,
   5128        {
   5129            B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure),  //
   5130                            U8(1),                                          //
   5131            B(PushContext), R(1),                                           //
   5132            B(Ldar), R(BytecodeGeneratorHelper::kLastParamIndex),           //
   5133            B(StaContextSlot), R(1), U8(first_context_slot),                //
   5134            B(CreateMappedArguments),                                       //
   5135            B(Star), R(0),                                                  //
   5136            B(Star), R(2),                                                  //
   5137            B(LdaZero),                                                     //
   5138            B(KeyedLoadICSloppy), R(2), U8(vector->GetIndex(slot)),         //
   5139            B(Return),                                                      //
   5140        }},
   5141       {"function f(a, b, c) { return arguments; }",
   5142        2 * kPointerSize,
   5143        4,
   5144        26,
   5145        {
   5146            B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure),  //
   5147                            U8(1),                                          //
   5148            B(PushContext), R(1),                                           //
   5149            B(Ldar), R(BytecodeGeneratorHelper::kLastParamIndex - 2),       //
   5150            B(StaContextSlot), R(1), U8(first_context_slot + 2),            //
   5151            B(Ldar), R(BytecodeGeneratorHelper::kLastParamIndex - 1),       //
   5152            B(StaContextSlot), R(1), U8(first_context_slot + 1),            //
   5153            B(Ldar), R(BytecodeGeneratorHelper::kLastParamIndex),           //
   5154            B(StaContextSlot), R(1), U8(first_context_slot),                //
   5155            B(CreateMappedArguments),                                       //
   5156            B(Star), R(0),                                                  //
   5157            B(Return),                                                      //
   5158        }},
   5159       {"function f(a, b, c) { 'use strict'; return arguments; }",
   5160        1 * kPointerSize,
   5161        4,
   5162        4,
   5163        {
   5164            B(CreateUnmappedArguments),  //
   5165            B(Star), R(0),               //
   5166            B(Return),                   //
   5167        }},
   5168   };
   5169 
   5170   for (size_t i = 0; i < arraysize(snippets); i++) {
   5171     Handle<BytecodeArray> bytecode_array =
   5172         helper.MakeBytecodeForFunction(snippets[i].code_snippet);
   5173     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   5174   }
   5175 }
   5176 
   5177 
   5178 TEST(IllegalRedeclaration) {
   5179   InitializedHandleScope handle_scope;
   5180   BytecodeGeneratorHelper helper;
   5181 
   5182   CHECK_GE(MessageTemplate::kVarRedeclaration, 128);
   5183   // Must adapt bytecode if this changes.
   5184 
   5185   ExpectedSnippet<Handle<Object>, 2> snippets[] = {
   5186       {"const a = 1; { var a = 2; }",
   5187        3 * kPointerSize,
   5188        1,
   5189        14,
   5190        {
   5191            B(LdaConstant), U8(0),                                       //
   5192            B(Star), R(1),                                               //
   5193            B(LdaConstant), U8(1),                                       //
   5194            B(Star), R(2),                                               //
   5195            B(CallRuntime), U16(Runtime::kNewSyntaxError), R(1), U8(2),  //
   5196            B(Throw),                                                    //
   5197        },
   5198        2,
   5199        {helper.factory()->NewNumberFromInt(MessageTemplate::kVarRedeclaration),
   5200         helper.factory()->NewStringFromAsciiChecked("a")}},
   5201   };
   5202 
   5203   for (size_t i = 0; i < arraysize(snippets); i++) {
   5204     Handle<BytecodeArray> bytecode_array =
   5205         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
   5206     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   5207   }
   5208 }
   5209 
   5210 
   5211 TEST(ForIn) {
   5212   InitializedHandleScope handle_scope;
   5213   BytecodeGeneratorHelper helper;
   5214   Zone zone;
   5215 
   5216   int simple_flags =
   5217       ArrayLiteral::kDisableMementos | ArrayLiteral::kShallowElements;
   5218   int deep_elements_flags =
   5219       ObjectLiteral::kFastElements | ObjectLiteral::kDisableMementos;
   5220 
   5221   FeedbackVectorSpec feedback_spec(&zone);
   5222   feedback_spec.AddStoreICSlot();
   5223   FeedbackVectorSlot slot2 = feedback_spec.AddStoreICSlot();
   5224   FeedbackVectorSlot slot3 = feedback_spec.AddStoreICSlot();
   5225   FeedbackVectorSlot slot4 = feedback_spec.AddStoreICSlot();
   5226   Handle<i::TypeFeedbackVector> vector =
   5227       i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec);
   5228 
   5229   ExpectedSnippet<InstanceType> snippets[] = {
   5230       {"for (var p in null) {}",
   5231        2 * kPointerSize,
   5232        1,
   5233        2,
   5234        {B(LdaUndefined), B(Return)},
   5235        0},
   5236       {"for (var p in undefined) {}",
   5237        2 * kPointerSize,
   5238        1,
   5239        2,
   5240        {B(LdaUndefined), B(Return)},
   5241        0},
   5242       {"for (var p in undefined) {}",
   5243        2 * kPointerSize,
   5244        1,
   5245        2,
   5246        {B(LdaUndefined), B(Return)},
   5247        0},
   5248       {"var x = 'potatoes';\n"
   5249        "for (var p in x) { return p; }",
   5250        8 * kPointerSize,
   5251        1,
   5252        45,
   5253        {
   5254            B(LdaConstant), U8(0),                 //
   5255            B(Star), R(1),                         //
   5256            B(JumpIfUndefined), U8(39),            //
   5257            B(JumpIfNull), U8(37),                 //
   5258            B(ToObject),                           //
   5259            B(JumpIfNull), U8(34),                 //
   5260            B(Star), R(3),                         //
   5261            B(ForInPrepare), R(4), R(5), R(6),     //
   5262            B(LdaZero),                            //
   5263            B(Star), R(7),                         //
   5264            B(ForInDone), R(7), R(6),              //
   5265            B(JumpIfTrue), U8(20),                 //
   5266            B(ForInNext), R(3), R(4), R(5), R(7),  //
   5267            B(JumpIfUndefined), U8(7),             //
   5268            B(Star), R(0),                         //
   5269            B(Star), R(2),                         //
   5270            B(Return),                             //
   5271            B(ForInStep), R(7),                    //
   5272            B(Star), R(7),                         //
   5273            B(Jump), U8(-21),                      //
   5274            B(LdaUndefined),                       //
   5275            B(Return),                             //
   5276        },
   5277        1,
   5278        {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
   5279       {"var x = 0;\n"
   5280        "for (var p in [1,2,3]) { x += p; }",
   5281        9 * kPointerSize,
   5282        1,
   5283        57,
   5284        {
   5285            B(LdaZero),                                  //
   5286            B(Star), R(1),                               //
   5287            B(CreateArrayLiteral), U8(0), U8(0), U8(3),  //
   5288            B(JumpIfUndefined), U8(48),                  //
   5289            B(JumpIfNull), U8(46),                       //
   5290            B(ToObject),                                 //
   5291            B(JumpIfNull), U8(43),                       //
   5292            B(Star), R(3),                               //
   5293            B(ForInPrepare), R(4), R(5), R(6),           //
   5294            B(LdaZero),                                  //
   5295            B(Star), R(7),                               //
   5296            B(ForInDone), R(7), R(6),                    //
   5297            B(JumpIfTrue), U8(29),                       //
   5298            B(ForInNext), R(3), R(4), R(5), R(7),        //
   5299            B(JumpIfUndefined), U8(16),                  //
   5300            B(Star), R(0),                               //
   5301            B(Star), R(2),                               //
   5302            B(Ldar), R(1),                               //
   5303            B(Star), R(8),                               //
   5304            B(Ldar), R(2),                               //
   5305            B(Add), R(8),                                //
   5306            B(Star), R(1),                               //
   5307            B(ForInStep), R(7),                          //
   5308            B(Star), R(7),                               //
   5309            B(Jump), U8(-30),                            //
   5310            B(LdaUndefined),                             //
   5311            B(Return),                                   //
   5312        },
   5313        1,
   5314        {InstanceType::FIXED_ARRAY_TYPE}},
   5315       {"var x = { 'a': 1, 'b': 2 };\n"
   5316        "for (x['a'] in [10, 20, 30]) {\n"
   5317        "  if (x['a'] == 10) continue;\n"
   5318        "  if (x['a'] == 20) break;\n"
   5319        "}",
   5320        8 * kPointerSize,
   5321        1,
   5322        94,
   5323        {
   5324            B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags),  //
   5325            B(Star), R(0),                                                  //
   5326            B(CreateArrayLiteral), U8(1), U8(1), U8(simple_flags),          //
   5327            B(JumpIfUndefined), U8(82),                                     //
   5328            B(JumpIfNull), U8(80),                                          //
   5329            B(ToObject),                                                    //
   5330            B(JumpIfNull), U8(77),                                          //
   5331            B(Star), R(1),                                                  //
   5332            B(ForInPrepare), R(2), R(3), R(4),                              //
   5333            B(LdaZero),                                                     //
   5334            B(Star), R(5),                                                  //
   5335            B(ForInDone), R(5), R(4),                                       //
   5336            B(JumpIfTrue), U8(63),                                          //
   5337            B(ForInNext), R(1), R(2), R(3), R(5),                           //
   5338            B(JumpIfUndefined), U8(50),                                     //
   5339            B(Star), R(6),                                                  //
   5340            B(Ldar), R(0),                                                  //
   5341            B(Star), R(7),                                                  //
   5342            B(Ldar), R(6),                                                  //
   5343            B(StoreICSloppy), R(7), U8(2), U8(vector->GetIndex(slot4)),     //
   5344            B(Ldar), R(0),                                                  //
   5345            B(Star), R(6),                                                  //
   5346            B(LoadICSloppy), R(6), U8(2), U8(vector->GetIndex(slot2)),      //
   5347            B(Star), R(7),                                                  //
   5348            B(LdaSmi8), U8(10),                                             //
   5349            B(TestEqual), R(7),                                             //
   5350            B(JumpIfFalse), U8(4),                                          //
   5351            B(Jump), U8(20),                                                //
   5352            B(Ldar), R(0),                                                  //
   5353            B(Star), R(6),                                                  //
   5354            B(LoadICSloppy), R(6), U8(2), U8(vector->GetIndex(slot3)),      //
   5355            B(Star), R(7),                                                  //
   5356            B(LdaSmi8), U8(20),                                             //
   5357            B(TestEqual), R(7),                                             //
   5358            B(JumpIfFalse), U8(4),                                          //
   5359            B(Jump), U8(8),                                                 //
   5360            B(ForInStep), R(5),                                             //
   5361            B(Star), R(5),                                                  //
   5362            B(Jump), U8(-64),                                               //
   5363            B(LdaUndefined),                                                //
   5364            B(Return),                                                      //
   5365        },
   5366        3,
   5367        {InstanceType::FIXED_ARRAY_TYPE, InstanceType::FIXED_ARRAY_TYPE,
   5368         InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
   5369       {"var x = [ 10, 11, 12 ] ;\n"
   5370        "for (x[0] in [1,2,3]) { return x[3]; }",
   5371        9 * kPointerSize,
   5372        1,
   5373        71,
   5374        {
   5375            B(CreateArrayLiteral), U8(0), U8(0), U8(simple_flags),           //
   5376            B(Star), R(0),                                                   //
   5377            B(CreateArrayLiteral), U8(1), U8(1), U8(simple_flags),           //
   5378            B(JumpIfUndefined), U8(59),                                      //
   5379            B(JumpIfNull), U8(57),                                           //
   5380            B(ToObject),                                                     //
   5381            B(JumpIfNull), U8(54),                                           //
   5382            B(Star), R(1),                                                   //
   5383            B(ForInPrepare), R(2), R(3), R(4),                               //
   5384            B(LdaZero),                                                      //
   5385            B(Star), R(5),                                                   //
   5386            B(ForInDone), R(5), R(4),                                        //
   5387            B(JumpIfTrue), U8(40),                                           //
   5388            B(ForInNext), R(1), R(2), R(3), R(5),                            //
   5389            B(JumpIfUndefined), U8(27),                                      //
   5390            B(Star), R(6),                                                   //
   5391            B(Ldar), R(0),                                                   //
   5392            B(Star), R(7),                                                   //
   5393            B(LdaZero),                                                      //
   5394            B(Star), R(8),                                                   //
   5395            B(Ldar), R(6),                                                   //
   5396            B(KeyedStoreICSloppy), R(7), R(8), U8(vector->GetIndex(slot3)),  //
   5397            B(Ldar), R(0),                                                   //
   5398            B(Star), R(6),                                                   //
   5399            B(LdaSmi8), U8(3),                                               //
   5400            B(KeyedLoadICSloppy), R(6), U8(vector->GetIndex(slot2)),         //
   5401            B(Return),                                                       //
   5402            B(ForInStep), R(5),                                              //
   5403            B(Star), R(5),                                                   //
   5404            B(Jump), U8(-41),                                                //
   5405            B(LdaUndefined),                                                 //
   5406            B(Return),                                                       //
   5407        },
   5408        2,
   5409        {InstanceType::FIXED_ARRAY_TYPE, InstanceType::FIXED_ARRAY_TYPE}},
   5410   };
   5411 
   5412   for (size_t i = 0; i < arraysize(snippets); i++) {
   5413     Handle<BytecodeArray> bytecode_array =
   5414         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
   5415     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   5416   }
   5417 }
   5418 
   5419 
   5420 TEST(Conditional) {
   5421   InitializedHandleScope handle_scope;
   5422   BytecodeGeneratorHelper helper;
   5423 
   5424   ExpectedSnippet<int> snippets[] = {
   5425       {"return 1 ? 2 : 3;",
   5426        0,
   5427        1,
   5428        11,
   5429        {
   5430            B(LdaSmi8), U8(1),               //
   5431            B(JumpIfToBooleanFalse), U8(6),  //
   5432            B(LdaSmi8), U8(2),               //
   5433            B(Jump), U8(4),                  //
   5434            B(LdaSmi8), U8(3),               //
   5435            B(Return),                       //
   5436        }},
   5437       {"return 1 ? 2 ? 3 : 4 : 5;",
   5438        0,
   5439        1,
   5440        19,
   5441        {
   5442            B(LdaSmi8), U8(1),                //
   5443            B(JumpIfToBooleanFalse), U8(14),  //
   5444            B(LdaSmi8), U8(2),                //
   5445            B(JumpIfToBooleanFalse), U8(6),   //
   5446            B(LdaSmi8), U8(3),                //
   5447            B(Jump), U8(4),                   //
   5448            B(LdaSmi8), U8(4),                //
   5449            B(Jump), U8(4),                   //
   5450            B(LdaSmi8), U8(5),                //
   5451            B(Return),                        //
   5452        }},
   5453   };
   5454 
   5455   for (size_t i = 0; i < arraysize(snippets); i++) {
   5456     Handle<BytecodeArray> bytecode_array =
   5457         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
   5458     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   5459   }
   5460 }
   5461 
   5462 
   5463 TEST(Switch) {
   5464   InitializedHandleScope handle_scope;
   5465   BytecodeGeneratorHelper helper;
   5466 
   5467   ExpectedSnippet<int> snippets[] = {
   5468       {"var a = 1;\n"
   5469        "switch(a) {\n"
   5470        " case 1: return 2;\n"
   5471        " case 2: return 3;\n"
   5472        "}\n",
   5473        3 * kPointerSize,
   5474        1,
   5475        30,
   5476        {
   5477            B(LdaSmi8), U8(1),         //
   5478            B(Star), R(1),             // The tag variable is allocated as a
   5479            B(Star), R(0),             // local by the parser, hence the store
   5480            B(Star), R(2),             // to another local register.
   5481            B(LdaSmi8), U8(1),         //
   5482            B(TestEqualStrict), R(2),  //
   5483            B(JumpIfTrue), U8(10),     //
   5484            B(LdaSmi8), U8(2),         //
   5485            B(TestEqualStrict), R(2),  //
   5486            B(JumpIfTrue), U8(7),      //
   5487            B(Jump), U8(8),            //
   5488            B(LdaSmi8), U8(2),         //
   5489            B(Return),                 //
   5490            B(LdaSmi8), U8(3),         //
   5491            B(Return),                 //
   5492            B(LdaUndefined),           //
   5493            B(Return),                 //
   5494        }},
   5495       {"var a = 1;\n"
   5496        "switch(a) {\n"
   5497        " case 1: a = 2; break;\n"
   5498        " case 2: a = 3; break;\n"
   5499        "}\n",
   5500        3 * kPointerSize,
   5501        1,
   5502        36,
   5503        {
   5504            B(LdaSmi8), U8(1),         //
   5505            B(Star), R(1),             //
   5506            B(Star), R(0),             //
   5507            B(Star), R(2),             //
   5508            B(LdaSmi8), U8(1),         //
   5509            B(TestEqualStrict), R(2),  //
   5510            B(JumpIfTrue), U8(10),     //
   5511            B(LdaSmi8), U8(2),         //
   5512            B(TestEqualStrict), R(2),  //
   5513            B(JumpIfTrue), U8(10),     //
   5514            B(Jump), U8(14),           //
   5515            B(LdaSmi8), U8(2),         //
   5516            B(Star), R(1),             //
   5517            B(Jump), U8(8),            //
   5518            B(LdaSmi8), U8(3),         //
   5519            B(Star), R(1),             //
   5520            B(Jump), U8(2),            //
   5521            B(LdaUndefined),           //
   5522            B(Return),                 //
   5523        }},
   5524       {"var a = 1;\n"
   5525        "switch(a) {\n"
   5526        " case 1: a = 2; // fall-through\n"
   5527        " case 2: a = 3; break;\n"
   5528        "}\n",
   5529        3 * kPointerSize,
   5530        1,
   5531        34,
   5532        {
   5533            B(LdaSmi8), U8(1),         //
   5534            B(Star), R(1),             //
   5535            B(Star), R(0),             //
   5536            B(Star), R(2),             //
   5537            B(LdaSmi8), U8(1),         //
   5538            B(TestEqualStrict), R(2),  //
   5539            B(JumpIfTrue), U8(10),     //
   5540            B(LdaSmi8), U8(2),         //
   5541            B(TestEqualStrict), R(2),  //
   5542            B(JumpIfTrue), U8(8),      //
   5543            B(Jump), U8(12),           //
   5544            B(LdaSmi8), U8(2),         //
   5545            B(Star), R(1),             //
   5546            B(LdaSmi8), U8(3),         //
   5547            B(Star), R(1),             //
   5548            B(Jump), U8(2),            //
   5549            B(LdaUndefined),           //
   5550            B(Return),                 //
   5551        }},
   5552       {"var a = 1;\n"
   5553        "switch(a) {\n"
   5554        " case 2: break;\n"
   5555        " case 3: break;\n"
   5556        " default: a = 1; break;\n"
   5557        "}\n",
   5558        3 * kPointerSize,
   5559        1,
   5560        34,
   5561        {
   5562            B(LdaSmi8), U8(1),         //
   5563            B(Star), R(1),             //
   5564            B(Star), R(0),             //
   5565            B(Star), R(2),             //
   5566            B(LdaSmi8), U8(2),         //
   5567            B(TestEqualStrict), R(2),  //
   5568            B(JumpIfTrue), U8(10),     //
   5569            B(LdaSmi8), U8(3),         //
   5570            B(TestEqualStrict), R(2),  //
   5571            B(JumpIfTrue), U8(6),      //
   5572            B(Jump), U8(6),            //
   5573            B(Jump), U8(10),           //
   5574            B(Jump), U8(8),            //
   5575            B(LdaSmi8), U8(1),         //
   5576            B(Star), R(1),             //
   5577            B(Jump), U8(2),            //
   5578            B(LdaUndefined),           //
   5579            B(Return),                 //
   5580        }},
   5581       {"var a = 1;\n"
   5582        "switch(typeof(a)) {\n"
   5583        " case 2: a = 1; break;\n"
   5584        " case 3: a = 2; break;\n"
   5585        " default: a = 3; break;\n"
   5586        "}\n",
   5587        3 * kPointerSize,
   5588        1,
   5589        43,
   5590        {
   5591            B(LdaSmi8), U8(1),         //
   5592            B(Star), R(1),             //
   5593            B(TypeOf),                 //
   5594            B(Star), R(0),             //
   5595            B(Star), R(2),             //
   5596            B(LdaSmi8), U8(2),         //
   5597            B(TestEqualStrict), R(2),  //
   5598            B(JumpIfTrue), U8(10),     //
   5599            B(LdaSmi8), U8(3),         //
   5600            B(TestEqualStrict), R(2),  //
   5601            B(JumpIfTrue), U8(10),     //
   5602            B(Jump), U8(14),           //
   5603            B(LdaSmi8), U8(1),         //
   5604            B(Star), R(1),             //
   5605            B(Jump), U8(14),           //
   5606            B(LdaSmi8), U8(2),         //
   5607            B(Star), R(1),             //
   5608            B(Jump), U8(8),            //
   5609            B(LdaSmi8), U8(3),         //
   5610            B(Star), R(1),             //
   5611            B(Jump), U8(2),            //
   5612            B(LdaUndefined),           //
   5613            B(Return),                 //
   5614        }},
   5615       {"var a = 1;\n"
   5616        "switch(a) {\n"
   5617        " case typeof(a): a = 1; break;\n"
   5618        " default: a = 2; break;\n"
   5619        "}\n",
   5620        3 * kPointerSize,
   5621        1,
   5622        31,
   5623        {
   5624            B(LdaSmi8), U8(1),         //
   5625            B(Star), R(1),             //
   5626            B(Star), R(0),             //
   5627            B(Star), R(2),             //
   5628            B(Ldar), R(1),             //
   5629            B(TypeOf),                 //
   5630            B(TestEqualStrict), R(2),  //
   5631            B(JumpIfTrue), U8(4),      //
   5632            B(Jump), U8(8),            //
   5633            B(LdaSmi8), U8(1),         //
   5634            B(Star), R(1),             //
   5635            B(Jump), U8(8),            //
   5636            B(LdaSmi8), U8(2),         //
   5637            B(Star), R(1),             //
   5638            B(Jump), U8(2),            //
   5639            B(LdaUndefined),           //
   5640            B(Return),                 //
   5641        }},
   5642       {"var a = 1;\n"
   5643        "switch(a) {\n"
   5644        " case 1:\n" REPEAT_64(SPACE, "  a = 2;")
   5645        "break;\n"
   5646        " case 2: a = 3; break;"
   5647        "}\n",
   5648        3 * kPointerSize,
   5649        1,
   5650        288,
   5651        {
   5652            B(LdaSmi8), U8(1),             //
   5653            B(Star), R(1),                 //
   5654            B(Star), R(0),                 //
   5655            B(Star), R(2),                 //
   5656            B(LdaSmi8), U8(1),             //
   5657            B(TestEqualStrict), R(2),      //
   5658            B(JumpIfTrue), U8(10),         //
   5659            B(LdaSmi8), U8(2),             //
   5660            B(TestEqualStrict), R(2),      //
   5661            B(JumpIfTrueConstant), U8(0),  //
   5662            B(JumpConstant), U8(1),        //
   5663            REPEAT_64(COMMA,               //
   5664                      B(LdaSmi8), U8(2),   //
   5665                      B(Star), R(1)),      //
   5666            B(Jump), U8(8),                //
   5667            B(LdaSmi8), U8(3),             //
   5668            B(Star), R(1),                 //
   5669            B(Jump), U8(2),                //
   5670            B(LdaUndefined),               //
   5671            B(Return),                     //
   5672        },
   5673        2,
   5674        {262, 266}},
   5675       {"var a = 1;\n"
   5676        "switch(a) {\n"
   5677        " case 1: \n"
   5678        "   switch(a + 1) {\n"
   5679        "      case 2 : a = 1; break;\n"
   5680        "      default : a = 2; break;\n"
   5681        "   }  // fall-through\n"
   5682        " case 2: a = 3;\n"
   5683        "}\n",
   5684        5 * kPointerSize,
   5685        1,
   5686        60,
   5687        {
   5688            B(LdaSmi8), U8(1),         //
   5689            B(Star), R(2),             //
   5690            B(Star), R(0),             //
   5691            B(Star), R(3),             //
   5692            B(LdaSmi8), U8(1),         //
   5693            B(TestEqualStrict), R(3),  //
   5694            B(JumpIfTrue), U8(10),     //
   5695            B(LdaSmi8), U8(2),         //
   5696            B(TestEqualStrict), R(3),  //
   5697            B(JumpIfTrue), U8(36),     //
   5698            B(Jump), U8(38),           //
   5699            B(Ldar), R(2),             //
   5700            B(Star), R(4),             //
   5701            B(LdaSmi8), U8(1),         //
   5702            B(Add), R(4),              //
   5703            B(Star), R(1),             //
   5704            B(Star), R(4),             //
   5705            B(LdaSmi8), U8(2),         //
   5706            B(TestEqualStrict), R(4),  //
   5707            B(JumpIfTrue), U8(4),      //
   5708            B(Jump), U8(8),            //
   5709            B(LdaSmi8), U8(1),         //
   5710            B(Star), R(2),             //
   5711            B(Jump), U8(8),            //
   5712            B(LdaSmi8), U8(2),         //
   5713            B(Star), R(2),             //
   5714            B(Jump), U8(2),            //
   5715            B(LdaSmi8), U8(3),         //
   5716            B(Star), R(2),             //
   5717            B(LdaUndefined),           //
   5718            B(Return),                 //
   5719        }},
   5720   };
   5721 
   5722   for (size_t i = 0; i < arraysize(snippets); i++) {
   5723     Handle<BytecodeArray> bytecode_array =
   5724         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
   5725     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   5726   }
   5727 }
   5728 
   5729 
   5730 TEST(BasicBlockToBoolean) {
   5731   InitializedHandleScope handle_scope;
   5732   BytecodeGeneratorHelper helper;
   5733 
   5734   // Check that we generate JumpIfToBoolean if they are at the start of basic
   5735   // blocks.
   5736   ExpectedSnippet<int> snippets[] = {
   5737       {"var a = 1; if (a || a < 0) { return 1; }",
   5738        2 * kPointerSize,
   5739        1,
   5740        20,
   5741        {
   5742            B(LdaSmi8), U8(1),               //
   5743            B(Star), R(0),                   //
   5744            B(JumpIfToBooleanTrue), U8(9),   //
   5745            B(Ldar), R(0),                   //
   5746            B(Star), R(1),                   //
   5747            B(LdaZero),                      //
   5748            B(TestLessThan), R(1),           //
   5749            B(JumpIfToBooleanFalse), U8(5),  //
   5750            B(LdaSmi8), U8(1),               //
   5751            B(Return),                       //
   5752            B(LdaUndefined),                 //
   5753            B(Return),                       //
   5754        }},
   5755       {"var a = 1; if (a && a < 0) { return 1; }",
   5756        2 * kPointerSize,
   5757        1,
   5758        20,
   5759        {
   5760            B(LdaSmi8), U8(1),               //
   5761            B(Star), R(0),                   //
   5762            B(JumpIfToBooleanFalse), U8(9),  //
   5763            B(Ldar), R(0),                   //
   5764            B(Star), R(1),                   //
   5765            B(LdaZero),                      //
   5766            B(TestLessThan), R(1),           //
   5767            B(JumpIfToBooleanFalse), U8(5),  //
   5768            B(LdaSmi8), U8(1),               //
   5769            B(Return),                       //
   5770            B(LdaUndefined),                 //
   5771            B(Return),                       //
   5772        }},
   5773       {"var a = 1; a = (a || a < 0) ? 2 : 3;",
   5774        2 * kPointerSize,
   5775        1,
   5776        25,
   5777        {
   5778            B(LdaSmi8), U8(1),               //
   5779            B(Star), R(0),                   //
   5780            B(JumpIfToBooleanTrue), U8(9),   //
   5781            B(Ldar), R(0),                   //
   5782            B(Star), R(1),                   //
   5783            B(LdaZero),                      //
   5784            B(TestLessThan), R(1),           //
   5785            B(JumpIfToBooleanFalse), U8(6),  //
   5786            B(LdaSmi8), U8(2),               //
   5787            B(Jump), U8(4),                  //
   5788            B(LdaSmi8), U8(3),               //
   5789            B(Star), R(0),                   //
   5790            B(LdaUndefined),                 //
   5791            B(Return),                       //
   5792        }},
   5793   };
   5794 
   5795   for (size_t i = 0; i < arraysize(snippets); i++) {
   5796     Handle<BytecodeArray> bytecode_array =
   5797         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
   5798     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   5799   }
   5800 }
   5801 
   5802 
   5803 TEST(DeadCodeRemoval) {
   5804   InitializedHandleScope handle_scope;
   5805   BytecodeGeneratorHelper helper;
   5806 
   5807   ExpectedSnippet<int> snippets[] = {
   5808       {"return; var a = 1; a();",
   5809        1 * kPointerSize,
   5810        1,
   5811        2,
   5812        {
   5813            B(LdaUndefined),  //
   5814            B(Return),        //
   5815        }},
   5816       {"if (false) { return; }; var a = 1;",
   5817        1 * kPointerSize,
   5818        1,
   5819        6,
   5820        {
   5821            B(LdaSmi8), U8(1),  //
   5822            B(Star), R(0),      //
   5823            B(LdaUndefined),    //
   5824            B(Return),          //
   5825        }},
   5826       {"if (true) { return 1; } else { return 2; };",
   5827        0,
   5828        1,
   5829        3,
   5830        {
   5831            B(LdaSmi8), U8(1),  //
   5832            B(Return),          //
   5833        }},
   5834       {"var a = 1; if (a) { return 1; }; return 2;",
   5835        1 * kPointerSize,
   5836        1,
   5837        12,
   5838        {
   5839            B(LdaSmi8), U8(1),               //
   5840            B(Star), R(0),                   //
   5841            B(JumpIfToBooleanFalse), U8(5),  //
   5842            B(LdaSmi8), U8(1),               //
   5843            B(Return),                       //
   5844            B(LdaSmi8), U8(2),               //
   5845            B(Return),                       //
   5846        }},
   5847   };
   5848 
   5849   for (size_t i = 0; i < arraysize(snippets); i++) {
   5850     Handle<BytecodeArray> bytecode_array =
   5851         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
   5852     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   5853   }
   5854 }
   5855 
   5856 
   5857 TEST(ThisFunction) {
   5858   InitializedHandleScope handle_scope;
   5859   BytecodeGeneratorHelper helper;
   5860 
   5861   int closure = Register::function_closure().index();
   5862 
   5863   ExpectedSnippet<int> snippets[] = {
   5864       {"var f;\n f = function f() { }",
   5865        1 * kPointerSize,
   5866        1,
   5867        9,
   5868        {
   5869            B(LdaTheHole),        //
   5870            B(Star), R(0),        //
   5871            B(Ldar), R(closure),  //
   5872            B(Star), R(0),        //
   5873            B(LdaUndefined),      //
   5874            B(Return),            //
   5875        }},
   5876       {"var f;\n f = function f() { return f; }",
   5877        1 * kPointerSize,
   5878        1,
   5879        8,
   5880        {
   5881            B(LdaTheHole),        //
   5882            B(Star), R(0),        //
   5883            B(Ldar), R(closure),  //
   5884            B(Star), R(0),        //
   5885            B(Return),            //
   5886        }},
   5887   };
   5888 
   5889   for (size_t i = 0; i < arraysize(snippets); i++) {
   5890     Handle<BytecodeArray> bytecode_array =
   5891         helper.MakeBytecodeForFunction(snippets[i].code_snippet);
   5892     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   5893   }
   5894 }
   5895 
   5896 
   5897 TEST(NewTarget) {
   5898   InitializedHandleScope handle_scope;
   5899   BytecodeGeneratorHelper helper;
   5900 
   5901   int new_target = Register::new_target().index();
   5902 
   5903   ExpectedSnippet<int> snippets[] = {
   5904       {"return new.target;",
   5905        1 * kPointerSize,
   5906        1,
   5907        5,
   5908        {
   5909            B(Ldar), R(new_target),  //
   5910            B(Star), R(0),           //
   5911            B(Return),               //
   5912        }},
   5913       {"new.target;",
   5914        1 * kPointerSize,
   5915        1,
   5916        6,
   5917        {
   5918            B(Ldar), R(new_target),  //
   5919            B(Star), R(0),           //
   5920            B(LdaUndefined),         //
   5921            B(Return),               //
   5922        }},
   5923   };
   5924 
   5925   for (size_t i = 0; i < arraysize(snippets); i++) {
   5926     Handle<BytecodeArray> bytecode_array =
   5927         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
   5928     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   5929   }
   5930 }
   5931 
   5932 
   5933 TEST(RemoveRedundantLdar) {
   5934   InitializedHandleScope handle_scope;
   5935   BytecodeGeneratorHelper helper;
   5936 
   5937   ExpectedSnippet<int> snippets[] = {
   5938       {"var ld_a = 1;\n"          // This test is to check Ldar does not
   5939        "while(true) {\n"          // get removed if the preceding Star is
   5940        "  ld_a = ld_a + ld_a;\n"  // in a different basicblock.
   5941        "  if (ld_a > 10) break;\n"
   5942        "}\n"
   5943        "return ld_a;",
   5944        2 * kPointerSize,
   5945        1,
   5946        29,
   5947        {B(LdaSmi8), U8(1),         //
   5948         B(Star), R(0),             //
   5949         B(Ldar), R(0),             //  This load should not be removed as it
   5950         B(Star), R(1),             //  is the target of the branch.
   5951         B(Ldar), R(0),             //
   5952         B(Add), R(1),              //
   5953         B(Star), R(0),             //
   5954         B(Star), R(1),             //
   5955         B(LdaSmi8), U8(10),        //
   5956         B(TestGreaterThan), R(1),  //
   5957         B(JumpIfFalse), U8(4),     //
   5958         B(Jump), U8(4),            //
   5959         B(Jump), U8(-20),          //
   5960         B(Ldar), R(0),             //
   5961         B(Return)}},
   5962       {"var ld_a = 1;\n"
   5963        "do {\n"
   5964        "  ld_a = ld_a + ld_a;\n"
   5965        "  if (ld_a > 10) continue;\n"
   5966        "} while(false);\n"
   5967        "return ld_a;",
   5968        2 * kPointerSize,
   5969        1,
   5970        27,
   5971        {B(LdaSmi8), U8(1),         //
   5972         B(Star), R(0),             //
   5973         B(Ldar), R(0),             //
   5974         B(Star), R(1),             //
   5975         B(Ldar), R(0),             //
   5976         B(Add), R(1),              //
   5977         B(Star), R(0),             //
   5978         B(Star), R(1),             //
   5979         B(LdaSmi8), U8(10),        //
   5980         B(TestGreaterThan), R(1),  //
   5981         B(JumpIfFalse), U8(4),     //
   5982         B(Jump), U8(2),            //
   5983         B(Ldar), R(0),             //
   5984         B(Return)}},
   5985       {"var ld_a = 1;\n"
   5986        "  ld_a = ld_a + ld_a;\n"
   5987        "  return ld_a;",
   5988        2 * kPointerSize,
   5989        1,
   5990        13,
   5991        {
   5992            B(LdaSmi8), U8(1),  //
   5993            B(Star), R(0),      //
   5994            B(Star), R(1),      //
   5995            B(Ldar), R(0),      //
   5996            B(Add), R(1),       //
   5997            B(Star), R(0),      //
   5998            B(Return)           //
   5999        }},
   6000   };
   6001 
   6002   for (size_t i = 0; i < arraysize(snippets); i++) {
   6003     Handle<BytecodeArray> bytecode_array =
   6004         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
   6005     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   6006   }
   6007 }
   6008 
   6009 
   6010 TEST(AssignmentsInBinaryExpression) {
   6011   InitializedHandleScope handle_scope;
   6012   BytecodeGeneratorHelper helper;
   6013 
   6014   ExpectedSnippet<const char*> snippets[] = {
   6015       {"var x = 0, y = 1;\n"
   6016        "return (x = 2, y = 3, x = 4, y = 5)",
   6017        2 * kPointerSize,
   6018        1,
   6019        24,
   6020        {
   6021            B(LdaZero), B(Star), R(0),  //
   6022            B(LdaSmi8), U8(1),          //
   6023            B(Star), R(1),              //
   6024            B(LdaSmi8), U8(2),          //
   6025            B(Star), R(0),              //
   6026            B(LdaSmi8), U8(3),          //
   6027            B(Star), R(1),              //
   6028            B(LdaSmi8), U8(4),          //
   6029            B(Star), R(0),              //
   6030            B(LdaSmi8), U8(5),          //
   6031            B(Star), R(1),              //
   6032            B(Return),                  //
   6033        },
   6034        0},
   6035       {"var x = 55;\n"
   6036        "var y = (x = 100);\n"
   6037        "return y",
   6038        2 * kPointerSize,
   6039        1,
   6040        11,
   6041        {
   6042            B(LdaSmi8), U8(55),   //
   6043            B(Star), R(0),        //
   6044            B(LdaSmi8), U8(100),  //
   6045            B(Star), R(0),        //
   6046            B(Star), R(1),        //
   6047            B(Return),            //
   6048        },
   6049        0},
   6050       {"var x = 55;\n"
   6051        "x = x + (x = 100) + (x = 101);\n"
   6052        "return x;",
   6053        3 * kPointerSize,
   6054        1,
   6055        23,
   6056        {
   6057            B(LdaSmi8), U8(55),   //
   6058            B(Star), R(0),        //
   6059            B(Star), R(1),        //
   6060            B(LdaSmi8), U8(100),  //
   6061            B(Star), R(0),        //
   6062            B(Add), R(1),         //
   6063            B(Star), R(2),        //
   6064            B(LdaSmi8), U8(101),  //
   6065            B(Star), R(0),        //
   6066            B(Add), R(2),         //
   6067            B(Star), R(0),        //
   6068            B(Return),            //
   6069        },
   6070        0},
   6071       {"var x = 55;\n"
   6072        "x = (x = 56) - x + (x = 57);\n"
   6073        "x++;\n"
   6074        "return x;",
   6075        3 * kPointerSize,
   6076        1,
   6077        31,
   6078        {
   6079            B(LdaSmi8), U8(55),  //
   6080            B(Star), R(0),       //
   6081            B(LdaSmi8), U8(56),  //
   6082            B(Star), R(0),       //
   6083            B(Star), R(1),       //
   6084            B(Ldar), R(0),       //
   6085            B(Sub), R(1),        //
   6086            B(Star), R(2),       //
   6087            B(LdaSmi8), U8(57),  //
   6088            B(Star), R(0),       //
   6089            B(Add), R(2),        //
   6090            B(Star), R(0),       //
   6091            B(ToNumber),         //
   6092            B(Star), R(1),       //
   6093            B(Inc),              //
   6094            B(Star), R(0),       //
   6095            B(Return),           //
   6096        },
   6097        0},
   6098       {"var x = 55;\n"
   6099        "var y = x + (x = 1) + (x = 2) + (x = 3);\n"
   6100        "return y;",
   6101        4 * kPointerSize,
   6102        1,
   6103        31,
   6104        {
   6105            B(LdaSmi8), U8(55),  //
   6106            B(Star), R(0),       //
   6107            B(Star), R(2),       //
   6108            B(LdaSmi8), U8(1),   //
   6109            B(Star), R(0),       //
   6110            B(Add), R(2),        //
   6111            B(Star), R(3),       //
   6112            B(LdaSmi8), U8(2),   //
   6113            B(Star), R(0),       //
   6114            B(Add), R(3),        //
   6115            B(Star), R(2),       //
   6116            B(LdaSmi8), U8(3),   //
   6117            B(Star), R(0),       //
   6118            B(Add), R(2),        //
   6119            B(Star), R(1),       //
   6120            B(Return),           //
   6121        },
   6122        0},
   6123       {"var x = 55;\n"
   6124        "var x = x + (x = 1) + (x = 2) + (x = 3);\n"
   6125        "return x;",
   6126        3 * kPointerSize,
   6127        1,
   6128        31,
   6129        {
   6130            B(LdaSmi8), U8(55),  //
   6131            B(Star), R(0),       //
   6132            B(Star), R(1),       //
   6133            B(LdaSmi8), U8(1),   //
   6134            B(Star), R(0),       //
   6135            B(Add), R(1),        //
   6136            B(Star), R(2),       //
   6137            B(LdaSmi8), U8(2),   //
   6138            B(Star), R(0),       //
   6139            B(Add), R(2),        //
   6140            B(Star), R(1),       //
   6141            B(LdaSmi8), U8(3),   //
   6142            B(Star), R(0),       //
   6143            B(Add), R(1),        //
   6144            B(Star), R(0),       //
   6145            B(Return),           //
   6146        },
   6147        0},
   6148       {"var x = 10, y = 20;\n"
   6149        "return x + (x = 1) + (x + 1) * (y = 2) + (y = 3) + (x = 4) + (y = 5) + "
   6150        "y;\n",
   6151        5 * kPointerSize,
   6152        1,
   6153        69,
   6154        {
   6155            B(LdaSmi8), U8(10),  //
   6156            B(Star), R(0),       //
   6157            B(LdaSmi8), U8(20),  //
   6158            B(Star), R(1),       //
   6159            B(Ldar), R(0),       //
   6160            B(Star), R(2),       //
   6161            B(LdaSmi8), U8(1),   //
   6162            B(Star), R(0),       //
   6163            B(Add), R(2),        //
   6164            B(Star), R(3),       //
   6165            B(Ldar), R(0),       //
   6166            B(Star), R(2),       //
   6167            B(LdaSmi8), U8(1),   //
   6168            B(Add), R(2),        //
   6169            B(Star), R(4),       //
   6170            B(LdaSmi8), U8(2),   //
   6171            B(Star), R(1),       //
   6172            B(Mul), R(4),        //
   6173            B(Add), R(3),        //
   6174            B(Star), R(2),       //
   6175            B(LdaSmi8), U8(3),   //
   6176            B(Star), R(1),       //
   6177            B(Add), R(2),        //
   6178            B(Star), R(3),       //
   6179            B(LdaSmi8), U8(4),   //
   6180            B(Star), R(0),       //
   6181            B(Add), R(3),        //
   6182            B(Star), R(2),       //
   6183            B(LdaSmi8), U8(5),   //
   6184            B(Star), R(1),       //
   6185            B(Add), R(2),        //
   6186            B(Star), R(3),       //
   6187            B(Ldar), R(1),       //
   6188            B(Add), R(3),        //
   6189            B(Return),           //
   6190        },
   6191        0},
   6192       {"var x = 17;\n"
   6193        "return 1 + x + (x++) + (++x);\n",
   6194        4 * kPointerSize,
   6195        1,
   6196        37,
   6197        {
   6198            B(LdaSmi8), U8(17),  //
   6199            B(Star), R(0),       //
   6200            B(LdaSmi8), U8(1),   //
   6201            B(Star), R(1),       //
   6202            B(Ldar), R(0),       //
   6203            B(Add), R(1),        //
   6204            B(Star), R(2),       //
   6205            B(Ldar), R(0),       //
   6206            B(ToNumber),         //
   6207            B(Star), R(1),       //
   6208            B(Inc),              //
   6209            B(Star), R(0),       //
   6210            B(Ldar), R(1),       //
   6211            B(Add), R(2),        //
   6212            B(Star), R(3),       //
   6213            B(Ldar), R(0),       //
   6214            B(ToNumber),         //
   6215            B(Inc),              //
   6216            B(Star), R(0),       //
   6217            B(Add), R(3),        //
   6218            B(Return),           //
   6219        },
   6220        0}};
   6221 
   6222   for (size_t i = 0; i < arraysize(snippets); i++) {
   6223     Handle<BytecodeArray> bytecode_array =
   6224         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
   6225     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   6226   }
   6227 }
   6228 
   6229 
   6230 TEST(Eval) {
   6231   InitializedHandleScope handle_scope;
   6232   BytecodeGeneratorHelper helper;
   6233   Zone zone;
   6234 
   6235   int closure = Register::function_closure().index();
   6236   int context = Register::function_context().index();
   6237   int new_target = Register::new_target().index();
   6238 
   6239   int first_context_slot = Context::MIN_CONTEXT_SLOTS;
   6240 
   6241   ExpectedSnippet<const char*> snippets[] = {
   6242       {"return eval('1;');",
   6243        9 * kPointerSize,
   6244        1,
   6245        67,
   6246        {
   6247            B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure),     //
   6248                            U8(1),                                             //
   6249            B(PushContext), R(0),                                              //
   6250            B(Ldar), THIS(1),                                                  //
   6251            B(StaContextSlot), R(0), U8(first_context_slot),                   //
   6252            B(CreateMappedArguments),                                          //
   6253            B(StaContextSlot), R(0), U8(first_context_slot + 1),               //
   6254            B(Ldar), R(new_target),                                            //
   6255            B(StaContextSlot), R(0), U8(first_context_slot + 2),               //
   6256            B(Mov), R(context), R(3),                                          //
   6257            B(LdaConstant), U8(0),                                             //
   6258            B(Star), R(4),                                                     //
   6259            B(CallRuntimeForPair), U16(Runtime::kLoadLookupSlot),              //
   6260                                   R(3), U8(2), R(1),                          //
   6261            B(LdaConstant), U8(1),                                             //
   6262            B(Star), R(3),                                                     //
   6263            B(Mov), R(1), R(4),                                                //
   6264            B(Mov), R(3), R(5),                                                //
   6265            B(Mov), R(closure), R(6),                                          //
   6266            B(LdaZero),                                                        //
   6267            B(Star), R(7),                                                     //
   6268            B(LdaSmi8), U8(10),                                                //
   6269            B(Star), R(8),                                                     //
   6270            B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4),    //
   6271                            U8(5),                                             //
   6272            B(Star), R(1),                                                     //
   6273            B(Call), R(1), R(2), U8(1), U8(0),                                 //
   6274            B(Return),                                                         //
   6275        },
   6276        2,
   6277        {"eval", "1;"}},
   6278   };
   6279 
   6280   for (size_t i = 0; i < arraysize(snippets); i++) {
   6281     Handle<BytecodeArray> bytecode_array =
   6282         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
   6283     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   6284   }
   6285 }
   6286 
   6287 
   6288 TEST(LookupSlot) {
   6289   InitializedHandleScope handle_scope;
   6290   BytecodeGeneratorHelper helper;
   6291 
   6292   int closure = Register::function_closure().index();
   6293   int first_context_slot = Context::MIN_CONTEXT_SLOTS;
   6294   int context = Register::function_context().index();
   6295   int new_target = Register::new_target().index();
   6296 
   6297   ExpectedSnippet<const char*> snippets[] = {
   6298       {"eval('var x = 10;'); return x;",
   6299        9 * kPointerSize,
   6300        1,
   6301        69,
   6302        {
   6303            B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure),     //
   6304                            U8(1),                                             //
   6305            B(PushContext), R(0),                                              //
   6306            B(Ldar), THIS(1),                                                  //
   6307            B(StaContextSlot), R(0), U8(first_context_slot),                   //
   6308            B(CreateMappedArguments),                                          //
   6309            B(StaContextSlot), R(0), U8(first_context_slot + 1),               //
   6310            B(Ldar), R(new_target),                                            //
   6311            B(StaContextSlot), R(0), U8(first_context_slot + 2),               //
   6312            B(Mov), R(context), R(3),                                          //
   6313            B(LdaConstant), U8(0),                                             //
   6314            B(Star), R(4),                                                     //
   6315            B(CallRuntimeForPair), U16(Runtime::kLoadLookupSlot),              //
   6316                                   R(3), U8(2), R(1),                          //
   6317            B(LdaConstant), U8(1),                                             //
   6318            B(Star), R(3),                                                     //
   6319            B(Mov), R(1), R(4),                                                //
   6320            B(Mov), R(3), R(5),                                                //
   6321            B(Mov), R(closure), R(6),                                          //
   6322            B(LdaZero),                                                        //
   6323            B(Star), R(7),                                                     //
   6324            B(LdaSmi8), U8(10),                                                //
   6325            B(Star), R(8),                                                     //
   6326            B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4),    //
   6327                            U8(5),                                             //
   6328            B(Star), R(1),                                                     //
   6329            B(Call), R(1), R(2), U8(1), U8(0),                                 //
   6330            B(LdaLookupSlot), U8(2),                                           //
   6331            B(Return),                                                         //
   6332        },
   6333        3,
   6334        {"eval", "var x = 10;", "x"}},
   6335       {"eval('var x = 10;'); return typeof x;",
   6336         9 * kPointerSize,
   6337         1,
   6338         70,
   6339         {
   6340            B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure),     //
   6341                            U8(1),                                             //
   6342            B(PushContext), R(0),                                              //
   6343            B(Ldar), THIS(1),                                                  //
   6344            B(StaContextSlot), R(0), U8(first_context_slot),                   //
   6345            B(CreateMappedArguments),                                          //
   6346            B(StaContextSlot), R(0), U8(first_context_slot + 1),               //
   6347            B(Ldar), R(new_target),                                            //
   6348            B(StaContextSlot), R(0), U8(first_context_slot + 2),               //
   6349            B(Mov), R(context), R(3),                                          //
   6350            B(LdaConstant), U8(0),                                             //
   6351            B(Star), R(4),                                                     //
   6352            B(CallRuntimeForPair), U16(Runtime::kLoadLookupSlot),              //
   6353                                   R(3), U8(2), R(1),                          //
   6354            B(LdaConstant), U8(1),                                             //
   6355            B(Star), R(3),                                                     //
   6356            B(Mov), R(1), R(4),                                                //
   6357            B(Mov), R(3), R(5),                                                //
   6358            B(Mov), R(closure), R(6),                                          //
   6359            B(LdaZero),                                                        //
   6360            B(Star), R(7),                                                     //
   6361            B(LdaSmi8), U8(10),                                                //
   6362            B(Star), R(8),                                                     //
   6363            B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4),    //
   6364                            U8(5),                                             //
   6365            B(Star), R(1),                                                     //
   6366            B(Call), R(1), R(2), U8(1), U8(0),                                 //
   6367            B(LdaLookupSlotInsideTypeof), U8(2),                               //
   6368            B(TypeOf),                                                         //
   6369            B(Return),                                                         //
   6370        },
   6371        3,
   6372        {"eval", "var x = 10;", "x"}},
   6373       {"x = 20; return eval('');",
   6374        9 * kPointerSize,
   6375        1,
   6376        71,
   6377        {
   6378            B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure),     //
   6379                            U8(1),                                             //
   6380            B(PushContext), R(0),                                              //
   6381            B(Ldar), THIS(1),                                                  //
   6382            B(StaContextSlot), R(0), U8(first_context_slot),                   //
   6383            B(CreateMappedArguments),                                          //
   6384            B(StaContextSlot), R(0), U8(first_context_slot + 1),               //
   6385            B(Ldar), R(new_target),                                            //
   6386            B(StaContextSlot), R(0), U8(first_context_slot + 2),               //
   6387            B(LdaSmi8), U8(20),                                                //
   6388            B(StaLookupSlotSloppy), U8(0),                                     //
   6389            B(Mov), R(context), R(3),                                          //
   6390            B(LdaConstant), U8(1),                                             //
   6391            B(Star), R(4),                                                     //
   6392            B(CallRuntimeForPair), U16(Runtime::kLoadLookupSlot),              //
   6393                                   R(3), U8(2), R(1),                          //
   6394            B(LdaConstant), U8(2),                                             //
   6395            B(Star), R(3),                                                     //
   6396            B(Mov), R(1), R(4),                                                //
   6397            B(Mov), R(3), R(5),                                                //
   6398            B(Mov), R(closure), R(6),                                          //
   6399            B(LdaZero),                                                        //
   6400            B(Star), R(7),                                                     //
   6401            B(LdaSmi8), U8(10),                                                //
   6402            B(Star), R(8),                                                     //
   6403            B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4),    //
   6404                            U8(5),                                             //
   6405            B(Star), R(1),                                                     //
   6406            B(Call), R(1), R(2), U8(1), U8(0),                                 //
   6407            B(Return),                                                         //
   6408        },
   6409        3,
   6410        {"x", "eval", ""}},
   6411   };
   6412 
   6413   for (size_t i = 0; i < arraysize(snippets); i++) {
   6414     Handle<BytecodeArray> bytecode_array =
   6415         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
   6416     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   6417   }
   6418 }
   6419 
   6420 
   6421 TEST(CallLookupSlot) {
   6422   InitializedHandleScope handle_scope;
   6423   BytecodeGeneratorHelper helper;
   6424   Zone zone;
   6425 
   6426   FeedbackVectorSpec feedback_spec(&zone);
   6427   FeedbackVectorSlot slot1 = feedback_spec.AddLoadICSlot();
   6428   FeedbackVectorSlot slot2 = feedback_spec.AddCallICSlot();
   6429   USE(slot1);
   6430 
   6431   Handle<i::TypeFeedbackVector> vector =
   6432       i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec);
   6433 
   6434   int closure = Register::function_closure().index();
   6435   int context = Register::function_context().index();
   6436   int new_target = Register::new_target().index();
   6437 
   6438   ExpectedSnippet<InstanceType> snippets[] = {
   6439       {"g = function(){}; eval(''); return g();",
   6440        9 * kPointerSize,
   6441        1,
   6442        90,
   6443        {
   6444            B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure),   //
   6445                            U8(1),                                           //
   6446            B(PushContext), R(0),                                            //
   6447            B(Ldar), THIS(1),                                                //
   6448            B(StaContextSlot), R(0), U8(4),                                  //
   6449            B(CreateMappedArguments),                                        //
   6450            B(StaContextSlot), R(0), U8(5),                                  //
   6451            B(Ldar), R(new_target),                                          //
   6452            B(StaContextSlot), R(0), U8(6),                                  //
   6453            B(CreateClosure), U8(0), U8(0),                                  //
   6454            B(StaLookupSlotSloppy), U8(1),                                   //
   6455            B(Mov), R(context), R(3),                                        //
   6456            B(LdaConstant), U8(2),                                           //
   6457            B(Star), R(4),                                                   //
   6458            B(CallRuntimeForPair), U16(Runtime::kLoadLookupSlot),            //
   6459                                   R(3), U8(2), R(1),                        //
   6460            B(LdaConstant), U8(3),                                           //
   6461            B(Star), R(3),                                                   //
   6462            B(Mov), R(1), R(4),                                              //
   6463            B(Mov), R(3), R(5),                                              //
   6464            B(Mov), R(closure), R(6),                                        //
   6465            B(LdaZero),                                                      //
   6466            B(Star), R(7),                                                   //
   6467            B(LdaSmi8), U8(10),                                              //
   6468            B(Star), R(8),                                                   //
   6469            B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4),  //
   6470                            U8(5),                                           //
   6471            B(Star), R(1),                                                   //
   6472            B(Call), R(1), R(2), U8(1), U8(0),                               //
   6473            B(Mov), R(context), R(3),                                        //
   6474            B(LdaConstant), U8(1),                                           //
   6475            B(Star), R(4),                                                   //
   6476            B(CallRuntimeForPair), U16(Runtime::kLoadLookupSlot),            //
   6477                                   R(3), U8(2), R(1),                        //
   6478            B(Call), R(1), R(2), U8(0), U8(vector->GetIndex(slot2)),         //
   6479            B(Return),                                                       //
   6480        },
   6481        4,
   6482        {InstanceType::SHARED_FUNCTION_INFO_TYPE,
   6483         InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
   6484         InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
   6485         InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
   6486   };
   6487 
   6488   for (size_t i = 0; i < arraysize(snippets); i++) {
   6489     Handle<BytecodeArray> bytecode_array =
   6490         helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
   6491     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   6492   }
   6493 }
   6494 
   6495 
   6496 TEST(LookupSlotInEval) {
   6497   InitializedHandleScope handle_scope;
   6498   BytecodeGeneratorHelper helper;
   6499 
   6500   const char* function_prologue = "var f;"
   6501                                   "var x = 1;"
   6502                                   "function f1() {"
   6503                                   "  eval(\"function t() {";
   6504   const char* function_epilogue = "        }; f = t; f();\");"
   6505                                   "}"
   6506                                   "f1();";
   6507 
   6508   ExpectedSnippet<const char*> snippets[] = {
   6509       {"return x;",
   6510        0 * kPointerSize,
   6511        1,
   6512        3,
   6513        {
   6514            B(LdaLookupSlot), U8(0),  //
   6515            B(Return)                 //
   6516        },
   6517        1,
   6518        {"x"}},
   6519       {"x = 10;",
   6520        0 * kPointerSize,
   6521        1,
   6522        6,
   6523        {
   6524            B(LdaSmi8), U8(10),             //
   6525            B(StaLookupSlotSloppy), U8(0),  //
   6526            B(LdaUndefined),                //
   6527            B(Return),                      //
   6528        },
   6529        1,
   6530        {"x"}},
   6531       {"'use strict'; x = 10;",
   6532        0 * kPointerSize,
   6533        1,
   6534        6,
   6535        {
   6536            B(LdaSmi8), U8(10),             //
   6537            B(StaLookupSlotStrict), U8(0),  //
   6538            B(LdaUndefined),                //
   6539            B(Return),                      //
   6540        },
   6541        1,
   6542        {"x"}},
   6543       {"return typeof x;",
   6544        0 * kPointerSize,
   6545        1,
   6546        4,
   6547        {
   6548            B(LdaLookupSlotInsideTypeof), U8(0),  //
   6549            B(TypeOf),                            //
   6550            B(Return),                            //
   6551        },
   6552        1,
   6553        {"x"}},
   6554   };
   6555 
   6556   for (size_t i = 0; i < arraysize(snippets); i++) {
   6557     std::string script = std::string(function_prologue) +
   6558                          std::string(snippets[i].code_snippet) +
   6559                          std::string(function_epilogue);
   6560     // TODO(mythria): use * as filter when function declarations are supported
   6561     // inside eval.
   6562     Handle<BytecodeArray> bytecode_array =
   6563         helper.MakeBytecode(script.c_str(), "t", "f");
   6564     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   6565   }
   6566 }
   6567 
   6568 
   6569 TEST(LookupSlotWideInEval) {
   6570   InitializedHandleScope handle_scope;
   6571   BytecodeGeneratorHelper helper;
   6572 
   6573   const char* function_prologue =
   6574       "var f;"
   6575       "var x = 1;"
   6576       "function f1() {"
   6577       "  eval(\"function t() {";
   6578   const char* function_epilogue =
   6579       "        }; f = t; f();\");"
   6580       "}"
   6581       "f1();";
   6582 
   6583   int const_count[] = {0, 0, 0, 0};
   6584   ExpectedSnippet<InstanceType, 257> snippets[] = {
   6585       {REPEAT_256(SPACE, "var y = 2.3;")
   6586        "return x;",
   6587        1 * kPointerSize,
   6588        1,
   6589        1028,
   6590        {
   6591            REPEAT_256(SPACE,                         //
   6592              B(LdaConstant), U8(const_count[0]++),   //
   6593              B(Star), R(0), )                        //
   6594            B(LdaLookupSlotWide), U16(256),           //
   6595            B(Return)                                 //
   6596        },
   6597        257,
   6598        {REPEAT_256(COMMA, InstanceType::HEAP_NUMBER_TYPE),
   6599         InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
   6600       {REPEAT_256(SPACE, "var y = 2.3;")
   6601        "return typeof x;",
   6602        1 * kPointerSize,
   6603        1,
   6604        1029,
   6605        {
   6606            REPEAT_256(SPACE,                            //
   6607              B(LdaConstant), U8(const_count[1]++),      //
   6608              B(Star), R(0), )                           //
   6609            B(LdaLookupSlotInsideTypeofWide), U16(256),  //
   6610            B(TypeOf),                                   //
   6611            B(Return)                                    //
   6612        },
   6613        257,
   6614        {REPEAT_256(COMMA, InstanceType::HEAP_NUMBER_TYPE),
   6615         InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
   6616       {REPEAT_256(SPACE, "var y = 2.3;")
   6617        "x = 10;",
   6618        1 * kPointerSize,
   6619        1,
   6620        1031,
   6621        {
   6622            REPEAT_256(SPACE,                        //
   6623              B(LdaConstant), U8(const_count[2]++),  //
   6624              B(Star), R(0), )                       //
   6625            B(LdaSmi8), U8(10),                      //
   6626            B(StaLookupSlotSloppyWide), U16(256),    //
   6627            B(LdaUndefined),                         //
   6628            B(Return)                                //
   6629        },
   6630        257,
   6631        {REPEAT_256(COMMA, InstanceType::HEAP_NUMBER_TYPE),
   6632         InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
   6633       {"'use strict';"
   6634        REPEAT_256(SPACE, "var y = 2.3;")
   6635        "x = 10;",
   6636        1 * kPointerSize,
   6637        1,
   6638        1031,
   6639        {
   6640            REPEAT_256(SPACE,
   6641              B(LdaConstant), U8(const_count[3]++),  //
   6642              B(Star), R(0), )                       //
   6643            B(LdaSmi8), U8(10),                      //
   6644            B(StaLookupSlotStrictWide), U16(256),    //
   6645            B(LdaUndefined),                         //
   6646            B(Return)                                //
   6647        },
   6648        257,
   6649        {REPEAT_256(COMMA, InstanceType::HEAP_NUMBER_TYPE),
   6650         InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
   6651   };
   6652 
   6653   for (size_t i = 0; i < arraysize(snippets); i++) {
   6654     std::string script = std::string(function_prologue) +
   6655                          std::string(snippets[i].code_snippet) +
   6656                          std::string(function_epilogue);
   6657     // TODO(mythria): use * as filter when function declarations are supported
   6658     // inside eval.
   6659     Handle<BytecodeArray> bytecode_array =
   6660         helper.MakeBytecode(script.c_str(), "t", "f");
   6661     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   6662   }
   6663 }
   6664 
   6665 
   6666 TEST(DeleteLookupSlotInEval) {
   6667   InitializedHandleScope handle_scope;
   6668   BytecodeGeneratorHelper helper;
   6669 
   6670   const char* function_prologue = "var f;"
   6671                                   "var x = 1;"
   6672                                   "z = 10;"
   6673                                   "function f1() {"
   6674                                   "  var y;"
   6675                                   "  eval(\"function t() {";
   6676   const char* function_epilogue = "        }; f = t; f();\");"
   6677                                   "}"
   6678                                   "f1();";
   6679 
   6680   ExpectedSnippet<const char*> snippets[] = {
   6681       {"delete x;",
   6682        0 * kPointerSize,
   6683        1,
   6684        5,
   6685        {
   6686            B(LdaConstant), U8(0),  //
   6687            B(DeleteLookupSlot),    //
   6688            B(LdaUndefined),        //
   6689            B(Return)               //
   6690        },
   6691        1,
   6692        {"x"}},
   6693       {"return delete y;",
   6694        0 * kPointerSize,
   6695        1,
   6696        2,
   6697        {
   6698            B(LdaFalse),        //
   6699            B(Return)           //
   6700        },
   6701        0},
   6702       {"return delete z;",
   6703        0 * kPointerSize,
   6704        1,
   6705        4,
   6706        {
   6707            B(LdaConstant), U8(0),  //
   6708            B(DeleteLookupSlot),    //
   6709            B(Return)               //
   6710        },
   6711        1,
   6712        {"z"}},
   6713   };
   6714 
   6715   for (size_t i = 0; i < arraysize(snippets); i++) {
   6716     std::string script = std::string(function_prologue) +
   6717                          std::string(snippets[i].code_snippet) +
   6718                          std::string(function_epilogue);
   6719     Handle<BytecodeArray> bytecode_array =
   6720         helper.MakeBytecode(script.c_str(), "t", "f");
   6721     CheckBytecodeArrayEqual(snippets[i], bytecode_array);
   6722   }
   6723 }
   6724 
   6725 }  // namespace interpreter
   6726 }  // namespace internal
   6727 }  // namespace v8
   6728