// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <tuple>

#include "src/init/v8.h"

#include "src/api/api-inl.h"
#include "src/base/overflowing-math.h"
#include "src/codegen/compiler.h"
#include "src/execution/execution.h"
#include "src/handles/handles.h"
#include "src/heap/heap-inl.h"
#include "src/interpreter/bytecode-array-builder.h"
#include "src/interpreter/bytecode-array-iterator.h"
#include "src/interpreter/bytecode-flags.h"
#include "src/interpreter/bytecode-label.h"
#include "src/interpreter/interpreter.h"
#include "src/numbers/hash-seed-inl.h"
#include "src/objects/heap-number-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/smi.h"
#include "test/cctest/cctest.h"
#include "test/cctest/interpreter/interpreter-tester.h"
#include "test/cctest/test-feedback-vector.h"

namespace v8 {
namespace internal {
namespace interpreter {

static int GetIndex(FeedbackSlot slot) {
  return FeedbackVector::GetIndex(slot);
}

using ToBooleanMode = BytecodeArrayBuilder::ToBooleanMode;

TEST(InterpreterReturn) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Zone* zone = handles.main_zone();
  Handle<Object> undefined_value = isolate->factory()->undefined_value();

  BytecodeArrayBuilder builder(zone, 1, 0);
  builder.Return();
  Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

  InterpreterTester tester(isolate, bytecode_array);
  auto callable = tester.GetCallable<>();
  Handle<Object> return_val = callable().ToHandleChecked();
  CHECK(return_val.is_identical_to(undefined_value));
}

TEST(InterpreterLoadUndefined) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Zone* zone = handles.main_zone();
  Handle<Object> undefined_value = isolate->factory()->undefined_value();

  BytecodeArrayBuilder builder(zone, 1, 0);
  builder.LoadUndefined().Return();
  Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

  InterpreterTester tester(isolate, bytecode_array);
  auto callable = tester.GetCallable<>();
  Handle<Object> return_val = callable().ToHandleChecked();
  CHECK(return_val.is_identical_to(undefined_value));
}

TEST(InterpreterLoadNull) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Zone* zone = handles.main_zone();
  Handle<Object> null_value = isolate->factory()->null_value();

  BytecodeArrayBuilder builder(zone, 1, 0);
  builder.LoadNull().Return();
  Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

  InterpreterTester tester(isolate, bytecode_array);
  auto callable = tester.GetCallable<>();
  Handle<Object> return_val = callable().ToHandleChecked();
  CHECK(return_val.is_identical_to(null_value));
}

TEST(InterpreterLoadTheHole) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Zone* zone = handles.main_zone();
  Handle<Object> the_hole_value = isolate->factory()->the_hole_value();

  BytecodeArrayBuilder builder(zone, 1, 0);
  builder.LoadTheHole().Return();
  Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

  InterpreterTester tester(isolate, bytecode_array);
  auto callable = tester.GetCallable<>();
  Handle<Object> return_val = callable().ToHandleChecked();
  CHECK(return_val.is_identical_to(the_hole_value));
}

TEST(InterpreterLoadTrue) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Zone* zone = handles.main_zone();
  Handle<Object> true_value = isolate->factory()->true_value();

  BytecodeArrayBuilder builder(zone, 1, 0);
  builder.LoadTrue().Return();
  Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

  InterpreterTester tester(isolate, bytecode_array);
  auto callable = tester.GetCallable<>();
  Handle<Object> return_val = callable().ToHandleChecked();
  CHECK(return_val.is_identical_to(true_value));
}

TEST(InterpreterLoadFalse) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Zone* zone = handles.main_zone();
  Handle<Object> false_value = isolate->factory()->false_value();

  BytecodeArrayBuilder builder(zone, 1, 0);
  builder.LoadFalse().Return();
  Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

  InterpreterTester tester(isolate, bytecode_array);
  auto callable = tester.GetCallable<>();
  Handle<Object> return_val = callable().ToHandleChecked();
  CHECK(return_val.is_identical_to(false_value));
}

TEST(InterpreterLoadLiteral) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Zone* zone = handles.main_zone();

  // Small Smis.
  for (int i = -128; i < 128; i++) {
    BytecodeArrayBuilder builder(zone, 1, 0);
    builder.LoadLiteral(Smi::FromInt(i)).Return();
    Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

    InterpreterTester tester(isolate, bytecode_array);
    auto callable = tester.GetCallable<>();
    Handle<Object> return_val = callable().ToHandleChecked();
    CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(i));
  }

  // Large Smis.
  {
    BytecodeArrayBuilder builder(zone, 1, 0);

    builder.LoadLiteral(Smi::FromInt(0x12345678)).Return();
    Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

    InterpreterTester tester(isolate, bytecode_array);
    auto callable = tester.GetCallable<>();
    Handle<Object> return_val = callable().ToHandleChecked();
    CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(0x12345678));
  }

  // Heap numbers.
  {
    AstValueFactory ast_factory(zone, isolate->ast_string_constants(),
                                HashSeed(isolate));

    BytecodeArrayBuilder builder(zone, 1, 0);

    builder.LoadLiteral(-2.1e19).Return();

    ast_factory.Internalize(isolate);
    Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

    InterpreterTester tester(isolate, bytecode_array);
    auto callable = tester.GetCallable<>();
    Handle<Object> return_val = callable().ToHandleChecked();
    CHECK_EQ(i::HeapNumber::cast(*return_val).value(), -2.1e19);
  }

  // Strings.
  {
    AstValueFactory ast_factory(zone, isolate->ast_string_constants(),
                                HashSeed(isolate));

    BytecodeArrayBuilder builder(zone, 1, 0);

    const AstRawString* raw_string = ast_factory.GetOneByteString("String");
    builder.LoadLiteral(raw_string).Return();

    ast_factory.Internalize(isolate);
    Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

    InterpreterTester tester(isolate, bytecode_array);
    auto callable = tester.GetCallable<>();
    Handle<Object> return_val = callable().ToHandleChecked();
    CHECK(i::String::cast(*return_val).Equals(*raw_string->string()));
  }
}

TEST(InterpreterLoadStoreRegisters) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Zone* zone = handles.main_zone();
  Handle<Object> true_value = isolate->factory()->true_value();
  for (int i = 0; i <= kMaxInt8; i++) {
    BytecodeArrayBuilder builder(zone, 1, i + 1);

    Register reg(i);
    builder.LoadTrue()
        .StoreAccumulatorInRegister(reg)
        .LoadFalse()
        .LoadAccumulatorWithRegister(reg)
        .Return();
    Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

    InterpreterTester tester(isolate, bytecode_array);
    auto callable = tester.GetCallable<>();
    Handle<Object> return_val = callable().ToHandleChecked();
    CHECK(return_val.is_identical_to(true_value));
  }
}

static const Token::Value kShiftOperators[] = {
    Token::Value::SHL, Token::Value::SAR, Token::Value::SHR};

static const Token::Value kArithmeticOperators[] = {
    Token::Value::BIT_OR, Token::Value::BIT_XOR, Token::Value::BIT_AND,
    Token::Value::SHL,    Token::Value::SAR,     Token::Value::SHR,
    Token::Value::ADD,    Token::Value::SUB,     Token::Value::MUL,
    Token::Value::DIV,    Token::Value::MOD};

static double BinaryOpC(Token::Value op, double lhs, double rhs) {
  switch (op) {
    case Token::Value::ADD:
      return lhs + rhs;
    case Token::Value::SUB:
      return lhs - rhs;
    case Token::Value::MUL:
      return lhs * rhs;
    case Token::Value::DIV:
      return base::Divide(lhs, rhs);
    case Token::Value::MOD:
      return Modulo(lhs, rhs);
    case Token::Value::BIT_OR:
      return (v8::internal::DoubleToInt32(lhs) |
              v8::internal::DoubleToInt32(rhs));
    case Token::Value::BIT_XOR:
      return (v8::internal::DoubleToInt32(lhs) ^
              v8::internal::DoubleToInt32(rhs));
    case Token::Value::BIT_AND:
      return (v8::internal::DoubleToInt32(lhs) &
              v8::internal::DoubleToInt32(rhs));
    case Token::Value::SHL: {
      return base::ShlWithWraparound(DoubleToInt32(lhs), DoubleToInt32(rhs));
    }
    case Token::Value::SAR: {
      int32_t val = v8::internal::DoubleToInt32(lhs);
      uint32_t count = v8::internal::DoubleToUint32(rhs) & 0x1F;
      int32_t result = val >> count;
      return result;
    }
    case Token::Value::SHR: {
      uint32_t val = v8::internal::DoubleToUint32(lhs);
      uint32_t count = v8::internal::DoubleToUint32(rhs) & 0x1F;
      uint32_t result = val >> count;
      return result;
    }
    default:
      UNREACHABLE();
  }
}

TEST(InterpreterShiftOpsSmi) {
  int lhs_inputs[] = {0, -17, -182, 1073741823, -1};
  int rhs_inputs[] = {5, 2, 1, -1, -2, 0, 31, 32, -32, 64, 37};
  for (size_t l = 0; l < arraysize(lhs_inputs); l++) {
    for (size_t r = 0; r < arraysize(rhs_inputs); r++) {
      for (size_t o = 0; o < arraysize(kShiftOperators); o++) {
        HandleAndZoneScope handles;
        Isolate* isolate = handles.main_isolate();
        Zone* zone = handles.main_zone();
        Factory* factory = isolate->factory();
        FeedbackVectorSpec feedback_spec(zone);
        BytecodeArrayBuilder builder(zone, 1, 1, &feedback_spec);

        FeedbackSlot slot = feedback_spec.AddBinaryOpICSlot();
        Handle<i::FeedbackMetadata> metadata =
            NewFeedbackMetadata(isolate, &feedback_spec);

        Register reg(0);
        int lhs = lhs_inputs[l];
        int rhs = rhs_inputs[r];
        builder.LoadLiteral(Smi::FromInt(lhs))
            .StoreAccumulatorInRegister(reg)
            .LoadLiteral(Smi::FromInt(rhs))
            .BinaryOperation(kShiftOperators[o], reg, GetIndex(slot))
            .Return();
        Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

        InterpreterTester tester(isolate, bytecode_array, metadata);
        auto callable = tester.GetCallable<>();
        Handle<Object> return_value = callable().ToHandleChecked();
        Handle<Object> expected_value =
            factory->NewNumber(BinaryOpC(kShiftOperators[o], lhs, rhs));
        CHECK(return_value->SameValue(*expected_value));
      }
    }
  }
}

TEST(InterpreterBinaryOpsSmi) {
  int lhs_inputs[] = {3266, 1024, 0, -17, -18000};
  int rhs_inputs[] = {3266, 5, 4, 3, 2, 1, -1, -2};
  for (size_t l = 0; l < arraysize(lhs_inputs); l++) {
    for (size_t r = 0; r < arraysize(rhs_inputs); r++) {
      for (size_t o = 0; o < arraysize(kArithmeticOperators); o++) {
        HandleAndZoneScope handles;
        Isolate* isolate = handles.main_isolate();
        Zone* zone = handles.main_zone();
        Factory* factory = isolate->factory();
        FeedbackVectorSpec feedback_spec(zone);
        BytecodeArrayBuilder builder(zone, 1, 1, &feedback_spec);

        FeedbackSlot slot = feedback_spec.AddBinaryOpICSlot();
        Handle<i::FeedbackMetadata> metadata =
            NewFeedbackMetadata(isolate, &feedback_spec);

        Register reg(0);
        int lhs = lhs_inputs[l];
        int rhs = rhs_inputs[r];
        builder.LoadLiteral(Smi::FromInt(lhs))
            .StoreAccumulatorInRegister(reg)
            .LoadLiteral(Smi::FromInt(rhs))
            .BinaryOperation(kArithmeticOperators[o], reg, GetIndex(slot))
            .Return();
        Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

        InterpreterTester tester(isolate, bytecode_array, metadata);
        auto callable = tester.GetCallable<>();
        Handle<Object> return_value = callable().ToHandleChecked();
        Handle<Object> expected_value =
            factory->NewNumber(BinaryOpC(kArithmeticOperators[o], lhs, rhs));
        CHECK(return_value->SameValue(*expected_value));
      }
    }
  }
}

TEST(InterpreterBinaryOpsHeapNumber) {
  double lhs_inputs[] = {3266.101, 1024.12, 0.01, -17.99, -18000.833, 9.1e17};
  double rhs_inputs[] = {3266.101, 5.999, 4.778, 3.331,  2.643,
                         1.1,      -1.8,  -2.9,  8.3e-27};
  for (size_t l = 0; l < arraysize(lhs_inputs); l++) {
    for (size_t r = 0; r < arraysize(rhs_inputs); r++) {
      for (size_t o = 0; o < arraysize(kArithmeticOperators); o++) {
        HandleAndZoneScope handles;
        Isolate* isolate = handles.main_isolate();
        Zone* zone = handles.main_zone();
        Factory* factory = isolate->factory();
        FeedbackVectorSpec feedback_spec(zone);
        BytecodeArrayBuilder builder(zone, 1, 1, &feedback_spec);

        FeedbackSlot slot = feedback_spec.AddBinaryOpICSlot();
        Handle<i::FeedbackMetadata> metadata =
            NewFeedbackMetadata(isolate, &feedback_spec);

        Register reg(0);
        double lhs = lhs_inputs[l];
        double rhs = rhs_inputs[r];
        builder.LoadLiteral(lhs)
            .StoreAccumulatorInRegister(reg)
            .LoadLiteral(rhs)
            .BinaryOperation(kArithmeticOperators[o], reg, GetIndex(slot))
            .Return();
        Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

        InterpreterTester tester(isolate, bytecode_array, metadata);
        auto callable = tester.GetCallable<>();
        Handle<Object> return_value = callable().ToHandleChecked();
        Handle<Object> expected_value =
            factory->NewNumber(BinaryOpC(kArithmeticOperators[o], lhs, rhs));
        CHECK(return_value->SameValue(*expected_value));
      }
    }
  }
}

TEST(InterpreterBinaryOpsBigInt) {
  // This test only checks that the recorded type feedback is kBigInt.
  AstBigInt inputs[] = {AstBigInt("1"), AstBigInt("-42"), AstBigInt("0xFFFF")};
  for (size_t l = 0; l < arraysize(inputs); l++) {
    for (size_t r = 0; r < arraysize(inputs); r++) {
      for (size_t o = 0; o < arraysize(kArithmeticOperators); o++) {
        // Skip over unsigned right shift.
        if (kArithmeticOperators[o] == Token::Value::SHR) continue;

        HandleAndZoneScope handles;
        Isolate* isolate = handles.main_isolate();
        Zone* zone = handles.main_zone();
        FeedbackVectorSpec feedback_spec(zone);
        BytecodeArrayBuilder builder(zone, 1, 1, &feedback_spec);

        FeedbackSlot slot = feedback_spec.AddBinaryOpICSlot();
        Handle<i::FeedbackMetadata> metadata =
            NewFeedbackMetadata(isolate, &feedback_spec);

        Register reg(0);
        auto lhs = inputs[l];
        auto rhs = inputs[r];
        builder.LoadLiteral(lhs)
            .StoreAccumulatorInRegister(reg)
            .LoadLiteral(rhs)
            .BinaryOperation(kArithmeticOperators[o], reg, GetIndex(slot))
            .Return();
        Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

        InterpreterTester tester(isolate, bytecode_array, metadata);
        auto callable = tester.GetCallable<>();
        Handle<Object> return_value = callable().ToHandleChecked();
        CHECK(return_value->IsBigInt());
        if (tester.HasFeedbackMetadata()) {
          MaybeObject feedback = callable.vector().Get(slot);
          CHECK(feedback->IsSmi());
          CHECK_EQ(BinaryOperationFeedback::kBigInt, feedback->ToSmi().value());
        }
      }
    }
  }
}

namespace {

struct LiteralForTest {
  enum Type { kString, kHeapNumber, kSmi, kTrue, kFalse, kUndefined, kNull };

  explicit LiteralForTest(const AstRawString* string)
      : type(kString), string(string) {}
  explicit LiteralForTest(double number) : type(kHeapNumber), number(number) {}
  explicit LiteralForTest(int smi) : type(kSmi), smi(smi) {}
  explicit LiteralForTest(Type type) : type(type) {}

  Type type;
  union {
    const AstRawString* string;
    double number;
    int smi;
  };
};

void LoadLiteralForTest(BytecodeArrayBuilder* builder,
                        const LiteralForTest& value) {
  switch (value.type) {
    case LiteralForTest::kString:
      builder->LoadLiteral(value.string);
      return;
    case LiteralForTest::kHeapNumber:
      builder->LoadLiteral(value.number);
      return;
    case LiteralForTest::kSmi:
      builder->LoadLiteral(Smi::FromInt(value.smi));
      return;
    case LiteralForTest::kTrue:
      builder->LoadTrue();
      return;
    case LiteralForTest::kFalse:
      builder->LoadFalse();
      return;
    case LiteralForTest::kUndefined:
      builder->LoadUndefined();
      return;
    case LiteralForTest::kNull:
      builder->LoadNull();
      return;
  }
  UNREACHABLE();
}

}  // anonymous namespace

TEST(InterpreterStringAdd) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Zone* zone = handles.main_zone();
  Factory* factory = isolate->factory();
  AstValueFactory ast_factory(zone, isolate->ast_string_constants(),
                              HashSeed(isolate));

  struct TestCase {
    const AstRawString* lhs;
    LiteralForTest rhs;
    Handle<Object> expected_value;
    int32_t expected_feedback;
  } test_cases[] = {
      {ast_factory.GetOneByteString("a"),
       LiteralForTest(ast_factory.GetOneByteString("b")),
       factory->NewStringFromStaticChars("ab"),
       BinaryOperationFeedback::kString},
      {ast_factory.GetOneByteString("aaaaaa"),
       LiteralForTest(ast_factory.GetOneByteString("b")),
       factory->NewStringFromStaticChars("aaaaaab"),
       BinaryOperationFeedback::kString},
      {ast_factory.GetOneByteString("aaa"),
       LiteralForTest(ast_factory.GetOneByteString("bbbbb")),
       factory->NewStringFromStaticChars("aaabbbbb"),
       BinaryOperationFeedback::kString},
      {ast_factory.GetOneByteString(""),
       LiteralForTest(ast_factory.GetOneByteString("b")),
       factory->NewStringFromStaticChars("b"),
       BinaryOperationFeedback::kString},
      {ast_factory.GetOneByteString("a"),
       LiteralForTest(ast_factory.GetOneByteString("")),
       factory->NewStringFromStaticChars("a"),
       BinaryOperationFeedback::kString},
      {ast_factory.GetOneByteString("1.11"), LiteralForTest(2.5),
       factory->NewStringFromStaticChars("1.112.5"),
       BinaryOperationFeedback::kAny},
      {ast_factory.GetOneByteString("-1.11"), LiteralForTest(2.56),
       factory->NewStringFromStaticChars("-1.112.56"),
       BinaryOperationFeedback::kAny},
      {ast_factory.GetOneByteString(""), LiteralForTest(2.5),
       factory->NewStringFromStaticChars("2.5"), BinaryOperationFeedback::kAny},
  };
  ast_factory.Internalize(isolate);

  for (size_t i = 0; i < arraysize(test_cases); i++) {
    FeedbackVectorSpec feedback_spec(zone);
    BytecodeArrayBuilder builder(zone, 1, 1, &feedback_spec);
    FeedbackSlot slot = feedback_spec.AddBinaryOpICSlot();
    Handle<i::FeedbackMetadata> metadata =
        NewFeedbackMetadata(isolate, &feedback_spec);

    Register reg(0);
    builder.LoadLiteral(test_cases[i].lhs).StoreAccumulatorInRegister(reg);
    LoadLiteralForTest(&builder, test_cases[i].rhs);
    builder.BinaryOperation(Token::Value::ADD, reg, GetIndex(slot)).Return();
    Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

    InterpreterTester tester(isolate, bytecode_array, metadata);
    auto callable = tester.GetCallable<>();
    Handle<Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*test_cases[i].expected_value));

    if (tester.HasFeedbackMetadata()) {
      MaybeObject feedback = callable.vector().Get(slot);
      CHECK(feedback->IsSmi());
      CHECK_EQ(test_cases[i].expected_feedback, feedback->ToSmi().value());
    }
  }
}

TEST(InterpreterReceiverParameter) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Zone* zone = handles.main_zone();
  BytecodeArrayBuilder builder(zone, 1, 0);

  builder.LoadAccumulatorWithRegister(builder.Receiver()).Return();
  Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

  Handle<Object> object = InterpreterTester::NewObject("({ val : 123 })");

  InterpreterTester tester(isolate, bytecode_array);
  auto callable = tester.GetCallableWithReceiver<>();
  Handle<Object> return_val = callable(object).ToHandleChecked();

  CHECK(return_val.is_identical_to(object));
}

TEST(InterpreterParameter0) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Zone* zone = handles.main_zone();
  BytecodeArrayBuilder builder(zone, 2, 0);

  builder.LoadAccumulatorWithRegister(builder.Parameter(0)).Return();
  Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

  InterpreterTester tester(isolate, bytecode_array);
  auto callable = tester.GetCallable<Handle<Object>>();

  // Check for heap objects.
  Handle<Object> true_value = isolate->factory()->true_value();
  Handle<Object> return_val = callable(true_value).ToHandleChecked();
  CHECK(return_val.is_identical_to(true_value));

  // Check for Smis.
  return_val = callable(Handle<Smi>(Smi::FromInt(3), handles.main_isolate()))
                   .ToHandleChecked();
  CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(3));
}

TEST(InterpreterParameter8) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Zone* zone = handles.main_zone();
  AstValueFactory ast_factory(zone, isolate->ast_string_constants(),
                              HashSeed(isolate));
  FeedbackVectorSpec feedback_spec(zone);
  BytecodeArrayBuilder builder(zone, 8, 0, &feedback_spec);

  FeedbackSlot slot = feedback_spec.AddBinaryOpICSlot();
  FeedbackSlot slot1 = feedback_spec.AddBinaryOpICSlot();
  FeedbackSlot slot2 = feedback_spec.AddBinaryOpICSlot();
  FeedbackSlot slot3 = feedback_spec.AddBinaryOpICSlot();
  FeedbackSlot slot4 = feedback_spec.AddBinaryOpICSlot();
  FeedbackSlot slot5 = feedback_spec.AddBinaryOpICSlot();
  FeedbackSlot slot6 = feedback_spec.AddBinaryOpICSlot();

  Handle<i::FeedbackMetadata> metadata =
      NewFeedbackMetadata(isolate, &feedback_spec);

  builder.LoadAccumulatorWithRegister(builder.Receiver())
      .BinaryOperation(Token::Value::ADD, builder.Parameter(0), GetIndex(slot))
      .BinaryOperation(Token::Value::ADD, builder.Parameter(1), GetIndex(slot1))
      .BinaryOperation(Token::Value::ADD, builder.Parameter(2), GetIndex(slot2))
      .BinaryOperation(Token::Value::ADD, builder.Parameter(3), GetIndex(slot3))
      .BinaryOperation(Token::Value::ADD, builder.Parameter(4), GetIndex(slot4))
      .BinaryOperation(Token::Value::ADD, builder.Parameter(5), GetIndex(slot5))
      .BinaryOperation(Token::Value::ADD, builder.Parameter(6), GetIndex(slot6))
      .Return();
  ast_factory.Internalize(isolate);
  Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

  InterpreterTester tester(isolate, bytecode_array, metadata);
  using H = Handle<Object>;
  auto callable = tester.GetCallableWithReceiver<H, H, H, H, H, H, H>();

  Handle<Smi> arg1 = Handle<Smi>(Smi::FromInt(1), handles.main_isolate());
  Handle<Smi> arg2 = Handle<Smi>(Smi::FromInt(2), handles.main_isolate());
  Handle<Smi> arg3 = Handle<Smi>(Smi::FromInt(3), handles.main_isolate());
  Handle<Smi> arg4 = Handle<Smi>(Smi::FromInt(4), handles.main_isolate());
  Handle<Smi> arg5 = Handle<Smi>(Smi::FromInt(5), handles.main_isolate());
  Handle<Smi> arg6 = Handle<Smi>(Smi::FromInt(6), handles.main_isolate());
  Handle<Smi> arg7 = Handle<Smi>(Smi::FromInt(7), handles.main_isolate());
  Handle<Smi> arg8 = Handle<Smi>(Smi::FromInt(8), handles.main_isolate());
  // Check for Smis.
  Handle<Object> return_val =
      callable(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
          .ToHandleChecked();
  CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(36));
}

