// Copyright 2014 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 <limits>

#include "src/init/v8.h"

#include "src/ast/scopes.h"
#include "src/interpreter/bytecode-array-builder.h"
#include "src/interpreter/bytecode-array-iterator.h"
#include "src/interpreter/bytecode-jump-table.h"
#include "src/interpreter/bytecode-label.h"
#include "src/interpreter/bytecode-register-allocator.h"
#include "src/numbers/hash-seed-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/smi.h"
#include "test/unittests/interpreter/bytecode-utils.h"
#include "test/unittests/test-utils.h"

namespace v8 {
namespace internal {
namespace interpreter {

class BytecodeArrayBuilderTest : public TestWithIsolateAndZone {
 public:
  BytecodeArrayBuilderTest() = default;
  ~BytecodeArrayBuilderTest() override = default;
};

using ToBooleanMode = BytecodeArrayBuilder::ToBooleanMode;

TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
  FeedbackVectorSpec feedback_spec(zone());
  BytecodeArrayBuilder builder(zone(), 1, 131, &feedback_spec);
  Factory* factory = isolate()->factory();
  AstValueFactory ast_factory(zone(), isolate()->ast_string_constants(),
                              HashSeed(isolate()));
  DeclarationScope scope(zone(), &ast_factory);

  CHECK_EQ(builder.locals_count(), 131);
  CHECK_EQ(builder.fixed_register_count(), 131);

  Register reg(0);
  Register other(reg.index() + 1);
  Register wide(128);
  RegisterList empty;
  RegisterList single = BytecodeUtils::NewRegisterList(0, 1);
  RegisterList pair = BytecodeUtils::NewRegisterList(0, 2);
  RegisterList triple = BytecodeUtils::NewRegisterList(0, 3);
  RegisterList reg_list = BytecodeUtils::NewRegisterList(0, 10);

  // Emit argument creation operations.
  builder.CreateArguments(CreateArgumentsType::kMappedArguments)
      .CreateArguments(CreateArgumentsType::kUnmappedArguments)
      .CreateArguments(CreateArgumentsType::kRestParameter);

  // Emit constant loads.
  builder.LoadLiteral(Smi::zero())
      .StoreAccumulatorInRegister(reg)
      .LoadLiteral(Smi::FromInt(8))
      .CompareOperation(Token::Value::EQ, reg,
                        1)  // Prevent peephole optimization
                            // LdaSmi, Star -> LdrSmi.
      .StoreAccumulatorInRegister(reg)
      .LoadLiteral(Smi::FromInt(10000000))
      .StoreAccumulatorInRegister(reg)
      .LoadLiteral(ast_factory.GetOneByteString("A constant"))
      .StoreAccumulatorInRegister(reg)
      .LoadUndefined()
      .StoreAccumulatorInRegister(reg)
      .LoadNull()
      .StoreAccumulatorInRegister(reg)
      .LoadTheHole()
      .StoreAccumulatorInRegister(reg)
      .LoadTrue()
      .StoreAccumulatorInRegister(reg)
      .LoadFalse()
      .StoreAccumulatorInRegister(wide);

  // Emit Ldar and Star taking care to foil the register optimizer.
  builder.LoadAccumulatorWithRegister(other)
      .BinaryOperation(Token::ADD, reg, 1)
      .StoreAccumulatorInRegister(reg)
      .LoadNull();

  // Emit register-register transfer.
  builder.MoveRegister(reg, other);
  builder.MoveRegister(reg, wide);

  FeedbackSlot load_global_slot =
      feedback_spec.AddLoadGlobalICSlot(NOT_INSIDE_TYPEOF);
  FeedbackSlot load_global_typeof_slot =
      feedback_spec.AddLoadGlobalICSlot(INSIDE_TYPEOF);
  FeedbackSlot sloppy_store_global_slot =
      feedback_spec.AddStoreGlobalICSlot(LanguageMode::kSloppy);
  FeedbackSlot load_slot = feedback_spec.AddLoadICSlot();
  FeedbackSlot call_slot = feedback_spec.AddCallICSlot();
  FeedbackSlot keyed_load_slot = feedback_spec.AddKeyedLoadICSlot();
  FeedbackSlot sloppy_store_slot =
      feedback_spec.AddStoreICSlot(LanguageMode::kSloppy);
  FeedbackSlot strict_store_slot =
      feedback_spec.AddStoreICSlot(LanguageMode::kStrict);
  FeedbackSlot sloppy_keyed_store_slot =
      feedback_spec.AddKeyedStoreICSlot(LanguageMode::kSloppy);
  FeedbackSlot strict_keyed_store_slot =
      feedback_spec.AddKeyedStoreICSlot(LanguageMode::kStrict);
  FeedbackSlot store_own_slot = feedback_spec.AddStoreOwnICSlot();
  FeedbackSlot store_array_element_slot =
      feedback_spec.AddStoreInArrayLiteralICSlot();