TEST(InterpreterBinaryOpTypeFeedback) {
  HandleAndZoneScope handles;
  i::Isolate* isolate = handles.main_isolate();
  Zone* zone = handles.main_zone();
  AstValueFactory ast_factory(zone, isolate->ast_string_constants(),
                              HashSeed(isolate));

  struct BinaryOpExpectation {
    Token::Value op;
    LiteralForTest arg1;
    LiteralForTest arg2;
    Handle<Object> result;
    int32_t feedback;
  };

  BinaryOpExpectation const kTestCases[] = {
      // ADD
      {Token::Value::ADD, LiteralForTest(2), LiteralForTest(3),
       Handle<Smi>(Smi::FromInt(5), isolate),
       BinaryOperationFeedback::kSignedSmall},
      {Token::Value::ADD, LiteralForTest(Smi::kMaxValue), LiteralForTest(1),
       isolate->factory()->NewHeapNumber(Smi::kMaxValue + 1.0),
       BinaryOperationFeedback::kNumber},
      {Token::Value::ADD, LiteralForTest(3.1415), LiteralForTest(3),
       isolate->factory()->NewHeapNumber(3.1415 + 3),
       BinaryOperationFeedback::kNumber},
      {Token::Value::ADD, LiteralForTest(3.1415), LiteralForTest(1.4142),
       isolate->factory()->NewHeapNumber(3.1415 + 1.4142),
       BinaryOperationFeedback::kNumber},
      {Token::Value::ADD, LiteralForTest(ast_factory.GetOneByteString("foo")),
       LiteralForTest(ast_factory.GetOneByteString("bar")),
       isolate->factory()->NewStringFromAsciiChecked("foobar"),
       BinaryOperationFeedback::kString},
      {Token::Value::ADD, LiteralForTest(2),
       LiteralForTest(ast_factory.GetOneByteString("2")),
       isolate->factory()->NewStringFromAsciiChecked("22"),
       BinaryOperationFeedback::kAny},
      // SUB
      {Token::Value::SUB, LiteralForTest(2), LiteralForTest(3),
       Handle<Smi>(Smi::FromInt(-1), isolate),
       BinaryOperationFeedback::kSignedSmall},
      {Token::Value::SUB, LiteralForTest(Smi::kMinValue), LiteralForTest(1),
       isolate->factory()->NewHeapNumber(Smi::kMinValue - 1.0),
       BinaryOperationFeedback::kNumber},
      {Token::Value::SUB, LiteralForTest(3.1415), LiteralForTest(3),
       isolate->factory()->NewHeapNumber(3.1415 - 3),
       BinaryOperationFeedback::kNumber},
      {Token::Value::SUB, LiteralForTest(3.1415), LiteralForTest(1.4142),
       isolate->factory()->NewHeapNumber(3.1415 - 1.4142),
       BinaryOperationFeedback::kNumber},
      {Token::Value::SUB, LiteralForTest(2),
       LiteralForTest(ast_factory.GetOneByteString("1")),
       Handle<Smi>(Smi::FromInt(1), isolate), BinaryOperationFeedback::kAny},
      // MUL
      {Token::Value::MUL, LiteralForTest(2), LiteralForTest(3),
       Handle<Smi>(Smi::FromInt(6), isolate),
       BinaryOperationFeedback::kSignedSmall},
      {Token::Value::MUL, LiteralForTest(Smi::kMinValue), LiteralForTest(2),
       isolate->factory()->NewHeapNumber(Smi::kMinValue * 2.0),
       BinaryOperationFeedback::kNumber},
      {Token::Value::MUL, LiteralForTest(3.1415), LiteralForTest(3),
       isolate->factory()->NewHeapNumber(3 * 3.1415),
       BinaryOperationFeedback::kNumber},
      {Token::Value::MUL, LiteralForTest(3.1415), LiteralForTest(1.4142),
       isolate->factory()->NewHeapNumber(3.1415 * 1.4142),
       BinaryOperationFeedback::kNumber},
      {Token::Value::MUL, LiteralForTest(2),
       LiteralForTest(ast_factory.GetOneByteString("1")),
       Handle<Smi>(Smi::FromInt(2), isolate), BinaryOperationFeedback::kAny},
      // DIV
      {Token::Value::DIV, LiteralForTest(6), LiteralForTest(3),
       Handle<Smi>(Smi::FromInt(2), isolate),
       BinaryOperationFeedback::kSignedSmall},
      {Token::Value::DIV, LiteralForTest(3), LiteralForTest(2),
       isolate->factory()->NewHeapNumber(3.0 / 2.0),
       BinaryOperationFeedback::kSignedSmallInputs},
      {Token::Value::DIV, LiteralForTest(3.1415), LiteralForTest(3),
       isolate->factory()->NewHeapNumber(3.1415 / 3),
       BinaryOperationFeedback::kNumber},
      {Token::Value::DIV, LiteralForTest(3.1415),
       LiteralForTest(-std::numeric_limits<double>::infinity()),
       isolate->factory()->NewHeapNumber(-0.0),
       BinaryOperationFeedback::kNumber},
      {Token::Value::DIV, LiteralForTest(2),
       LiteralForTest(ast_factory.GetOneByteString("1")),
       Handle<Smi>(Smi::FromInt(2), isolate), BinaryOperationFeedback::kAny},
      // MOD
      {Token::Value::MOD, LiteralForTest(5), LiteralForTest(3),
       Handle<Smi>(Smi::FromInt(2), isolate),
       BinaryOperationFeedback::kSignedSmall},
      {Token::Value::MOD, LiteralForTest(-4), LiteralForTest(2),
       isolate->factory()->NewHeapNumber(-0.0),
       BinaryOperationFeedback::kNumber},
      {Token::Value::MOD, LiteralForTest(3.1415), LiteralForTest(3),
       isolate->factory()->NewHeapNumber(fmod(3.1415, 3.0)),
       BinaryOperationFeedback::kNumber},
      {Token::Value::MOD, LiteralForTest(-3.1415), LiteralForTest(-1.4142),
       isolate->factory()->NewHeapNumber(fmod(-3.1415, -1.4142)),
       BinaryOperationFeedback::kNumber},
      {Token::Value::MOD, LiteralForTest(3),
       LiteralForTest(ast_factory.GetOneByteString("-2")),
       Handle<Smi>(Smi::FromInt(1), isolate), BinaryOperationFeedback::kAny}};
  ast_factory.Internalize(isolate);

  for (const BinaryOpExpectation& test_case : kTestCases) {
    i::FeedbackVectorSpec feedback_spec(zone);
    BytecodeArrayBuilder builder(zone, 1, 1, &feedback_spec);

    i::FeedbackSlot slot0 = feedback_spec.AddBinaryOpICSlot();

    Handle<i::FeedbackMetadata> metadata =
        i::NewFeedbackMetadata(isolate, &feedback_spec);

    Register reg(0);
    LoadLiteralForTest(&builder, test_case.arg1);
    builder.StoreAccumulatorInRegister(reg);
    LoadLiteralForTest(&builder, test_case.arg2);
    builder.BinaryOperation(test_case.op, reg, GetIndex(slot0)).Return();

    Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

    InterpreterTester tester(isolate, bytecode_array, metadata);
    auto callable = tester.GetCallable<>();

    Handle<Object> return_val = callable().ToHandleChecked();
    MaybeObject feedback0 = callable.vector().Get(slot0);
    CHECK(feedback0->IsSmi());
    CHECK_EQ(test_case.feedback, feedback0->ToSmi().value());
    CHECK(Object::Equals(isolate, test_case.result, return_val).ToChecked());
  }
}

TEST(InterpreterBinaryOpSmiTypeFeedback) {
  HandleAndZoneScope handles;
  i::Isolate* isolate = handles.main_isolate();
  Zone* zone = handles.main_zone();
  AstValueFactory ast_factory(zone, isolate->ast_string_constants(),
                              HashSeed(isolate));

  struct BinaryOpExpectation {
    Token::Value op;
    LiteralForTest arg1;
    int32_t arg2;
    Handle<Object> result;
    int32_t feedback;
  };

  BinaryOpExpectation const kTestCases[] = {
      // ADD
      {Token::Value::ADD, LiteralForTest(2), 42,
       Handle<Smi>(Smi::FromInt(44), isolate),
       BinaryOperationFeedback::kSignedSmall},
      {Token::Value::ADD, LiteralForTest(2), Smi::kMaxValue,
       isolate->factory()->NewHeapNumber(Smi::kMaxValue + 2.0),
       BinaryOperationFeedback::kNumber},
      {Token::Value::ADD, LiteralForTest(3.1415), 2,
       isolate->factory()->NewHeapNumber(3.1415 + 2.0),
       BinaryOperationFeedback::kNumber},
      {Token::Value::ADD, LiteralForTest(ast_factory.GetOneByteString("2")), 2,
       isolate->factory()->NewStringFromAsciiChecked("22"),
       BinaryOperationFeedback::kAny},
      // SUB
      {Token::Value::SUB, LiteralForTest(2), 42,
       Handle<Smi>(Smi::FromInt(-40), isolate),
       BinaryOperationFeedback::kSignedSmall},
      {Token::Value::SUB, LiteralForTest(Smi::kMinValue), 1,
       isolate->factory()->NewHeapNumber(Smi::kMinValue - 1.0),
       BinaryOperationFeedback::kNumber},
      {Token::Value::SUB, LiteralForTest(3.1415), 2,
       isolate->factory()->NewHeapNumber(3.1415 - 2.0),
       BinaryOperationFeedback::kNumber},
      {Token::Value::SUB, LiteralForTest(ast_factory.GetOneByteString("2")), 2,
       Handle<Smi>(Smi::zero(), isolate), BinaryOperationFeedback::kAny},
      // BIT_OR
      {Token::Value::BIT_OR, LiteralForTest(4), 1,
       Handle<Smi>(Smi::FromInt(5), isolate),
       BinaryOperationFeedback::kSignedSmall},
      {Token::Value::BIT_OR, LiteralForTest(3.1415), 8,
       Handle<Smi>(Smi::FromInt(11), isolate),
       BinaryOperationFeedback::kNumber},
      {Token::Value::BIT_OR, LiteralForTest(ast_factory.GetOneByteString("2")),
       1, Handle<Smi>(Smi::FromInt(3), isolate), BinaryOperationFeedback::kAny},
      // BIT_AND
      {Token::Value::BIT_AND, LiteralForTest(3), 1,
       Handle<Smi>(Smi::FromInt(1), isolate),
       BinaryOperationFeedback::kSignedSmall},
      {Token::Value::BIT_AND, LiteralForTest(3.1415), 2,
       Handle<Smi>(Smi::FromInt(2), isolate), BinaryOperationFeedback::kNumber},
      {Token::Value::BIT_AND, LiteralForTest(ast_factory.GetOneByteString("2")),
       1, Handle<Smi>(Smi::zero(), isolate), BinaryOperationFeedback::kAny},
      // SHL
      {Token::Value::SHL, LiteralForTest(3), 1,
       Handle<Smi>(Smi::FromInt(6), isolate),
       BinaryOperationFeedback::kSignedSmall},
      {Token::Value::SHL, LiteralForTest(3.1415), 2,
       Handle<Smi>(Smi::FromInt(12), isolate),
       BinaryOperationFeedback::kNumber},
      {Token::Value::SHL, LiteralForTest(ast_factory.GetOneByteString("2")), 1,
       Handle<Smi>(Smi::FromInt(4), isolate), BinaryOperationFeedback::kAny},
      // SAR
      {Token::Value::SAR, LiteralForTest(3), 1,
       Handle<Smi>(Smi::FromInt(1), isolate),
       BinaryOperationFeedback::kSignedSmall},
      {Token::Value::SAR, LiteralForTest(3.1415), 2,
       Handle<Smi>(Smi::zero(), isolate), BinaryOperationFeedback::kNumber},
      {Token::Value::SAR, LiteralForTest(ast_factory.GetOneByteString("2")), 1,
       Handle<Smi>(Smi::FromInt(1), isolate), BinaryOperationFeedback::kAny}};
  ast_factory.Internalize(isolate);

  for (const BinaryOpExpectation& test_case : kTestCases) {
    i::FeedbackVectorSpec feedback_spec(zone);
    BytecodeArrayBuilder builder(zone, 1, 1, &feedback_spec);

    i::FeedbackSlot slot0 = feedback_spec.AddBinaryOpICSlot();

    Handle<i::FeedbackMetadata> metadata =
        i::NewFeedbackMetadata(isolate, &feedback_spec);

    Register reg(0);
    LoadLiteralForTest(&builder, test_case.arg1);
    builder.StoreAccumulatorInRegister(reg)
        .LoadLiteral(Smi::FromInt(test_case.arg2))
        .BinaryOperation(test_case.op, reg, GetIndex(slot0))
        .Return();

    Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

    InterpreterTester tester(isolate, bytecode_array, metadata);
    auto callable = tester.GetCallable<>();

    Handle<Object> return_val = callable().ToHandleChecked();
    MaybeObject feedback0 = callable.vector().Get(slot0);
    CHECK(feedback0->IsSmi());
    CHECK_EQ(test_case.feedback, feedback0->ToSmi().value());
    CHECK(Object::Equals(isolate, test_case.result, return_val).ToChecked());
  }
}

TEST(InterpreterUnaryOpFeedback) {
  HandleAndZoneScope handles;
  i::Isolate* isolate = handles.main_isolate();
  Zone* zone = handles.main_zone();

  Handle<Smi> smi_one = Handle<Smi>(Smi::FromInt(1), isolate);
  Handle<Smi> smi_max = Handle<Smi>(Smi::FromInt(Smi::kMaxValue), isolate);
  Handle<Smi> smi_min = Handle<Smi>(Smi::FromInt(Smi::kMinValue), isolate);
  Handle<HeapNumber> number = isolate->factory()->NewHeapNumber(2.1);
  Handle<BigInt> bigint =
      BigInt::FromNumber(isolate, smi_max).ToHandleChecked();
  Handle<String> str = isolate->factory()->NewStringFromAsciiChecked("42");

  struct TestCase {
    Token::Value op;
    Handle<Smi> smi_feedback_value;
    Handle<Smi> smi_to_number_feedback_value;
    Handle<HeapNumber> number_feedback_value;
    Handle<BigInt> bigint_feedback_value;
    Handle<Object> any_feedback_value;
  };
  TestCase const kTestCases[] = {
      // Testing ADD and BIT_NOT would require generalizing the test setup.
      {Token::Value::SUB, smi_one, smi_min, number, bigint, str},
      {Token::Value::INC, smi_one, smi_max, number, bigint, str},
      {Token::Value::DEC, smi_one, smi_min, number, bigint, str}};
  for (TestCase const& test_case : kTestCases) {
    i::FeedbackVectorSpec feedback_spec(zone);
    BytecodeArrayBuilder builder(zone, 6, 0, &feedback_spec);

    i::FeedbackSlot slot0 = feedback_spec.AddBinaryOpICSlot();
    i::FeedbackSlot slot1 = feedback_spec.AddBinaryOpICSlot();
    i::FeedbackSlot slot2 = feedback_spec.AddBinaryOpICSlot();
    i::FeedbackSlot slot3 = feedback_spec.AddBinaryOpICSlot();
    i::FeedbackSlot slot4 = feedback_spec.AddBinaryOpICSlot();

    Handle<i::FeedbackMetadata> metadata =
        i::NewFeedbackMetadata(isolate, &feedback_spec);

    builder.LoadAccumulatorWithRegister(builder.Parameter(0))
        .UnaryOperation(test_case.op, GetIndex(slot0))
        .LoadAccumulatorWithRegister(builder.Parameter(1))
        .UnaryOperation(test_case.op, GetIndex(slot1))
        .LoadAccumulatorWithRegister(builder.Parameter(2))
        .UnaryOperation(test_case.op, GetIndex(slot2))
        .LoadAccumulatorWithRegister(builder.Parameter(3))
        .UnaryOperation(test_case.op, GetIndex(slot3))
        .LoadAccumulatorWithRegister(builder.Parameter(4))
        .UnaryOperation(test_case.op, GetIndex(slot4))
        .Return();

    Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

    InterpreterTester tester(isolate, bytecode_array, metadata);
    using H = Handle<Object>;
    auto callable = tester.GetCallable<H, H, H, H, H>();

    Handle<Object> return_val =
        callable(test_case.smi_feedback_value,
                 test_case.smi_to_number_feedback_value,
                 test_case.number_feedback_value,
                 test_case.bigint_feedback_value, test_case.any_feedback_value)
            .ToHandleChecked();
    USE(return_val);
    MaybeObject feedback0 = callable.vector().Get(slot0);
    CHECK(feedback0->IsSmi());
    CHECK_EQ(BinaryOperationFeedback::kSignedSmall, feedback0->ToSmi().value());

    MaybeObject feedback1 = callable.vector().Get(slot1);
    CHECK(feedback1->IsSmi());
    CHECK_EQ(BinaryOperationFeedback::kNumber, feedback1->ToSmi().value());

    MaybeObject feedback2 = callable.vector().Get(slot2);
    CHECK(feedback2->IsSmi());
    CHECK_EQ(BinaryOperationFeedback::kNumber, feedback2->ToSmi().value());

    MaybeObject feedback3 = callable.vector().Get(slot3);
    CHECK(feedback3->IsSmi());
    CHECK_EQ(BinaryOperationFeedback::kBigInt, feedback3->ToSmi().value());

    MaybeObject feedback4 = callable.vector().Get(slot4);
    CHECK(feedback4->IsSmi());
    CHECK_EQ(BinaryOperationFeedback::kAny, feedback4->ToSmi().value());
  }
}

TEST(InterpreterBitwiseTypeFeedback) {
  HandleAndZoneScope handles;
  i::Isolate* isolate = handles.main_isolate();
  Zone* zone = handles.main_zone();
  const Token::Value kBitwiseBinaryOperators[] = {
      Token::Value::BIT_OR, Token::Value::BIT_XOR, Token::Value::BIT_AND,
      Token::Value::SHL,    Token::Value::SHR,     Token::Value::SAR};

  for (Token::Value op : kBitwiseBinaryOperators) {
    i::FeedbackVectorSpec feedback_spec(zone);
    BytecodeArrayBuilder builder(zone, 5, 0, &feedback_spec);

    i::FeedbackSlot slot0 = feedback_spec.AddBinaryOpICSlot();
    i::FeedbackSlot slot1 = feedback_spec.AddBinaryOpICSlot();
    i::FeedbackSlot slot2 = feedback_spec.AddBinaryOpICSlot();

    Handle<i::FeedbackMetadata> metadata =
        i::NewFeedbackMetadata(isolate, &feedback_spec);

    builder.LoadAccumulatorWithRegister(builder.Parameter(0))
        .BinaryOperation(op, builder.Parameter(1), GetIndex(slot0))
        .BinaryOperation(op, builder.Parameter(2), GetIndex(slot1))
        .BinaryOperation(op, builder.Parameter(3), GetIndex(slot2))
        .Return();

    Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

    InterpreterTester tester(isolate, bytecode_array, metadata);
    using H = Handle<Object>;
    auto callable = tester.GetCallable<H, H, H, H>();

    Handle<Smi> arg1 = Handle<Smi>(Smi::FromInt(2), isolate);
    Handle<Smi> arg2 = Handle<Smi>(Smi::FromInt(2), isolate);
    Handle<HeapNumber> arg3 = isolate->factory()->NewHeapNumber(2.2);
    Handle<String> arg4 = isolate->factory()->NewStringFromAsciiChecked("2");

    Handle<Object> return_val =
        callable(arg1, arg2, arg3, arg4).ToHandleChecked();
    USE(return_val);
    MaybeObject feedback0 = callable.vector().Get(slot0);
    CHECK(feedback0->IsSmi());
    CHECK_EQ(BinaryOperationFeedback::kSignedSmall, feedback0->ToSmi().value());

    MaybeObject feedback1 = callable.vector().Get(slot1);
    CHECK(feedback1->IsSmi());
    CHECK_EQ(BinaryOperationFeedback::kNumber, feedback1->ToSmi().value());

    MaybeObject feedback2 = callable.vector().Get(slot2);
    CHECK(feedback2->IsSmi());
    CHECK_EQ(BinaryOperationFeedback::kAny, feedback2->ToSmi().value());
  }
}

TEST(InterpreterParameter1Assign) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Zone* zone = handles.main_zone();
  BytecodeArrayBuilder builder(zone, 1, 0);

  builder.LoadLiteral(Smi::FromInt(5))
      .StoreAccumulatorInRegister(builder.Receiver())
      .LoadAccumulatorWithRegister(builder.Receiver())
      .Return();
  Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

  InterpreterTester tester(isolate, bytecode_array);
  auto callable = tester.GetCallableWithReceiver<>();

  Handle<Object> return_val =
      callable(Handle<Smi>(Smi::FromInt(3), handles.main_isolate()))
          .ToHandleChecked();
  CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(5));
}

TEST(InterpreterLoadGlobal) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();

  // Test loading a global.
  std::string source(
      "var global = 321;\n"
      "function " +
      InterpreterTester::function_name() +
      "() {\n"
      "  return global;\n"
      "}");
  InterpreterTester tester(isolate, source.c_str());
  auto callable = tester.GetCallable<>();

  Handle<Object> return_val = callable().ToHandleChecked();
  CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(321));
}

TEST(InterpreterStoreGlobal) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();

  // Test storing to a global.
  std::string source(
      "var global = 321;\n"
      "function " +
      InterpreterTester::function_name() +
      "() {\n"
      "  global = 999;\n"
      "}");
  InterpreterTester tester(isolate, source.c_str());
  auto callable = tester.GetCallable<>();

  callable().ToHandleChecked();
  Handle<i::String> name = factory->InternalizeUtf8String("global");
  Handle<i::Object> global_obj =
      Object::GetProperty(isolate, isolate->global_object(), name)
          .ToHandleChecked();
  CHECK_EQ(Smi::cast(*global_obj), Smi::FromInt(999));
}

TEST(InterpreterCallGlobal) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();

  // Test calling a global function.
  std::string source(
      "function g_add(a, b) { return a + b; }\n"
      "function " +
      InterpreterTester::function_name() +
      "() {\n"
      "  return g_add(5, 10);\n"
      "}");
  InterpreterTester tester(isolate, source.c_str());
  auto callable = tester.GetCallable<>();

  Handle<Object> return_val = callable().ToHandleChecked();
  CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(15));
}

TEST(InterpreterLoadUnallocated) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();

  // Test loading an unallocated global.
  std::string source(
      "unallocated = 123;\n"
      "function " +
      InterpreterTester::function_name() +
      "() {\n"
      "  return unallocated;\n"
      "}");
  InterpreterTester tester(isolate, source.c_str());
  auto callable = tester.GetCallable<>();

  Handle<Object> return_val = callable().ToHandleChecked();
  CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(123));
}

TEST(InterpreterStoreUnallocated) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();

  // Test storing to an unallocated global.
  std::string source(
      "unallocated = 321;\n"
      "function " +
      InterpreterTester::function_name() +
      "() {\n"
      "  unallocated = 999;\n"
      "}");
  InterpreterTester tester(isolate, source.c_str());
  auto callable = tester.GetCallable<>();

  callable().ToHandleChecked();
  Handle<i::String> name = factory->InternalizeUtf8String("unallocated");
  Handle<i::Object> global_obj =
      Object::GetProperty(isolate, isolate->global_object(), name)
          .ToHandleChecked();
  CHECK_EQ(Smi::cast(*global_obj), Smi::FromInt(999));
}

TEST(InterpreterLoadNamedProperty) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Zone* zone = handles.main_zone();
  AstValueFactory ast_factory(zone, isolate->ast_string_constants(),
                              HashSeed(isolate));

  FeedbackVectorSpec feedback_spec(zone);
  FeedbackSlot slot = feedback_spec.AddLoadICSlot();

  Handle<i::FeedbackMetadata> metadata =
      NewFeedbackMetadata(isolate, &feedback_spec);

  const AstRawString* name = ast_factory.GetOneByteString("val");

  BytecodeArrayBuilder builder(zone, 1, 0, &feedback_spec);

  builder.LoadNamedProperty(builder.Receiver(), name, GetIndex(slot)).Return();
  ast_factory.Internalize(isolate);
  Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

  InterpreterTester tester(isolate, bytecode_array, metadata);
  auto callable = tester.GetCallableWithReceiver<>();

  Handle<Object> object = InterpreterTester::NewObject("({ val : 123 })");
  // Test IC miss.
  Handle<Object> return_val = callable(object).ToHandleChecked();
  CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(123));

  // Test transition to monomorphic IC.
  return_val = callable(object).ToHandleChecked();
  CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(123));

  // Test transition to polymorphic IC.
  Handle<Object> object2 =
      InterpreterTester::NewObject("({ val : 456, other : 123 })");
  return_val = callable(object2).ToHandleChecked();
  CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(456));

  // Test transition to megamorphic IC.
  Handle<Object> object3 =
      InterpreterTester::NewObject("({ val : 789, val2 : 123 })");
  callable(object3).ToHandleChecked();
  Handle<Object> object4 =
      InterpreterTester::NewObject("({ val : 789, val3 : 123 })");
  callable(object4).ToHandleChecked();
  Handle<Object> object5 =
      InterpreterTester::NewObject("({ val : 789, val4 : 123 })");
  return_val = callable(object5).ToHandleChecked();
  CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(789));
}