  // Emit global load / store operations.
  const AstRawString* name = ast_factory.GetOneByteString("var_name");
  builder
      .LoadGlobal(name, load_global_slot.ToInt(), TypeofMode::NOT_INSIDE_TYPEOF)
      .LoadGlobal(name, load_global_typeof_slot.ToInt(),
                  TypeofMode::INSIDE_TYPEOF)
      .StoreGlobal(name, sloppy_store_global_slot.ToInt());

  // Emit context operations.
  builder.PushContext(reg)
      .PopContext(reg)
      .LoadContextSlot(reg, 1, 0, BytecodeArrayBuilder::kMutableSlot)
      .StoreContextSlot(reg, 1, 0)
      .LoadContextSlot(reg, 2, 0, BytecodeArrayBuilder::kImmutableSlot)
      .StoreContextSlot(reg, 3, 0);

  // Emit context operations which operate on the local context.
  builder
      .LoadContextSlot(Register::current_context(), 1, 0,
                       BytecodeArrayBuilder::kMutableSlot)
      .StoreContextSlot(Register::current_context(), 1, 0)
      .LoadContextSlot(Register::current_context(), 2, 0,
                       BytecodeArrayBuilder::kImmutableSlot)
      .StoreContextSlot(Register::current_context(), 3, 0);

  // Emit load / store property operations.
  builder.LoadNamedProperty(reg, name, load_slot.ToInt())
      .LoadNamedPropertyNoFeedback(reg, name)
      .LoadNamedPropertyFromSuper(reg, name, load_slot.ToInt())
      .LoadKeyedProperty(reg, keyed_load_slot.ToInt())
      .StoreNamedProperty(reg, name, sloppy_store_slot.ToInt(),
                          LanguageMode::kSloppy)
      .StoreNamedPropertyNoFeedback(reg, name, LanguageMode::kStrict)
      .StoreNamedPropertyNoFeedback(reg, name, LanguageMode::kSloppy)
      .StoreKeyedProperty(reg, reg, sloppy_keyed_store_slot.ToInt(),
                          LanguageMode::kSloppy)
      .StoreNamedProperty(reg, name, strict_store_slot.ToInt(),
                          LanguageMode::kStrict)
      .StoreKeyedProperty(reg, reg, strict_keyed_store_slot.ToInt(),
                          LanguageMode::kStrict)
      .StoreNamedOwnProperty(reg, name, store_own_slot.ToInt())
      .StoreInArrayLiteral(reg, reg, store_array_element_slot.ToInt());

  // Emit Iterator-protocol operations
  builder.GetIterator(reg, load_slot.ToInt(), call_slot.ToInt());

  // Emit load / store lookup slots.
  builder.LoadLookupSlot(name, TypeofMode::NOT_INSIDE_TYPEOF)
      .LoadLookupSlot(name, TypeofMode::INSIDE_TYPEOF)
      .StoreLookupSlot(name, LanguageMode::kSloppy, LookupHoistingMode::kNormal)
      .StoreLookupSlot(name, LanguageMode::kSloppy,
                       LookupHoistingMode::kLegacySloppy)
      .StoreLookupSlot(name, LanguageMode::kStrict,
                       LookupHoistingMode::kNormal);

  // Emit load / store lookup slots with context fast paths.
  builder.LoadLookupContextSlot(name, TypeofMode::NOT_INSIDE_TYPEOF, 1, 0)
      .LoadLookupContextSlot(name, TypeofMode::INSIDE_TYPEOF, 1, 0);

  // Emit load / store lookup slots with global fast paths.
  builder.LoadLookupGlobalSlot(name, TypeofMode::NOT_INSIDE_TYPEOF, 1, 0)
      .LoadLookupGlobalSlot(name, TypeofMode::INSIDE_TYPEOF, 1, 0);

  // Emit closure operations.
  builder.CreateClosure(0, 1, static_cast<int>(AllocationType::kYoung));

  // Emit create context operation.
  builder.CreateBlockContext(&scope);
  builder.CreateCatchContext(reg, &scope);
  builder.CreateFunctionContext(&scope, 1);
  builder.CreateEvalContext(&scope, 1);
  builder.CreateWithContext(reg, &scope);