TEST(InterpreterLoadKeyedProperty) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Zone* zone = handles.main_zone();
  AstValueFactory ast_factory(zone, isolate->ast_string_constants(),
                              HashSeed(isolate));

  FeedbackVectorSpec feedback_spec(zone);
  FeedbackSlot slot = feedback_spec.AddKeyedLoadICSlot();

  Handle<i::FeedbackMetadata> metadata =
      NewFeedbackMetadata(isolate, &feedback_spec);

  const AstRawString* key = ast_factory.GetOneByteString("key");

  BytecodeArrayBuilder builder(zone, 1, 1, &feedback_spec);

  builder.LoadLiteral(key)
      .LoadKeyedProperty(builder.Receiver(), GetIndex(slot))
      .Return();
  ast_factory.Internalize(isolate);
  Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

  InterpreterTester tester(isolate, bytecode_array, metadata);
  auto callable = tester.GetCallableWithReceiver<>();

  Handle<Object> object = InterpreterTester::NewObject("({ key : 123 })");
  // Test IC miss.
  Handle<Object> return_val = callable(object).ToHandleChecked();
  CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(123));

  // Test transition to monomorphic IC.
  return_val = callable(object).ToHandleChecked();
  CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(123));

  // Test transition to megamorphic IC.
  Handle<Object> object3 =
      InterpreterTester::NewObject("({ key : 789, val2 : 123 })");
  return_val = callable(object3).ToHandleChecked();
  CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(789));
}

TEST(InterpreterStoreNamedProperty) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Zone* zone = handles.main_zone();
  AstValueFactory ast_factory(zone, isolate->ast_string_constants(),
                              HashSeed(isolate));

  FeedbackVectorSpec feedback_spec(zone);
  FeedbackSlot slot = feedback_spec.AddStoreICSlot(LanguageMode::kStrict);

  Handle<i::FeedbackMetadata> metadata =
      NewFeedbackMetadata(isolate, &feedback_spec);

  const AstRawString* name = ast_factory.GetOneByteString("val");

  BytecodeArrayBuilder builder(zone, 1, 0, &feedback_spec);

  builder.LoadLiteral(Smi::FromInt(999))
      .StoreNamedProperty(builder.Receiver(), name, GetIndex(slot),
                          LanguageMode::kStrict)
      .Return();
  ast_factory.Internalize(isolate);
  Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

  InterpreterTester tester(isolate, bytecode_array, metadata);
  auto callable = tester.GetCallableWithReceiver<>();
  Handle<Object> object = InterpreterTester::NewObject("({ val : 123 })");
  // Test IC miss.
  Handle<Object> result;
  callable(object).ToHandleChecked();
  CHECK(Runtime::GetObjectProperty(isolate, object, name->string())
            .ToHandle(&result));
  CHECK_EQ(Smi::cast(*result), Smi::FromInt(999));

  // Test transition to monomorphic IC.
  callable(object).ToHandleChecked();
  CHECK(Runtime::GetObjectProperty(isolate, object, name->string())
            .ToHandle(&result));
  CHECK_EQ(Smi::cast(*result), Smi::FromInt(999));

  // Test transition to polymorphic IC.
  Handle<Object> object2 =
      InterpreterTester::NewObject("({ val : 456, other : 123 })");
  callable(object2).ToHandleChecked();
  CHECK(Runtime::GetObjectProperty(isolate, object2, name->string())
            .ToHandle(&result));
  CHECK_EQ(Smi::cast(*result), Smi::FromInt(999));

  // Test transition to megamorphic IC.
  Handle<Object> object3 =
      InterpreterTester::NewObject("({ val : 789, val2 : 123 })");
  callable(object3).ToHandleChecked();
  Handle<Object> object4 =
      InterpreterTester::NewObject("({ val : 789, val3 : 123 })");
  callable(object4).ToHandleChecked();
  Handle<Object> object5 =
      InterpreterTester::NewObject("({ val : 789, val4 : 123 })");
  callable(object5).ToHandleChecked();
  CHECK(Runtime::GetObjectProperty(isolate, object5, name->string())
            .ToHandle(&result));
  CHECK_EQ(Smi::cast(*result), Smi::FromInt(999));
}

TEST(InterpreterStoreKeyedProperty) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Zone* zone = handles.main_zone();
  AstValueFactory ast_factory(zone, isolate->ast_string_constants(),
                              HashSeed(isolate));

  FeedbackVectorSpec feedback_spec(zone);
  FeedbackSlot slot = feedback_spec.AddKeyedStoreICSlot(LanguageMode::kSloppy);

  Handle<i::FeedbackMetadata> metadata =
      NewFeedbackMetadata(isolate, &feedback_spec);

  const AstRawString* name = ast_factory.GetOneByteString("val");

  BytecodeArrayBuilder builder(zone, 1, 1, &feedback_spec);

  builder.LoadLiteral(name)
      .StoreAccumulatorInRegister(Register(0))
      .LoadLiteral(Smi::FromInt(999))
      .StoreKeyedProperty(builder.Receiver(), Register(0), GetIndex(slot),
                          i::LanguageMode::kSloppy)
      .Return();
  ast_factory.Internalize(isolate);
  Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

  InterpreterTester tester(isolate, bytecode_array, metadata);
  auto callable = tester.GetCallableWithReceiver<>();
  Handle<Object> object = InterpreterTester::NewObject("({ val : 123 })");
  // Test IC miss.
  Handle<Object> result;
  callable(object).ToHandleChecked();
  CHECK(Runtime::GetObjectProperty(isolate, object, name->string())
            .ToHandle(&result));
  CHECK_EQ(Smi::cast(*result), Smi::FromInt(999));

  // Test transition to monomorphic IC.
  callable(object).ToHandleChecked();
  CHECK(Runtime::GetObjectProperty(isolate, object, name->string())
            .ToHandle(&result));
  CHECK_EQ(Smi::cast(*result), Smi::FromInt(999));

  // Test transition to megamorphic IC.
  Handle<Object> object2 =
      InterpreterTester::NewObject("({ val : 456, other : 123 })");
  callable(object2).ToHandleChecked();
  CHECK(Runtime::GetObjectProperty(isolate, object2, name->string())
            .ToHandle(&result));
  CHECK_EQ(Smi::cast(*result), Smi::FromInt(999));
}

TEST(InterpreterCall) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Zone* zone = handles.main_zone();
  Factory* factory = isolate->factory();

  FeedbackVectorSpec feedback_spec(zone);
  FeedbackSlot slot = feedback_spec.AddLoadICSlot();
  FeedbackSlot call_slot = feedback_spec.AddCallICSlot();

  Handle<i::FeedbackMetadata> metadata =
      NewFeedbackMetadata(isolate, &feedback_spec);
  int slot_index = GetIndex(slot);
  int call_slot_index = -1;
  call_slot_index = GetIndex(call_slot);

  // Check with no args.
  {
    AstValueFactory ast_factory(zone, isolate->ast_string_constants(),
                                HashSeed(isolate));
    const AstRawString* name = ast_factory.GetOneByteString("func");

    BytecodeArrayBuilder builder(zone, 1, 1, &feedback_spec);
    Register reg = builder.register_allocator()->NewRegister();
    RegisterList args = builder.register_allocator()->NewRegisterList(1);
    builder.LoadNamedProperty(builder.Receiver(), name, slot_index)
        .StoreAccumulatorInRegister(reg)
        .MoveRegister(builder.Receiver(), args[0]);

    builder.CallProperty(reg, args, call_slot_index);

    builder.Return();
    ast_factory.Internalize(isolate);
    Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

    InterpreterTester tester(isolate, bytecode_array, metadata);
    auto callable = tester.GetCallableWithReceiver<>();

    Handle<Object> object = InterpreterTester::NewObject(
        "new (function Obj() { this.func = function() { return 0x265; }})()");
    Handle<Object> return_val = callable(object).ToHandleChecked();
    CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(0x265));
  }

  // Check that receiver is passed properly.
  {
    AstValueFactory ast_factory(zone, isolate->ast_string_constants(),
                                HashSeed(isolate));
    const AstRawString* name = ast_factory.GetOneByteString("func");

    BytecodeArrayBuilder builder(zone, 1, 1, &feedback_spec);
    Register reg = builder.register_allocator()->NewRegister();
    RegisterList args = builder.register_allocator()->NewRegisterList(1);
    builder.LoadNamedProperty(builder.Receiver(), name, slot_index)
        .StoreAccumulatorInRegister(reg)
        .MoveRegister(builder.Receiver(), args[0]);
    builder.CallProperty(reg, args, call_slot_index);
    builder.Return();
    ast_factory.Internalize(isolate);
    Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

    InterpreterTester tester(isolate, bytecode_array, metadata);
    auto callable = tester.GetCallableWithReceiver<>();

    Handle<Object> object = InterpreterTester::NewObject(
        "new (function Obj() {"
        "  this.val = 1234;"
        "  this.func = function() { return this.val; };"
        "})()");
    Handle<Object> return_val = callable(object).ToHandleChecked();
    CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(1234));
  }

  // Check with two parameters (+ receiver).
  {
    AstValueFactory ast_factory(zone, isolate->ast_string_constants(),
                                HashSeed(isolate));
    const AstRawString* name = ast_factory.GetOneByteString("func");

    BytecodeArrayBuilder builder(zone, 1, 4, &feedback_spec);
    Register reg = builder.register_allocator()->NewRegister();
    RegisterList args = builder.register_allocator()->NewRegisterList(3);

    builder.LoadNamedProperty(builder.Receiver(), name, slot_index)
        .StoreAccumulatorInRegister(reg)
        .LoadAccumulatorWithRegister(builder.Receiver())
        .StoreAccumulatorInRegister(args[0])
        .LoadLiteral(Smi::FromInt(51))
        .StoreAccumulatorInRegister(args[1])
        .LoadLiteral(Smi::FromInt(11))
        .StoreAccumulatorInRegister(args[2]);

    builder.CallProperty(reg, args, call_slot_index);

    builder.Return();

    ast_factory.Internalize(isolate);
    Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

    InterpreterTester tester(isolate, bytecode_array, metadata);
    auto callable = tester.GetCallableWithReceiver<>();

    Handle<Object> object = InterpreterTester::NewObject(
        "new (function Obj() { "
        "  this.func = function(a, b) { return a - b; }"
        "})()");
    Handle<Object> return_val = callable(object).ToHandleChecked();
    CHECK(return_val->SameValue(Smi::FromInt(40)));
  }

  // Check with 10 parameters (+ receiver).
  {
    AstValueFactory ast_factory(zone, isolate->ast_string_constants(),
                                HashSeed(isolate));
    const AstRawString* name = ast_factory.GetOneByteString("func");

    BytecodeArrayBuilder builder(zone, 1, 12, &feedback_spec);
    Register reg = builder.register_allocator()->NewRegister();
    RegisterList args = builder.register_allocator()->NewRegisterList(11);

    builder.LoadNamedProperty(builder.Receiver(), name, slot_index)
        .StoreAccumulatorInRegister(reg)
        .LoadAccumulatorWithRegister(builder.Receiver())
        .StoreAccumulatorInRegister(args[0])
        .LoadLiteral(ast_factory.GetOneByteString("a"))
        .StoreAccumulatorInRegister(args[1])
        .LoadLiteral(ast_factory.GetOneByteString("b"))
        .StoreAccumulatorInRegister(args[2])
        .LoadLiteral(ast_factory.GetOneByteString("c"))
        .StoreAccumulatorInRegister(args[3])
        .LoadLiteral(ast_factory.GetOneByteString("d"))
        .StoreAccumulatorInRegister(args[4])
        .LoadLiteral(ast_factory.GetOneByteString("e"))
        .StoreAccumulatorInRegister(args[5])
        .LoadLiteral(ast_factory.GetOneByteString("f"))
        .StoreAccumulatorInRegister(args[6])
        .LoadLiteral(ast_factory.GetOneByteString("g"))
        .StoreAccumulatorInRegister(args[7])
        .LoadLiteral(ast_factory.GetOneByteString("h"))
        .StoreAccumulatorInRegister(args[8])
        .LoadLiteral(ast_factory.GetOneByteString("i"))
        .StoreAccumulatorInRegister(args[9])
        .LoadLiteral(ast_factory.GetOneByteString("j"))
        .StoreAccumulatorInRegister(args[10]);

    builder.CallProperty(reg, args, call_slot_index);

    builder.Return();

    ast_factory.Internalize(isolate);
    Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

    InterpreterTester tester(isolate, bytecode_array, metadata);
    auto callable = tester.GetCallableWithReceiver<>();

    Handle<Object> object = InterpreterTester::NewObject(
        "new (function Obj() { "
        "  this.prefix = \"prefix_\";"
        "  this.func = function(a, b, c, d, e, f, g, h, i, j) {"
        "      return this.prefix + a + b + c + d + e + f + g + h + i + j;"
        "  }"
        "})()");
    Handle<Object> return_val = callable(object).ToHandleChecked();
    Handle<i::String> expected =
        factory->NewStringFromAsciiChecked("prefix_abcdefghij");
    CHECK(i::String::cast(*return_val).Equals(*expected));
  }
}

static BytecodeArrayBuilder& SetRegister(BytecodeArrayBuilder* builder,
                                         Register reg, int value,
                                         Register scratch) {
  return builder->StoreAccumulatorInRegister(scratch)
      .LoadLiteral(Smi::FromInt(value))
      .StoreAccumulatorInRegister(reg)
      .LoadAccumulatorWithRegister(scratch);
}

static BytecodeArrayBuilder& IncrementRegister(BytecodeArrayBuilder* builder,
                                               Register reg, int value,
                                               Register scratch,
                                               int slot_index) {
  return builder->StoreAccumulatorInRegister(scratch)
      .LoadLiteral(Smi::FromInt(value))
      .BinaryOperation(Token::Value::ADD, reg, slot_index)
      .StoreAccumulatorInRegister(reg)
      .LoadAccumulatorWithRegister(scratch);
}

TEST(InterpreterJumps) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Zone* zone = handles.main_zone();
  FeedbackVectorSpec feedback_spec(zone);
  BytecodeArrayBuilder builder(zone, 1, 2, &feedback_spec);

  FeedbackSlot slot = feedback_spec.AddBinaryOpICSlot();
  FeedbackSlot slot1 = feedback_spec.AddBinaryOpICSlot();
  FeedbackSlot slot2 = feedback_spec.AddBinaryOpICSlot();

  Handle<i::FeedbackMetadata> metadata =
      NewFeedbackMetadata(isolate, &feedback_spec);

  Register reg(0), scratch(1);
  BytecodeLoopHeader loop_header;
  BytecodeLabel label[2];

  builder.LoadLiteral(Smi::zero())
      .StoreAccumulatorInRegister(reg)
      .Jump(&label[0]);
  SetRegister(&builder, reg, 1024, scratch).Bind(&loop_header);
  IncrementRegister(&builder, reg, 1, scratch, GetIndex(slot)).Jump(&label[1]);
  SetRegister(&builder, reg, 2048, scratch).Bind(&label[0]);
  IncrementRegister(&builder, reg, 2, scratch, GetIndex(slot1))
      .JumpLoop(&loop_header, 0, 0);
  SetRegister(&builder, reg, 4096, scratch).Bind(&label[1]);
  IncrementRegister(&builder, reg, 4, scratch, GetIndex(slot2))
      .LoadAccumulatorWithRegister(reg)
      .Return();

  Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);
  InterpreterTester tester(isolate, bytecode_array, metadata);
  auto callable = tester.GetCallable<>();
  Handle<Object> return_value = callable().ToHandleChecked();
  CHECK_EQ(Smi::ToInt(*return_value), 7);
}

TEST(InterpreterConditionalJumps) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Zone* zone = handles.main_zone();
  FeedbackVectorSpec feedback_spec(zone);
  BytecodeArrayBuilder builder(zone, 1, 2, &feedback_spec);

  FeedbackSlot slot = feedback_spec.AddBinaryOpICSlot();
  FeedbackSlot slot1 = feedback_spec.AddBinaryOpICSlot();
  FeedbackSlot slot2 = feedback_spec.AddBinaryOpICSlot();
  FeedbackSlot slot3 = feedback_spec.AddBinaryOpICSlot();
  FeedbackSlot slot4 = feedback_spec.AddBinaryOpICSlot();

  Handle<i::FeedbackMetadata> metadata =
      NewFeedbackMetadata(isolate, &feedback_spec);

  Register reg(0), scratch(1);
  BytecodeLabel label[2];
  BytecodeLabel done, done1;

  builder.LoadLiteral(Smi::zero())
      .StoreAccumulatorInRegister(reg)
      .LoadFalse()
      .JumpIfFalse(ToBooleanMode::kAlreadyBoolean, &label[0]);
  IncrementRegister(&builder, reg, 1024, scratch, GetIndex(slot))
      .Bind(&label[0])
      .LoadTrue()
      .JumpIfFalse(ToBooleanMode::kAlreadyBoolean, &done);
  IncrementRegister(&builder, reg, 1, scratch, GetIndex(slot1))
      .LoadTrue()
      .JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &label[1]);
  IncrementRegister(&builder, reg, 2048, scratch, GetIndex(slot2))
      .Bind(&label[1]);
  IncrementRegister(&builder, reg, 2, scratch, GetIndex(slot3))
      .LoadFalse()
      .JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &done1);
  IncrementRegister(&builder, reg, 4, scratch, GetIndex(slot4))
      .LoadAccumulatorWithRegister(reg)
      .Bind(&done)
      .Bind(&done1)
      .Return();

  Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);
  InterpreterTester tester(isolate, bytecode_array, metadata);
  auto callable = tester.GetCallable<>();
  Handle<Object> return_value = callable().ToHandleChecked();
  CHECK_EQ(Smi::ToInt(*return_value), 7);
}

TEST(InterpreterConditionalJumps2) {
  // TODO(oth): Add tests for all conditional jumps near and far.
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Zone* zone = handles.main_zone();
  FeedbackVectorSpec feedback_spec(zone);
  BytecodeArrayBuilder builder(zone, 1, 2, &feedback_spec);

  FeedbackSlot slot = feedback_spec.AddBinaryOpICSlot();
  FeedbackSlot slot1 = feedback_spec.AddBinaryOpICSlot();
  FeedbackSlot slot2 = feedback_spec.AddBinaryOpICSlot();
  FeedbackSlot slot3 = feedback_spec.AddBinaryOpICSlot();
  FeedbackSlot slot4 = feedback_spec.AddBinaryOpICSlot();

  Handle<i::FeedbackMetadata> metadata =
      NewFeedbackMetadata(isolate, &feedback_spec);

  Register reg(0), scratch(1);
  BytecodeLabel label[2];
  BytecodeLabel done, done1;

  builder.LoadLiteral(Smi::zero())
      .StoreAccumulatorInRegister(reg)
      .LoadFalse()
      .JumpIfFalse(ToBooleanMode::kAlreadyBoolean, &label[0]);
  IncrementRegister(&builder, reg, 1024, scratch, GetIndex(slot))
      .Bind(&label[0])
      .LoadTrue()
      .JumpIfFalse(ToBooleanMode::kAlreadyBoolean, &done);
  IncrementRegister(&builder, reg, 1, scratch, GetIndex(slot1))
      .LoadTrue()
      .JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &label[1]);
  IncrementRegister(&builder, reg, 2048, scratch, GetIndex(slot2))
      .Bind(&label[1]);
  IncrementRegister(&builder, reg, 2, scratch, GetIndex(slot3))
      .LoadFalse()
      .JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &done1);
  IncrementRegister(&builder, reg, 4, scratch, GetIndex(slot4))
      .LoadAccumulatorWithRegister(reg)
      .Bind(&done)
      .Bind(&done1)
      .Return();

  Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);
  InterpreterTester tester(isolate, bytecode_array, metadata);
  auto callable = tester.GetCallable<>();
  Handle<Object> return_value = callable().ToHandleChecked();
  CHECK_EQ(Smi::ToInt(*return_value), 7);
}

TEST(InterpreterJumpConstantWith16BitOperand) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Zone* zone = handles.main_zone();
  AstValueFactory ast_factory(zone, isolate->ast_string_constants(),
                              HashSeed(isolate));
  FeedbackVectorSpec feedback_spec(zone);
  BytecodeArrayBuilder builder(zone, 1, 257, &feedback_spec);

  FeedbackSlot slot = feedback_spec.AddBinaryOpICSlot();
  Handle<i::FeedbackMetadata> metadata =
      NewFeedbackMetadata(isolate, &feedback_spec);

  Register reg(0), scratch(256);
  BytecodeLabel done, fake;

  builder.LoadLiteral(Smi::zero());
  builder.StoreAccumulatorInRegister(reg);
  // Conditional jump to the fake label, to force both basic blocks to be live.
  builder.JumpIfTrue(ToBooleanMode::kConvertToBoolean, &fake);
  // Consume all 8-bit operands
  for (int i = 1; i <= 256; i++) {
    builder.LoadLiteral(i + 0.5);
    builder.BinaryOperation(Token::Value::ADD, reg, GetIndex(slot));
    builder.StoreAccumulatorInRegister(reg);
  }
  builder.Jump(&done);

  // Emit more than 16-bit immediate operands worth of code to jump over.
  builder.Bind(&fake);
  for (int i = 0; i < 6600; i++) {
    builder.LoadLiteral(Smi::zero());  // 1-byte
    builder.BinaryOperation(Token::Value::ADD, scratch,
                            GetIndex(slot));      // 6-bytes
    builder.StoreAccumulatorInRegister(scratch);  // 4-bytes
    builder.MoveRegister(scratch, reg);           // 6-bytes
  }
  builder.Bind(&done);
  builder.LoadAccumulatorWithRegister(reg);
  builder.Return();

  ast_factory.Internalize(isolate);
  Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);
  BytecodeArrayIterator iterator(bytecode_array);

  bool found_16bit_constant_jump = false;
  while (!iterator.done()) {
    if (iterator.current_bytecode() == Bytecode::kJumpConstant &&
        iterator.current_operand_scale() == OperandScale::kDouble) {
      found_16bit_constant_jump = true;
      break;
    }
    iterator.Advance();
  }
  CHECK(found_16bit_constant_jump);

  InterpreterTester tester(isolate, bytecode_array, metadata);
  auto callable = tester.GetCallable<>();
  Handle<Object> return_value = callable().ToHandleChecked();
  CHECK_EQ(Handle<HeapNumber>::cast(return_value)->value(),
           256.0 / 2 * (1.5 + 256.5));
}

TEST(InterpreterJumpWith32BitOperand) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Zone* zone = handles.main_zone();
  AstValueFactory ast_factory(zone, isolate->ast_string_constants(),
                              HashSeed(isolate));
  BytecodeArrayBuilder builder(zone, 1, 1);
  Register reg(0);
  BytecodeLabel done;

  builder.LoadLiteral(Smi::zero());
  builder.StoreAccumulatorInRegister(reg);
  // Consume all 16-bit constant pool entries. Make sure to use doubles so that
  // the jump can't re-use an integer.
  for (int i = 1; i <= 65536; i++) {
    builder.LoadLiteral(i + 0.5);
  }
  builder.Jump(&done);
  builder.LoadLiteral(Smi::zero());
  builder.Bind(&done);
  builder.Return();

  ast_factory.Internalize(isolate);
  Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

  BytecodeArrayIterator iterator(bytecode_array);

  bool found_32bit_jump = false;
  while (!iterator.done()) {
    if (iterator.current_bytecode() == Bytecode::kJump &&
        iterator.current_operand_scale() == OperandScale::kQuadruple) {
      found_32bit_jump = true;
      break;
    }
    iterator.Advance();
  }
  CHECK(found_32bit_jump);

  InterpreterTester tester(isolate, bytecode_array);
  auto callable = tester.GetCallable<>();
  Handle<Object> return_value = callable().ToHandleChecked();
  CHECK_EQ(Handle<HeapNumber>::cast(return_value)->value(), 65536.5);
}

static const Token::Value kComparisonTypes[] = {
    Token::Value::EQ,  Token::Value::EQ_STRICT, Token::Value::LT,
    Token::Value::LTE, Token::Value::GT,        Token::Value::GTE};

template <typename T>
bool CompareC(Token::Value op, T lhs, T rhs, bool types_differed = false) {
  switch (op) {
    case Token::Value::EQ:
      return lhs == rhs;
    case Token::Value::NE:
      return lhs != rhs;
    case Token::Value::EQ_STRICT:
      return (lhs == rhs) && !types_differed;
    case Token::Value::NE_STRICT:
      return (lhs != rhs) || types_differed;
    case Token::Value::LT:
      return lhs < rhs;
    case Token::Value::LTE:
      return lhs <= rhs;
    case Token::Value::GT:
      return lhs > rhs;
    case Token::Value::GTE:
      return lhs >= rhs;
    default:
      UNREACHABLE();
  }
}

TEST(InterpreterSmiComparisons) {
  // NB Constants cover 31-bit space.
  int inputs[] = {v8::internal::kMinInt / 2,
                  v8::internal::kMinInt / 4,
                  -108733832,
                  -999,
                  -42,
                  -2,
                  -1,
                  0,
                  +1,
                  +2,
                  42,
                  12345678,
                  v8::internal::kMaxInt / 4,
                  v8::internal::kMaxInt / 2};

  for (size_t c = 0; c < arraysize(kComparisonTypes); c++) {
    Token::Value comparison = kComparisonTypes[c];
    for (size_t i = 0; i < arraysize(inputs); i++) {
      for (size_t j = 0; j < arraysize(inputs); j++) {
        HandleAndZoneScope handles;
        Isolate* isolate = handles.main_isolate();
        Zone* zone = handles.main_zone();
        FeedbackVectorSpec feedback_spec(zone);
        BytecodeArrayBuilder builder(zone, 1, 1, &feedback_spec);

        FeedbackSlot slot = feedback_spec.AddCompareICSlot();
        Handle<i::FeedbackMetadata> metadata =
            NewFeedbackMetadata(isolate, &feedback_spec);

        Register r0(0);
        builder.LoadLiteral(Smi::FromInt(inputs[i]))
            .StoreAccumulatorInRegister(r0)
            .LoadLiteral(Smi::FromInt(inputs[j]))
            .CompareOperation(comparison, r0, GetIndex(slot))
            .Return();

        Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);
        InterpreterTester tester(isolate, bytecode_array, metadata);
        auto callable = tester.GetCallable<>();
        Handle<Object> return_value = callable().ToHandleChecked();
        CHECK(return_value->IsBoolean());
        CHECK_EQ(return_value->BooleanValue(isolate),
                 CompareC(comparison, inputs[i], inputs[j]));
        if (tester.HasFeedbackMetadata()) {
          MaybeObject feedback = callable.vector().Get(slot);
          CHECK(feedback->IsSmi());
          CHECK_EQ(CompareOperationFeedback::kSignedSmall,
                   feedback->ToSmi().value());
        }
      }
    }
  }
}