  // Emit literal creation operations.
  builder.CreateRegExpLiteral(ast_factory.GetOneByteString("a"), 0, 0);
  builder.CreateArrayLiteral(0, 0, 0);
  builder.CreateObjectLiteral(0, 0, 0);

  // Emit tagged template operations.
  builder.GetTemplateObject(0, 0);

  // Call operations.
  builder.CallAnyReceiver(reg, reg_list, 1)
      .CallProperty(reg, reg_list, 1)
      .CallProperty(reg, single, 1)
      .CallProperty(reg, pair, 1)
      .CallProperty(reg, triple, 1)
      .CallUndefinedReceiver(reg, reg_list, 1)
      .CallUndefinedReceiver(reg, empty, 1)
      .CallUndefinedReceiver(reg, single, 1)
      .CallUndefinedReceiver(reg, pair, 1)
      .CallRuntime(Runtime::kIsArray, reg)
      .CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, reg_list, pair)
      .CallJSRuntime(Context::OBJECT_CREATE, reg_list)
      .CallWithSpread(reg, reg_list, 1)
      .CallNoFeedback(reg, reg_list);

  // Emit binary operator invocations.
  builder.BinaryOperation(Token::Value::ADD, reg, 1)
      .BinaryOperation(Token::Value::SUB, reg, 2)
      .BinaryOperation(Token::Value::MUL, reg, 3)
      .BinaryOperation(Token::Value::DIV, reg, 4)
      .BinaryOperation(Token::Value::MOD, reg, 5)
      .BinaryOperation(Token::Value::EXP, reg, 6);

  // Emit bitwise operator invocations
  builder.BinaryOperation(Token::Value::BIT_OR, reg, 6)
      .BinaryOperation(Token::Value::BIT_XOR, reg, 7)
      .BinaryOperation(Token::Value::BIT_AND, reg, 8);

  // Emit shift operator invocations
  builder.BinaryOperation(Token::Value::SHL, reg, 9)
      .BinaryOperation(Token::Value::SAR, reg, 10)
      .BinaryOperation(Token::Value::SHR, reg, 11);

  // Emit Smi binary operations.
  builder.BinaryOperationSmiLiteral(Token::Value::ADD, Smi::FromInt(42), 2)
      .BinaryOperationSmiLiteral(Token::Value::SUB, Smi::FromInt(42), 2)
      .BinaryOperationSmiLiteral(Token::Value::MUL, Smi::FromInt(42), 2)
      .BinaryOperationSmiLiteral(Token::Value::DIV, Smi::FromInt(42), 2)
      .BinaryOperationSmiLiteral(Token::Value::MOD, Smi::FromInt(42), 2)
      .BinaryOperationSmiLiteral(Token::Value::EXP, Smi::FromInt(42), 2)
      .BinaryOperationSmiLiteral(Token::Value::BIT_OR, Smi::FromInt(42), 2)
      .BinaryOperationSmiLiteral(Token::Value::BIT_XOR, Smi::FromInt(42), 2)
      .BinaryOperationSmiLiteral(Token::Value::BIT_AND, Smi::FromInt(42), 2)
      .BinaryOperationSmiLiteral(Token::Value::SHL, Smi::FromInt(42), 2)
      .BinaryOperationSmiLiteral(Token::Value::SAR, Smi::FromInt(42), 2)
      .BinaryOperationSmiLiteral(Token::Value::SHR, Smi::FromInt(42), 2);

  // Emit unary and count operator invocations.
  builder.UnaryOperation(Token::Value::INC, 1)
      .UnaryOperation(Token::Value::DEC, 1)
      .UnaryOperation(Token::Value::ADD, 1)
      .UnaryOperation(Token::Value::SUB, 1)
      .UnaryOperation(Token::Value::BIT_NOT, 1);

  // Emit unary operator invocations.
  builder.LogicalNot(ToBooleanMode::kConvertToBoolean)
      .LogicalNot(ToBooleanMode::kAlreadyBoolean)
      .TypeOf();

  // Emit delete
  builder.Delete(reg, LanguageMode::kSloppy).Delete(reg, LanguageMode::kStrict);

  // Emit construct.
  builder.Construct(reg, reg_list, 1).ConstructWithSpread(reg, reg_list, 1);

  // Emit test operator invocations.
  builder.CompareOperation(Token::Value::EQ, reg, 1)
      .CompareOperation(Token::Value::EQ_STRICT, reg, 2)
      .CompareOperation(Token::Value::LT, reg, 3)
      .CompareOperation(Token::Value::GT, reg, 4)
      .CompareOperation(Token::Value::LTE, reg, 5)
      .CompareOperation(Token::Value::GTE, reg, 6)
      .CompareTypeOf(TestTypeOfFlags::LiteralFlag::kNumber)
      .CompareOperation(Token::Value::INSTANCEOF, reg, 7)
      .CompareOperation(Token::Value::IN, reg, 8)
      .CompareReference(reg)
      .CompareUndetectable()
      .CompareUndefined()
      .CompareNull();