TEST(InterpreterHeapNumberComparisons) {
  double inputs[] = {std::numeric_limits<double>::min(),
                     std::numeric_limits<double>::max(),
                     -0.001,
                     0.01,
                     0.1000001,
                     1e99,
                     -1e-99};
  for (size_t c = 0; c < arraysize(kComparisonTypes); c++) {
    Token::Value comparison = kComparisonTypes[c];
    for (size_t i = 0; i < arraysize(inputs); i++) {
      for (size_t j = 0; j < arraysize(inputs); j++) {
        HandleAndZoneScope handles;
        Isolate* isolate = handles.main_isolate();
        Zone* zone = handles.main_zone();
        AstValueFactory ast_factory(zone, isolate->ast_string_constants(),
                                    HashSeed(isolate));

        FeedbackVectorSpec feedback_spec(zone);
        BytecodeArrayBuilder builder(zone, 1, 1, &feedback_spec);

        FeedbackSlot slot = feedback_spec.AddCompareICSlot();
        Handle<i::FeedbackMetadata> metadata =
            NewFeedbackMetadata(isolate, &feedback_spec);

        Register r0(0);
        builder.LoadLiteral(inputs[i])
            .StoreAccumulatorInRegister(r0)
            .LoadLiteral(inputs[j])
            .CompareOperation(comparison, r0, GetIndex(slot))
            .Return();

        ast_factory.Internalize(isolate);
        Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);
        InterpreterTester tester(isolate, bytecode_array, metadata);
        auto callable = tester.GetCallable<>();
        Handle<Object> return_value = callable().ToHandleChecked();
        CHECK(return_value->IsBoolean());
        CHECK_EQ(return_value->BooleanValue(isolate),
                 CompareC(comparison, inputs[i], inputs[j]));
        if (tester.HasFeedbackMetadata()) {
          MaybeObject feedback = callable.vector().Get(slot);
          CHECK(feedback->IsSmi());
          CHECK_EQ(CompareOperationFeedback::kNumber,
                   feedback->ToSmi().value());
        }
      }
    }
  }
}

TEST(InterpreterBigIntComparisons) {
  // This test only checks that the recorded type feedback is kBigInt.
  AstBigInt inputs[] = {AstBigInt("0"), AstBigInt("-42"),
                        AstBigInt("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")};
  for (size_t c = 0; c < arraysize(kComparisonTypes); c++) {
    Token::Value comparison = kComparisonTypes[c];
    for (size_t i = 0; i < arraysize(inputs); i++) {
      for (size_t j = 0; j < arraysize(inputs); j++) {
        HandleAndZoneScope handles;
        Isolate* isolate = handles.main_isolate();
        Zone* zone = handles.main_zone();
        AstValueFactory ast_factory(zone, isolate->ast_string_constants(),
                                    HashSeed(isolate));

        FeedbackVectorSpec feedback_spec(zone);
        BytecodeArrayBuilder builder(zone, 1, 1, &feedback_spec);

        FeedbackSlot slot = feedback_spec.AddCompareICSlot();
        Handle<i::FeedbackMetadata> metadata =
            NewFeedbackMetadata(isolate, &feedback_spec);

        Register r0(0);
        builder.LoadLiteral(inputs[i])
            .StoreAccumulatorInRegister(r0)
            .LoadLiteral(inputs[j])
            .CompareOperation(comparison, r0, GetIndex(slot))
            .Return();

        ast_factory.Internalize(isolate);
        Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);
        InterpreterTester tester(isolate, bytecode_array, metadata);
        auto callable = tester.GetCallable<>();
        Handle<Object> return_value = callable().ToHandleChecked();
        CHECK(return_value->IsBoolean());
        if (tester.HasFeedbackMetadata()) {
          MaybeObject feedback = callable.vector().Get(slot);
          CHECK(feedback->IsSmi());
          CHECK_EQ(CompareOperationFeedback::kBigInt,
                   feedback->ToSmi().value());
        }
      }
    }
  }
}

TEST(InterpreterStringComparisons) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Zone* zone = handles.main_zone();

  std::string inputs[] = {"A", "abc", "z", "", "Foo!", "Foo"};

  for (size_t c = 0; c < arraysize(kComparisonTypes); c++) {
    Token::Value comparison = kComparisonTypes[c];
    for (size_t i = 0; i < arraysize(inputs); i++) {
      for (size_t j = 0; j < arraysize(inputs); j++) {
        AstValueFactory ast_factory(zone, isolate->ast_string_constants(),
                                    HashSeed(isolate));

        CanonicalHandleScope canonical(isolate);
        const char* lhs = inputs[i].c_str();
        const char* rhs = inputs[j].c_str();

        FeedbackVectorSpec feedback_spec(zone);
        FeedbackSlot slot = feedback_spec.AddCompareICSlot();
        Handle<i::FeedbackMetadata> metadata =
            NewFeedbackMetadata(isolate, &feedback_spec);

        BytecodeArrayBuilder builder(zone, 1, 1, &feedback_spec);
        Register r0(0);
        builder.LoadLiteral(ast_factory.GetOneByteString(lhs))
            .StoreAccumulatorInRegister(r0)
            .LoadLiteral(ast_factory.GetOneByteString(rhs))
            .CompareOperation(comparison, r0, GetIndex(slot))
            .Return();

        ast_factory.Internalize(isolate);
        Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);
        InterpreterTester tester(isolate, bytecode_array, metadata);
        auto callable = tester.GetCallable<>();
        Handle<Object> return_value = callable().ToHandleChecked();
        CHECK(return_value->IsBoolean());
        CHECK_EQ(return_value->BooleanValue(isolate),
                 CompareC(comparison, inputs[i], inputs[j]));
        if (tester.HasFeedbackMetadata()) {
          MaybeObject feedback = callable.vector().Get(slot);
          CHECK(feedback->IsSmi());
          int const expected_feedback =
              Token::IsOrderedRelationalCompareOp(comparison)
                  ? CompareOperationFeedback::kString
                  : CompareOperationFeedback::kInternalizedString;
          CHECK_EQ(expected_feedback, feedback->ToSmi().value());
        }
      }
    }
  }
}

static void LoadStringAndAddSpace(BytecodeArrayBuilder* builder,
                                  AstValueFactory* ast_factory,
                                  const char* cstr,
                                  FeedbackSlot string_add_slot) {
  Register string_reg = builder->register_allocator()->NewRegister();

  (*builder)
      .LoadLiteral(ast_factory->GetOneByteString(cstr))
      .StoreAccumulatorInRegister(string_reg)
      .LoadLiteral(ast_factory->GetOneByteString(" "))
      .BinaryOperation(Token::Value::ADD, string_reg,
                       GetIndex(string_add_slot));
}

TEST(InterpreterMixedComparisons) {
  // This test compares a HeapNumber with a String. The latter is
  // convertible to a HeapNumber so comparison will be between numeric
  // values except for the strict comparisons where no conversion is
  // performed.
  const char* inputs[] = {"-1.77", "-40.333", "0.01", "55.77e50", "2.01"};

  enum WhichSideString { kLhsIsString, kRhsIsString };

  enum StringType { kInternalizedStringConstant, kComputedString };

  for (size_t c = 0; c < arraysize(kComparisonTypes); c++) {
    Token::Value comparison = kComparisonTypes[c];
    for (size_t i = 0; i < arraysize(inputs); i++) {
      for (size_t j = 0; j < arraysize(inputs); j++) {
        // We test the case where either the lhs or the rhs is a string...
        for (WhichSideString which_side : {kLhsIsString, kRhsIsString}) {
          // ... and the case when the string is internalized or computed.
          for (StringType string_type :
               {kInternalizedStringConstant, kComputedString}) {
            const char* lhs_cstr = inputs[i];
            const char* rhs_cstr = inputs[j];
            double lhs = StringToDouble(lhs_cstr, ConversionFlags::NO_FLAGS);
            double rhs = StringToDouble(rhs_cstr, ConversionFlags::NO_FLAGS);
            HandleAndZoneScope handles;
            Isolate* isolate = handles.main_isolate();
            Zone* zone = handles.main_zone();
            AstValueFactory ast_factory(zone, isolate->ast_string_constants(),
                                        HashSeed(isolate));
            FeedbackVectorSpec feedback_spec(zone);
            BytecodeArrayBuilder builder(zone, 1, 0, &feedback_spec);

            FeedbackSlot string_add_slot = feedback_spec.AddBinaryOpICSlot();
            FeedbackSlot slot = feedback_spec.AddCompareICSlot();
            Handle<i::FeedbackMetadata> metadata =
                NewFeedbackMetadata(isolate, &feedback_spec);

            // lhs is in a register, rhs is in the accumulator.
            Register lhs_reg = builder.register_allocator()->NewRegister();

            if (which_side == kRhsIsString) {
              // Comparison with HeapNumber on the lhs and String on the rhs.

              builder.LoadLiteral(lhs).StoreAccumulatorInRegister(lhs_reg);

              if (string_type == kInternalizedStringConstant) {
                // rhs string is internalized.
                builder.LoadLiteral(ast_factory.GetOneByteString(rhs_cstr));
              } else {
                CHECK_EQ(string_type, kComputedString);
                // rhs string is not internalized (append a space to the end).
                LoadStringAndAddSpace(&builder, &ast_factory, rhs_cstr,
                                      string_add_slot);
              }
            } else {
              CHECK_EQ(which_side, kLhsIsString);
              // Comparison with String on the lhs and HeapNumber on the rhs.

              if (string_type == kInternalizedStringConstant) {
                // lhs string is internalized
                builder.LoadLiteral(ast_factory.GetOneByteString(lhs_cstr));
              } else {
                CHECK_EQ(string_type, kComputedString);
                // lhs string is not internalized (append a space to the end).
                LoadStringAndAddSpace(&builder, &ast_factory, lhs_cstr,
                                      string_add_slot);
              }
              builder.StoreAccumulatorInRegister(lhs_reg);

              builder.LoadLiteral(rhs);
            }

            builder.CompareOperation(comparison, lhs_reg, GetIndex(slot))
                .Return();

            ast_factory.Internalize(isolate);
            Handle<BytecodeArray> bytecode_array =
                builder.ToBytecodeArray(isolate);
            InterpreterTester tester(isolate, bytecode_array, metadata);
            auto callable = tester.GetCallable<>();
            Handle<Object> return_value = callable().ToHandleChecked();
            CHECK(return_value->IsBoolean());
            CHECK_EQ(return_value->BooleanValue(isolate),
                     CompareC(comparison, lhs, rhs, true));
            if (tester.HasFeedbackMetadata()) {
              MaybeObject feedback = callable.vector().Get(slot);
              CHECK(feedback->IsSmi());
              if (kComparisonTypes[c] == Token::Value::EQ) {
                // For sloppy equality, we have more precise feedback.
                CHECK_EQ(
                    CompareOperationFeedback::kNumber |
                        (string_type == kInternalizedStringConstant
                             ? CompareOperationFeedback::kInternalizedString
                             : CompareOperationFeedback::kString),
                    feedback->ToSmi().value());
              } else {
                // Comparison with a number and string collects kAny feedback.
                CHECK_EQ(CompareOperationFeedback::kAny,
                         feedback->ToSmi().value());
              }
            }
          }
        }
      }
    }
  }
}

TEST(InterpreterStrictNotEqual) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();
  const char* code_snippet =
      "function f(lhs, rhs) {\n"
      "  return lhs !== rhs;\n"
      "}\n"
      "f(0, 0);\n";
  InterpreterTester tester(isolate, code_snippet);
  auto callable = tester.GetCallable<Handle<Object>, Handle<Object>>();

  // Test passing different types.
  const char* inputs[] = {"-1.77", "-40.333", "0.01", "55.77e5", "2.01"};
  for (size_t i = 0; i < arraysize(inputs); i++) {
    for (size_t j = 0; j < arraysize(inputs); j++) {
      double lhs = StringToDouble(inputs[i], ConversionFlags::NO_FLAGS);
      double rhs = StringToDouble(inputs[j], ConversionFlags::NO_FLAGS);
      Handle<Object> lhs_obj = factory->NewNumber(lhs);
      Handle<Object> rhs_obj = factory->NewStringFromAsciiChecked(inputs[j]);

      Handle<Object> return_value =
          callable(lhs_obj, rhs_obj).ToHandleChecked();
      CHECK(return_value->IsBoolean());
      CHECK_EQ(return_value->BooleanValue(isolate),
               CompareC(Token::Value::NE_STRICT, lhs, rhs, true));
    }
  }

  // Test passing string types.
  const char* inputs_str[] = {"A", "abc", "z", "", "Foo!", "Foo"};
  for (size_t i = 0; i < arraysize(inputs_str); i++) {
    for (size_t j = 0; j < arraysize(inputs_str); j++) {
      Handle<Object> lhs_obj =
          factory->NewStringFromAsciiChecked(inputs_str[i]);
      Handle<Object> rhs_obj =
          factory->NewStringFromAsciiChecked(inputs_str[j]);

      Handle<Object> return_value =
          callable(lhs_obj, rhs_obj).ToHandleChecked();
      CHECK(return_value->IsBoolean());
      CHECK_EQ(return_value->BooleanValue(isolate),
               CompareC(Token::Value::NE_STRICT, inputs_str[i], inputs_str[j]));
    }
  }

  // Test passing doubles.
  double inputs_number[] = {std::numeric_limits<double>::min(),
                            std::numeric_limits<double>::max(),
                            -0.001,
                            0.01,
                            0.1000001,
                            1e99,
                            -1e-99};
  for (size_t i = 0; i < arraysize(inputs_number); i++) {
    for (size_t j = 0; j < arraysize(inputs_number); j++) {
      Handle<Object> lhs_obj = factory->NewNumber(inputs_number[i]);
      Handle<Object> rhs_obj = factory->NewNumber(inputs_number[j]);

      Handle<Object> return_value =
          callable(lhs_obj, rhs_obj).ToHandleChecked();
      CHECK(return_value->IsBoolean());
      CHECK_EQ(return_value->BooleanValue(isolate),
               CompareC(Token::Value::NE_STRICT, inputs_number[i],
                        inputs_number[j]));
    }
  }
}

TEST(InterpreterCompareTypeOf) {
  using LiteralFlag = TestTypeOfFlags::LiteralFlag;
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();
  Zone* zone = handles.main_zone();
  std::pair<Handle<Object>, LiteralFlag> inputs[] = {
      {handle(Smi::FromInt(24), isolate), LiteralFlag::kNumber},
      {factory->NewNumber(2.5), LiteralFlag::kNumber},
      {factory->NewStringFromAsciiChecked("foo"), LiteralFlag::kString},
      {factory
           ->NewConsString(factory->NewStringFromAsciiChecked("foo"),
                           factory->NewStringFromAsciiChecked("bar"))
           .ToHandleChecked(),
       LiteralFlag::kString},
      {factory->prototype_string(), LiteralFlag::kString},
      {factory->NewSymbol(), LiteralFlag::kSymbol},
      {factory->true_value(), LiteralFlag::kBoolean},
      {factory->false_value(), LiteralFlag::kBoolean},
      {factory->undefined_value(), LiteralFlag::kUndefined},
      {InterpreterTester::NewObject(
           "(function() { return function() {}; })();"),
       LiteralFlag::kFunction},
      {InterpreterTester::NewObject("new Object();"), LiteralFlag::kObject},
      {factory->null_value(), LiteralFlag::kObject},
  };
  const LiteralFlag kLiterals[] = {
#define LITERAL_FLAG(name, _) LiteralFlag::k##name,
      TYPEOF_LITERAL_LIST(LITERAL_FLAG)
#undef LITERAL_FLAG
  };

  for (size_t l = 0; l < arraysize(kLiterals); l++) {
    LiteralFlag literal_flag = kLiterals[l];
    if (literal_flag == LiteralFlag::kOther) continue;

    BytecodeArrayBuilder builder(zone, 2, 0);
    builder.LoadAccumulatorWithRegister(builder.Parameter(0))
        .CompareTypeOf(kLiterals[l])
        .Return();
    Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);
    InterpreterTester tester(isolate, bytecode_array);
    auto callable = tester.GetCallable<Handle<Object>>();

    for (size_t i = 0; i < arraysize(inputs); i++) {
      Handle<Object> return_value = callable(inputs[i].first).ToHandleChecked();
      CHECK(return_value->IsBoolean());
      CHECK_EQ(return_value->BooleanValue(isolate),
               inputs[i].second == literal_flag);
    }
  }
}

TEST(InterpreterInstanceOf) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Zone* zone = handles.main_zone();
  Factory* factory = isolate->factory();
  Handle<i::String> name = factory->NewStringFromAsciiChecked("cons");
  Handle<i::JSFunction> func = factory->NewFunctionForTest(name);
  Handle<i::JSObject> instance = factory->NewJSObject(func);
  Handle<i::Object> other = factory->NewNumber(3.3333);
  Handle<i::Object> cases[] = {Handle<i::Object>::cast(instance), other};
  for (size_t i = 0; i < arraysize(cases); i++) {
    bool expected_value = (i == 0);
    FeedbackVectorSpec feedback_spec(zone);
    BytecodeArrayBuilder builder(zone, 1, 1, &feedback_spec);

    Register r0(0);
    size_t case_entry = builder.AllocateDeferredConstantPoolEntry();
    builder.SetDeferredConstantPoolEntry(case_entry, cases[i]);
    builder.LoadConstantPoolEntry(case_entry).StoreAccumulatorInRegister(r0);

    FeedbackSlot slot = feedback_spec.AddInstanceOfSlot();
    Handle<i::FeedbackMetadata> metadata =
        NewFeedbackMetadata(isolate, &feedback_spec);

    size_t func_entry = builder.AllocateDeferredConstantPoolEntry();
    builder.SetDeferredConstantPoolEntry(func_entry, func);
    builder.LoadConstantPoolEntry(func_entry)
        .CompareOperation(Token::Value::INSTANCEOF, r0, GetIndex(slot))
        .Return();

    Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);
    InterpreterTester tester(isolate, bytecode_array, metadata);
    auto callable = tester.GetCallable<>();
    Handle<Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->IsBoolean());
    CHECK_EQ(return_value->BooleanValue(isolate), expected_value);
  }
}

TEST(InterpreterTestIn) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Zone* zone = handles.main_zone();
  Factory* factory = isolate->factory();
  // Allocate an array
  Handle<i::JSArray> array =
      factory->NewJSArray(0, i::ElementsKind::PACKED_SMI_ELEMENTS);
  // Check for these properties on the array object
  const char* properties[] = {"length", "fuzzle", "x", "0"};
  for (size_t i = 0; i < arraysize(properties); i++) {
    AstValueFactory ast_factory(zone, isolate->ast_string_constants(),
                                HashSeed(isolate));

    bool expected_value = (i == 0);
    FeedbackVectorSpec feedback_spec(zone);
    BytecodeArrayBuilder builder(zone, 1, 1, &feedback_spec);

    Register r0(0);
    builder.LoadLiteral(ast_factory.GetOneByteString(properties[i]))
        .StoreAccumulatorInRegister(r0);

    FeedbackSlot slot = feedback_spec.AddKeyedHasICSlot();
    Handle<i::FeedbackMetadata> metadata =
        NewFeedbackMetadata(isolate, &feedback_spec);

    size_t array_entry = builder.AllocateDeferredConstantPoolEntry();
    builder.SetDeferredConstantPoolEntry(array_entry, array);
    builder.LoadConstantPoolEntry(array_entry)
        .CompareOperation(Token::Value::IN, r0, GetIndex(slot))
        .Return();

    ast_factory.Internalize(isolate);
    Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);
    InterpreterTester tester(isolate, bytecode_array, metadata);
    auto callable = tester.GetCallable<>();
    Handle<Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->IsBoolean());
    CHECK_EQ(return_value->BooleanValue(isolate), expected_value);
  }
}

TEST(InterpreterUnaryNot) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Zone* zone = handles.main_zone();
  for (size_t i = 1; i < 10; i++) {
    bool expected_value = ((i & 1) == 1);
    BytecodeArrayBuilder builder(zone, 1, 0);

    Register r0(0);
    builder.LoadFalse();
    for (size_t j = 0; j < i; j++) {
      builder.LogicalNot(ToBooleanMode::kAlreadyBoolean);
    }
    builder.Return();
    Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);
    InterpreterTester tester(isolate, bytecode_array);
    auto callable = tester.GetCallable<>();
    Handle<Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->IsBoolean());
    CHECK_EQ(return_value->BooleanValue(isolate), expected_value);
  }
}

TEST(InterpreterUnaryNotNonBoolean) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Zone* zone = handles.main_zone();
  AstValueFactory ast_factory(zone, isolate->ast_string_constants(),
                              HashSeed(isolate));

  std::pair<LiteralForTest, bool> object_type_tuples[] = {
      std::make_pair(LiteralForTest(LiteralForTest::kUndefined), true),
      std::make_pair(LiteralForTest(LiteralForTest::kNull), true),
      std::make_pair(LiteralForTest(LiteralForTest::kFalse), true),
      std::make_pair(LiteralForTest(LiteralForTest::kTrue), false),
      std::make_pair(LiteralForTest(9.1), false),
      std::make_pair(LiteralForTest(0), true),
      std::make_pair(LiteralForTest(ast_factory.GetOneByteString("hello")),
                     false),
      std::make_pair(LiteralForTest(ast_factory.GetOneByteString("")), true),
  };
  ast_factory.Internalize(isolate);

  for (size_t i = 0; i < arraysize(object_type_tuples); i++) {
    BytecodeArrayBuilder builder(zone, 1, 0);

    Register r0(0);
    LoadLiteralForTest(&builder, object_type_tuples[i].first);
    builder.LogicalNot(ToBooleanMode::kConvertToBoolean).Return();
    Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);
    InterpreterTester tester(isolate, bytecode_array);
    auto callable = tester.GetCallable<>();
    Handle<Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->IsBoolean());
    CHECK_EQ(return_value->BooleanValue(isolate), object_type_tuples[i].second);
  }
}

TEST(InterpreterTypeof) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();

  std::pair<const char*, const char*> typeof_vals[] = {
      std::make_pair("return typeof undefined;", "undefined"),
      std::make_pair("return typeof null;", "object"),
      std::make_pair("return typeof true;", "boolean"),
      std::make_pair("return typeof false;", "boolean"),
      std::make_pair("return typeof 9.1;", "number"),
      std::make_pair("return typeof 7771;", "number"),
      std::make_pair("return typeof 'hello';", "string"),
      std::make_pair("return typeof global_unallocated;", "undefined"),
  };

  for (size_t i = 0; i < arraysize(typeof_vals); i++) {
    std::string source(InterpreterTester::SourceForBody(typeof_vals[i].first));
    InterpreterTester tester(isolate, source.c_str());

    auto callable = tester.GetCallable<>();
    Handle<v8::internal::String> return_value =
        Handle<v8::internal::String>::cast(callable().ToHandleChecked());
    auto actual = return_value->ToCString();
    CHECK_EQ(strcmp(&actual[0], typeof_vals[i].second), 0);
  }
}

TEST(InterpreterCallRuntime) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Zone* zone = handles.main_zone();

  BytecodeArrayBuilder builder(zone, 1, 2);
  RegisterList args = builder.register_allocator()->NewRegisterList(2);

  builder.LoadLiteral(Smi::FromInt(15))
      .StoreAccumulatorInRegister(args[0])
      .LoadLiteral(Smi::FromInt(40))
      .StoreAccumulatorInRegister(args[1])
      .CallRuntime(Runtime::kAdd, args)
      .Return();
  Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

  InterpreterTester tester(isolate, bytecode_array);
  auto callable = tester.GetCallable<>();

  Handle<Object> return_val = callable().ToHandleChecked();
  CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(55));
}

TEST(InterpreterInvokeIntrinsic) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Zone* zone = handles.main_zone();

  BytecodeArrayBuilder builder(zone, 1, 2);

  builder.LoadLiteral(Smi::FromInt(15))
      .StoreAccumulatorInRegister(Register(0))
      .CallRuntime(Runtime::kInlineIsArray, Register(0))
      .Return();
  Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);

  InterpreterTester tester(isolate, bytecode_array);
  auto callable = tester.GetCallable<>();

  Handle<Object> return_val = callable().ToHandleChecked();
  CHECK(return_val->IsBoolean());
  CHECK_EQ(return_val->BooleanValue(isolate), false);
}

TEST(InterpreterFunctionLiteral) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();

  // Test calling a function literal.
  std::string source("function " + InterpreterTester::function_name() +
                     "(a) {\n"
                     "  return (function(x){ return x + 2; })(a);\n"
                     "}");
  InterpreterTester tester(isolate, source.c_str());
  auto callable = tester.GetCallable<Handle<Object>>();

  Handle<i::Object> return_val =
      callable(Handle<Smi>(Smi::FromInt(3), handles.main_isolate()))
          .ToHandleChecked();
  CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(5));
}

TEST(InterpreterRegExpLiterals) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();

  std::pair<const char*, Handle<Object>> literals[] = {
      std::make_pair("return /abd/.exec('cccabbdd');\n", factory->null_value()),
      std::make_pair("return /ab+d/.exec('cccabbdd')[0];\n",
                     factory->NewStringFromStaticChars("abbd")),
      std::make_pair("return /AbC/i.exec('ssaBC')[0];\n",
                     factory->NewStringFromStaticChars("aBC")),
      std::make_pair("return 'ssaBC'.match(/AbC/i)[0];\n",
                     factory->NewStringFromStaticChars("aBC")),
      std::make_pair("return 'ssaBCtAbC'.match(/(AbC)/gi)[1];\n",
                     factory->NewStringFromStaticChars("AbC")),
  };

  for (size_t i = 0; i < arraysize(literals); i++) {
    std::string source(InterpreterTester::SourceForBody(literals[i].first));
    InterpreterTester tester(isolate, source.c_str());
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*literals[i].second));
  }
}

TEST(InterpreterArrayLiterals) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();

  std::pair<const char*, Handle<Object>> literals[] = {
      std::make_pair("return [][0];\n", factory->undefined_value()),
      std::make_pair("return [1, 3, 2][1];\n",
                     handle(Smi::FromInt(3), isolate)),
      std::make_pair("return ['a', 'b', 'c'][2];\n",
                     factory->NewStringFromStaticChars("c")),
      std::make_pair("var a = 100; return [a, a + 1, a + 2, a + 3][2];\n",
                     handle(Smi::FromInt(102), isolate)),
      std::make_pair("return [[1, 2, 3], ['a', 'b', 'c']][1][0];\n",
                     factory->NewStringFromStaticChars("a")),
      std::make_pair("var t = 't'; return [[t, t + 'est'], [1 + t]][0][1];\n",
                     factory->NewStringFromStaticChars("test"))};

  for (size_t i = 0; i < arraysize(literals); i++) {
    std::string source(InterpreterTester::SourceForBody(literals[i].first));
    InterpreterTester tester(isolate, source.c_str());
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*literals[i].second));
  }
}

TEST(InterpreterObjectLiterals) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();

  std::pair<const char*, Handle<Object>> literals[] = {
      std::make_pair("return { }.name;", factory->undefined_value()),
      std::make_pair("return { name: 'string', val: 9.2 }.name;",
                     factory->NewStringFromStaticChars("string")),
      std::make_pair("var a = 15; return { name: 'string', val: a }.val;",
                     handle(Smi::FromInt(15), isolate)),
      std::make_pair("var a = 5; return { val: a, val: a + 1 }.val;",
                     handle(Smi::FromInt(6), isolate)),
      std::make_pair("return { func: function() { return 'test' } }.func();",
                     factory->NewStringFromStaticChars("test")),
      std::make_pair("return { func(a) { return a + 'st'; } }.func('te');",
                     factory->NewStringFromStaticChars("test")),
      std::make_pair("return { get a() { return 22; } }.a;",
                     handle(Smi::FromInt(22), isolate)),
      std::make_pair("var a = { get b() { return this.x + 't'; },\n"
                     "          set b(val) { this.x = val + 's' } };\n"
                     "a.b = 'te';\n"
                     "return a.b;",
                     factory->NewStringFromStaticChars("test")),
      std::make_pair("var a = 123; return { 1: a }[1];",
                     handle(Smi::FromInt(123), isolate)),
      std::make_pair("return Object.getPrototypeOf({ __proto__: null });",
                     factory->null_value()),
      std::make_pair("var a = 'test'; return { [a]: 1 }.test;",
                     handle(Smi::FromInt(1), isolate)),
      std::make_pair("var a = 'test'; return { b: a, [a]: a + 'ing' }['test']",
                     factory->NewStringFromStaticChars("testing")),
      std::make_pair("var a = 'proto_str';\n"
                     "var b = { [a]: 1, __proto__: { var : a } };\n"
                     "return Object.getPrototypeOf(b).var",
                     factory->NewStringFromStaticChars("proto_str")),
      std::make_pair("var n = 'name';\n"
                     "return { [n]: 'val', get a() { return 987 } }['a'];",
                     handle(Smi::FromInt(987), isolate)),
  };

  for (size_t i = 0; i < arraysize(literals); i++) {
    std::string source(InterpreterTester::SourceForBody(literals[i].first));
    InterpreterTester tester(isolate, source.c_str());
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*literals[i].second));
  }
}

TEST(InterpreterConstruct) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();

  std::string source(
      "function counter() { this.count = 0; }\n"
      "function " +
      InterpreterTester::function_name() +
      "() {\n"
      "  var c = new counter();\n"
      "  return c.count;\n"
      "}");
  InterpreterTester tester(isolate, source.c_str());
  auto callable = tester.GetCallable<>();

  Handle<Object> return_val = callable().ToHandleChecked();
  CHECK_EQ(Smi::cast(*return_val), Smi::zero());
}

TEST(InterpreterConstructWithArgument) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();

  std::string source(
      "function counter(arg0) { this.count = 17; this.x = arg0; }\n"
      "function " +
      InterpreterTester::function_name() +
      "() {\n"
      "  var c = new counter(3);\n"
      "  return c.x;\n"
      "}");
  InterpreterTester tester(isolate, source.c_str());
  auto callable = tester.GetCallable<>();

  Handle<Object> return_val = callable().ToHandleChecked();
  CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(3));
}

TEST(InterpreterConstructWithArguments) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();

  std::string source(
      "function counter(arg0, arg1) {\n"
      "  this.count = 7; this.x = arg0; this.y = arg1;\n"
      "}\n"
      "function " +
      InterpreterTester::function_name() +
      "() {\n"
      "  var c = new counter(3, 5);\n"
      "  return c.count + c.x + c.y;\n"
      "}");
  InterpreterTester tester(isolate, source.c_str());
  auto callable = tester.GetCallable<>();

  Handle<Object> return_val = callable().ToHandleChecked();
  CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(15));
}

TEST(InterpreterContextVariables) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();

  std::ostringstream unique_vars;
  for (int i = 0; i < 250; i++) {
    unique_vars << "var a" << i << " = 0;";
  }
  std::pair<std::string, Handle<Object>> context_vars[] = {
      std::make_pair("var a; (function() { a = 1; })(); return a;",
                     handle(Smi::FromInt(1), isolate)),
      std::make_pair("var a = 10; (function() { a; })(); return a;",
                     handle(Smi::FromInt(10), isolate)),
      std::make_pair("var a = 20; var b = 30;\n"
                     "return (function() { return a + b; })();",
                     handle(Smi::FromInt(50), isolate)),
      std::make_pair("'use strict'; let a = 1;\n"
                     "{ let b = 2; return (function() { return a + b; })(); }",
                     handle(Smi::FromInt(3), isolate)),
      std::make_pair("'use strict'; let a = 10;\n"
                     "{ let b = 20; var c = function() { [a, b] };\n"
                     "  return a + b; }",
                     handle(Smi::FromInt(30), isolate)),
      std::make_pair("'use strict';" + unique_vars.str() +
                         "eval(); var b = 100; return b;",
                     handle(Smi::FromInt(100), isolate)),
  };

  for (size_t i = 0; i < arraysize(context_vars); i++) {
    std::string source(
        InterpreterTester::SourceForBody(context_vars[i].first.c_str()));
    InterpreterTester tester(isolate, source.c_str());
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*context_vars[i].second));
  }
}

TEST(InterpreterContextParameters) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();

  std::pair<const char*, Handle<Object>> context_params[] = {
      std::make_pair("return (function() { return arg1; })();",
                     handle(Smi::FromInt(1), isolate)),
      std::make_pair("(function() { arg1 = 4; })(); return arg1;",
                     handle(Smi::FromInt(4), isolate)),
      std::make_pair("(function() { arg3 = arg2 - arg1; })(); return arg3;",
                     handle(Smi::FromInt(1), isolate)),
  };

  for (size_t i = 0; i < arraysize(context_params); i++) {
    std::string source = "function " + InterpreterTester::function_name() +
                         "(arg1, arg2, arg3) {" + context_params[i].first + "}";
    InterpreterTester tester(isolate, source.c_str());
    auto callable =
        tester.GetCallable<Handle<Object>, Handle<Object>, Handle<Object>>();

    Handle<Object> a1 = handle(Smi::FromInt(1), isolate);
    Handle<Object> a2 = handle(Smi::FromInt(2), isolate);
    Handle<Object> a3 = handle(Smi::FromInt(3), isolate);
    Handle<i::Object> return_value = callable(a1, a2, a3).ToHandleChecked();
    CHECK(return_value->SameValue(*context_params[i].second));
  }
}

TEST(InterpreterOuterContextVariables) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();

  std::pair<const char*, Handle<Object>> context_vars[] = {
      std::make_pair("return outerVar * innerArg;",
                     handle(Smi::FromInt(200), isolate)),
      std::make_pair("outerVar = innerArg; return outerVar",
                     handle(Smi::FromInt(20), isolate)),
  };

  std::string header(
      "function Outer() {"
      "  var outerVar = 10;"
      "  function Inner(innerArg) {"
      "    this.innerFunc = function() { ");
  std::string footer(
      "  }}"
      "  this.getInnerFunc = function() { return new Inner(20).innerFunc; }"
      "}"
      "var f = new Outer().getInnerFunc();");

  for (size_t i = 0; i < arraysize(context_vars); i++) {
    std::string source = header + context_vars[i].first + footer;
    InterpreterTester tester(isolate, source.c_str(), "*");
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*context_vars[i].second));
  }
}

TEST(InterpreterComma) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();

  std::pair<const char*, Handle<Object>> literals[] = {
      std::make_pair("var a; return 0, a;\n", factory->undefined_value()),
      std::make_pair("return 'a', 2.2, 3;\n", handle(Smi::FromInt(3), isolate)),
      std::make_pair("return 'a', 'b', 'c';\n",
                     factory->NewStringFromStaticChars("c")),
      std::make_pair("return 3.2, 2.3, 4.5;\n", factory->NewNumber(4.5)),
      std::make_pair("var a = 10; return b = a, b = b+1;\n",
                     handle(Smi::FromInt(11), isolate)),
      std::make_pair("var a = 10; return b = a, b = b+1, b + 10;\n",
                     handle(Smi::FromInt(21), isolate))};

  for (size_t i = 0; i < arraysize(literals); i++) {
    std::string source(InterpreterTester::SourceForBody(literals[i].first));
    InterpreterTester tester(isolate, source.c_str());
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*literals[i].second));
  }
}

TEST(InterpreterLogicalOr) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();

  std::pair<const char*, Handle<Object>> literals[] = {
      std::make_pair("var a, b; return a || b;\n", factory->undefined_value()),
      std::make_pair("var a, b = 10; return a || b;\n",
                     handle(Smi::FromInt(10), isolate)),
      std::make_pair("var a = '0', b = 10; return a || b;\n",
                     factory->NewStringFromStaticChars("0")),
      std::make_pair("return 0 || 3.2;\n", factory->NewNumber(3.2)),
      std::make_pair("return 'a' || 0;\n",
                     factory->NewStringFromStaticChars("a")),
      std::make_pair("var a = '0', b = 10; return (a == 0) || b;\n",
                     factory->true_value())};

  for (size_t i = 0; i < arraysize(literals); i++) {
    std::string source(InterpreterTester::SourceForBody(literals[i].first));
    InterpreterTester tester(isolate, source.c_str());
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*literals[i].second));
  }
}

TEST(InterpreterLogicalAnd) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();

  std::pair<const char*, Handle<Object>> literals[] = {
      std::make_pair("var a, b = 10; return a && b;\n",
                     factory->undefined_value()),
      std::make_pair("var a = 0, b = 10; return a && b / a;\n",
                     handle(Smi::zero(), isolate)),
      std::make_pair("var a = '0', b = 10; return a && b;\n",
                     handle(Smi::FromInt(10), isolate)),
      std::make_pair("return 0.0 && 3.2;\n", handle(Smi::zero(), isolate)),
      std::make_pair("return 'a' && 'b';\n",
                     factory->NewStringFromStaticChars("b")),
      std::make_pair("return 'a' && 0 || 'b', 'c';\n",
                     factory->NewStringFromStaticChars("c")),
      std::make_pair("var x = 1, y = 3; return x && 0 + 1 || y;\n",
                     handle(Smi::FromInt(1), isolate)),
      std::make_pair("var x = 1, y = 3; return (x == 1) && (3 == 3) || y;\n",
                     factory->true_value())};

  for (size_t i = 0; i < arraysize(literals); i++) {
    std::string source(InterpreterTester::SourceForBody(literals[i].first));
    InterpreterTester tester(isolate, source.c_str());
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*literals[i].second));
  }
}

TEST(InterpreterTryCatch) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();

  std::pair<const char*, Handle<Object>> catches[] = {
      std::make_pair("var a = 1; try { a = 2 } catch(e) { a = 3 }; return a;",
                     handle(Smi::FromInt(2), isolate)),
      std::make_pair("var a; try { undef.x } catch(e) { a = 2 }; return a;",
                     handle(Smi::FromInt(2), isolate)),
      std::make_pair("var a; try { throw 1 } catch(e) { a = e + 2 }; return a;",
                     handle(Smi::FromInt(3), isolate)),
      std::make_pair("var a; try { throw 1 } catch(e) { a = e + 2 };"
                     "       try { throw a } catch(e) { a = e + 3 }; return a;",
                     handle(Smi::FromInt(6), isolate)),
  };

  for (size_t i = 0; i < arraysize(catches); i++) {
    std::string source(InterpreterTester::SourceForBody(catches[i].first));
    InterpreterTester tester(isolate, source.c_str());
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*catches[i].second));
  }
}

TEST(InterpreterTryFinally) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();

  std::pair<const char*, Handle<Object>> finallies[] = {
      std::make_pair(
          "var a = 1; try { a = a + 1; } finally { a = a + 2; }; return a;",
          factory->NewStringFromStaticChars("R4")),
      std::make_pair(
          "var a = 1; try { a = 2; return 23; } finally { a = 3 }; return a;",
          factory->NewStringFromStaticChars("R23")),
      std::make_pair(
          "var a = 1; try { a = 2; throw 23; } finally { a = 3 }; return a;",
          factory->NewStringFromStaticChars("E23")),
      std::make_pair(
          "var a = 1; try { a = 2; throw 23; } finally { return a; };",
          factory->NewStringFromStaticChars("R2")),
      std::make_pair(
          "var a = 1; try { a = 2; throw 23; } finally { throw 42; };",
          factory->NewStringFromStaticChars("E42")),
      std::make_pair("var a = 1; for (var i = 10; i < 20; i += 5) {"
                     "  try { a = 2; break; } finally { a = 3; }"
                     "} return a + i;",
                     factory->NewStringFromStaticChars("R13")),
      std::make_pair("var a = 1; for (var i = 10; i < 20; i += 5) {"
                     "  try { a = 2; continue; } finally { a = 3; }"
                     "} return a + i;",
                     factory->NewStringFromStaticChars("R23")),
      std::make_pair("var a = 1; try { a = 2;"
                     "  try { a = 3; throw 23; } finally { a = 4; }"
                     "} catch(e) { a = a + e; } return a;",
                     factory->NewStringFromStaticChars("R27")),
      std::make_pair("var func_name;"
                     "function tcf2(a) {"
                     "  try { throw new Error('boom');} "
                     "  catch(e) {return 153; } "
                     "  finally {func_name = tcf2.name;}"
                     "}"
                     "tcf2();"
                     "return func_name;",
                     factory->NewStringFromStaticChars("Rtcf2")),
  };

  const char* try_wrapper =
      "(function() { try { return 'R' + f() } catch(e) { return 'E' + e }})()";

  for (size_t i = 0; i < arraysize(finallies); i++) {
    std::string source(InterpreterTester::SourceForBody(finallies[i].first));
    InterpreterTester tester(isolate, source.c_str());
    tester.GetCallable<>();
    Handle<Object> wrapped = v8::Utils::OpenHandle(*CompileRun(try_wrapper));
    CHECK(wrapped->SameValue(*finallies[i].second));
  }
}

TEST(InterpreterThrow) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();

  std::pair<const char*, Handle<Object>> throws[] = {
      std::make_pair("throw undefined;\n", factory->undefined_value()),
      std::make_pair("throw 1;\n", handle(Smi::FromInt(1), isolate)),
      std::make_pair("throw 'Error';\n",
                     factory->NewStringFromStaticChars("Error")),
      std::make_pair("var a = true; if (a) { throw 'Error'; }\n",
                     factory->NewStringFromStaticChars("Error")),
      std::make_pair("var a = false; if (a) { throw 'Error'; }\n",
                     factory->undefined_value()),
      std::make_pair("throw 'Error1'; throw 'Error2'\n",
                     factory->NewStringFromStaticChars("Error1")),
  };

  const char* try_wrapper =
      "(function() { try { f(); } catch(e) { return e; }})()";

  for (size_t i = 0; i < arraysize(throws); i++) {
    std::string source(InterpreterTester::SourceForBody(throws[i].first));
    InterpreterTester tester(isolate, source.c_str());
    tester.GetCallable<>();
    Handle<Object> thrown_obj = v8::Utils::OpenHandle(*CompileRun(try_wrapper));
    CHECK(thrown_obj->SameValue(*throws[i].second));
  }
}

TEST(InterpreterCountOperators) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();

  std::pair<const char*, Handle<Object>> count_ops[] = {
      std::make_pair("var a = 1; return ++a;",
                     handle(Smi::FromInt(2), isolate)),
      std::make_pair("var a = 1; return a++;",
                     handle(Smi::FromInt(1), isolate)),
      std::make_pair("var a = 5; return --a;",
                     handle(Smi::FromInt(4), isolate)),
      std::make_pair("var a = 5; return a--;",
                     handle(Smi::FromInt(5), isolate)),
      std::make_pair("var a = 5.2; return --a;", factory->NewHeapNumber(4.2)),
      std::make_pair("var a = 'string'; return ++a;", factory->nan_value()),
      std::make_pair("var a = 'string'; return a--;", factory->nan_value()),
      std::make_pair("var a = true; return ++a;",
                     handle(Smi::FromInt(2), isolate)),
      std::make_pair("var a = false; return a--;",
                     handle(Smi::zero(), isolate)),
      std::make_pair("var a = { val: 11 }; return ++a.val;",
                     handle(Smi::FromInt(12), isolate)),
      std::make_pair("var a = { val: 11 }; return a.val--;",
                     handle(Smi::FromInt(11), isolate)),
      std::make_pair("var a = { val: 11 }; return ++a.val;",
                     handle(Smi::FromInt(12), isolate)),
      std::make_pair("var name = 'val'; var a = { val: 22 }; return --a[name];",
                     handle(Smi::FromInt(21), isolate)),
      std::make_pair("var name = 'val'; var a = { val: 22 }; return a[name]++;",
                     handle(Smi::FromInt(22), isolate)),
      std::make_pair("var a = 1; (function() { a = 2 })(); return ++a;",
                     handle(Smi::FromInt(3), isolate)),
      std::make_pair("var a = 1; (function() { a = 2 })(); return a--;",
                     handle(Smi::FromInt(2), isolate)),
      std::make_pair("var i = 5; while(i--) {}; return i;",
                     handle(Smi::FromInt(-1), isolate)),
      std::make_pair("var i = 1; if(i--) { return 1; } else { return 2; };",
                     handle(Smi::FromInt(1), isolate)),
      std::make_pair("var i = -2; do {} while(i++) {}; return i;",
                     handle(Smi::FromInt(1), isolate)),
      std::make_pair("var i = -1; for(; i++; ) {}; return i",
                     handle(Smi::FromInt(1), isolate)),
      std::make_pair("var i = 20; switch(i++) {\n"
                     "  case 20: return 1;\n"
                     "  default: return 2;\n"
                     "}",
                     handle(Smi::FromInt(1), isolate)),
  };

  for (size_t i = 0; i < arraysize(count_ops); i++) {
    std::string source(InterpreterTester::SourceForBody(count_ops[i].first));
    InterpreterTester tester(isolate, source.c_str());
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*count_ops[i].second));
  }
}

TEST(InterpreterGlobalCountOperators) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();

  std::pair<const char*, Handle<Object>> count_ops[] = {
      std::make_pair("var global = 100;function f(){ return ++global; }",
                     handle(Smi::FromInt(101), isolate)),
      std::make_pair("var global = 100; function f(){ return --global; }",
                     handle(Smi::FromInt(99), isolate)),
      std::make_pair("var global = 100; function f(){ return global++; }",
                     handle(Smi::FromInt(100), isolate)),
      std::make_pair("unallocated = 200; function f(){ return ++unallocated; }",
                     handle(Smi::FromInt(201), isolate)),
      std::make_pair("unallocated = 200; function f(){ return --unallocated; }",
                     handle(Smi::FromInt(199), isolate)),
      std::make_pair("unallocated = 200; function f(){ return unallocated++; }",
                     handle(Smi::FromInt(200), isolate)),
  };

  for (size_t i = 0; i < arraysize(count_ops); i++) {
    InterpreterTester tester(isolate, count_ops[i].first);
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*count_ops[i].second));
  }
}

TEST(InterpreterCompoundExpressions) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();

  std::pair<const char*, Handle<Object>> compound_expr[] = {
      std::make_pair("var a = 1; a += 2; return a;",
                     Handle<Object>(Smi::FromInt(3), isolate)),
      std::make_pair("var a = 10; a /= 2; return a;",
                     Handle<Object>(Smi::FromInt(5), isolate)),
      std::make_pair("var a = 'test'; a += 'ing'; return a;",
                     factory->NewStringFromStaticChars("testing")),
      std::make_pair("var a = { val: 2 }; a.val *= 2; return a.val;",
                     Handle<Object>(Smi::FromInt(4), isolate)),
      std::make_pair("var a = 1; (function f() { a = 2; })(); a += 24;"
                     "return a;",
                     Handle<Object>(Smi::FromInt(26), isolate)),
  };

  for (size_t i = 0; i < arraysize(compound_expr); i++) {
    std::string source(
        InterpreterTester::SourceForBody(compound_expr[i].first));
    InterpreterTester tester(isolate, source.c_str());
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*compound_expr[i].second));
  }
}

TEST(InterpreterGlobalCompoundExpressions) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();

  std::pair<const char*, Handle<Object>> compound_expr[2] = {
      std::make_pair("var global = 100;"
                     "function f() { global += 20; return global; }",
                     Handle<Object>(Smi::FromInt(120), isolate)),
      std::make_pair("unallocated = 100;"
                     "function f() { unallocated -= 20; return unallocated; }",
                     Handle<Object>(Smi::FromInt(80), isolate)),
  };

  for (size_t i = 0; i < arraysize(compound_expr); i++) {
    InterpreterTester tester(isolate, compound_expr[i].first);
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*compound_expr[i].second));
  }
}

TEST(InterpreterCreateArguments) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();

  std::pair<const char*, int> create_args[] = {
      std::make_pair("function f() { return arguments[0]; }", 0),
      std::make_pair("function f(a) { return arguments[0]; }", 0),
      std::make_pair("function f() { return arguments[2]; }", 2),
      std::make_pair("function f(a) { return arguments[2]; }", 2),
      std::make_pair("function f(a, b, c, d) { return arguments[2]; }", 2),
      std::make_pair("function f(a) {"
                     "'use strict'; return arguments[0]; }",
                     0),
      std::make_pair("function f(a, b, c, d) {"
                     "'use strict'; return arguments[2]; }",
                     2),
      // Check arguments are mapped in sloppy mode and unmapped in strict.
      std::make_pair("function f(a, b, c, d) {"
                     "  c = b; return arguments[2]; }",
                     1),
      std::make_pair("function f(a, b, c, d) {"
                     "  'use strict'; c = b; return arguments[2]; }",
                     2),
      // Check arguments for duplicate parameters in sloppy mode.
      std::make_pair("function f(a, a, b) { return arguments[1]; }", 1),
      // check rest parameters
      std::make_pair("function f(...restArray) { return restArray[0]; }", 0),
      std::make_pair("function f(a, ...restArray) { return restArray[0]; }", 1),
      std::make_pair("function f(a, ...restArray) { return arguments[0]; }", 0),
      std::make_pair("function f(a, ...restArray) { return arguments[1]; }", 1),
      std::make_pair("function f(a, ...restArray) { return restArray[1]; }", 2),
      std::make_pair("function f(a, ...arguments) { return arguments[0]; }", 1),
      std::make_pair("function f(a, b, ...restArray) { return restArray[0]; }",
                     2),
  };

  // Test passing no arguments.
  for (size_t i = 0; i < arraysize(create_args); i++) {
    InterpreterTester tester(isolate, create_args[i].first);
    auto callable = tester.GetCallable<>();
    Handle<Object> return_val = callable().ToHandleChecked();
    CHECK(return_val.is_identical_to(factory->undefined_value()));
  }

  // Test passing one argument.
  for (size_t i = 0; i < arraysize(create_args); i++) {
    InterpreterTester tester(isolate, create_args[i].first);
    auto callable = tester.GetCallable<Handle<Object>>();
    Handle<Object> return_val =
        callable(handle(Smi::FromInt(40), isolate)).ToHandleChecked();
    if (create_args[i].second == 0) {
      CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(40));
    } else {
      CHECK(return_val.is_identical_to(factory->undefined_value()));
    }
  }

  // Test passing three argument.
  for (size_t i = 0; i < arraysize(create_args); i++) {
    Handle<Object> args[3] = {
        handle(Smi::FromInt(40), isolate),
        handle(Smi::FromInt(60), isolate),
        handle(Smi::FromInt(80), isolate),
    };

    InterpreterTester tester(isolate, create_args[i].first);
    auto callable =
        tester.GetCallable<Handle<Object>, Handle<Object>, Handle<Object>>();
    Handle<Object> return_val =
        callable(args[0], args[1], args[2]).ToHandleChecked();
    CHECK(return_val->SameValue(*args[create_args[i].second]));
  }
}