  // Emit conversion operator invocations.
  builder.ToNumber(1).ToNumeric(1).ToObject(reg).ToName(reg).ToString();

  // Emit GetSuperConstructor.
  builder.GetSuperConstructor(reg);

  // Constructor check for GetSuperConstructor.
  builder.ThrowIfNotSuperConstructor(reg);

  // Hole checks.
  builder.ThrowReferenceErrorIfHole(name)
      .ThrowSuperAlreadyCalledIfNotHole()
      .ThrowSuperNotCalledIfHole();

  // Short jumps with Imm8 operands
  {
    BytecodeLoopHeader loop_header;
    BytecodeLabel after_jump1, after_jump2, after_jump3, after_jump4,
        after_jump5, after_jump6, after_jump7, after_jump8, after_jump9,
        after_jump10, after_jump11, after_loop;
    builder.JumpIfNull(&after_loop)
        .Bind(&loop_header)
        .Jump(&after_jump1)
        .Bind(&after_jump1)
        .JumpIfNull(&after_jump2)
        .Bind(&after_jump2)
        .JumpIfNotNull(&after_jump3)
        .Bind(&after_jump3)
        .JumpIfUndefined(&after_jump4)
        .Bind(&after_jump4)
        .JumpIfNotUndefined(&after_jump5)
        .Bind(&after_jump5)
        .JumpIfUndefinedOrNull(&after_jump6)
        .Bind(&after_jump6)
        .JumpIfJSReceiver(&after_jump7)
        .Bind(&after_jump7)
        .JumpIfTrue(ToBooleanMode::kConvertToBoolean, &after_jump8)
        .Bind(&after_jump8)
        .JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &after_jump9)
        .Bind(&after_jump9)
        .JumpIfFalse(ToBooleanMode::kConvertToBoolean, &after_jump10)
        .Bind(&after_jump10)
        .JumpIfFalse(ToBooleanMode::kAlreadyBoolean, &after_jump11)
        .Bind(&after_jump11)
        .JumpLoop(&loop_header, 0, 0)
        .Bind(&after_loop);
  }