TEST(InterpreterConditional) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();

  std::pair<const char*, Handle<Object>> conditional[] = {
      std::make_pair("return true ? 2 : 3;", handle(Smi::FromInt(2), isolate)),
      std::make_pair("return false ? 2 : 3;", handle(Smi::FromInt(3), isolate)),
      std::make_pair("var a = 1; return a ? 20 : 30;",
                     handle(Smi::FromInt(20), isolate)),
      std::make_pair("var a = 1; return a ? 20 : 30;",
                     handle(Smi::FromInt(20), isolate)),
      std::make_pair("var a = 'string'; return a ? 20 : 30;",
                     handle(Smi::FromInt(20), isolate)),
      std::make_pair("var a = undefined; return a ? 20 : 30;",
                     handle(Smi::FromInt(30), isolate)),
      std::make_pair("return 1 ? 2 ? 3 : 4 : 5;",
                     handle(Smi::FromInt(3), isolate)),
      std::make_pair("return 0 ? 2 ? 3 : 4 : 5;",
                     handle(Smi::FromInt(5), isolate)),
  };

  for (size_t i = 0; i < arraysize(conditional); i++) {
    std::string source(InterpreterTester::SourceForBody(conditional[i].first));
    InterpreterTester tester(isolate, source.c_str());
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*conditional[i].second));
  }
}

TEST(InterpreterDelete) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();

  // Tests for delete for local variables that work both in strict
  // and sloppy modes
  std::pair<const char*, Handle<Object>> test_delete[] = {
      std::make_pair(
          "var a = { x:10, y:'abc', z:30.2}; delete a.x; return a.x;\n",
          factory->undefined_value()),
      std::make_pair(
          "var b = { x:10, y:'abc', z:30.2}; delete b.x; return b.y;\n",
          factory->NewStringFromStaticChars("abc")),
      std::make_pair("var c = { x:10, y:'abc', z:30.2}; var d = c; delete d.x; "
                     "return c.x;\n",
                     factory->undefined_value()),
      std::make_pair("var e = { x:10, y:'abc', z:30.2}; var g = e; delete g.x; "
                     "return e.y;\n",
                     factory->NewStringFromStaticChars("abc")),
      std::make_pair("var a = { x:10, y:'abc', z:30.2};\n"
                     "var b = a;"
                     "delete b.x;"
                     "return b.x;\n",
                     factory->undefined_value()),
      std::make_pair("var a = {1:10};\n"
                     "(function f1() {return a;});"
                     "return delete a[1];",
                     factory->ToBoolean(true)),
      std::make_pair("return delete this;", factory->ToBoolean(true)),
      std::make_pair("return delete 'test';", factory->ToBoolean(true))};

  // Test delete in sloppy mode
  for (size_t i = 0; i < arraysize(test_delete); i++) {
    std::string source(InterpreterTester::SourceForBody(test_delete[i].first));
    InterpreterTester tester(isolate, source.c_str());
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*test_delete[i].second));
  }

  // Test delete in strict mode
  for (size_t i = 0; i < arraysize(test_delete); i++) {
    std::string strict_test =
        "'use strict'; " + std::string(test_delete[i].first);
    std::string source(InterpreterTester::SourceForBody(strict_test.c_str()));
    InterpreterTester tester(isolate, source.c_str());
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*test_delete[i].second));
  }
}

TEST(InterpreterDeleteSloppyUnqualifiedIdentifier) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();

  // These tests generate a syntax error for strict mode. We don't
  // test for it here.
  std::pair<const char*, Handle<Object>> test_delete[] = {
      std::make_pair("var sloppy_a = { x:10, y:'abc'};\n"
                     "var sloppy_b = delete sloppy_a;\n"
                     "if (delete sloppy_a) {\n"
                     "  return undefined;\n"
                     "} else {\n"
                     "  return sloppy_a.x;\n"
                     "}\n",
                     Handle<Object>(Smi::FromInt(10), isolate)),
      // TODO(mythria) When try-catch is implemented change the tests to check
      // if delete actually deletes
      std::make_pair("sloppy_a = { x:10, y:'abc'};\n"
                     "var sloppy_b = delete sloppy_a;\n"
                     // "try{return a.x;} catch(e) {return b;}\n"
                     "return sloppy_b;",
                     factory->ToBoolean(true)),
      std::make_pair("sloppy_a = { x:10, y:'abc'};\n"
                     "var sloppy_b = delete sloppy_c;\n"
                     "return sloppy_b;",
                     factory->ToBoolean(true))};

  for (size_t i = 0; i < arraysize(test_delete); i++) {
    std::string source(InterpreterTester::SourceForBody(test_delete[i].first));
    InterpreterTester tester(isolate, source.c_str());
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*test_delete[i].second));
  }
}

TEST(InterpreterGlobalDelete) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();

  std::pair<const char*, Handle<Object>> test_global_delete[] = {
      std::make_pair("var a = { x:10, y:'abc', z:30.2 };\n"
                     "function f() {\n"
                     "  delete a.x;\n"
                     "  return a.x;\n"
                     "}\n"
                     "f();\n",
                     factory->undefined_value()),
      std::make_pair("var b = {1:10, 2:'abc', 3:30.2 };\n"
                     "function f() {\n"
                     "  delete b[2];\n"
                     "  return b[1];\n"
                     " }\n"
                     "f();\n",
                     Handle<Object>(Smi::FromInt(10), isolate)),
      std::make_pair("var c = { x:10, y:'abc', z:30.2 };\n"
                     "function f() {\n"
                     "   var d = c;\n"
                     "   delete d.y;\n"
                     "   return d.x;\n"
                     "}\n"
                     "f();\n",
                     Handle<Object>(Smi::FromInt(10), isolate)),
      std::make_pair("e = { x:10, y:'abc' };\n"
                     "function f() {\n"
                     "  return delete e;\n"
                     "}\n"
                     "f();\n",
                     factory->ToBoolean(true)),
      std::make_pair("var g = { x:10, y:'abc' };\n"
                     "function f() {\n"
                     "  return delete g;\n"
                     "}\n"
                     "f();\n",
                     factory->ToBoolean(false)),
      std::make_pair("function f() {\n"
                     "  var obj = {h:10, f1() {return delete this;}};\n"
                     "  return obj.f1();\n"
                     "}\n"
                     "f();",
                     factory->ToBoolean(true)),
      std::make_pair("function f() {\n"
                     "  var obj = {h:10,\n"
                     "             f1() {\n"
                     "              'use strict';\n"
                     "              return delete this.h;}};\n"
                     "  return obj.f1();\n"
                     "}\n"
                     "f();",
                     factory->ToBoolean(true))};

  for (size_t i = 0; i < arraysize(test_global_delete); i++) {
    InterpreterTester tester(isolate, test_global_delete[i].first);
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*test_global_delete[i].second));
  }
}

TEST(InterpreterBasicLoops) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();

  std::pair<const char*, Handle<Object>> loops[] = {
      std::make_pair("var a = 10; var b = 1;\n"
                     "while (a) {\n"
                     "  b = b * 2;\n"
                     "  a = a - 1;\n"
                     "};\n"
                     "return b;\n",
                     factory->NewHeapNumber(1024)),
      std::make_pair("var a = 1; var b = 1;\n"
                     "do {\n"
                     "  b = b * 2;\n"
                     "  --a;\n"
                     "} while(a);\n"
                     "return b;\n",
                     handle(Smi::FromInt(2), isolate)),
      std::make_pair("var b = 1;\n"
                     "for ( var a = 10; a; a--) {\n"
                     "  b *= 2;\n"
                     "}\n"
                     "return b;",
                     factory->NewHeapNumber(1024)),
      std::make_pair("var a = 10; var b = 1;\n"
                     "while (a > 0) {\n"
                     "  b = b * 2;\n"
                     "  a = a - 1;\n"
                     "};\n"
                     "return b;\n",
                     factory->NewHeapNumber(1024)),
      std::make_pair("var a = 1; var b = 1;\n"
                     "do {\n"
                     "  b = b * 2;\n"
                     "  --a;\n"
                     "} while(a);\n"
                     "return b;\n",
                     handle(Smi::FromInt(2), isolate)),
      std::make_pair("var b = 1;\n"
                     "for ( var a = 10; a > 0; a--) {\n"
                     "  b *= 2;\n"
                     "}\n"
                     "return b;",
                     factory->NewHeapNumber(1024)),
      std::make_pair("var a = 10; var b = 1;\n"
                     "while (false) {\n"
                     "  b = b * 2;\n"
                     "  a = a - 1;\n"
                     "}\n"
                     "return b;\n",
                     Handle<Object>(Smi::FromInt(1), isolate)),
      std::make_pair("var a = 10; var b = 1;\n"
                     "while (true) {\n"
                     "  b = b * 2;\n"
                     "  a = a - 1;\n"
                     "  if (a == 0) break;"
                     "  continue;"
                     "}\n"
                     "return b;\n",
                     factory->NewHeapNumber(1024)),
      std::make_pair("var a = 10; var b = 1;\n"
                     "do {\n"
                     "  b = b * 2;\n"
                     "  a = a - 1;\n"
                     "  if (a == 0) break;"
                     "} while(true);\n"
                     "return b;\n",
                     factory->NewHeapNumber(1024)),
      std::make_pair("var a = 10; var b = 1;\n"
                     "do {\n"
                     "  b = b * 2;\n"
                     "  a = a - 1;\n"
                     "  if (a == 0) break;"
                     "} while(false);\n"
                     "return b;\n",
                     Handle<Object>(Smi::FromInt(2), isolate)),
      std::make_pair("var a = 10; var b = 1;\n"
                     "for ( a = 1, b = 30; false; ) {\n"
                     "  b = b * 2;\n"
                     "}\n"
                     "return b;\n",
                     Handle<Object>(Smi::FromInt(30), isolate))};

  for (size_t i = 0; i < arraysize(loops); i++) {
    std::string source(InterpreterTester::SourceForBody(loops[i].first));
    InterpreterTester tester(isolate, source.c_str());
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*loops[i].second));
  }
}

TEST(InterpreterForIn) {
  std::pair<const char*, int> for_in_samples[] = {
      {"var r = -1;\n"
       "for (var a in null) { r = a; }\n"
       "return r;\n",
       -1},
      {"var r = -1;\n"
       "for (var a in undefined) { r = a; }\n"
       "return r;\n",
       -1},
      {"var r = 0;\n"
       "for (var a in [0,6,7,9]) { r = r + (1 << a); }\n"
       "return r;\n",
       0xF},
      {"var r = 0;\n"
       "for (var a in [0,6,7,9]) { r = r + (1 << a); }\n"
       "var r = 0;\n"
       "for (var a in [0,6,7,9]) { r = r + (1 << a); }\n"
       "return r;\n",
       0xF},
      {"var r = 0;\n"
       "for (var a in 'foobar') { r = r + (1 << a); }\n"
       "return r;\n",
       0x3F},
      {"var r = 0;\n"
       "for (var a in {1:0, 10:1, 100:2, 1000:3}) {\n"
       "  r = r + Number(a);\n"
       " }\n"
       " return r;\n",
       1111},
      {"var r = 0;\n"
       "var data = {1:0, 10:1, 100:2, 1000:3};\n"
       "for (var a in data) {\n"
       "  if (a == 1) delete data[1];\n"
       "  r = r + Number(a);\n"
       " }\n"
       " return r;\n",
       1111},
      {"var r = 0;\n"
       "var data = {1:0, 10:1, 100:2, 1000:3};\n"
       "for (var a in data) {\n"
       "  if (a == 10) delete data[100];\n"
       "  r = r + Number(a);\n"
       " }\n"
       " return r;\n",
       1011},
      {"var r = 0;\n"
       "var data = {1:0, 10:1, 100:2, 1000:3};\n"
       "for (var a in data) {\n"
       "  if (a == 10) data[10000] = 4;\n"
       "  r = r + Number(a);\n"
       " }\n"
       " return r;\n",
       1111},
      {"var r = 0;\n"
       "var input = 'foobar';\n"
       "for (var a in input) {\n"
       "  if (input[a] == 'b') break;\n"
       "  r = r + (1 << a);\n"
       "}\n"
       "return r;\n",
       0x7},
      {"var r = 0;\n"
       "var input = 'foobar';\n"
       "for (var a in input) {\n"
       " if (input[a] == 'b') continue;\n"
       " r = r + (1 << a);\n"
       "}\n"
       "return r;\n",
       0x37},
      {"var r = 0;\n"
       "var data = {1:0, 10:1, 100:2, 1000:3};\n"
       "for (var a in data) {\n"
       "  if (a == 10) {\n"
       "     data[10000] = 4;\n"
       "  }\n"
       "  r = r + Number(a);\n"
       "}\n"
       "return r;\n",
       1111},
      {"var r = [ 3 ];\n"
       "var data = {1:0, 10:1, 100:2, 1000:3};\n"
       "for (r[10] in data) {\n"
       "}\n"
       "return Number(r[10]);\n",
       1000},
      {"var r = [ 3 ];\n"
       "var data = {1:0, 10:1, 100:2, 1000:3};\n"
       "for (r['100'] in data) {\n"
       "}\n"
       "return Number(r['100']);\n",
       1000},
      {"var obj = {}\n"
       "var descObj = new Boolean(false);\n"
       "var accessed = 0;\n"
       "descObj.enumerable = true;\n"
       "Object.defineProperties(obj, { prop:descObj });\n"
       "for (var p in obj) {\n"
       "  if (p === 'prop') { accessed = 1; }\n"
       "}\n"
       "return accessed;",
       1},
      {"var appointment = {};\n"
       "Object.defineProperty(appointment, 'startTime', {\n"
       "    value: 1001,\n"
       "    writable: false,\n"
       "    enumerable: false,\n"
       "    configurable: true\n"
       "});\n"
       "Object.defineProperty(appointment, 'name', {\n"
       "    value: 'NAME',\n"
       "    writable: false,\n"
       "    enumerable: false,\n"
       "    configurable: true\n"
       "});\n"
       "var meeting = Object.create(appointment);\n"
       "Object.defineProperty(meeting, 'conferenceCall', {\n"
       "    value: 'In-person meeting',\n"
       "    writable: false,\n"
       "    enumerable: false,\n"
       "    configurable: true\n"
       "});\n"
       "\n"
       "var teamMeeting = Object.create(meeting);\n"
       "\n"
       "var flags = 0;\n"
       "for (var p in teamMeeting) {\n"
       "    if (p === 'startTime') {\n"
       "        flags |= 1;\n"
       "    }\n"
       "    if (p === 'name') {\n"
       "        flags |= 2;\n"
       "    }\n"
       "    if (p === 'conferenceCall') {\n"
       "        flags |= 4;\n"
       "    }\n"
       "}\n"
       "\n"
       "var hasOwnProperty = !teamMeeting.hasOwnProperty('name') &&\n"
       "    !teamMeeting.hasOwnProperty('startTime') &&\n"
       "    !teamMeeting.hasOwnProperty('conferenceCall');\n"
       "if (!hasOwnProperty) {\n"
       "    flags |= 8;\n"
       "}\n"
       "return flags;\n",
       0},
      {"var data = {x:23, y:34};\n"
       " var result = 0;\n"
       "var o = {};\n"
       "var arr = [o];\n"
       "for (arr[0].p in data)\n"       // This is to test if value is loaded
       "  result += data[arr[0].p];\n"  // back from accumulator before storing
       "return result;\n",              // named properties.
       57},
      {"var data = {x:23, y:34};\n"
       "var result = 0;\n"
       "var o = {};\n"
       "var i = 0;\n"
       "for (o[i++] in data)\n"       // This is to test if value is loaded
       "  result += data[o[i-1]];\n"  // back from accumulator before
       "return result;\n",            // storing keyed properties.
       57}};

  // Two passes are made for this test. On the first, 8-bit register
  // operands are employed, and on the 16-bit register operands are
  // used.
  for (int pass = 0; pass < 2; pass++) {
    HandleAndZoneScope handles;
    Isolate* isolate = handles.main_isolate();
    std::ostringstream wide_os;
    if (pass == 1) {
      for (int i = 0; i < 200; i++) {
        wide_os << "var local" << i << " = 0;\n";
      }
    }

    for (size_t i = 0; i < arraysize(for_in_samples); i++) {
      std::ostringstream body_os;
      body_os << wide_os.str() << for_in_samples[i].first;
      std::string body(body_os.str());
      std::string function = InterpreterTester::SourceForBody(body.c_str());
      InterpreterTester tester(isolate, function.c_str());
      auto callable = tester.GetCallable<>();
      Handle<Object> return_val = callable().ToHandleChecked();
      CHECK_EQ(Handle<Smi>::cast(return_val)->value(),
               for_in_samples[i].second);
    }
  }
}

TEST(InterpreterForOf) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();

  std::pair<const char*, Handle<Object>> for_of[] = {
      {"function f() {\n"
       "  var r = 0;\n"
       "  for (var a of [0,6,7,9]) { r += a; }\n"
       "  return r;\n"
       "}",
       handle(Smi::FromInt(22), isolate)},
      {"function f() {\n"
       "  var r = '';\n"
       "  for (var a of 'foobar') { r = a + r; }\n"
       "  return r;\n"
       "}",
       factory->NewStringFromStaticChars("raboof")},
      {"function f() {\n"
       "  var a = [1, 2, 3];\n"
       "  a.name = 4;\n"
       "  var r = 0;\n"
       "  for (var x of a) { r += x; }\n"
       "  return r;\n"
       "}",
       handle(Smi::FromInt(6), isolate)},
      {"function f() {\n"
       "  var r = '';\n"
       "  var data = [1, 2, 3]; \n"
       "  for (a of data) { delete data[0]; r += a; } return r; }",
       factory->NewStringFromStaticChars("123")},
      {"function f() {\n"
       "  var r = '';\n"
       "  var data = [1, 2, 3]; \n"
       "  for (a of data) { delete data[2]; r += a; } return r; }",
       factory->NewStringFromStaticChars("12undefined")},
      {"function f() {\n"
       "  var r = '';\n"
       "  var data = [1, 2, 3]; \n"
       "  for (a of data) { delete data; r += a; } return r; }",
       factory->NewStringFromStaticChars("123")},
      {"function f() {\n"
       "  var r = '';\n"
       "  var input = 'foobar';\n"
       "  for (var a of input) {\n"
       "    if (a == 'b') break;\n"
       "    r += a;\n"
       "  }\n"
       "  return r;\n"
       "}",
       factory->NewStringFromStaticChars("foo")},
      {"function f() {\n"
       "  var r = '';\n"
       "  var input = 'foobar';\n"
       "  for (var a of input) {\n"
       "    if (a == 'b') continue;\n"
       "    r += a;\n"
       "  }\n"
       "  return r;\n"
       "}",
       factory->NewStringFromStaticChars("fooar")},
      {"function f() {\n"
       "  var r = '';\n"
       "  var data = [1, 2, 3, 4]; \n"
       "  for (a of data) { data[2] = 567; r += a; }\n"
       "  return r;\n"
       "}",
       factory->NewStringFromStaticChars("125674")},
      {"function f() {\n"
       "  var r = '';\n"
       "  var data = [1, 2, 3, 4]; \n"
       "  for (a of data) { data[4] = 567; r += a; }\n"
       "  return r;\n"
       "}",
       factory->NewStringFromStaticChars("1234567")},
      {"function f() {\n"
       "  var r = '';\n"
       "  var data = [1, 2, 3, 4]; \n"
       "  for (a of data) { data[5] = 567; r += a; }\n"
       "  return r;\n"
       "}",
       factory->NewStringFromStaticChars("1234undefined567")},
      {"function f() {\n"
       "  var r = '';\n"
       "  var obj = new Object();\n"
       "  obj[Symbol.iterator] = function() { return {\n"
       "    index: 3,\n"
       "    data: ['a', 'b', 'c', 'd'],"
       "    next: function() {"
       "      return {"
       "        done: this.index == -1,\n"
       "        value: this.index < 0 ? undefined : this.data[this.index--]\n"
       "      }\n"
       "    }\n"
       "    }}\n"
       "  for (a of obj) { r += a }\n"
       "  return r;\n"
       "}",
       factory->NewStringFromStaticChars("dcba")},
  };

  for (size_t i = 0; i < arraysize(for_of); i++) {
    InterpreterTester tester(isolate, for_of[i].first);
    auto callable = tester.GetCallable<>();
    Handle<Object> return_val = callable().ToHandleChecked();
    CHECK(return_val->SameValue(*for_of[i].second));
  }
}

TEST(InterpreterSwitch) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();

  std::pair<const char*, Handle<Object>> switch_ops[] = {
      std::make_pair("var a = 1;\n"
                     "switch(a) {\n"
                     " case 1: return 2;\n"
                     " case 2: return 3;\n"
                     "}\n",
                     handle(Smi::FromInt(2), isolate)),
      std::make_pair("var a = 1;\n"
                     "switch(a) {\n"
                     " case 2: a = 2; break;\n"
                     " case 1: a = 3; break;\n"
                     "}\n"
                     "return a;",
                     handle(Smi::FromInt(3), isolate)),
      std::make_pair("var a = 1;\n"
                     "switch(a) {\n"
                     " case 1: a = 2; // fall-through\n"
                     " case 2: a = 3; break;\n"
                     "}\n"
                     "return a;",
                     handle(Smi::FromInt(3), isolate)),
      std::make_pair("var a = 100;\n"
                     "switch(a) {\n"
                     " case 1: return 100;\n"
                     " case 2: return 200;\n"
                     "}\n"
                     "return undefined;",
                     factory->undefined_value()),
      std::make_pair("var a = 100;\n"
                     "switch(a) {\n"
                     " case 1: return 100;\n"
                     " case 2: return 200;\n"
                     " default: return 300;\n"
                     "}\n"
                     "return undefined;",
                     handle(Smi::FromInt(300), isolate)),
      std::make_pair("var a = 100;\n"
                     "switch(typeof(a)) {\n"
                     " case 'string': return 1;\n"
                     " case 'number': return 2;\n"
                     " default: return 3;\n"
                     "}\n",
                     handle(Smi::FromInt(2), isolate)),
      std::make_pair("var a = 100;\n"
                     "switch(a) {\n"
                     " case a += 20: return 1;\n"
                     " case a -= 10: return 2;\n"
                     " case a -= 10: return 3;\n"
                     " default: return 3;\n"
                     "}\n",
                     handle(Smi::FromInt(3), isolate)),
      std::make_pair("var a = 1;\n"
                     "switch(a) {\n"
                     " case 1: \n"
                     "   switch(a + 1) {\n"
                     "      case 2 : a += 1; break;\n"
                     "      default : a += 2; break;\n"
                     "   }  // fall-through\n"
                     " case 2: a += 3;\n"
                     "}\n"
                     "return a;",
                     handle(Smi::FromInt(5), isolate)),
  };

  for (size_t i = 0; i < arraysize(switch_ops); i++) {
    std::string source(InterpreterTester::SourceForBody(switch_ops[i].first));
    InterpreterTester tester(isolate, source.c_str());
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*switch_ops[i].second));
  }
}

TEST(InterpreterSloppyThis) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();

  std::pair<const char*, Handle<Object>> sloppy_this[] = {
      std::make_pair("var global_val = 100;\n"
                     "function f() { return this.global_val; }\n",
                     handle(Smi::FromInt(100), isolate)),
      std::make_pair("var global_val = 110;\n"
                     "function g() { return this.global_val; };"
                     "function f() { return g(); }\n",
                     handle(Smi::FromInt(110), isolate)),
      std::make_pair("var global_val = 110;\n"
                     "function g() { return this.global_val };"
                     "function f() { 'use strict'; return g(); }\n",
                     handle(Smi::FromInt(110), isolate)),
      std::make_pair("function f() { 'use strict'; return this; }\n",
                     factory->undefined_value()),
      std::make_pair("function g() { 'use strict'; return this; };"
                     "function f() { return g(); }\n",
                     factory->undefined_value()),
  };

  for (size_t i = 0; i < arraysize(sloppy_this); i++) {
    InterpreterTester tester(isolate, sloppy_this[i].first);
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*sloppy_this[i].second));
  }
}

TEST(InterpreterThisFunction) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();

  InterpreterTester tester(isolate,
                           "var f;\n f = function f() { return f.name; }");
  auto callable = tester.GetCallable<>();

  Handle<i::Object> return_value = callable().ToHandleChecked();
  CHECK(return_value->SameValue(*factory->NewStringFromStaticChars("f")));
}

TEST(InterpreterNewTarget) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();

  // TODO(rmcilroy): Add tests that we get the original constructor for
  // superclass constructors once we have class support.
  InterpreterTester tester(isolate, "function f() { this.a = new.target; }");
  auto callable = tester.GetCallable<>();
  callable().ToHandleChecked();

  Handle<Object> new_target_name = v8::Utils::OpenHandle(
      *CompileRun("(function() { return (new f()).a.name; })();"));
  CHECK(new_target_name->SameValue(*factory->NewStringFromStaticChars("f")));
}

TEST(InterpreterAssignmentInExpressions) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();

  std::pair<const char*, int> samples[] = {
      {"function f() {\n"
       "  var x = 7;\n"
       "  var y = x + (x = 1) + (x = 2);\n"
       "  return y;\n"
       "}",
       10},
      {"function f() {\n"
       "  var x = 7;\n"
       "  var y = x + (x = 1) + (x = 2);\n"
       "  return x;\n"
       "}",
       2},
      {"function f() {\n"
       "  var x = 55;\n"
       "  x = x + (x = 100) + (x = 101);\n"
       "  return x;\n"
       "}",
       256},
      {"function f() {\n"
       "  var x = 7;\n"
       "  return ++x + x + x++;\n"
       "}",
       24},
      {"function f() {\n"
       "  var x = 7;\n"
       "  var y = 1 + ++x + x + x++;\n"
       "  return x;\n"
       "}",
       9},
      {"function f() {\n"
       "  var x = 7;\n"
       "  var y = ++x + x + x++;\n"
       "  return x;\n"
       "}",
       9},
      {"function f() {\n"
       "  var x = 7, y = 100, z = 1000;\n"
       "  return x + (x += 3) + y + (y *= 10) + (z *= 7) + z;\n"
       "}",
       15117},
      {"function f() {\n"
       "  var inner = function (x) { return x + (x = 2) + (x = 4) + x; };\n"
       "  return inner(1);\n"
       "}",
       11},
      {"function f() {\n"
       "  var x = 1, y = 2;\n"
       "  x = x + (x = 3) + y + (y = 4), y = y + (y = 5) + y + x;\n"
       "  return x + y;\n"
       "}",
       10 + 24},
      {"function f() {\n"
       "  var x = 0;\n"
       "  var y = x | (x = 1) | (x = 2);\n"
       "  return x;\n"
       "}",
       2},
      {"function f() {\n"
       "  var x = 0;\n"
       "  var y = x || (x = 1);\n"
       "  return x;\n"
       "}",
       1},
      {"function f() {\n"
       "  var x = 1;\n"
       "  var y = x && (x = 2) && (x = 3);\n"
       "  return x;\n"
       "}",
       3},
      {"function f() {\n"
       "  var x = 1;\n"
       "  var y = x || (x = 2);\n"
       "  return x;\n"
       "}",
       1},
      {"function f() {\n"
       "  var x = 1;\n"
       "  x = (x << (x = 3)) | (x = 16);\n"
       "  return x;\n"
       "}",
       24},
      {"function f() {\n"
       "  var r = 7;\n"
       "  var s = 11;\n"
       "  var t = 13;\n"
       "  var u = r + s + t + (r = 10) + (s = 20) +"
       "          (t = (r + s)) + r + s + t;\n"
       "  return r + s + t + u;\n"
       "}",
       211},
      {"function f() {\n"
       "  var r = 7;\n"
       "  var s = 11;\n"
       "  var t = 13;\n"
       "  return r > (3 * s * (s = 1)) ? (t + (t += 1)) : (r + (r = 4));\n"
       "}",
       11},
      {"function f() {\n"
       "  var r = 7;\n"
       "  var s = 11;\n"
       "  var t = 13;\n"
       "  return r > (3 * s * (s = 0)) ? (t + (t += 1)) : (r + (r = 4));\n"
       "}",
       27},
      {"function f() {\n"
       "  var r = 7;\n"
       "  var s = 11;\n"
       "  var t = 13;\n"
       "  return (r + (r = 5)) > s ? r : t;\n"
       "}",
       5},
      {"function f(a) {\n"
       "  return a + (arguments[0] = 10);\n"
       "}",
       50},
      {"function f(a) {\n"
       "  return a + (arguments[0] = 10) + a;\n"
       "}",
       60},
      {"function f(a) {\n"
       "  return a + (arguments[0] = 10) + arguments[0];\n"
       "}",
       60},
  };

  const int arg_value = 40;
  for (size_t i = 0; i < arraysize(samples); i++) {
    InterpreterTester tester(isolate, samples[i].first);
    auto callable = tester.GetCallable<Handle<Object>>();
    Handle<Object> return_val =
        callable(handle(Smi::FromInt(arg_value), handles.main_isolate()))
            .ToHandleChecked();
    CHECK_EQ(Handle<Smi>::cast(return_val)->value(), samples[i].second);
  }
}

TEST(InterpreterToName) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();

  std::pair<const char*, Handle<Object>> to_name_tests[] = {
      {"var a = 'val'; var obj = {[a] : 10}; return obj.val;",
       factory->NewNumberFromInt(10)},
      {"var a = 20; var obj = {[a] : 10}; return obj['20'];",
       factory->NewNumberFromInt(10)},
      {"var a = 20; var obj = {[a] : 10}; return obj[20];",
       factory->NewNumberFromInt(10)},
      {"var a = {val:23}; var obj = {[a] : 10}; return obj[a];",
       factory->NewNumberFromInt(10)},
      {"var a = {val:23}; var obj = {[a] : 10};\n"
       "return obj['[object Object]'];",
       factory->NewNumberFromInt(10)},
      {"var a = {toString : function() { return 'x'}};\n"
       "var obj = {[a] : 10};\n"
       "return obj.x;",
       factory->NewNumberFromInt(10)},
      {"var a = {valueOf : function() { return 'x'}};\n"
       "var obj = {[a] : 10};\n"
       "return obj.x;",
       factory->undefined_value()},
      {"var a = {[Symbol.toPrimitive] : function() { return 'x'}};\n"
       "var obj = {[a] : 10};\n"
       "return obj.x;",
       factory->NewNumberFromInt(10)},
  };

  for (size_t i = 0; i < arraysize(to_name_tests); i++) {
    std::string source(
        InterpreterTester::SourceForBody(to_name_tests[i].first));
    InterpreterTester tester(isolate, source.c_str());
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*to_name_tests[i].second));
  }
}

TEST(TemporaryRegisterAllocation) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();

  std::pair<const char*, Handle<Object>> reg_tests[] = {
      {"function add(a, b, c) {"
       "   return a + b + c;"
       "}"
       "function f() {"
       "  var a = 10, b = 10;"
       "   return add(a, b++, b);"
       "}",
       factory->NewNumberFromInt(31)},
      {"function add(a, b, c, d) {"
       "  return a + b + c + d;"
       "}"
       "function f() {"
       "  var x = 10, y = 20, z = 30;"
       "  return x + add(x, (y= x++), x, z);"
       "}",
       factory->NewNumberFromInt(71)},
  };

  for (size_t i = 0; i < arraysize(reg_tests); i++) {
    InterpreterTester tester(isolate, reg_tests[i].first);
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*reg_tests[i].second));
  }
}

TEST(InterpreterLookupSlot) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();

  // TODO(mythria): Add more tests when we have support for eval/with.
  const char* function_prologue =
      "var f;"
      "var x = 1;"
      "function f1() {"
      "  eval(\"function t() {";
  const char* function_epilogue =
      "        }; f = t;\");"
      "}"
      "f1();";

  std::pair<const char*, Handle<Object>> lookup_slot[] = {
      {"return x;", handle(Smi::FromInt(1), isolate)},
      {"return typeof x;", factory->NewStringFromStaticChars("number")},
      {"return typeof dummy;", factory->NewStringFromStaticChars("undefined")},
      {"x = 10; return x;", handle(Smi::FromInt(10), isolate)},
      {"'use strict'; x = 20; return x;", handle(Smi::FromInt(20), isolate)},
  };

  for (size_t i = 0; i < arraysize(lookup_slot); i++) {
    std::string script = std::string(function_prologue) +
                         std::string(lookup_slot[i].first) +
                         std::string(function_epilogue);

    InterpreterTester tester(isolate, script.c_str(), "t");
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*lookup_slot[i].second));
  }
}

TEST(InterpreterLookupContextSlot) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();

  const char* inner_function_prologue = "function inner() {";
  const char* inner_function_epilogue = "};";
  const char* outer_function_epilogue = "return inner();";

  std::tuple<const char*, const char*, Handle<Object>> lookup_slot[] = {
      // Eval in inner context.
      std::make_tuple("var x = 0;", "eval(''); return x;",
                      handle(Smi::zero(), isolate)),
      std::make_tuple("var x = 0;", "eval('var x = 1'); return x;",
                      handle(Smi::FromInt(1), isolate)),
      std::make_tuple("var x = 0;",
                      "'use strict'; eval('var x = 1'); return x;",
                      handle(Smi::zero(), isolate)),
      // Eval in outer context.
      std::make_tuple("var x = 0; eval('');", "return x;",
                      handle(Smi::zero(), isolate)),
      std::make_tuple("var x = 0; eval('var x = 1');", "return x;",
                      handle(Smi::FromInt(1), isolate)),
      std::make_tuple("'use strict'; var x = 0; eval('var x = 1');",
                      "return x;", handle(Smi::zero(), isolate)),
  };

  for (size_t i = 0; i < arraysize(lookup_slot); i++) {
    std::string body = std::string(std::get<0>(lookup_slot[i])) +
                       std::string(inner_function_prologue) +
                       std::string(std::get<1>(lookup_slot[i])) +
                       std::string(inner_function_epilogue) +
                       std::string(outer_function_epilogue);
    std::string script = InterpreterTester::SourceForBody(body.c_str());

    InterpreterTester tester(isolate, script.c_str());
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*std::get<2>(lookup_slot[i])));
  }
}

TEST(InterpreterLookupGlobalSlot) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();

  const char* inner_function_prologue = "function inner() {";
  const char* inner_function_epilogue = "};";
  const char* outer_function_epilogue = "return inner();";

  std::tuple<const char*, const char*, Handle<Object>> lookup_slot[] = {
      // Eval in inner context.
      std::make_tuple("x = 0;", "eval(''); return x;",
                      handle(Smi::zero(), isolate)),
      std::make_tuple("x = 0;", "eval('var x = 1'); return x;",
                      handle(Smi::FromInt(1), isolate)),
      std::make_tuple("x = 0;", "'use strict'; eval('var x = 1'); return x;",
                      handle(Smi::zero(), isolate)),
      // Eval in outer context.
      std::make_tuple("x = 0; eval('');", "return x;",
                      handle(Smi::zero(), isolate)),
      std::make_tuple("x = 0; eval('var x = 1');", "return x;",
                      handle(Smi::FromInt(1), isolate)),
      std::make_tuple("'use strict'; x = 0; eval('var x = 1');", "return x;",
                      handle(Smi::zero(), isolate)),
  };

  for (size_t i = 0; i < arraysize(lookup_slot); i++) {
    std::string body = std::string(std::get<0>(lookup_slot[i])) +
                       std::string(inner_function_prologue) +
                       std::string(std::get<1>(lookup_slot[i])) +
                       std::string(inner_function_epilogue) +
                       std::string(outer_function_epilogue);
    std::string script = InterpreterTester::SourceForBody(body.c_str());

    InterpreterTester tester(isolate, script.c_str());
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*std::get<2>(lookup_slot[i])));
  }
}

TEST(InterpreterCallLookupSlot) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();

  std::pair<const char*, Handle<Object>> call_lookup[] = {
      {"g = function(){ return 2 }; eval(''); return g();",
       handle(Smi::FromInt(2), isolate)},
      {"g = function(){ return 2 }; eval('g = function() {return 3}');\n"
       "return g();",
       handle(Smi::FromInt(3), isolate)},
      {"g = { x: function(){ return this.y }, y: 20 };\n"
       "eval('g = { x: g.x, y: 30 }');\n"
       "return g.x();",
       handle(Smi::FromInt(30), isolate)},
  };

  for (size_t i = 0; i < arraysize(call_lookup); i++) {
    std::string source(InterpreterTester::SourceForBody(call_lookup[i].first));
    InterpreterTester tester(isolate, source.c_str());
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*call_lookup[i].second));
  }
}

TEST(InterpreterLookupSlotWide) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();

  const char* function_prologue =
      "var f;"
      "var x = 1;"
      "function f1() {"
      "  eval(\"function t() {";
  const char* function_epilogue =
      "        }; f = t;\");"
      "}"
      "f1();";
  std::ostringstream str;
  str << "var y = 2.3;";
  for (int i = 1; i < 256; i++) {
    str << "y = " << 2.3 + i << ";";
  }
  std::string init_function_body = str.str();

  std::pair<std::string, Handle<Object>> lookup_slot[] = {
      {init_function_body + "return x;", handle(Smi::FromInt(1), isolate)},
      {init_function_body + "return typeof x;",
       factory->NewStringFromStaticChars("number")},
      {init_function_body + "return x = 10;",
       handle(Smi::FromInt(10), isolate)},
      {"'use strict';" + init_function_body + "x = 20; return x;",
       handle(Smi::FromInt(20), isolate)},
  };

  for (size_t i = 0; i < arraysize(lookup_slot); i++) {
    std::string script = std::string(function_prologue) + lookup_slot[i].first +
                         std::string(function_epilogue);

    InterpreterTester tester(isolate, script.c_str(), "t");
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*lookup_slot[i].second));
  }
}

TEST(InterpreterDeleteLookupSlot) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();

  // TODO(mythria): Add more tests when we have support for eval/with.
  const char* function_prologue =
      "var f;"
      "var x = 1;"
      "y = 10;"
      "var obj = {val:10};"
      "var z = 30;"
      "function f1() {"
      "  var z = 20;"
      "  eval(\"function t() {";
  const char* function_epilogue =
      "        }; f = t;\");"
      "}"
      "f1();";

  std::pair<const char*, Handle<Object>> delete_lookup_slot[] = {
      {"return delete x;", factory->false_value()},
      {"return delete y;", factory->true_value()},
      {"return delete z;", factory->false_value()},
      {"return delete obj.val;", factory->true_value()},
      {"'use strict'; return delete obj.val;", factory->true_value()},
  };

  for (size_t i = 0; i < arraysize(delete_lookup_slot); i++) {
    std::string script = std::string(function_prologue) +
                         std::string(delete_lookup_slot[i].first) +
                         std::string(function_epilogue);

    InterpreterTester tester(isolate, script.c_str(), "t");
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*delete_lookup_slot[i].second));
  }
}

TEST(JumpWithConstantsAndWideConstants) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();
  const int kStep = 13;
  for (int constants = 11; constants < 256 + 3 * kStep; constants += kStep) {
    std::ostringstream filler_os;
    // Generate a string that consumes constant pool entries and
    // spread out branch distances in script below.
    for (int i = 0; i < constants; i++) {
      filler_os << "var x_ = 'x_" << i << "';\n";
    }
    std::string filler(filler_os.str());
    std::ostringstream script_os;
    script_os << "function " << InterpreterTester::function_name() << "(a) {\n";
    script_os << "  " << filler;
    script_os << "  for (var i = a; i < 2; i++) {\n";
    script_os << "  " << filler;
    script_os << "    if (i == 0) { " << filler << "i = 10; continue; }\n";
    script_os << "    else if (i == a) { " << filler << "i = 12; break; }\n";
    script_os << "    else { " << filler << " }\n";
    script_os << "  }\n";
    script_os << "  return i;\n";
    script_os << "}\n";
    std::string script(script_os.str());
    for (int a = 0; a < 3; a++) {
      InterpreterTester tester(isolate, script.c_str());
      auto callable = tester.GetCallable<Handle<Object>>();
      Handle<Object> argument = factory->NewNumberFromInt(a);
      Handle<Object> return_val = callable(argument).ToHandleChecked();
      static const int results[] = {11, 12, 2};
      CHECK_EQ(Handle<Smi>::cast(return_val)->value(), results[a]);
    }
  }
}

TEST(InterpreterEval) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();

  std::pair<const char*, Handle<Object>> eval[] = {
      {"return eval('1;');", handle(Smi::FromInt(1), isolate)},
      {"return eval('100 * 20;');", handle(Smi::FromInt(2000), isolate)},
      {"var x = 10; return eval('x + 20;');",
       handle(Smi::FromInt(30), isolate)},
      {"var x = 10; eval('x = 33;'); return x;",
       handle(Smi::FromInt(33), isolate)},
      {"'use strict'; var x = 20; var z = 0;\n"
       "eval('var x = 33; z = x;'); return x + z;",
       handle(Smi::FromInt(53), isolate)},
      {"eval('var x = 33;'); eval('var y = x + 20'); return x + y;",
       handle(Smi::FromInt(86), isolate)},
      {"var x = 1; eval('for(i = 0; i < 10; i++) x = x + 1;'); return x",
       handle(Smi::FromInt(11), isolate)},
      {"var x = 10; eval('var x = 20;'); return x;",
       handle(Smi::FromInt(20), isolate)},
      {"var x = 1; eval('\"use strict\"; var x = 2;'); return x;",
       handle(Smi::FromInt(1), isolate)},
      {"'use strict'; var x = 1; eval('var x = 2;'); return x;",
       handle(Smi::FromInt(1), isolate)},
      {"var x = 10; eval('x + 20;'); return typeof x;",
       factory->NewStringFromStaticChars("number")},
      {"eval('var y = 10;'); return typeof unallocated;",
       factory->NewStringFromStaticChars("undefined")},
      {"'use strict'; eval('var y = 10;'); return typeof unallocated;",
       factory->NewStringFromStaticChars("undefined")},
      {"eval('var x = 10;'); return typeof x;",
       factory->NewStringFromStaticChars("number")},
      {"var x = {}; eval('var x = 10;'); return typeof x;",
       factory->NewStringFromStaticChars("number")},
      {"'use strict'; var x = {}; eval('var x = 10;'); return typeof x;",
       factory->NewStringFromStaticChars("object")},
  };

  for (size_t i = 0; i < arraysize(eval); i++) {
    std::string source(InterpreterTester::SourceForBody(eval[i].first));
    InterpreterTester tester(isolate, source.c_str());
    auto callable = tester.GetCallable<>();
    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*eval[i].second));
  }
}

TEST(InterpreterEvalParams) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();

  std::pair<const char*, Handle<Object>> eval_params[] = {
      {"var x = 10; return eval('x + p1;');",
       handle(Smi::FromInt(30), isolate)},
      {"var x = 10; eval('p1 = x;'); return p1;",
       handle(Smi::FromInt(10), isolate)},
      {"var a = 10;"
       "function inner() { return eval('a + p1;');}"
       "return inner();",
       handle(Smi::FromInt(30), isolate)},
  };

  for (size_t i = 0; i < arraysize(eval_params); i++) {
    std::string source = "function " + InterpreterTester::function_name() +
                         "(p1) {" + eval_params[i].first + "}";
    InterpreterTester tester(isolate, source.c_str());
    auto callable = tester.GetCallable<Handle<Object>>();

    Handle<i::Object> return_value =
        callable(handle(Smi::FromInt(20), isolate)).ToHandleChecked();
    CHECK(return_value->SameValue(*eval_params[i].second));
  }
}

TEST(InterpreterEvalGlobal) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();

  std::pair<const char*, Handle<Object>> eval_global[] = {
      {"function add_global() { eval('function test() { z = 33; }; test()'); };"
       "function f() { add_global(); return z; }; f();",
       handle(Smi::FromInt(33), isolate)},
      {"function add_global() {\n"
       " eval('\"use strict\"; function test() { y = 33; };"
       "      try { test() } catch(e) {}');\n"
       "}\n"
       "function f() { add_global(); return typeof y; } f();",
       factory->NewStringFromStaticChars("undefined")},
  };

  for (size_t i = 0; i < arraysize(eval_global); i++) {
    InterpreterTester tester(isolate, eval_global[i].first, "test");
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*eval_global[i].second));
  }
}

TEST(InterpreterEvalVariableDecl) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();

  std::pair<const char*, Handle<Object>> eval_global[] = {
      {"function f() { eval('var x = 10; x++;'); return x; }",
       handle(Smi::FromInt(11), isolate)},
      {"function f() { var x = 20; eval('var x = 10; x++;'); return x; }",
       handle(Smi::FromInt(11), isolate)},
      {"function f() {"
       " var x = 20;"
       " eval('\"use strict\"; var x = 10; x++;');"
       " return x; }",
       handle(Smi::FromInt(20), isolate)},
      {"function f() {"
       " var y = 30;"
       " eval('var x = {1:20}; x[2]=y;');"
       " return x[2]; }",
       handle(Smi::FromInt(30), isolate)},
      {"function f() {"
       " eval('var x = {name:\"test\"};');"
       " return x.name; }",
       factory->NewStringFromStaticChars("test")},
      {"function f() {"
       "  eval('var x = [{name:\"test\"}, {type:\"cc\"}];');"
       "  return x[1].type+x[0].name; }",
       factory->NewStringFromStaticChars("cctest")},
      {"function f() {\n"
       " var x = 3;\n"
       " var get_eval_x;\n"
       " eval('\"use strict\"; "
       "      var x = 20; "
       "      get_eval_x = function func() {return x;};');\n"
       " return get_eval_x() + x;\n"
       "}",
       handle(Smi::FromInt(23), isolate)},
      // TODO(mythria): Add tests with const declarations.
  };

  for (size_t i = 0; i < arraysize(eval_global); i++) {
    InterpreterTester tester(isolate, eval_global[i].first, "*");
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*eval_global[i].second));
  }
}

TEST(InterpreterEvalFunctionDecl) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();

  std::pair<const char*, Handle<Object>> eval_func_decl[] = {
      {"function f() {\n"
       " var x = 3;\n"
       " eval('var x = 20;"
       "       function get_x() {return x;};');\n"
       " return get_x() + x;\n"
       "}",
       handle(Smi::FromInt(40), isolate)},
  };

  for (size_t i = 0; i < arraysize(eval_func_decl); i++) {
    InterpreterTester tester(isolate, eval_func_decl[i].first, "*");
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*eval_func_decl[i].second));
  }
}

TEST(InterpreterWideRegisterArithmetic) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();

  static const size_t kMaxRegisterForTest = 150;
  std::ostringstream os;
  os << "function " << InterpreterTester::function_name() << "(arg) {\n";
  os << "  var retval = -77;\n";
  for (size_t i = 0; i < kMaxRegisterForTest; i++) {
    os << "  var x" << i << " = " << i << ";\n";
  }
  for (size_t i = 0; i < kMaxRegisterForTest / 2; i++) {
    size_t j = kMaxRegisterForTest - i - 1;
    os << "  var tmp = x" << j << ";\n";
    os << "  var x" << j << " = x" << i << ";\n";
    os << "  var x" << i << " = tmp;\n";
  }
  for (size_t i = 0; i < kMaxRegisterForTest / 2; i++) {
    size_t j = kMaxRegisterForTest - i - 1;
    os << "  var tmp = x" << j << ";\n";
    os << "  var x" << j << " = x" << i << ";\n";
    os << "  var x" << i << " = tmp;\n";
  }
  for (size_t i = 0; i < kMaxRegisterForTest; i++) {
    os << "  if (arg == " << i << ") {\n"  //
       << "    retval = x" << i << ";\n"   //
       << "  }\n";                         //
  }
  os << "  return retval;\n";
  os << "}\n";

  std::string source = os.str();
  InterpreterTester tester(isolate, source.c_str());
  auto callable = tester.GetCallable<Handle<Object>>();
  for (size_t i = 0; i < kMaxRegisterForTest; i++) {
    Handle<Object> arg = handle(Smi::FromInt(static_cast<int>(i)), isolate);
    Handle<Object> return_value = callable(arg).ToHandleChecked();
    CHECK(return_value->SameValue(*arg));
  }
}

TEST(InterpreterCallWideRegisters) {
  static const int kPeriod = 25;
  static const int kLength = 512;
  static const int kStartChar = 65;

  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();

  for (int pass = 0; pass < 3; pass += 1) {
    std::ostringstream os;
    for (int i = 0; i < pass * 97; i += 1) {
      os << "var x" << i << " = " << i << "\n";
    }
    os << "return String.fromCharCode(";
    os << kStartChar;
    for (int i = 1; i < kLength; i += 1) {
      os << "," << kStartChar + (i % kPeriod);
    }
    os << ");";
    std::string source = InterpreterTester::SourceForBody(os.str().c_str());
    InterpreterTester tester(isolate, source.c_str());
    auto callable = tester.GetCallable();
    Handle<Object> return_val = callable().ToHandleChecked();
    Handle<String> return_string = Handle<String>::cast(return_val);
    CHECK_EQ(return_string->length(), kLength);
    for (int i = 0; i < kLength; i += 1) {
      CHECK_EQ(return_string->Get(i), 65 + (i % kPeriod));
    }
  }
}