  BytecodeLabel end[11];
  {
    // Longer jumps with constant operands
    BytecodeLabel after_jump;
    builder.JumpIfNull(&after_jump)
        .Jump(&end[0])
        .Bind(&after_jump)
        .JumpIfTrue(ToBooleanMode::kConvertToBoolean, &end[1])
        .JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &end[2])
        .JumpIfFalse(ToBooleanMode::kConvertToBoolean, &end[3])
        .JumpIfFalse(ToBooleanMode::kAlreadyBoolean, &end[4])
        .JumpIfNull(&end[5])
        .JumpIfNotNull(&end[6])
        .JumpIfUndefined(&end[7])
        .JumpIfNotUndefined(&end[8])
        .JumpIfUndefinedOrNull(&end[9])
        .LoadLiteral(ast_factory.prototype_string())
        .JumpIfJSReceiver(&end[10]);
  }

  // Emit Smi table switch bytecode.
  BytecodeJumpTable* jump_table = builder.AllocateJumpTable(1, 0);
  builder.SwitchOnSmiNoFeedback(jump_table).Bind(jump_table, 0);

  // Emit set pending message bytecode.
  builder.SetPendingMessage();

  // Emit throw and re-throw in it's own basic block so that the rest of the
  // code isn't omitted due to being dead.
  BytecodeLabel after_throw, after_rethrow;
  builder.JumpIfNull(&after_throw).Throw().Bind(&after_throw);
  builder.JumpIfNull(&after_rethrow).ReThrow().Bind(&after_rethrow);

  builder.ForInEnumerate(reg)
      .ForInPrepare(triple, 1)
      .ForInContinue(reg, reg)
      .ForInNext(reg, reg, pair, 1)
      .ForInStep(reg);

  // Wide constant pool loads
  for (int i = 0; i < 256; i++) {
    // Emit junk in constant pool to force wide constant pool index.
    builder.LoadLiteral(2.5321 + i);
  }
  builder.LoadLiteral(Smi::FromInt(20000000));
  const AstRawString* wide_name = ast_factory.GetOneByteString("var_wide_name");

  builder.StoreDataPropertyInLiteral(reg, reg,
                                     DataPropertyInLiteralFlag::kNoFlags, 0);

  // Emit wide context operations.
  builder.LoadContextSlot(reg, 1024, 0, BytecodeArrayBuilder::kMutableSlot)
      .StoreContextSlot(reg, 1024, 0);

  // Emit wide load / store lookup slots.
  builder.LoadLookupSlot(wide_name, TypeofMode::NOT_INSIDE_TYPEOF)
      .LoadLookupSlot(wide_name, TypeofMode::INSIDE_TYPEOF)
      .StoreLookupSlot(wide_name, LanguageMode::kSloppy,
                       LookupHoistingMode::kNormal)
      .StoreLookupSlot(wide_name, LanguageMode::kSloppy,
                       LookupHoistingMode::kLegacySloppy)
      .StoreLookupSlot(wide_name, LanguageMode::kStrict,
                       LookupHoistingMode::kNormal);

  // CreateClosureWide
  builder.CreateClosure(1000, 321, static_cast<int>(AllocationType::kYoung));

  // Emit wide variant of literal creation operations.
  builder
      .CreateRegExpLiteral(ast_factory.GetOneByteString("wide_literal"), 0, 0)
      .CreateArrayLiteral(0, 0, 0)
      .CreateEmptyArrayLiteral(0)
      .CreateArrayFromIterable()
      .CreateObjectLiteral(0, 0, 0)
      .CreateEmptyObjectLiteral()
      .CloneObject(reg, 0, 0);

  // Emit load and store operations for module variables.
  builder.LoadModuleVariable(-1, 42)
      .LoadModuleVariable(0, 42)
      .LoadModuleVariable(1, 42)
      .StoreModuleVariable(-1, 42)
      .StoreModuleVariable(0, 42)
      .StoreModuleVariable(1, 42);

  // Emit generator operations.
  {
    // We have to skip over suspend because it returns and marks the remaining
    // bytecode dead.
    BytecodeLabel after_suspend;
    builder.JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &after_suspend)
        .SuspendGenerator(reg, reg_list, 0)
        .Bind(&after_suspend)
        .ResumeGenerator(reg, reg_list);
  }
  BytecodeJumpTable* gen_jump_table = builder.AllocateJumpTable(1, 0);
  builder.SwitchOnGeneratorState(reg, gen_jump_table).Bind(gen_jump_table, 0);

  // Intrinsics handled by the interpreter.
  builder.CallRuntime(Runtime::kInlineIsArray, reg_list);

  // Emit debugger bytecode.
  builder.Debugger();

  // Emit abort bytecode.
  BytecodeLabel after_abort;
  builder.JumpIfNull(&after_abort)
      .Abort(AbortReason::kOperandIsASmi)
      .Bind(&after_abort);

  // Insert dummy ops to force longer jumps.
  for (int i = 0; i < 256; i++) {
    builder.Debugger();
  }

  // Emit block counter increments.
  builder.IncBlockCounter(0);

  // Bind labels for long jumps at the very end.
  for (size_t i = 0; i < arraysize(end); i++) {
    builder.Bind(&end[i]);
  }

  // Return must be the last instruction.
  builder.Return();

  // Generate BytecodeArray.
  scope.SetScriptScopeInfo(factory->NewScopeInfo(1));
  ast_factory.Internalize(isolate());
  Handle<BytecodeArray> the_array = builder.ToBytecodeArray(isolate());
  CHECK_EQ(the_array->frame_size(),
           builder.total_register_count() * kSystemPointerSize);

  // Build scorecard of bytecodes encountered in the BytecodeArray.
  std::vector<int> scorecard(Bytecodes::ToByte(Bytecode::kLast) + 1);

  Bytecode final_bytecode = Bytecode::kLdaZero;
  int i = 0;
  while (i < the_array->length()) {
    uint8_t code = the_array->get(i);
    scorecard[code] += 1;
    final_bytecode = Bytecodes::FromByte(code);
    OperandScale operand_scale = OperandScale::kSingle;
    int prefix_offset = 0;
    if (Bytecodes::IsPrefixScalingBytecode(final_bytecode)) {
      operand_scale = Bytecodes::PrefixBytecodeToOperandScale(final_bytecode);
      prefix_offset = 1;
      code = the_array->get(i + 1);
      scorecard[code] += 1;
      final_bytecode = Bytecodes::FromByte(code);
    }
    i += prefix_offset + Bytecodes::Size(final_bytecode, operand_scale);
  }

  // Insert entry for illegal bytecode as this is never willingly emitted.
  scorecard[Bytecodes::ToByte(Bytecode::kIllegal)] = 1;

  // Bytecode for CollectTypeProfile is only emitted when
  // Type Information for DevTools is turned on.
  scorecard[Bytecodes::ToByte(Bytecode::kCollectTypeProfile)] = 1;

  // Check return occurs at the end and only once in the BytecodeArray.
  CHECK_EQ(final_bytecode, Bytecode::kReturn);
  CHECK_EQ(scorecard[Bytecodes::ToByte(final_bytecode)], 1);