TEST(InterpreterWideParametersPickOne) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  static const int kParameterCount = 130;
  for (int parameter = 0; parameter < 10; parameter++) {
    std::ostringstream os;
    os << "function " << InterpreterTester::function_name() << "(arg) {\n";
    os << "  function selector(i";
    for (int i = 0; i < kParameterCount; i++) {
      os << ","
         << "a" << i;
    }
    os << ") {\n";
    os << "  return a" << parameter << ";\n";
    os << "  };\n";
    os << "  return selector(arg";
    for (int i = 0; i < kParameterCount; i++) {
      os << "," << i;
    }
    os << ");";
    os << "}\n";

    std::string source = os.str();
    InterpreterTester tester(isolate, source.c_str(), "*");
    auto callable = tester.GetCallable<Handle<Object>>();
    Handle<Object> arg = handle(Smi::FromInt(0xAA55), isolate);
    Handle<Object> return_value = callable(arg).ToHandleChecked();
    Handle<Smi> actual = Handle<Smi>::cast(return_value);
    CHECK_EQ(actual->value(), parameter);
  }
}

TEST(InterpreterWideParametersSummation) {
  static int kParameterCount = 200;
  static int kBaseValue = 17000;
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  std::ostringstream os;
  os << "function " << InterpreterTester::function_name() << "(arg) {\n";
  os << "  function summation(i";
  for (int i = 0; i < kParameterCount; i++) {
    os << ","
       << "a" << i;
  }
  os << ") {\n";
  os << "    var sum = " << kBaseValue << ";\n";
  os << "    switch(i) {\n";
  for (int i = 0; i < kParameterCount; i++) {
    int j = kParameterCount - i - 1;
    os << "      case " << j << ": sum += a" << j << ";\n";
  }
  os << "  }\n";
  os << "    return sum;\n";
  os << "  };\n";
  os << "  return summation(arg";
  for (int i = 0; i < kParameterCount; i++) {
    os << "," << i;
  }
  os << ");";
  os << "}\n";

  std::string source = os.str();
  InterpreterTester tester(isolate, source.c_str(), "*");
  auto callable = tester.GetCallable<Handle<Object>>();
  for (int i = 0; i < kParameterCount; i++) {
    Handle<Object> arg = handle(Smi::FromInt(i), isolate);
    Handle<Object> return_value = callable(arg).ToHandleChecked();
    int expected = kBaseValue + i * (i + 1) / 2;
    Handle<Smi> actual = Handle<Smi>::cast(return_value);
    CHECK_EQ(actual->value(), expected);
  }
}

TEST(InterpreterWithStatement) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();

  std::pair<const char*, Handle<Object>> with_stmt[] = {
      {"with({x:42}) return x;", handle(Smi::FromInt(42), isolate)},
      {"with({}) { var y = 10; return y;}", handle(Smi::FromInt(10), isolate)},
      {"var y = {x:42};"
       " function inner() {"
       "   var x = 20;"
       "   with(y) return x;"
       "}"
       "return inner();",
       handle(Smi::FromInt(42), isolate)},
      {"var y = {x:42};"
       " function inner(o) {"
       "   var x = 20;"
       "   with(o) return x;"
       "}"
       "return inner(y);",
       handle(Smi::FromInt(42), isolate)},
  };

  for (size_t i = 0; i < arraysize(with_stmt); i++) {
    std::string source(InterpreterTester::SourceForBody(with_stmt[i].first));
    InterpreterTester tester(isolate, source.c_str());
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*with_stmt[i].second));
  }
}

TEST(InterpreterClassLiterals) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  std::pair<const char*, Handle<Object>> examples[] = {
      {"class C {\n"
       "  constructor(x) { this.x_ = x; }\n"
       "  method() { return this.x_; }\n"
       "}\n"
       "return new C(99).method();",
       handle(Smi::FromInt(99), isolate)},
      {"class C {\n"
       "  constructor(x) { this.x_ = x; }\n"
       "  static static_method(x) { return x; }\n"
       "}\n"
       "return C.static_method(101);",
       handle(Smi::FromInt(101), isolate)},
      {"class C {\n"
       "  get x() { return 102; }\n"
       "}\n"
       "return new C().x",
       handle(Smi::FromInt(102), isolate)},
      {"class C {\n"
       "  static get x() { return 103; }\n"
       "}\n"
       "return C.x",
       handle(Smi::FromInt(103), isolate)},
      {"class C {\n"
       "  constructor() { this.x_ = 0; }"
       "  set x(value) { this.x_ = value; }\n"
       "  get x() { return this.x_; }\n"
       "}\n"
       "var c = new C();"
       "c.x = 104;"
       "return c.x;",
       handle(Smi::FromInt(104), isolate)},
      {"var x = 0;"
       "class C {\n"
       "  static set x(value) { x = value; }\n"
       "  static get x() { return x; }\n"
       "}\n"
       "C.x = 105;"
       "return C.x;",
       handle(Smi::FromInt(105), isolate)},
      {"var method = 'f';"
       "class C {\n"
       "  [method]() { return 106; }\n"
       "}\n"
       "return new C().f();",
       handle(Smi::FromInt(106), isolate)},
  };

  for (size_t i = 0; i < arraysize(examples); ++i) {
    std::string source(InterpreterTester::SourceForBody(examples[i].first));
    InterpreterTester tester(isolate, source.c_str(), "*");
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*examples[i].second));
  }
}

TEST(InterpreterClassAndSuperClass) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  std::pair<const char*, Handle<Object>> examples[] = {
      {"class A {\n"
       "  constructor(x) { this.x_ = x; }\n"
       "  method() { return this.x_; }\n"
       "}\n"
       "class B extends A {\n"
       "   constructor(x, y) { super(x); this.y_ = y; }\n"
       "   method() { return super.method() + 1; }\n"
       "}\n"
       "return new B(998, 0).method();\n",
       handle(Smi::FromInt(999), isolate)},
      {"class A {\n"
       "  constructor() { this.x_ = 2; this.y_ = 3; }\n"
       "}\n"
       "class B extends A {\n"
       "  constructor() { super(); }"
       "  method() { this.x_++; this.y_++; return this.x_ + this.y_; }\n"
       "}\n"
       "return new B().method();\n",
       handle(Smi::FromInt(7), isolate)},
      {"var calls = 0;\n"
       "class B {}\n"
       "B.prototype.x = 42;\n"
       "class C extends B {\n"
       "  constructor() {\n"
       "    super();\n"
       "    calls++;\n"
       "  }\n"
       "}\n"
       "new C;\n"
       "return calls;\n",
       handle(Smi::FromInt(1), isolate)},
      {"class A {\n"
       "  method() { return 1; }\n"
       "  get x() { return 2; }\n"
       "}\n"
       "class B extends A {\n"
       "  method() { return super.x === 2 ? super.method() : -1; }\n"
       "}\n"
       "return new B().method();\n",
       handle(Smi::FromInt(1), isolate)},
      {"var object = { setY(v) { super.y = v; }};\n"
       "object.setY(10);\n"
       "return object.y;\n",
       handle(Smi::FromInt(10), isolate)},
  };

  for (size_t i = 0; i < arraysize(examples); ++i) {
    std::string source(InterpreterTester::SourceForBody(examples[i].first));
    InterpreterTester tester(isolate, source.c_str(), "*");
    auto callable = tester.GetCallable<>();
    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*examples[i].second));
  }
}

TEST(InterpreterConstDeclaration) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();

  std::pair<const char*, Handle<Object>> const_decl[] = {
      {"const x = 3; return x;", handle(Smi::FromInt(3), isolate)},
      {"let x = 10; x = x + 20; return x;", handle(Smi::FromInt(30), isolate)},
      {"let x = 10; x = 20; return x;", handle(Smi::FromInt(20), isolate)},
      {"let x; x = 20; return x;", handle(Smi::FromInt(20), isolate)},
      {"let x; return x;", factory->undefined_value()},
      {"var x = 10; { let x = 30; } return x;",
       handle(Smi::FromInt(10), isolate)},
      {"let x = 10; { let x = 20; } return x;",
       handle(Smi::FromInt(10), isolate)},
      {"var x = 10; eval('let x = 20;'); return x;",
       handle(Smi::FromInt(10), isolate)},
      {"var x = 10; eval('const x = 20;'); return x;",
       handle(Smi::FromInt(10), isolate)},
      {"var x = 10; { const x = 20; } return x;",
       handle(Smi::FromInt(10), isolate)},
      {"var x = 10; { const x = 20; return x;} return -1;",
       handle(Smi::FromInt(20), isolate)},
      {"var a = 10;\n"
       "for (var i = 0; i < 10; ++i) {\n"
       " const x = i;\n"  // const declarations are block scoped.
       " a = a + x;\n"
       "}\n"
       "return a;\n",
       handle(Smi::FromInt(55), isolate)},
  };

  // Tests for sloppy mode.
  for (size_t i = 0; i < arraysize(const_decl); i++) {
    std::string source(InterpreterTester::SourceForBody(const_decl[i].first));
    InterpreterTester tester(isolate, source.c_str());
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*const_decl[i].second));
  }

  // Tests for strict mode.
  for (size_t i = 0; i < arraysize(const_decl); i++) {
    std::string strict_body =
        "'use strict'; " + std::string(const_decl[i].first);
    std::string source(InterpreterTester::SourceForBody(strict_body.c_str()));
    InterpreterTester tester(isolate, source.c_str());
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*const_decl[i].second));
  }
}

TEST(InterpreterConstDeclarationLookupSlots) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();

  std::pair<const char*, Handle<Object>> const_decl[] = {
      {"const x = 3; function f1() {return x;}; return x;",
       handle(Smi::FromInt(3), isolate)},
      {"let x = 10; x = x + 20; function f1() {return x;}; return x;",
       handle(Smi::FromInt(30), isolate)},
      {"let x; x = 20; function f1() {return x;}; return x;",
       handle(Smi::FromInt(20), isolate)},
      {"let x; function f1() {return x;}; return x;",
       factory->undefined_value()},
  };

  // Tests for sloppy mode.
  for (size_t i = 0; i < arraysize(const_decl); i++) {
    std::string source(InterpreterTester::SourceForBody(const_decl[i].first));
    InterpreterTester tester(isolate, source.c_str());
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*const_decl[i].second));
  }

  // Tests for strict mode.
  for (size_t i = 0; i < arraysize(const_decl); i++) {
    std::string strict_body =
        "'use strict'; " + std::string(const_decl[i].first);
    std::string source(InterpreterTester::SourceForBody(strict_body.c_str()));
    InterpreterTester tester(isolate, source.c_str());
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*const_decl[i].second));
  }
}

TEST(InterpreterConstInLookupContextChain) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();

  const char* prologue =
      "function OuterMost() {\n"
      "  const outerConst = 10;\n"
      "  let outerLet = 20;\n"
      "  function Outer() {\n"
      "    function Inner() {\n"
      "      this.innerFunc = function() { ";
  const char* epilogue =
      "      }\n"
      "    }\n"
      "    this.getInnerFunc ="
      "         function() {return new Inner().innerFunc;}\n"
      "  }\n"
      "  this.getOuterFunc ="
      "     function() {return new Outer().getInnerFunc();}"
      "}\n"
      "var f = new OuterMost().getOuterFunc();\n"
      "f();\n";
  std::pair<const char*, Handle<Object>> const_decl[] = {
      {"return outerConst;", handle(Smi::FromInt(10), isolate)},
      {"return outerLet;", handle(Smi::FromInt(20), isolate)},
      {"outerLet = 30; return outerLet;", handle(Smi::FromInt(30), isolate)},
      {"var outerLet = 40; return outerLet;",
       handle(Smi::FromInt(40), isolate)},
      {"var outerConst = 50; return outerConst;",
       handle(Smi::FromInt(50), isolate)},
      {"try { outerConst = 30 } catch(e) { return -1; }",
       handle(Smi::FromInt(-1), isolate)}};

  for (size_t i = 0; i < arraysize(const_decl); i++) {
    std::string script = std::string(prologue) +
                         std::string(const_decl[i].first) +
                         std::string(epilogue);
    InterpreterTester tester(isolate, script.c_str(), "*");
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*const_decl[i].second));
  }
}

TEST(InterpreterIllegalConstDeclaration) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();

  std::pair<const char*, const char*> const_decl[] = {
      {"const x = x = 10 + 3; return x;",
       "Uncaught ReferenceError: Cannot access 'x' before initialization"},
      {"const x = 10; x = 20; return x;",
       "Uncaught TypeError: Assignment to constant variable."},
      {"const x = 10; { x = 20; } return x;",
       "Uncaught TypeError: Assignment to constant variable."},
      {"const x = 10; eval('x = 20;'); return x;",
       "Uncaught TypeError: Assignment to constant variable."},
      {"let x = x + 10; return x;",
       "Uncaught ReferenceError: Cannot access 'x' before initialization"},
      {"'use strict'; (function f1() { f1 = 123; })() ",
       "Uncaught TypeError: Assignment to constant variable."},
  };

  // Tests for sloppy mode.
  for (size_t i = 0; i < arraysize(const_decl); i++) {
    std::string source(InterpreterTester::SourceForBody(const_decl[i].first));
    InterpreterTester tester(isolate, source.c_str());
    v8::Local<v8::String> message = tester.CheckThrowsReturnMessage()->Get();
    v8::Local<v8::String> expected_string = v8_str(const_decl[i].second);
    CHECK(
        message->Equals(CcTest::isolate()->GetCurrentContext(), expected_string)
            .FromJust());
  }

  // Tests for strict mode.
  for (size_t i = 0; i < arraysize(const_decl); i++) {
    std::string strict_body =
        "'use strict'; " + std::string(const_decl[i].first);
    std::string source(InterpreterTester::SourceForBody(strict_body.c_str()));
    InterpreterTester tester(isolate, source.c_str());
    v8::Local<v8::String> message = tester.CheckThrowsReturnMessage()->Get();
    v8::Local<v8::String> expected_string = v8_str(const_decl[i].second);
    CHECK(
        message->Equals(CcTest::isolate()->GetCurrentContext(), expected_string)
            .FromJust());
  }
}

TEST(InterpreterGenerators) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Factory* factory = isolate->factory();

  std::pair<const char*, Handle<Object>> tests[] = {
      {"function* f() { }; return f().next().value",
       factory->undefined_value()},
      {"function* f() { yield 42 }; return f().next().value",
       factory->NewNumberFromInt(42)},
      {"function* f() { for (let x of [42]) yield x}; return f().next().value",
       factory->NewNumberFromInt(42)},
  };

  for (size_t i = 0; i < arraysize(tests); i++) {
    std::string source(InterpreterTester::SourceForBody(tests[i].first));
    InterpreterTester tester(isolate, source.c_str());
    auto callable = tester.GetCallable<>();

    Handle<i::Object> return_value = callable().ToHandleChecked();
    CHECK(return_value->SameValue(*tests[i].second));
  }
}

#ifndef V8_TARGET_ARCH_ARM
TEST(InterpreterWithNativeStack) {
  i::FLAG_interpreted_frames_native_stack = true;

  HandleAndZoneScope handles;
  i::Isolate* isolate = handles.main_isolate();

  const char* source_text =
      "function testInterpreterWithNativeStack(a,b) { return a + b };";

  i::Handle<i::Object> o = v8::Utils::OpenHandle(*v8_compile(source_text));
  i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o);

  CHECK(f->shared().HasBytecodeArray());
  i::Code code = f->shared().GetCode();
  i::Handle<i::Code> interpreter_entry_trampoline =
      BUILTIN_CODE(isolate, InterpreterEntryTrampoline);

  CHECK(code.IsCode());
  CHECK(code.is_interpreter_trampoline_builtin());
  CHECK_NE(code.address(), interpreter_entry_trampoline->address());
}
#endif  // V8_TARGET_ARCH_ARM

TEST(InterpreterGetBytecodeHandler) {
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();
  Interpreter* interpreter = isolate->interpreter();

  // Test that single-width bytecode handlers deserializer correctly.
  Code wide_handler =
      interpreter->GetBytecodeHandler(Bytecode::kWide, OperandScale::kSingle);

  CHECK_EQ(wide_handler.builtin_index(), Builtins::kWideHandler);

  Code add_handler =
      interpreter->GetBytecodeHandler(Bytecode::kAdd, OperandScale::kSingle);

  CHECK_EQ(add_handler.builtin_index(), Builtins::kAddHandler);

  // Test that double-width bytecode handlers deserializer correctly, including
  // an illegal bytecode handler since there is no Wide.Wide handler.
  Code wide_wide_handler =
      interpreter->GetBytecodeHandler(Bytecode::kWide, OperandScale::kDouble);

  CHECK_EQ(wide_wide_handler.builtin_index(), Builtins::kIllegalHandler);

  Code add_wide_handler =
      interpreter->GetBytecodeHandler(Bytecode::kAdd, OperandScale::kDouble);

  CHECK_EQ(add_wide_handler.builtin_index(), Builtins::kAddWideHandler);
}

TEST(InterpreterCollectSourcePositions) {
  FLAG_enable_lazy_source_positions = true;
  FLAG_stress_lazy_source_positions = false;
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();

  const char* source =
      "(function () {\n"
      "  return 1;\n"
      "})";

  Handle<JSFunction> function = Handle<JSFunction>::cast(v8::Utils::OpenHandle(
      *v8::Local<v8::Function>::Cast(CompileRun(source))));

  Handle<SharedFunctionInfo> sfi = handle(function->shared(), isolate);
  Handle<BytecodeArray> bytecode_array =
      handle(sfi->GetBytecodeArray(), isolate);
  CHECK(!bytecode_array->HasSourcePositionTable());

  Compiler::CollectSourcePositions(isolate, sfi);

  ByteArray source_position_table = bytecode_array->SourcePositionTable();
  CHECK(bytecode_array->HasSourcePositionTable());
  CHECK_GT(source_position_table.length(), 0);
}

TEST(InterpreterCollectSourcePositions_StackOverflow) {
  FLAG_enable_lazy_source_positions = true;
  FLAG_stress_lazy_source_positions = false;
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();

  const char* source =
      "(function () {\n"
      "  return 1;\n"
      "})";

  Handle<JSFunction> function = Handle<JSFunction>::cast(v8::Utils::OpenHandle(
      *v8::Local<v8::Function>::Cast(CompileRun(source))));

  Handle<SharedFunctionInfo> sfi = handle(function->shared(), isolate);
  Handle<BytecodeArray> bytecode_array =
      handle(sfi->GetBytecodeArray(), isolate);
  CHECK(!bytecode_array->HasSourcePositionTable());

  // Make the stack limit the same as the current position so recompilation
  // overflows.
  uint64_t previous_limit = isolate->stack_guard()->real_climit();
  isolate->stack_guard()->SetStackLimit(GetCurrentStackPosition());
  Compiler::CollectSourcePositions(isolate, sfi);
  // Stack overflowed so source position table can be returned but is empty.
  ByteArray source_position_table = bytecode_array->SourcePositionTable();
  CHECK(!bytecode_array->HasSourcePositionTable());
  CHECK_EQ(source_position_table.length(), 0);

  // Reset the stack limit and try again.
  isolate->stack_guard()->SetStackLimit(previous_limit);
  Compiler::CollectSourcePositions(isolate, sfi);
  source_position_table = bytecode_array->SourcePositionTable();
  CHECK(bytecode_array->HasSourcePositionTable());
  CHECK_GT(source_position_table.length(), 0);
}

TEST(InterpreterCollectSourcePositions_ThrowFrom1stFrame) {
  FLAG_enable_lazy_source_positions = true;
  FLAG_stress_lazy_source_positions = false;
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();

  const char* source =
      R"javascript(
      (function () {
        throw new Error();
      });
      )javascript";

  Handle<JSFunction> function = Handle<JSFunction>::cast(v8::Utils::OpenHandle(
      *v8::Local<v8::Function>::Cast(CompileRun(source))));

  Handle<SharedFunctionInfo> sfi = handle(function->shared(), isolate);
  // This is the bytecode for the top-level iife.
  Handle<BytecodeArray> bytecode_array =
      handle(sfi->GetBytecodeArray(), isolate);
  CHECK(!bytecode_array->HasSourcePositionTable());

  {
    v8::TryCatch try_catch(CcTest::isolate());
    MaybeHandle<Object> result = Execution::Call(
        isolate, function, ReadOnlyRoots(isolate).undefined_value_handle(), 0,
        nullptr);
    CHECK(result.is_null());
    CHECK(try_catch.HasCaught());
  }

  // The exception was caught but source positions were not retrieved from it so
  // there should be no source position table.
  CHECK(!bytecode_array->HasSourcePositionTable());
}

TEST(InterpreterCollectSourcePositions_ThrowFrom2ndFrame) {
  FLAG_enable_lazy_source_positions = true;
  FLAG_stress_lazy_source_positions = false;
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();

  const char* source =
      R"javascript(
      (function () {
        (function () {
          throw new Error();
        })();
      });
      )javascript";

  Handle<JSFunction> function = Handle<JSFunction>::cast(v8::Utils::OpenHandle(
      *v8::Local<v8::Function>::Cast(CompileRun(source))));

  Handle<SharedFunctionInfo> sfi = handle(function->shared(), isolate);
  // This is the bytecode for the top-level iife.
  Handle<BytecodeArray> bytecode_array =
      handle(sfi->GetBytecodeArray(), isolate);
  CHECK(!bytecode_array->HasSourcePositionTable());

  {
    v8::TryCatch try_catch(CcTest::isolate());
    MaybeHandle<Object> result = Execution::Call(
        isolate, function, ReadOnlyRoots(isolate).undefined_value_handle(), 0,
        nullptr);
    CHECK(result.is_null());
    CHECK(try_catch.HasCaught());
  }

  // The exception was caught but source positions were not retrieved from it so
  // there should be no source position table.
  CHECK(!bytecode_array->HasSourcePositionTable());
}

namespace {

void CheckStringEqual(const char* expected_ptr, const char* actual_ptr) {
  CHECK_NOT_NULL(expected_ptr);
  CHECK_NOT_NULL(actual_ptr);
  std::string expected(expected_ptr);
  std::string actual(actual_ptr);
  CHECK_EQ(expected, actual);
}

void CheckStringEqual(const char* expected_ptr, Handle<Object> actual_handle) {
  v8::String::Utf8Value utf8(
      v8::Isolate::GetCurrent(),
      v8::Utils::ToLocal(Handle<String>::cast(actual_handle)));
  CheckStringEqual(expected_ptr, *utf8);
}

}  // namespace

TEST(InterpreterCollectSourcePositions_GenerateStackTrace) {
  FLAG_enable_lazy_source_positions = true;
  FLAG_stress_lazy_source_positions = false;
  HandleAndZoneScope handles;
  Isolate* isolate = handles.main_isolate();

  const char* source =
      R"javascript(
      (function () {
        try {
          throw new Error();
        } catch (e) {
          return e.stack;
        }
      });
      )javascript";

  Handle<JSFunction> function = Handle<JSFunction>::cast(v8::Utils::OpenHandle(
      *v8::Local<v8::Function>::Cast(CompileRun(source))));

  Handle<SharedFunctionInfo> sfi = handle(function->shared(), isolate);
  Handle<BytecodeArray> bytecode_array =
      handle(sfi->GetBytecodeArray(), isolate);
  CHECK(!bytecode_array->HasSourcePositionTable());

  {
    Handle<Object> result =
        Execution::Call(isolate, function,
                        ReadOnlyRoots(isolate).undefined_value_handle(), 0,
                        nullptr)
            .ToHandleChecked();
    CheckStringEqual("Error\n    at <anonymous>:4:17", result);
  }

  CHECK(bytecode_array->HasSourcePositionTable());
  ByteArray source_position_table = bytecode_array->SourcePositionTable();
  CHECK_GT(source_position_table.length(), 0);
}

TEST(InterpreterLookupNameOfBytecodeHandler) {
  Interpreter* interpreter = CcTest::i_isolate()->interpreter();
  Code ldaLookupSlot = interpreter->GetBytecodeHandler(Bytecode::kLdaLookupSlot,
                                                       OperandScale::kSingle);
  CheckStringEqual("LdaLookupSlotHandler",
                   interpreter->LookupNameOfBytecodeHandler(ldaLookupSlot));
  Code wideLdaLookupSlot = interpreter->GetBytecodeHandler(
      Bytecode::kLdaLookupSlot, OperandScale::kDouble);
  CheckStringEqual("LdaLookupSlotWideHandler",
                   interpreter->LookupNameOfBytecodeHandler(wideLdaLookupSlot));
  Code extraWideLdaLookupSlot = interpreter->GetBytecodeHandler(
      Bytecode::kLdaLookupSlot, OperandScale::kQuadruple);
  CheckStringEqual(
      "LdaLookupSlotExtraWideHandler",
      interpreter->LookupNameOfBytecodeHandler(extraWideLdaLookupSlot));
}

}  // namespace interpreter
}  // namespace internal
}  // namespace v8