#define CHECK_BYTECODE_PRESENT(Name, ...)                                \
  /* Check Bytecode is marked in scorecard, unless it's a debug break */ \
  if (!Bytecodes::IsDebugBreak(Bytecode::k##Name)) {                     \
    EXPECT_GE(scorecard[Bytecodes::ToByte(Bytecode::k##Name)], 1);       \
  }
  BYTECODE_LIST(CHECK_BYTECODE_PRESENT)
#undef CHECK_BYTECODE_PRESENT
}

TEST_F(BytecodeArrayBuilderTest, FrameSizesLookGood) {
  for (int locals = 0; locals < 5; locals++) {
    for (int temps = 0; temps < 3; temps++) {
      BytecodeArrayBuilder builder(zone(), 1, locals);
      BytecodeRegisterAllocator* allocator(builder.register_allocator());
      for (int i = 0; i < locals; i++) {
        builder.LoadLiteral(Smi::zero());
        builder.StoreAccumulatorInRegister(Register(i));
      }
      for (int i = 0; i < temps; i++) {
        Register temp = allocator->NewRegister();
        builder.LoadLiteral(Smi::zero());
        builder.StoreAccumulatorInRegister(temp);
        // Ensure temporaries are used so not optimized away by the
        // register optimizer.
        builder.ToName(temp);
      }
      builder.Return();

      Handle<BytecodeArray> the_array = builder.ToBytecodeArray(isolate());
      int total_registers = locals + temps;
      CHECK_EQ(the_array->frame_size(), total_registers * kSystemPointerSize);
    }
  }
}

TEST_F(BytecodeArrayBuilderTest, RegisterValues) {
  int index = 1;

  Register the_register(index);
  CHECK_EQ(the_register.index(), index);

  int actual_operand = the_register.ToOperand();
  int actual_index = Register::FromOperand(actual_operand).index();
  CHECK_EQ(actual_index, index);
}

TEST_F(BytecodeArrayBuilderTest, Parameters) {
  BytecodeArrayBuilder builder(zone(), 10, 0);

  Register receiver(builder.Receiver());
  Register param8(builder.Parameter(8));
  CHECK_EQ(receiver.index() - param8.index(), 9);
}

TEST_F(BytecodeArrayBuilderTest, Constants) {
  BytecodeArrayBuilder builder(zone(), 1, 0);
  AstValueFactory ast_factory(zone(), isolate()->ast_string_constants(),
                              HashSeed(isolate()));

  double heap_num_1 = 3.14;
  double heap_num_2 = 5.2;
  double nan = std::numeric_limits<double>::quiet_NaN();
  const AstRawString* string = ast_factory.GetOneByteString("foo");
  const AstRawString* string_copy = ast_factory.GetOneByteString("foo");

  builder.LoadLiteral(heap_num_1)
      .LoadLiteral(heap_num_2)
      .LoadLiteral(string)
      .LoadLiteral(heap_num_1)
      .LoadLiteral(heap_num_1)
      .LoadLiteral(nan)
      .LoadLiteral(string_copy)
      .LoadLiteral(heap_num_2)
      .LoadLiteral(nan)
      .Return();

  ast_factory.Internalize(isolate());
  Handle<BytecodeArray> array = builder.ToBytecodeArray(isolate());
  // Should only have one entry for each identical constant.
  EXPECT_EQ(4, array->constant_pool().length());
}

TEST_F(BytecodeArrayBuilderTest, ForwardJumps) {
  static const int kFarJumpDistance = 256 + 20;

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

  Register reg(0);
  BytecodeLabel far0, far1, far2, far3, far4;
  BytecodeLabel near0, near1, near2, near3, near4;
  BytecodeLabel after_jump_near0, after_jump_far0;

  builder.JumpIfNull(&after_jump_near0)
      .Jump(&near0)
      .Bind(&after_jump_near0)
      .CompareOperation(Token::Value::EQ, reg, 1)
      .JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &near1)
      .CompareOperation(Token::Value::EQ, reg, 2)
      .JumpIfFalse(ToBooleanMode::kAlreadyBoolean, &near2)
      .BinaryOperation(Token::Value::ADD, reg, 1)
      .JumpIfTrue(ToBooleanMode::kConvertToBoolean, &near3)
      .BinaryOperation(Token::Value::ADD, reg, 2)
      .JumpIfFalse(ToBooleanMode::kConvertToBoolean, &near4)
      .Bind(&near0)
      .Bind(&near1)
      .Bind(&near2)
      .Bind(&near3)
      .Bind(&near4)
      .JumpIfNull(&after_jump_far0)
      .Jump(&far0)
      .Bind(&after_jump_far0)
      .CompareOperation(Token::Value::EQ, reg, 3)
      .JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &far1)
      .CompareOperation(Token::Value::EQ, reg, 4)
      .JumpIfFalse(ToBooleanMode::kAlreadyBoolean, &far2)
      .BinaryOperation(Token::Value::ADD, reg, 3)
      .JumpIfTrue(ToBooleanMode::kConvertToBoolean, &far3)
      .BinaryOperation(Token::Value::ADD, reg, 4)
      .JumpIfFalse(ToBooleanMode::kConvertToBoolean, &far4);
  for (int i = 0; i < kFarJumpDistance - 22; i++) {
    builder.Debugger();
  }
  builder.Bind(&far0).Bind(&far1).Bind(&far2).Bind(&far3).Bind(&far4);
  builder.Return();

  Handle<BytecodeArray> array = builder.ToBytecodeArray(isolate());
  DCHECK_EQ(array->length(), 48 + kFarJumpDistance - 22 + 1);

  BytecodeArrayIterator iterator(array);

  // Ignore JumpIfNull operation.
  iterator.Advance();

  CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
  CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), 22);
  iterator.Advance();

  // Ignore compare operation.
  iterator.Advance();

  CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrue);
  CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), 17);
  iterator.Advance();

  // Ignore compare operation.
  iterator.Advance();

  CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalse);
  CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), 12);
  iterator.Advance();

  // Ignore add operation.
  iterator.Advance();

  CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue);
  CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), 7);
  iterator.Advance();

  // Ignore add operation.
  iterator.Advance();

  CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse);
  CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), 2);
  iterator.Advance();

  // Ignore JumpIfNull operation.
  iterator.Advance();

  CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpConstant);
  CHECK_EQ(*(iterator.GetConstantForIndexOperand(0, isolate())),
           Smi::FromInt(kFarJumpDistance));
  iterator.Advance();

  // Ignore compare operation.
  iterator.Advance();

  CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrueConstant);
  CHECK_EQ(*(iterator.GetConstantForIndexOperand(0, isolate())),
           Smi::FromInt(kFarJumpDistance - 5));
  iterator.Advance();

  // Ignore compare operation.
  iterator.Advance();

  CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalseConstant);
  CHECK_EQ(*(iterator.GetConstantForIndexOperand(0, isolate())),
           Smi::FromInt(kFarJumpDistance - 10));
  iterator.Advance();

  // Ignore add operation.
  iterator.Advance();

  CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrueConstant);
  CHECK_EQ(*(iterator.GetConstantForIndexOperand(0, isolate())),
           Smi::FromInt(kFarJumpDistance - 15));
  iterator.Advance();

  // Ignore add operation.
  iterator.Advance();

  CHECK_EQ(iterator.current_bytecode(),
           Bytecode::kJumpIfToBooleanFalseConstant);
  CHECK_EQ(*(iterator.GetConstantForIndexOperand(0, isolate())),
           Smi::FromInt(kFarJumpDistance - 20));
  iterator.Advance();
}

TEST_F(BytecodeArrayBuilderTest, BackwardJumps) {
  BytecodeArrayBuilder builder(zone(), 1, 1);

  Register reg(0);

  BytecodeLabel end;
  builder.JumpIfNull(&end);

  BytecodeLabel after_loop;
  // Conditional jump to force the code after the JumpLoop to be live.
  // Technically this jump is illegal because it's jumping into the middle of
  // the subsequent loops, but that's ok for this unit test.
  BytecodeLoopHeader loop_header;
  builder.JumpIfNull(&after_loop)
      .Bind(&loop_header)
      .JumpLoop(&loop_header, 0, 0)
      .Bind(&after_loop);
  for (int i = 0; i < 42; i++) {
    BytecodeLabel after_loop;
    // Conditional jump to force the code after the JumpLoop to be live.
    builder.JumpIfNull(&after_loop)
        .JumpLoop(&loop_header, 0, 0)
        .Bind(&after_loop);
  }

  // Add padding to force wide backwards jumps.
  for (int i = 0; i < 256; i++) {
    builder.Debugger();
  }

  builder.JumpLoop(&loop_header, 0, 0);
  builder.Bind(&end);
  builder.Return();

  Handle<BytecodeArray> array = builder.ToBytecodeArray(isolate());
  BytecodeArrayIterator iterator(array);
  // Ignore the JumpIfNull to the end
  iterator.Advance();
  // Ignore the JumpIfNull to after the first JumpLoop
  iterator.Advance();
  CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpLoop);
  CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), 0);
  iterator.Advance();
  for (unsigned i = 0; i < 42; i++) {
    // Ignore the JumpIfNull to after the JumpLoop
    iterator.Advance();

    CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpLoop);
    CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
    // offset of 5 (because kJumpLoop takes two immediate operands and
    // JumpIfNull takes 1)
    CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), i * 5 + 5);
    iterator.Advance();
  }
  // Check padding to force wide backwards jumps.
  for (int i = 0; i < 256; i++) {
    CHECK_EQ(iterator.current_bytecode(), Bytecode::kDebugger);
    iterator.Advance();
  }
  CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpLoop);
  CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble);
  CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), 42 * 5 + 256 + 4);
  iterator.Advance();
  CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
  iterator.Advance();
  CHECK(iterator.done());
}

TEST_F(BytecodeArrayBuilderTest, SmallSwitch) {
  BytecodeArrayBuilder builder(zone(), 1, 1);

  // Small jump table that fits into the single-size constant pool
  int small_jump_table_size = 5;
  int small_jump_table_base = -2;
  BytecodeJumpTable* small_jump_table =
      builder.AllocateJumpTable(small_jump_table_size, small_jump_table_base);

  builder.LoadLiteral(Smi::FromInt(7)).SwitchOnSmiNoFeedback(small_jump_table);
  for (int i = 0; i < small_jump_table_size; i++) {
    builder.Bind(small_jump_table, small_jump_table_base + i).Debugger();
  }
  builder.Return();

  Handle<BytecodeArray> array = builder.ToBytecodeArray(isolate());
  BytecodeArrayIterator iterator(array);

  CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaSmi);
  iterator.Advance();

  CHECK_EQ(iterator.current_bytecode(), Bytecode::kSwitchOnSmiNoFeedback);
  CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
  {
    int i = 0;
    int switch_end =
        iterator.current_offset() + iterator.current_bytecode_size();

    for (const auto& entry : iterator.GetJumpTableTargetOffsets()) {
      CHECK_EQ(entry.case_value, small_jump_table_base + i);
      CHECK_EQ(entry.target_offset, switch_end + i);

      i++;
    }
    CHECK_EQ(i, small_jump_table_size);
  }
  iterator.Advance();

  for (int i = 0; i < small_jump_table_size; i++) {
    CHECK_EQ(iterator.current_bytecode(), Bytecode::kDebugger);
    iterator.Advance();
  }

  CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
  iterator.Advance();
  CHECK(iterator.done());
}

TEST_F(BytecodeArrayBuilderTest, WideSwitch) {
  BytecodeArrayBuilder builder(zone(), 1, 1);

  // Large jump table that requires a wide Switch bytecode.
  int large_jump_table_size = 256;
  int large_jump_table_base = -10;
  BytecodeJumpTable* large_jump_table =
      builder.AllocateJumpTable(large_jump_table_size, large_jump_table_base);

  builder.LoadLiteral(Smi::FromInt(7)).SwitchOnSmiNoFeedback(large_jump_table);
  for (int i = 0; i < large_jump_table_size; i++) {
    builder.Bind(large_jump_table, large_jump_table_base + i).Debugger();
  }
  builder.Return();

  Handle<BytecodeArray> array = builder.ToBytecodeArray(isolate());
  BytecodeArrayIterator iterator(array);

  CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaSmi);
  iterator.Advance();

  CHECK_EQ(iterator.current_bytecode(), Bytecode::kSwitchOnSmiNoFeedback);
  CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble);
  {
    int i = 0;
    int switch_end =
        iterator.current_offset() + iterator.current_bytecode_size();

    for (const auto& entry : iterator.GetJumpTableTargetOffsets()) {
      CHECK_EQ(entry.case_value, large_jump_table_base + i);
      CHECK_EQ(entry.target_offset, switch_end + i);

      i++;
    }
    CHECK_EQ(i, large_jump_table_size);
  }
  iterator.Advance();

  for (int i = 0; i < large_jump_table_size; i++) {
    CHECK_EQ(iterator.current_bytecode(), Bytecode::kDebugger);
    iterator.Advance();
  }

  CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
  iterator.Advance();
  CHECK(iterator.done());
}

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