// Copyright 2017 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 "src/interpreter/interpreter-generator.h"

#include <array>
#include <tuple>

#include "src/builtins/builtins-arguments-gen.h"
#include "src/builtins/builtins-constructor-gen.h"
#include "src/builtins/builtins-conversion-gen.h"
#include "src/builtins/builtins-forin-gen.h"
#include "src/builtins/builtins-string-gen.h"
#include "src/code-events.h"
#include "src/code-factory.h"
#include "src/factory.h"
#include "src/ic/accessor-assembler.h"
#include "src/ic/binary-op-assembler.h"
#include "src/interpreter/bytecode-flags.h"
#include "src/interpreter/bytecodes.h"
#include "src/interpreter/interpreter-assembler.h"
#include "src/interpreter/interpreter-intrinsics-generator.h"
#include "src/objects-inl.h"

namespace v8 {
namespace internal {
namespace interpreter {

namespace {

using compiler::Node;
typedef CodeStubAssembler::Label Label;
typedef CodeStubAssembler::Variable Variable;

#define IGNITION_HANDLER(Name, BaseAssembler)                         \
  class Name##Assembler : public BaseAssembler {                      \
   public:                                                            \
    explicit Name##Assembler(compiler::CodeAssemblerState* state,     \
                             Bytecode bytecode, OperandScale scale)   \
        : BaseAssembler(state, bytecode, scale) {}                    \
    static void Generate(compiler::CodeAssemblerState* state,         \
                         OperandScale scale);                         \
                                                                      \
   private:                                                           \
    void GenerateImpl();                                              \
    DISALLOW_COPY_AND_ASSIGN(Name##Assembler);                        \
  };                                                                  \
  void Name##Assembler::Generate(compiler::CodeAssemblerState* state, \
                                 OperandScale scale) {                \
    Name##Assembler assembler(state, Bytecode::k##Name, scale);       \
    state->SetInitialDebugInformation(#Name, __FILE__, __LINE__);     \
    assembler.GenerateImpl();                                         \
  }                                                                   \
  void Name##Assembler::GenerateImpl()

// LdaZero
//
// Load literal '0' into the accumulator.
IGNITION_HANDLER(LdaZero, InterpreterAssembler) {
  Node* zero_value = NumberConstant(0.0);
  SetAccumulator(zero_value);
  Dispatch();
}

// LdaSmi <imm>
//
// Load an integer literal into the accumulator as a Smi.
IGNITION_HANDLER(LdaSmi, InterpreterAssembler) {
  Node* smi_int = BytecodeOperandImmSmi(0);
  SetAccumulator(smi_int);
  Dispatch();
}

// LdaConstant <idx>
//
// Load constant literal at |idx| in the constant pool into the accumulator.
IGNITION_HANDLER(LdaConstant, InterpreterAssembler) {
  Node* index = BytecodeOperandIdx(0);
  Node* constant = LoadConstantPoolEntry(index);
  SetAccumulator(constant);
  Dispatch();
}

// LdaUndefined
//
// Load Undefined into the accumulator.
IGNITION_HANDLER(LdaUndefined, InterpreterAssembler) {
  SetAccumulator(UndefinedConstant());
  Dispatch();
}

// LdaNull
//
// Load Null into the accumulator.
IGNITION_HANDLER(LdaNull, InterpreterAssembler) {
  SetAccumulator(NullConstant());
  Dispatch();
}

// LdaTheHole
//
// Load TheHole into the accumulator.
IGNITION_HANDLER(LdaTheHole, InterpreterAssembler) {
  SetAccumulator(TheHoleConstant());
  Dispatch();
}

// LdaTrue
//
// Load True into the accumulator.
IGNITION_HANDLER(LdaTrue, InterpreterAssembler) {
  SetAccumulator(TrueConstant());
  Dispatch();
}

// LdaFalse
//
// Load False into the accumulator.
IGNITION_HANDLER(LdaFalse, InterpreterAssembler) {
  SetAccumulator(FalseConstant());
  Dispatch();
}

// Ldar <src>
//
// Load accumulator with value from register <src>.
IGNITION_HANDLER(Ldar, InterpreterAssembler) {
  Node* reg_index = BytecodeOperandReg(0);
  Node* value = LoadRegister(reg_index);
  SetAccumulator(value);
  Dispatch();
}

// Star <dst>
//
// Store accumulator to register <dst>.
IGNITION_HANDLER(Star, InterpreterAssembler) {
  Node* reg_index = BytecodeOperandReg(0);
  Node* accumulator = GetAccumulator();
  StoreRegister(accumulator, reg_index);
  Dispatch();
}

// Mov <src> <dst>
//
// Stores the value of register <src> to register <dst>.
IGNITION_HANDLER(Mov, InterpreterAssembler) {
  Node* src_index = BytecodeOperandReg(0);
  Node* src_value = LoadRegister(src_index);
  Node* dst_index = BytecodeOperandReg(1);
  StoreRegister(src_value, dst_index);
  Dispatch();
}

class InterpreterLoadGlobalAssembler : public InterpreterAssembler {
 public:
  InterpreterLoadGlobalAssembler(CodeAssemblerState* state, Bytecode bytecode,
                                 OperandScale operand_scale)
      : InterpreterAssembler(state, bytecode, operand_scale) {}

  void LdaGlobal(int slot_operand_index, int name_operand_index,
                 TypeofMode typeof_mode) {
    // Must be kept in sync with AccessorAssembler::LoadGlobalIC.

    // Load the global via the LoadGlobalIC.
    Node* feedback_vector = LoadFeedbackVector();
    Node* feedback_slot = BytecodeOperandIdx(slot_operand_index);

    AccessorAssembler accessor_asm(state());

    Label try_handler(this, Label::kDeferred), miss(this, Label::kDeferred);

    // Fast path without frame construction for the data case.
    {
      Label done(this);
      Variable var_result(this, MachineRepresentation::kTagged);
      ExitPoint exit_point(this, &done, &var_result);

      accessor_asm.LoadGlobalIC_TryPropertyCellCase(
          feedback_vector, feedback_slot, &exit_point, &try_handler, &miss,
          CodeStubAssembler::INTPTR_PARAMETERS);

      BIND(&done);
      SetAccumulator(var_result.value());
      Dispatch();
    }

    // Slow path with frame construction.
    {
      Label done(this);
      Variable var_result(this, MachineRepresentation::kTagged);
      ExitPoint exit_point(this, &done, &var_result);

      BIND(&try_handler);
      {
        Node* context = GetContext();
        Node* smi_slot = SmiTag(feedback_slot);
        Node* name_index = BytecodeOperandIdx(name_operand_index);
        Node* name = LoadConstantPoolEntry(name_index);

        AccessorAssembler::LoadICParameters params(context, nullptr, name,
                                                   smi_slot, feedback_vector);
        accessor_asm.LoadGlobalIC_TryHandlerCase(&params, typeof_mode,
                                                 &exit_point, &miss);
      }

      BIND(&miss);
      {
        Node* context = GetContext();
        Node* smi_slot = SmiTag(feedback_slot);
        Node* name_index = BytecodeOperandIdx(name_operand_index);
        Node* name = LoadConstantPoolEntry(name_index);

        AccessorAssembler::LoadICParameters params(context, nullptr, name,
                                                   smi_slot, feedback_vector);
        accessor_asm.LoadGlobalIC_MissCase(&params, &exit_point);
      }

      BIND(&done);
      {
        SetAccumulator(var_result.value());
        Dispatch();
      }
    }
  }
};

// LdaGlobal <name_index> <slot>
//
// Load the global with name in constant pool entry <name_index> into the
// accumulator using FeedBackVector slot <slot> outside of a typeof.
IGNITION_HANDLER(LdaGlobal, InterpreterLoadGlobalAssembler) {
  static const int kNameOperandIndex = 0;
  static const int kSlotOperandIndex = 1;

  LdaGlobal(kSlotOperandIndex, kNameOperandIndex, NOT_INSIDE_TYPEOF);
}

// LdaGlobalInsideTypeof <name_index> <slot>
//
// Load the global with name in constant pool entry <name_index> into the
// accumulator using FeedBackVector slot <slot> inside of a typeof.
IGNITION_HANDLER(LdaGlobalInsideTypeof, InterpreterLoadGlobalAssembler) {
  static const int kNameOperandIndex = 0;
  static const int kSlotOperandIndex = 1;

  LdaGlobal(kSlotOperandIndex, kNameOperandIndex, INSIDE_TYPEOF);
}

class InterpreterStoreGlobalAssembler : public InterpreterAssembler {
 public:
  InterpreterStoreGlobalAssembler(CodeAssemblerState* state, Bytecode bytecode,
                                  OperandScale operand_scale)
      : InterpreterAssembler(state, bytecode, operand_scale) {}

  void StaGlobal(Callable ic) {
    // Get the global object.
    Node* context = GetContext();
    Node* native_context = LoadNativeContext(context);
    Node* global = LoadContextElement(native_context, Context::EXTENSION_INDEX);

    // Store the global via the StoreIC.
    Node* code_target = HeapConstant(ic.code());
    Node* constant_index = BytecodeOperandIdx(0);
    Node* name = LoadConstantPoolEntry(constant_index);
    Node* value = GetAccumulator();
    Node* raw_slot = BytecodeOperandIdx(1);
    Node* smi_slot = SmiTag(raw_slot);
    Node* feedback_vector = LoadFeedbackVector();
    CallStub(ic.descriptor(), code_target, context, global, name, value,
             smi_slot, feedback_vector);
    Dispatch();
  }
};

// StaGlobalSloppy <name_index> <slot>
//
// Store the value in the accumulator into the global with name in constant pool
// entry <name_index> using FeedBackVector slot <slot> in sloppy mode.
IGNITION_HANDLER(StaGlobalSloppy, InterpreterStoreGlobalAssembler) {
  Callable ic = CodeFactory::StoreGlobalICInOptimizedCode(isolate(), SLOPPY);
  StaGlobal(ic);
}

// StaGlobalStrict <name_index> <slot>
//
// Store the value in the accumulator into the global with name in constant pool
// entry <name_index> using FeedBackVector slot <slot> in strict mode.
IGNITION_HANDLER(StaGlobalStrict, InterpreterStoreGlobalAssembler) {
  Callable ic = CodeFactory::StoreGlobalICInOptimizedCode(isolate(), STRICT);
  StaGlobal(ic);
}

// LdaContextSlot <context> <slot_index> <depth>
//
// Load the object in |slot_index| of the context at |depth| in the context
// chain starting at |context| into the accumulator.
IGNITION_HANDLER(LdaContextSlot, InterpreterAssembler) {
  Node* reg_index = BytecodeOperandReg(0);
  Node* context = LoadRegister(reg_index);
  Node* slot_index = BytecodeOperandIdx(1);
  Node* depth = BytecodeOperandUImm(2);
  Node* slot_context = GetContextAtDepth(context, depth);
  Node* result = LoadContextElement(slot_context, slot_index);
  SetAccumulator(result);
  Dispatch();
}

// LdaImmutableContextSlot <context> <slot_index> <depth>
//
// Load the object in |slot_index| of the context at |depth| in the context
// chain starting at |context| into the accumulator.
IGNITION_HANDLER(LdaImmutableContextSlot, InterpreterAssembler) {
  // Same as LdaContextSlot, should never be called.
  UNREACHABLE();
}

// LdaCurrentContextSlot <slot_index>
//
// Load the object in |slot_index| of the current context into the accumulator.
IGNITION_HANDLER(LdaCurrentContextSlot, InterpreterAssembler) {
  Node* slot_index = BytecodeOperandIdx(0);
  Node* slot_context = GetContext();
  Node* result = LoadContextElement(slot_context, slot_index);
  SetAccumulator(result);
  Dispatch();
}

// LdaImmutableCurrentContextSlot <slot_index>
//
// Load the object in |slot_index| of the current context into the accumulator.
IGNITION_HANDLER(LdaImmutableCurrentContextSlot, InterpreterAssembler) {
  // Same as LdaCurrentContextSlot, should never be called.
  UNREACHABLE();
}

// StaContextSlot <context> <slot_index> <depth>
//
// Stores the object in the accumulator into |slot_index| of the context at
// |depth| in the context chain starting at |context|.
IGNITION_HANDLER(StaContextSlot, InterpreterAssembler) {
  Node* value = GetAccumulator();
  Node* reg_index = BytecodeOperandReg(0);
  Node* context = LoadRegister(reg_index);
  Node* slot_index = BytecodeOperandIdx(1);
  Node* depth = BytecodeOperandUImm(2);
  Node* slot_context = GetContextAtDepth(context, depth);
  StoreContextElement(slot_context, slot_index, value);
  Dispatch();
}

// StaCurrentContextSlot <slot_index>
//
// Stores the object in the accumulator into |slot_index| of the current
// context.
IGNITION_HANDLER(StaCurrentContextSlot, InterpreterAssembler) {
  Node* value = GetAccumulator();
  Node* slot_index = BytecodeOperandIdx(0);
  Node* slot_context = GetContext();
  StoreContextElement(slot_context, slot_index, value);
  Dispatch();
}

// LdaLookupSlot <name_index>
//
// Lookup the object with the name in constant pool entry |name_index|
// dynamically.
IGNITION_HANDLER(LdaLookupSlot, InterpreterAssembler) {
  Node* name_index = BytecodeOperandIdx(0);
  Node* name = LoadConstantPoolEntry(name_index);
  Node* context = GetContext();
  Node* result = CallRuntime(Runtime::kLoadLookupSlot, context, name);
  SetAccumulator(result);
  Dispatch();
}

// LdaLookupSlotInsideTypeof <name_index>
//
// Lookup the object with the name in constant pool entry |name_index|
// dynamically without causing a NoReferenceError.
IGNITION_HANDLER(LdaLookupSlotInsideTypeof, InterpreterAssembler) {
  Node* name_index = BytecodeOperandIdx(0);
  Node* name = LoadConstantPoolEntry(name_index);
  Node* context = GetContext();
  Node* result =
      CallRuntime(Runtime::kLoadLookupSlotInsideTypeof, context, name);
  SetAccumulator(result);
  Dispatch();
}

class InterpreterLookupContextSlotAssembler : public InterpreterAssembler {
 public:
  InterpreterLookupContextSlotAssembler(CodeAssemblerState* state,
                                        Bytecode bytecode,
                                        OperandScale operand_scale)
      : InterpreterAssembler(state, bytecode, operand_scale) {}

  void LookupContextSlot(Runtime::FunctionId function_id) {
    Node* context = GetContext();
    Node* name_index = BytecodeOperandIdx(0);
    Node* slot_index = BytecodeOperandIdx(1);
    Node* depth = BytecodeOperandUImm(2);

    Label slowpath(this, Label::kDeferred);

    // Check for context extensions to allow the fast path.
    GotoIfHasContextExtensionUpToDepth(context, depth, &slowpath);

    // Fast path does a normal load context.
    {
      Node* slot_context = GetContextAtDepth(context, depth);
      Node* result = LoadContextElement(slot_context, slot_index);
      SetAccumulator(result);
      Dispatch();
    }

    // Slow path when we have to call out to the runtime.
    BIND(&slowpath);
    {
      Node* name = LoadConstantPoolEntry(name_index);
      Node* result = CallRuntime(function_id, context, name);
      SetAccumulator(result);
      Dispatch();
    }
  }
};

// LdaLookupSlot <name_index>
//
// Lookup the object with the name in constant pool entry |name_index|
// dynamically.
IGNITION_HANDLER(LdaLookupContextSlot, InterpreterLookupContextSlotAssembler) {
  LookupContextSlot(Runtime::kLoadLookupSlot);
}

// LdaLookupSlotInsideTypeof <name_index>
//
// Lookup the object with the name in constant pool entry |name_index|
// dynamically without causing a NoReferenceError.
IGNITION_HANDLER(LdaLookupContextSlotInsideTypeof,
                 InterpreterLookupContextSlotAssembler) {
  LookupContextSlot(Runtime::kLoadLookupSlotInsideTypeof);
}

class InterpreterLookupGlobalAssembler : public InterpreterLoadGlobalAssembler {
 public:
  InterpreterLookupGlobalAssembler(CodeAssemblerState* state, Bytecode bytecode,
                                   OperandScale operand_scale)
      : InterpreterLoadGlobalAssembler(state, bytecode, operand_scale) {}

  void LookupGlobalSlot(Runtime::FunctionId function_id) {
    Node* context = GetContext();
    Node* depth = BytecodeOperandUImm(2);

    Label slowpath(this, Label::kDeferred);

    // Check for context extensions to allow the fast path
    GotoIfHasContextExtensionUpToDepth(context, depth, &slowpath);

    // Fast path does a normal load global
    {
      static const int kNameOperandIndex = 0;
      static const int kSlotOperandIndex = 1;

      TypeofMode typeof_mode =
          function_id == Runtime::kLoadLookupSlotInsideTypeof
              ? INSIDE_TYPEOF
              : NOT_INSIDE_TYPEOF;

      LdaGlobal(kSlotOperandIndex, kNameOperandIndex, typeof_mode);
    }

    // Slow path when we have to call out to the runtime
    BIND(&slowpath);
    {
      Node* name_index = BytecodeOperandIdx(0);
      Node* name = LoadConstantPoolEntry(name_index);
      Node* result = CallRuntime(function_id, context, name);
      SetAccumulator(result);
      Dispatch();
    }
  }
};

// LdaLookupGlobalSlot <name_index> <feedback_slot> <depth>
//
// Lookup the object with the name in constant pool entry |name_index|
// dynamically.
IGNITION_HANDLER(LdaLookupGlobalSlot, InterpreterLookupGlobalAssembler) {
  LookupGlobalSlot(Runtime::kLoadLookupSlot);
}

// LdaLookupGlobalSlotInsideTypeof <name_index> <feedback_slot> <depth>
//
// Lookup the object with the name in constant pool entry |name_index|
// dynamically without causing a NoReferenceError.
IGNITION_HANDLER(LdaLookupGlobalSlotInsideTypeof,
                 InterpreterLookupGlobalAssembler) {
  LookupGlobalSlot(Runtime::kLoadLookupSlotInsideTypeof);
}

// StaLookupSlotSloppy <name_index> <flags>
//
// Store the object in accumulator to the object with the name in constant
// pool entry |name_index|.
IGNITION_HANDLER(StaLookupSlot, InterpreterAssembler) {
  Node* value = GetAccumulator();
  Node* index = BytecodeOperandIdx(0);
  Node* bytecode_flags = BytecodeOperandFlag(1);
  Node* name = LoadConstantPoolEntry(index);
  Node* context = GetContext();
  Variable var_result(this, MachineRepresentation::kTagged);

  Label sloppy(this), strict(this), end(this);
  DCHECK_EQ(0, SLOPPY);
  DCHECK_EQ(1, STRICT);
  DCHECK_EQ(0, static_cast<int>(LookupHoistingMode::kNormal));
  DCHECK_EQ(1, static_cast<int>(LookupHoistingMode::kLegacySloppy));
  Branch(IsSetWord32<StoreLookupSlotFlags::LanguageModeBit>(bytecode_flags),
         &strict, &sloppy);

  BIND(&strict);
  {
    CSA_ASSERT(this, IsClearWord32<StoreLookupSlotFlags::LookupHoistingModeBit>(
                         bytecode_flags));
    var_result.Bind(
        CallRuntime(Runtime::kStoreLookupSlot_Strict, context, name, value));
    Goto(&end);
  }

  BIND(&sloppy);
  {
    Label hoisting(this), ordinary(this);
    Branch(IsSetWord32<StoreLookupSlotFlags::LookupHoistingModeBit>(
               bytecode_flags),
           &hoisting, &ordinary);

    BIND(&hoisting);
    {
      var_result.Bind(CallRuntime(Runtime::kStoreLookupSlot_SloppyHoisting,
                                  context, name, value));
      Goto(&end);
    }

    BIND(&ordinary);
    {
      var_result.Bind(
          CallRuntime(Runtime::kStoreLookupSlot_Sloppy, context, name, value));
      Goto(&end);
    }
  }

  BIND(&end);
  {
    SetAccumulator(var_result.value());
    Dispatch();
  }
}

// LdaNamedProperty <object> <name_index> <slot>
//
// Calls the LoadIC at FeedBackVector slot <slot> for <object> and the name at
// constant pool entry <name_index>.
IGNITION_HANDLER(LdaNamedProperty, InterpreterAssembler) {
  Node* feedback_vector = LoadFeedbackVector();
  Node* feedback_slot = BytecodeOperandIdx(2);
  Node* smi_slot = SmiTag(feedback_slot);

  // Load receiver.
  Node* register_index = BytecodeOperandReg(0);
  Node* recv = LoadRegister(register_index);

  // Load the name.
  // TODO(jgruber): Not needed for monomorphic smi handler constant/field case.
  Node* constant_index = BytecodeOperandIdx(1);
  Node* name = LoadConstantPoolEntry(constant_index);

  Node* context = GetContext();

  Label done(this);
  Variable var_result(this, MachineRepresentation::kTagged);
  ExitPoint exit_point(this, &done, &var_result);

  AccessorAssembler::LoadICParameters params(context, recv, name, smi_slot,
                                             feedback_vector);
  AccessorAssembler accessor_asm(state());
  accessor_asm.LoadIC_BytecodeHandler(&params, &exit_point);

  BIND(&done);
  {
    SetAccumulator(var_result.value());
    Dispatch();
  }
}

// KeyedLoadIC <object> <slot>
//
// Calls the KeyedLoadIC at FeedBackVector slot <slot> for <object> and the key
// in the accumulator.
IGNITION_HANDLER(LdaKeyedProperty, InterpreterAssembler) {
  Callable ic = Builtins::CallableFor(isolate(), Builtins::kKeyedLoadIC);
  Node* code_target = HeapConstant(ic.code());
  Node* reg_index = BytecodeOperandReg(0);
  Node* object = LoadRegister(reg_index);
  Node* name = GetAccumulator();
  Node* raw_slot = BytecodeOperandIdx(1);
  Node* smi_slot = SmiTag(raw_slot);
  Node* feedback_vector = LoadFeedbackVector();
  Node* context = GetContext();
  Node* result = CallStub(ic.descriptor(), code_target, context, object, name,
                          smi_slot, feedback_vector);
  SetAccumulator(result);
  Dispatch();
}

class InterpreterStoreNamedPropertyAssembler : public InterpreterAssembler {
 public:
  InterpreterStoreNamedPropertyAssembler(CodeAssemblerState* state,
                                         Bytecode bytecode,
                                         OperandScale operand_scale)
      : InterpreterAssembler(state, bytecode, operand_scale) {}

  void StaNamedProperty(Callable ic) {
    Node* code_target = HeapConstant(ic.code());
    Node* object_reg_index = BytecodeOperandReg(0);
    Node* object = LoadRegister(object_reg_index);
    Node* constant_index = BytecodeOperandIdx(1);
    Node* name = LoadConstantPoolEntry(constant_index);
    Node* value = GetAccumulator();
    Node* raw_slot = BytecodeOperandIdx(2);
    Node* smi_slot = SmiTag(raw_slot);
    Node* feedback_vector = LoadFeedbackVector();
    Node* context = GetContext();
    CallStub(ic.descriptor(), code_target, context, object, name, value,
             smi_slot, feedback_vector);
    Dispatch();
  }
};

// StaNamedPropertySloppy <object> <name_index> <slot>
//
// Calls the sloppy mode StoreIC at FeedBackVector slot <slot> for <object> and
// the name in constant pool entry <name_index> with the value in the
// accumulator.
IGNITION_HANDLER(StaNamedPropertySloppy,
                 InterpreterStoreNamedPropertyAssembler) {
  Callable ic = CodeFactory::StoreICInOptimizedCode(isolate(), SLOPPY);
  StaNamedProperty(ic);
}

// StaNamedPropertyStrict <object> <name_index> <slot>
//
// Calls the strict mode StoreIC at FeedBackVector slot <slot> for <object> and
// the name in constant pool entry <name_index> with the value in the
// accumulator.
IGNITION_HANDLER(StaNamedPropertyStrict,
                 InterpreterStoreNamedPropertyAssembler) {
  Callable ic = CodeFactory::StoreICInOptimizedCode(isolate(), STRICT);
  StaNamedProperty(ic);
}

// StaNamedOwnProperty <object> <name_index> <slot>
//
// Calls the StoreOwnIC at FeedBackVector slot <slot> for <object> and
// the name in constant pool entry <name_index> with the value in the
// accumulator.
IGNITION_HANDLER(StaNamedOwnProperty, InterpreterStoreNamedPropertyAssembler) {
  Callable ic = CodeFactory::StoreOwnICInOptimizedCode(isolate());
  StaNamedProperty(ic);
}

class InterpreterStoreKeyedPropertyAssembler : public InterpreterAssembler {
 public:
  InterpreterStoreKeyedPropertyAssembler(CodeAssemblerState* state,
                                         Bytecode bytecode,
                                         OperandScale operand_scale)
      : InterpreterAssembler(state, bytecode, operand_scale) {}

  void StaKeyedProperty(Callable ic) {
    Node* code_target = HeapConstant(ic.code());
    Node* object_reg_index = BytecodeOperandReg(0);
    Node* object = LoadRegister(object_reg_index);
    Node* name_reg_index = BytecodeOperandReg(1);
    Node* name = LoadRegister(name_reg_index);
    Node* value = GetAccumulator();
    Node* raw_slot = BytecodeOperandIdx(2);
    Node* smi_slot = SmiTag(raw_slot);
    Node* feedback_vector = LoadFeedbackVector();
    Node* context = GetContext();
    CallStub(ic.descriptor(), code_target, context, object, name, value,
             smi_slot, feedback_vector);
    Dispatch();
  }
};

// StaKeyedPropertySloppy <object> <key> <slot>
//
// Calls the sloppy mode KeyStoreIC at FeedBackVector slot <slot> for <object>
// and the key <key> with the value in the accumulator.
IGNITION_HANDLER(StaKeyedPropertySloppy,
                 InterpreterStoreKeyedPropertyAssembler) {
  Callable ic = CodeFactory::KeyedStoreICInOptimizedCode(isolate(), SLOPPY);
  StaKeyedProperty(ic);
}

// StaKeyedPropertyStrict <object> <key> <slot>
//
// Calls the strict mode KeyStoreIC at FeedBackVector slot <slot> for <object>
// and the key <key> with the value in the accumulator.
IGNITION_HANDLER(StaKeyedPropertyStrict,
                 InterpreterStoreKeyedPropertyAssembler) {
  Callable ic = CodeFactory::KeyedStoreICInOptimizedCode(isolate(), STRICT);
  StaKeyedProperty(ic);
}

// StaDataPropertyInLiteral <object> <name> <flags>
//
// Define a property <name> with value from the accumulator in <object>.
// Property attributes and whether set_function_name are stored in
// DataPropertyInLiteralFlags <flags>.
//
// This definition is not observable and is used only for definitions
// in object or class literals.
IGNITION_HANDLER(StaDataPropertyInLiteral, InterpreterAssembler) {
  Node* object = LoadRegister(BytecodeOperandReg(0));
  Node* name = LoadRegister(BytecodeOperandReg(1));
  Node* value = GetAccumulator();
  Node* flags = SmiFromWord32(BytecodeOperandFlag(2));
  Node* vector_index = SmiTag(BytecodeOperandIdx(3));

  Node* feedback_vector = LoadFeedbackVector();
  Node* context = GetContext();

  CallRuntime(Runtime::kDefineDataPropertyInLiteral, context, object, name,
              value, flags, feedback_vector, vector_index);
  Dispatch();
}

IGNITION_HANDLER(CollectTypeProfile, InterpreterAssembler) {
  Node* position = BytecodeOperandImmSmi(0);
  Node* value = GetAccumulator();

  Node* feedback_vector = LoadFeedbackVector();
  Node* context = GetContext();

  CallRuntime(Runtime::kCollectTypeProfile, context, position, value,
              feedback_vector);
  Dispatch();
}

// LdaModuleVariable <cell_index> <depth>
//
// Load the contents of a module variable into the accumulator.  The variable is
// identified by <cell_index>.  <depth> is the depth of the current context
// relative to the module context.
IGNITION_HANDLER(LdaModuleVariable, InterpreterAssembler) {
  Node* cell_index = BytecodeOperandImmIntPtr(0);
  Node* depth = BytecodeOperandUImm(1);

  Node* module_context = GetContextAtDepth(GetContext(), depth);
  Node* module = LoadContextElement(module_context, Context::EXTENSION_INDEX);

  Label if_export(this), if_import(this), end(this);
  Branch(IntPtrGreaterThan(cell_index, IntPtrConstant(0)), &if_export,
         &if_import);

  BIND(&if_export);
  {
    Node* regular_exports =
        LoadObjectField(module, Module::kRegularExportsOffset);
    // The actual array index is (cell_index - 1).
    Node* export_index = IntPtrSub(cell_index, IntPtrConstant(1));
    Node* cell = LoadFixedArrayElement(regular_exports, export_index);
    SetAccumulator(LoadObjectField(cell, Cell::kValueOffset));
    Goto(&end);
  }

  BIND(&if_import);
  {
    Node* regular_imports =
        LoadObjectField(module, Module::kRegularImportsOffset);
    // The actual array index is (-cell_index - 1).
    Node* import_index = IntPtrSub(IntPtrConstant(-1), cell_index);
    Node* cell = LoadFixedArrayElement(regular_imports, import_index);
    SetAccumulator(LoadObjectField(cell, Cell::kValueOffset));
    Goto(&end);
  }

  BIND(&end);
  Dispatch();
}

// StaModuleVariable <cell_index> <depth>
//
// Store accumulator to the module variable identified by <cell_index>.
// <depth> is the depth of the current context relative to the module context.
IGNITION_HANDLER(StaModuleVariable, InterpreterAssembler) {
  Node* value = GetAccumulator();
  Node* cell_index = BytecodeOperandImmIntPtr(0);
  Node* depth = BytecodeOperandUImm(1);

  Node* module_context = GetContextAtDepth(GetContext(), depth);
  Node* module = LoadContextElement(module_context, Context::EXTENSION_INDEX);

  Label if_export(this), if_import(this), end(this);
  Branch(IntPtrGreaterThan(cell_index, IntPtrConstant(0)), &if_export,
         &if_import);

  BIND(&if_export);
  {
    Node* regular_exports =
        LoadObjectField(module, Module::kRegularExportsOffset);
    // The actual array index is (cell_index - 1).
    Node* export_index = IntPtrSub(cell_index, IntPtrConstant(1));
    Node* cell = LoadFixedArrayElement(regular_exports, export_index);
    StoreObjectField(cell, Cell::kValueOffset, value);
    Goto(&end);
  }

  BIND(&if_import);
  {
    // Not supported (probably never).
    Abort(kUnsupportedModuleOperation);
    Goto(&end);
  }

  BIND(&end);
  Dispatch();
}

// PushContext <context>
//
// Saves the current context in <context>, and pushes the accumulator as the
// new current context.
IGNITION_HANDLER(PushContext, InterpreterAssembler) {
  Node* reg_index = BytecodeOperandReg(0);
  Node* new_context = GetAccumulator();
  Node* old_context = GetContext();
  StoreRegister(old_context, reg_index);
  SetContext(new_context);
  Dispatch();
}

// PopContext <context>
//
// Pops the current context and sets <context> as the new context.
IGNITION_HANDLER(PopContext, InterpreterAssembler) {
  Node* reg_index = BytecodeOperandReg(0);
  Node* context = LoadRegister(reg_index);
  SetContext(context);
  Dispatch();
}

class InterpreterBinaryOpAssembler : public InterpreterAssembler {
 public:
  InterpreterBinaryOpAssembler(CodeAssemblerState* state, Bytecode bytecode,
                               OperandScale operand_scale)
      : InterpreterAssembler(state, bytecode, operand_scale) {}

  typedef Node* (BinaryOpAssembler::*BinaryOpGenerator)(
      Node* context, Node* left, Node* right, Node* slot, Node* vector,
      Node* function, bool lhs_is_smi);

  void BinaryOpWithFeedback(BinaryOpGenerator generator) {
    Node* reg_index = BytecodeOperandReg(0);
    Node* lhs = LoadRegister(reg_index);
    Node* rhs = GetAccumulator();
    Node* context = GetContext();
    Node* slot_index = BytecodeOperandIdx(1);
    Node* feedback_vector = LoadFeedbackVector();
    Node* function = LoadRegister(Register::function_closure());

    BinaryOpAssembler binop_asm(state());
    Node* result = (binop_asm.*generator)(context, lhs, rhs, slot_index,
                                          feedback_vector, function, false);
    SetAccumulator(result);
    Dispatch();
  }

  void BinaryOpSmiWithFeedback(BinaryOpGenerator generator) {
    Node* lhs = GetAccumulator();
    Node* rhs = BytecodeOperandImmSmi(0);
    Node* context = GetContext();
    Node* slot_index = BytecodeOperandIdx(1);
    Node* feedback_vector = LoadFeedbackVector();
    Node* function = LoadRegister(Register::function_closure());

    BinaryOpAssembler binop_asm(state());
    Node* result = (binop_asm.*generator)(context, lhs, rhs, slot_index,
                                          feedback_vector, function, true);
    SetAccumulator(result);
    Dispatch();
  }
};

// Add <src>
//
// Add register <src> to accumulator.
IGNITION_HANDLER(Add, InterpreterBinaryOpAssembler) {
  BinaryOpWithFeedback(&BinaryOpAssembler::Generate_AddWithFeedback);
}

// Sub <src>
//
// Subtract register <src> from accumulator.
IGNITION_HANDLER(Sub, InterpreterBinaryOpAssembler) {
  BinaryOpWithFeedback(&BinaryOpAssembler::Generate_SubtractWithFeedback);
}

// Mul <src>
//
// Multiply accumulator by register <src>.
IGNITION_HANDLER(Mul, InterpreterBinaryOpAssembler) {
  BinaryOpWithFeedback(&BinaryOpAssembler::Generate_MultiplyWithFeedback);
}

// Div <src>
//
// Divide register <src> by accumulator.
IGNITION_HANDLER(Div, InterpreterBinaryOpAssembler) {
  BinaryOpWithFeedback(&BinaryOpAssembler::Generate_DivideWithFeedback);
}

// Mod <src>
//
// Modulo register <src> by accumulator.
IGNITION_HANDLER(Mod, InterpreterBinaryOpAssembler) {
  BinaryOpWithFeedback(&BinaryOpAssembler::Generate_ModulusWithFeedback);
}

// AddSmi <imm>
//
// Adds an immediate value <imm> to the value in the accumulator.
IGNITION_HANDLER(AddSmi, InterpreterBinaryOpAssembler) {
  BinaryOpSmiWithFeedback(&BinaryOpAssembler::Generate_AddWithFeedback);
}

// SubSmi <imm>
//
// Subtracts an immediate value <imm> from the value in the accumulator.
IGNITION_HANDLER(SubSmi, InterpreterBinaryOpAssembler) {
  BinaryOpSmiWithFeedback(&BinaryOpAssembler::Generate_SubtractWithFeedback);
}

// MulSmi <imm>
//
// Multiplies an immediate value <imm> to the value in the accumulator.
IGNITION_HANDLER(MulSmi, InterpreterBinaryOpAssembler) {
  BinaryOpSmiWithFeedback(&BinaryOpAssembler::Generate_MultiplyWithFeedback);
}

// DivSmi <imm>
//
// Divides the value in the accumulator by immediate value <imm>.
IGNITION_HANDLER(DivSmi, InterpreterBinaryOpAssembler) {
  BinaryOpSmiWithFeedback(&BinaryOpAssembler::Generate_DivideWithFeedback);
}

// ModSmi <imm>
//
// Modulo accumulator by immediate value <imm>.
IGNITION_HANDLER(ModSmi, InterpreterBinaryOpAssembler) {
  BinaryOpSmiWithFeedback(&BinaryOpAssembler::Generate_ModulusWithFeedback);
}

class InterpreterBitwiseBinaryOpAssembler : public InterpreterAssembler {
 public:
  InterpreterBitwiseBinaryOpAssembler(CodeAssemblerState* state,
                                      Bytecode bytecode,
                                      OperandScale operand_scale)
      : InterpreterAssembler(state, bytecode, operand_scale) {}

  void BitwiseBinaryOpWithFeedback(Token::Value bitwise_op) {
    Node* reg_index = BytecodeOperandReg(0);
    Node* lhs = LoadRegister(reg_index);
    Node* rhs = GetAccumulator();
    Node* context = GetContext();
    Node* slot_index = BytecodeOperandIdx(1);
    Node* feedback_vector = LoadFeedbackVector();

    Variable var_lhs_type_feedback(this, MachineRepresentation::kTaggedSigned),
        var_rhs_type_feedback(this, MachineRepresentation::kTaggedSigned);
    Node* lhs_value = TruncateTaggedToWord32WithFeedback(
        context, lhs, &var_lhs_type_feedback);
    Node* rhs_value = TruncateTaggedToWord32WithFeedback(
        context, rhs, &var_rhs_type_feedback);
    Node* result = nullptr;

    switch (bitwise_op) {
      case Token::BIT_OR: {
        Node* value = Word32Or(lhs_value, rhs_value);
        result = ChangeInt32ToTagged(value);
      } break;
      case Token::BIT_AND: {
        Node* value = Word32And(lhs_value, rhs_value);
        result = ChangeInt32ToTagged(value);
      } break;
      case Token::BIT_XOR: {
        Node* value = Word32Xor(lhs_value, rhs_value);
        result = ChangeInt32ToTagged(value);
      } break;
      case Token::SHL: {
        Node* value =
            Word32Shl(lhs_value, Word32And(rhs_value, Int32Constant(0x1f)));
        result = ChangeInt32ToTagged(value);
      } break;
      case Token::SHR: {
        Node* value =
            Word32Shr(lhs_value, Word32And(rhs_value, Int32Constant(0x1f)));
        result = ChangeUint32ToTagged(value);
      } break;
      case Token::SAR: {
        Node* value =
            Word32Sar(lhs_value, Word32And(rhs_value, Int32Constant(0x1f)));
        result = ChangeInt32ToTagged(value);
      } break;
      default:
        UNREACHABLE();
    }

    Node* result_type = SelectSmiConstant(TaggedIsSmi(result),
                                          BinaryOperationFeedback::kSignedSmall,
                                          BinaryOperationFeedback::kNumber);

    if (FLAG_debug_code) {
      Label ok(this);
      GotoIf(TaggedIsSmi(result), &ok);
      Node* result_map = LoadMap(result);
      AbortIfWordNotEqual(result_map, HeapNumberMapConstant(),
                          kExpectedHeapNumber);
      Goto(&ok);
      BIND(&ok);
    }

    Node* input_feedback =
        SmiOr(var_lhs_type_feedback.value(), var_rhs_type_feedback.value());
    Node* function = LoadRegister(Register::function_closure());
    UpdateFeedback(SmiOr(result_type, input_feedback), feedback_vector,
                   slot_index, function);
    SetAccumulator(result);
    Dispatch();
  }
};

// BitwiseOr <src>
//
// BitwiseOr register <src> to accumulator.
IGNITION_HANDLER(BitwiseOr, InterpreterBitwiseBinaryOpAssembler) {
  BitwiseBinaryOpWithFeedback(Token::BIT_OR);
}

// BitwiseXor <src>
//
// BitwiseXor register <src> to accumulator.
IGNITION_HANDLER(BitwiseXor, InterpreterBitwiseBinaryOpAssembler) {
  BitwiseBinaryOpWithFeedback(Token::BIT_XOR);
}

// BitwiseAnd <src>
//
// BitwiseAnd register <src> to accumulator.
IGNITION_HANDLER(BitwiseAnd, InterpreterBitwiseBinaryOpAssembler) {
  BitwiseBinaryOpWithFeedback(Token::BIT_AND);
}

// ShiftLeft <src>
//
// Left shifts register <src> by the count specified in the accumulator.
// Register <src> is converted to an int32 and the accumulator to uint32
// before the operation. 5 lsb bits from the accumulator are used as count
// i.e. <src> << (accumulator & 0x1F).
IGNITION_HANDLER(ShiftLeft, InterpreterBitwiseBinaryOpAssembler) {
  BitwiseBinaryOpWithFeedback(Token::SHL);
}

// ShiftRight <src>
//
// Right shifts register <src> by the count specified in the accumulator.
// Result is sign extended. Register <src> is converted to an int32 and the
// accumulator to uint32 before the operation. 5 lsb bits from the accumulator
// are used as count i.e. <src> >> (accumulator & 0x1F).
IGNITION_HANDLER(ShiftRight, InterpreterBitwiseBinaryOpAssembler) {
  BitwiseBinaryOpWithFeedback(Token::SAR);
}

// ShiftRightLogical <src>
//
// Right Shifts register <src> by the count specified in the accumulator.
// Result is zero-filled. The accumulator and register <src> are converted to
// uint32 before the operation 5 lsb bits from the accumulator are used as
// count i.e. <src> << (accumulator & 0x1F).
IGNITION_HANDLER(ShiftRightLogical, InterpreterBitwiseBinaryOpAssembler) {
  BitwiseBinaryOpWithFeedback(Token::SHR);
}

// BitwiseOr <imm>
//
// BitwiseOr accumulator with <imm>.
IGNITION_HANDLER(BitwiseOrSmi, InterpreterAssembler) {
  Node* left = GetAccumulator();
  Node* right = BytecodeOperandImmSmi(0);
  Node* slot_index = BytecodeOperandIdx(1);
  Node* feedback_vector = LoadFeedbackVector();
  Node* context = GetContext();

  Variable var_lhs_type_feedback(this, MachineRepresentation::kTaggedSigned);
  Node* lhs_value =
      TruncateTaggedToWord32WithFeedback(context, left, &var_lhs_type_feedback);
  Node* rhs_value = SmiToWord32(right);
  Node* value = Word32Or(lhs_value, rhs_value);
  Node* result = ChangeInt32ToTagged(value);
  Node* result_type = SelectSmiConstant(TaggedIsSmi(result),
                                        BinaryOperationFeedback::kSignedSmall,
                                        BinaryOperationFeedback::kNumber);
  Node* function = LoadRegister(Register::function_closure());
  UpdateFeedback(SmiOr(result_type, var_lhs_type_feedback.value()),
                 feedback_vector, slot_index, function);
  SetAccumulator(result);
  Dispatch();
}

// BitwiseXor <imm>
//
// BitwiseXor accumulator with <imm>.
IGNITION_HANDLER(BitwiseXorSmi, InterpreterAssembler) {
  Node* left = GetAccumulator();
  Node* right = BytecodeOperandImmSmi(0);
  Node* slot_index = BytecodeOperandIdx(1);
  Node* feedback_vector = LoadFeedbackVector();
  Node* context = GetContext();

  Variable var_lhs_type_feedback(this, MachineRepresentation::kTaggedSigned);
  Node* lhs_value =
      TruncateTaggedToWord32WithFeedback(context, left, &var_lhs_type_feedback);
  Node* rhs_value = SmiToWord32(right);
  Node* value = Word32Xor(lhs_value, rhs_value);
  Node* result = ChangeInt32ToTagged(value);
  Node* result_type = SelectSmiConstant(TaggedIsSmi(result),
                                        BinaryOperationFeedback::kSignedSmall,
                                        BinaryOperationFeedback::kNumber);
  Node* function = LoadRegister(Register::function_closure());
  UpdateFeedback(SmiOr(result_type, var_lhs_type_feedback.value()),
                 feedback_vector, slot_index, function);
  SetAccumulator(result);
  Dispatch();
}

// BitwiseAnd <imm>
//
// BitwiseAnd accumulator with <imm>.
IGNITION_HANDLER(BitwiseAndSmi, InterpreterAssembler) {
  Node* left = GetAccumulator();
  Node* right = BytecodeOperandImmSmi(0);
  Node* slot_index = BytecodeOperandIdx(1);
  Node* feedback_vector = LoadFeedbackVector();
  Node* context = GetContext();

  Variable var_lhs_type_feedback(this, MachineRepresentation::kTaggedSigned);
  Node* lhs_value =
      TruncateTaggedToWord32WithFeedback(context, left, &var_lhs_type_feedback);
  Node* rhs_value = SmiToWord32(right);
  Node* value = Word32And(lhs_value, rhs_value);
  Node* result = ChangeInt32ToTagged(value);
  Node* result_type = SelectSmiConstant(TaggedIsSmi(result),
                                        BinaryOperationFeedback::kSignedSmall,
                                        BinaryOperationFeedback::kNumber);
  Node* function = LoadRegister(Register::function_closure());
  UpdateFeedback(SmiOr(result_type, var_lhs_type_feedback.value()),
                 feedback_vector, slot_index, function);
  SetAccumulator(result);
  Dispatch();
}

// ShiftLeftSmi <imm>
//
// Left shifts accumulator by the count specified in <imm>.
// The accumulator is converted to an int32 before the operation. The 5
// lsb bits from <imm> are used as count i.e. <src> << (<imm> & 0x1F).
IGNITION_HANDLER(ShiftLeftSmi, InterpreterAssembler) {
  Node* left = GetAccumulator();
  Node* right = BytecodeOperandImmSmi(0);
  Node* slot_index = BytecodeOperandIdx(1);
  Node* feedback_vector = LoadFeedbackVector();
  Node* context = GetContext();

  Variable var_lhs_type_feedback(this, MachineRepresentation::kTaggedSigned);
  Node* lhs_value =
      TruncateTaggedToWord32WithFeedback(context, left, &var_lhs_type_feedback);
  Node* rhs_value = SmiToWord32(right);
  Node* shift_count = Word32And(rhs_value, Int32Constant(0x1f));
  Node* value = Word32Shl(lhs_value, shift_count);
  Node* result = ChangeInt32ToTagged(value);
  Node* result_type = SelectSmiConstant(TaggedIsSmi(result),
                                        BinaryOperationFeedback::kSignedSmall,
                                        BinaryOperationFeedback::kNumber);
  Node* function = LoadRegister(Register::function_closure());
  UpdateFeedback(SmiOr(result_type, var_lhs_type_feedback.value()),
                 feedback_vector, slot_index, function);
  SetAccumulator(result);
  Dispatch();
}

// ShiftRightSmi <imm>
//
// Right shifts accumulator by the count specified in <imm>. Result is sign
// extended. The accumulator is converted to an int32 before the operation. The
// 5 lsb bits from <imm> are used as count i.e. <src> << (<imm> & 0x1F).
IGNITION_HANDLER(ShiftRightSmi, InterpreterAssembler) {
  Node* left = GetAccumulator();
  Node* right = BytecodeOperandImmSmi(0);
  Node* slot_index = BytecodeOperandIdx(1);
  Node* feedback_vector = LoadFeedbackVector();
  Node* context = GetContext();

  Variable var_lhs_type_feedback(this, MachineRepresentation::kTaggedSigned);
  Node* lhs_value =
      TruncateTaggedToWord32WithFeedback(context, left, &var_lhs_type_feedback);
  Node* rhs_value = SmiToWord32(right);
  Node* shift_count = Word32And(rhs_value, Int32Constant(0x1f));
  Node* value = Word32Sar(lhs_value, shift_count);
  Node* result = ChangeInt32ToTagged(value);
  Node* result_type = SelectSmiConstant(TaggedIsSmi(result),
                                        BinaryOperationFeedback::kSignedSmall,
                                        BinaryOperationFeedback::kNumber);
  Node* function = LoadRegister(Register::function_closure());
  UpdateFeedback(SmiOr(result_type, var_lhs_type_feedback.value()),
                 feedback_vector, slot_index, function);
  SetAccumulator(result);
  Dispatch();
}

// ShiftRightLogicalSmi <imm>
//
// Right shifts accumulator by the count specified in <imm>. Result is zero
// extended. The accumulator is converted to an int32 before the operation. The
// 5 lsb bits from <imm> are used as count i.e. <src> << (<imm> & 0x1F).
IGNITION_HANDLER(ShiftRightLogicalSmi, InterpreterAssembler) {
  Node* left = GetAccumulator();
  Node* right = BytecodeOperandImmSmi(0);
  Node* slot_index = BytecodeOperandIdx(1);
  Node* feedback_vector = LoadFeedbackVector();
  Node* context = GetContext();

  Variable var_lhs_type_feedback(this, MachineRepresentation::kTaggedSigned);
  Node* lhs_value =
      TruncateTaggedToWord32WithFeedback(context, left, &var_lhs_type_feedback);
  Node* rhs_value = SmiToWord32(right);
  Node* shift_count = Word32And(rhs_value, Int32Constant(0x1f));
  Node* value = Word32Shr(lhs_value, shift_count);
  Node* result = ChangeUint32ToTagged(value);
  Node* result_type = SelectSmiConstant(TaggedIsSmi(result),
                                        BinaryOperationFeedback::kSignedSmall,
                                        BinaryOperationFeedback::kNumber);
  Node* function = LoadRegister(Register::function_closure());
  UpdateFeedback(SmiOr(result_type, var_lhs_type_feedback.value()),
                 feedback_vector, slot_index, function);
  SetAccumulator(result);
  Dispatch();
}

// ToName <dst>
//
// Convert the object referenced by the accumulator to a name.
IGNITION_HANDLER(ToName, InterpreterAssembler) {
  Node* object = GetAccumulator();
  Node* context = GetContext();
  Node* result = ToName(context, object);
  StoreRegister(result, BytecodeOperandReg(0));
  Dispatch();
}

// ToNumber <dst> <slot>
//
// Convert the object referenced by the accumulator to a number.
IGNITION_HANDLER(ToNumber, InterpreterAssembler) {
  Node* object = GetAccumulator();
  Node* context = GetContext();

  // Convert the {object} to a Number and collect feedback for the {object}.
  Variable var_type_feedback(this, MachineRepresentation::kTaggedSigned);
  Variable var_result(this, MachineRepresentation::kTagged);
  Label if_done(this), if_objectissmi(this), if_objectisnumber(this),
      if_objectisother(this, Label::kDeferred);

  GotoIf(TaggedIsSmi(object), &if_objectissmi);
  Branch(IsHeapNumber(object), &if_objectisnumber, &if_objectisother);

  BIND(&if_objectissmi);
  {
    var_result.Bind(object);
    var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kSignedSmall));
    Goto(&if_done);
  }

  BIND(&if_objectisnumber);
  {
    var_result.Bind(object);
    var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kNumber));
    Goto(&if_done);
  }

  BIND(&if_objectisother);
  {
    // Convert the {object} to a Number.
    var_result.Bind(CallBuiltin(Builtins::kNonNumberToNumber, context, object));
    var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kAny));
    Goto(&if_done);
  }

  BIND(&if_done);
  StoreRegister(var_result.value(), BytecodeOperandReg(0));

  // Record the type feedback collected for {object}.
  Node* slot_index = BytecodeOperandIdx(1);
  Node* feedback_vector = LoadFeedbackVector();
  Node* function = LoadRegister(Register::function_closure());
  UpdateFeedback(var_type_feedback.value(), feedback_vector, slot_index,
                 function);

  Dispatch();
}

// ToObject <dst>
//
// Convert the object referenced by the accumulator to a JSReceiver.
IGNITION_HANDLER(ToObject, InterpreterAssembler) {
  Callable callable = Builtins::CallableFor(isolate(), Builtins::kToObject);
  Node* target = HeapConstant(callable.code());
  Node* accumulator = GetAccumulator();
  Node* context = GetContext();
  Node* result = CallStub(callable.descriptor(), target, context, accumulator);
  StoreRegister(result, BytecodeOperandReg(0));
  Dispatch();
}

// ToPrimitiveToString <dst>
//
// Convert the object referenced by the accumulator to a primitive, and then
// convert the operand to a string, in preparation to be used by StringConcat.
IGNITION_HANDLER(ToPrimitiveToString, InterpreterAssembler) {
  VARIABLE(feedback, MachineRepresentation::kTagged);
  ConversionBuiltinsAssembler conversions_assembler(state());
  Node* result = conversions_assembler.ToPrimitiveToString(
      GetContext(), GetAccumulator(), &feedback);

  Node* function = LoadRegister(Register::function_closure());
  UpdateFeedback(feedback.value(), LoadFeedbackVector(), BytecodeOperandIdx(1),
                 function);
  StoreRegister(result, BytecodeOperandReg(0));
  Dispatch();
}

// StringConcat <first_reg> <reg_count>
//
// Concatenates the string values in registers <first_reg> to
// <first_reg> + <reg_count - 1> and saves the result in the accumulator.
IGNITION_HANDLER(StringConcat, InterpreterAssembler) {
  Label call_runtime(this, Label::kDeferred), done(this);

  Node* first_reg_ptr = RegisterLocation(BytecodeOperandReg(0));
  Node* reg_count = BytecodeOperandCount(1);
  Node* context = GetContext();

  VARIABLE(result, MachineRepresentation::kTagged);
  StringBuiltinsAssembler string_assembler(state());
  result.Bind(string_assembler.ConcatenateStrings(context, first_reg_ptr,
                                                  reg_count, &call_runtime));
  Goto(&done);

  BIND(&call_runtime);
  {
    Comment("Call runtime.");
    Node* runtime_id = Int32Constant(Runtime::kStringConcat);
    result.Bind(CallRuntimeN(runtime_id, context, first_reg_ptr, reg_count));
    Goto(&done);
  }

  BIND(&done);
  SetAccumulator(result.value());
  Dispatch();
}

// Inc
//
// Increments value in the accumulator by one.
IGNITION_HANDLER(Inc, InterpreterAssembler) {
  Node* value = GetAccumulator();
  Node* context = GetContext();
  Node* slot_index = BytecodeOperandIdx(0);
  Node* feedback_vector = LoadFeedbackVector();

  // Shared entry for floating point increment.
  Label do_finc(this), end(this);
  Variable var_finc_value(this, MachineRepresentation::kFloat64);

  // We might need to try again due to ToNumber conversion.
  Variable value_var(this, MachineRepresentation::kTagged);
  Variable result_var(this, MachineRepresentation::kTagged);
  Variable var_type_feedback(this, MachineRepresentation::kTaggedSigned);
  Variable* loop_vars[] = {&value_var, &var_type_feedback};
  Label start(this, 2, loop_vars);
  value_var.Bind(value);
  var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kNone));
  Goto(&start);
  BIND(&start);
  {
    value = value_var.value();

    Label if_issmi(this), if_isnotsmi(this);
    Branch(TaggedIsSmi(value), &if_issmi, &if_isnotsmi);

    BIND(&if_issmi);
    {
      // Try fast Smi addition first.
      Node* one = SmiConstant(1);
      Node* pair = IntPtrAddWithOverflow(BitcastTaggedToWord(value),
                                         BitcastTaggedToWord(one));
      Node* overflow = Projection(1, pair);

      // Check if the Smi addition overflowed.
      Label if_overflow(this), if_notoverflow(this);
      Branch(overflow, &if_overflow, &if_notoverflow);

      BIND(&if_notoverflow);
      var_type_feedback.Bind(
          SmiOr(var_type_feedback.value(),
                SmiConstant(BinaryOperationFeedback::kSignedSmall)));
      result_var.Bind(BitcastWordToTaggedSigned(Projection(0, pair)));
      Goto(&end);

      BIND(&if_overflow);
      {
        var_finc_value.Bind(SmiToFloat64(value));
        Goto(&do_finc);
      }
    }

    BIND(&if_isnotsmi);
    {
      // Check if the value is a HeapNumber.
      Label if_valueisnumber(this), if_valuenotnumber(this, Label::kDeferred);
      Node* value_map = LoadMap(value);
      Branch(IsHeapNumberMap(value_map), &if_valueisnumber, &if_valuenotnumber);

      BIND(&if_valueisnumber);
      {
        // Load the HeapNumber value.
        var_finc_value.Bind(LoadHeapNumberValue(value));
        Goto(&do_finc);
      }

      BIND(&if_valuenotnumber);
      {
        // We do not require an Or with earlier feedback here because once we
        // convert the value to a number, we cannot reach this path. We can
        // only reach this path on the first pass when the feedback is kNone.
        CSA_ASSERT(this, SmiEqual(var_type_feedback.value(),
                                  SmiConstant(BinaryOperationFeedback::kNone)));

        Label if_valueisoddball(this), if_valuenotoddball(this);
        Node* instance_type = LoadMapInstanceType(value_map);
        Node* is_oddball =
            Word32Equal(instance_type, Int32Constant(ODDBALL_TYPE));
        Branch(is_oddball, &if_valueisoddball, &if_valuenotoddball);

        BIND(&if_valueisoddball);
        {
          // Convert Oddball to Number and check again.
          value_var.Bind(LoadObjectField(value, Oddball::kToNumberOffset));
          var_type_feedback.Bind(
              SmiConstant(BinaryOperationFeedback::kNumberOrOddball));
          Goto(&start);
        }

        BIND(&if_valuenotoddball);
        {
          // Convert to a Number first and try again.
          var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kAny));
          value_var.Bind(
              CallBuiltin(Builtins::kNonNumberToNumber, context, value));
          Goto(&start);
        }
      }
    }
  }

  BIND(&do_finc);
  {
    Node* finc_value = var_finc_value.value();
    Node* one = Float64Constant(1.0);
    Node* finc_result = Float64Add(finc_value, one);
    var_type_feedback.Bind(
        SmiOr(var_type_feedback.value(),
              SmiConstant(BinaryOperationFeedback::kNumber)));
    result_var.Bind(AllocateHeapNumberWithValue(finc_result));
    Goto(&end);
  }

  BIND(&end);
  Node* function = LoadRegister(Register::function_closure());
  UpdateFeedback(var_type_feedback.value(), feedback_vector, slot_index,
                 function);

  SetAccumulator(result_var.value());
  Dispatch();
}

// Dec
//
// Decrements value in the accumulator by one.
IGNITION_HANDLER(Dec, InterpreterAssembler) {
  Node* value = GetAccumulator();
  Node* context = GetContext();
  Node* slot_index = BytecodeOperandIdx(0);
  Node* feedback_vector = LoadFeedbackVector();

  // Shared entry for floating point decrement.
  Label do_fdec(this), end(this);
  Variable var_fdec_value(this, MachineRepresentation::kFloat64);

  // We might need to try again due to ToNumber conversion.
  Variable value_var(this, MachineRepresentation::kTagged);
  Variable result_var(this, MachineRepresentation::kTagged);
  Variable var_type_feedback(this, MachineRepresentation::kTaggedSigned);
  Variable* loop_vars[] = {&value_var, &var_type_feedback};
  Label start(this, 2, loop_vars);
  var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kNone));
  value_var.Bind(value);
  Goto(&start);
  BIND(&start);
  {
    value = value_var.value();

    Label if_issmi(this), if_isnotsmi(this);
    Branch(TaggedIsSmi(value), &if_issmi, &if_isnotsmi);

    BIND(&if_issmi);
    {
      // Try fast Smi subtraction first.
      Node* one = SmiConstant(1);
      Node* pair = IntPtrSubWithOverflow(BitcastTaggedToWord(value),
                                         BitcastTaggedToWord(one));
      Node* overflow = Projection(1, pair);

      // Check if the Smi subtraction overflowed.
      Label if_overflow(this), if_notoverflow(this);
      Branch(overflow, &if_overflow, &if_notoverflow);

      BIND(&if_notoverflow);
      var_type_feedback.Bind(
          SmiOr(var_type_feedback.value(),
                SmiConstant(BinaryOperationFeedback::kSignedSmall)));
      result_var.Bind(BitcastWordToTaggedSigned(Projection(0, pair)));
      Goto(&end);

      BIND(&if_overflow);
      {
        var_fdec_value.Bind(SmiToFloat64(value));
        Goto(&do_fdec);
      }
    }

    BIND(&if_isnotsmi);
    {
      // Check if the value is a HeapNumber.
      Label if_valueisnumber(this), if_valuenotnumber(this, Label::kDeferred);
      Node* value_map = LoadMap(value);
      Branch(IsHeapNumberMap(value_map), &if_valueisnumber, &if_valuenotnumber);

      BIND(&if_valueisnumber);
      {
        // Load the HeapNumber value.
        var_fdec_value.Bind(LoadHeapNumberValue(value));
        Goto(&do_fdec);
      }

      BIND(&if_valuenotnumber);
      {
        // We do not require an Or with earlier feedback here because once we
        // convert the value to a number, we cannot reach this path. We can
        // only reach this path on the first pass when the feedback is kNone.
        CSA_ASSERT(this, SmiEqual(var_type_feedback.value(),
                                  SmiConstant(BinaryOperationFeedback::kNone)));

        Label if_valueisoddball(this), if_valuenotoddball(this);
        Node* instance_type = LoadMapInstanceType(value_map);
        Node* is_oddball =
            Word32Equal(instance_type, Int32Constant(ODDBALL_TYPE));
        Branch(is_oddball, &if_valueisoddball, &if_valuenotoddball);

        BIND(&if_valueisoddball);
        {
          // Convert Oddball to Number and check again.
          value_var.Bind(LoadObjectField(value, Oddball::kToNumberOffset));
          var_type_feedback.Bind(
              SmiConstant(BinaryOperationFeedback::kNumberOrOddball));
          Goto(&start);
        }

        BIND(&if_valuenotoddball);
        {
          // Convert to a Number first and try again.
          var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kAny));
          value_var.Bind(
              CallBuiltin(Builtins::kNonNumberToNumber, context, value));
          Goto(&start);
        }
      }
    }
  }

  BIND(&do_fdec);
  {
    Node* fdec_value = var_fdec_value.value();
    Node* one = Float64Constant(1.0);
    Node* fdec_result = Float64Sub(fdec_value, one);
    var_type_feedback.Bind(
        SmiOr(var_type_feedback.value(),
              SmiConstant(BinaryOperationFeedback::kNumber)));
    result_var.Bind(AllocateHeapNumberWithValue(fdec_result));
    Goto(&end);
  }

  BIND(&end);
  Node* function = LoadRegister(Register::function_closure());
  UpdateFeedback(var_type_feedback.value(), feedback_vector, slot_index,
                 function);

  SetAccumulator(result_var.value());
  Dispatch();
}

// LogicalNot
//
// Perform logical-not on the accumulator, first casting the
// accumulator to a boolean value if required.
// ToBooleanLogicalNot
IGNITION_HANDLER(ToBooleanLogicalNot, InterpreterAssembler) {
  Node* value = GetAccumulator();
  Variable result(this, MachineRepresentation::kTagged);
  Label if_true(this), if_false(this), end(this);
  Node* true_value = BooleanConstant(true);
  Node* false_value = BooleanConstant(false);
  BranchIfToBooleanIsTrue(value, &if_true, &if_false);
  BIND(&if_true);
  {
    result.Bind(false_value);
    Goto(&end);
  }
  BIND(&if_false);
  {
    result.Bind(true_value);
    Goto(&end);
  }
  BIND(&end);
  SetAccumulator(result.value());
  Dispatch();
}

// LogicalNot
//
// Perform logical-not on the accumulator, which must already be a boolean
// value.
IGNITION_HANDLER(LogicalNot, InterpreterAssembler) {
  Node* value = GetAccumulator();
  Variable result(this, MachineRepresentation::kTagged);
  Label if_true(this), if_false(this), end(this);
  Node* true_value = BooleanConstant(true);
  Node* false_value = BooleanConstant(false);
  Branch(WordEqual(value, true_value), &if_true, &if_false);
  BIND(&if_true);
  {
    result.Bind(false_value);
    Goto(&end);
  }
  BIND(&if_false);
  {
    if (FLAG_debug_code) {
      AbortIfWordNotEqual(value, false_value,
                          BailoutReason::kExpectedBooleanValue);
    }
    result.Bind(true_value);
    Goto(&end);
  }
  BIND(&end);
  SetAccumulator(result.value());
  Dispatch();
}

// TypeOf
//
// Load the accumulator with the string representating type of the
// object in the accumulator.
IGNITION_HANDLER(TypeOf, InterpreterAssembler) {
  Node* value = GetAccumulator();
  Node* result = Typeof(value);
  SetAccumulator(result);
  Dispatch();
}

// DeletePropertyStrict
//
// Delete the property specified in the accumulator from the object
// referenced by the register operand following strict mode semantics.
IGNITION_HANDLER(DeletePropertyStrict, InterpreterAssembler) {
  Node* reg_index = BytecodeOperandReg(0);
  Node* object = LoadRegister(reg_index);
  Node* key = GetAccumulator();
  Node* context = GetContext();
  Node* result = CallBuiltin(Builtins::kDeleteProperty, context, object, key,
                             SmiConstant(STRICT));
  SetAccumulator(result);
  Dispatch();
}

// DeletePropertySloppy
//
// Delete the property specified in the accumulator from the object
// referenced by the register operand following sloppy mode semantics.
IGNITION_HANDLER(DeletePropertySloppy, InterpreterAssembler) {
  Node* reg_index = BytecodeOperandReg(0);
  Node* object = LoadRegister(reg_index);
  Node* key = GetAccumulator();
  Node* context = GetContext();
  Node* result = CallBuiltin(Builtins::kDeleteProperty, context, object, key,
                             SmiConstant(SLOPPY));
  SetAccumulator(result);
  Dispatch();
}

// GetSuperConstructor
//
// Get the super constructor from the object referenced by the accumulator.
// The result is stored in register |reg|.
IGNITION_HANDLER(GetSuperConstructor, InterpreterAssembler) {
  Node* active_function = GetAccumulator();
  Node* context = GetContext();
  Node* result = GetSuperConstructor(active_function, context);
  Node* reg = BytecodeOperandReg(0);
  StoreRegister(result, reg);
  Dispatch();
}

class InterpreterJSCallAssembler : public InterpreterAssembler {
 public:
  InterpreterJSCallAssembler(CodeAssemblerState* state, Bytecode bytecode,
                             OperandScale operand_scale)
      : InterpreterAssembler(state, bytecode, operand_scale) {}

  // Generates code to perform a JS call that collects type feedback.
  void JSCall(ConvertReceiverMode receiver_mode) {
    Node* function_reg = BytecodeOperandReg(0);
    Node* function = LoadRegister(function_reg);
    Node* first_arg_reg = BytecodeOperandReg(1);
    Node* first_arg = RegisterLocation(first_arg_reg);
    Node* arg_list_count = BytecodeOperandCount(2);
    Node* args_count;
    if (receiver_mode == ConvertReceiverMode::kNullOrUndefined) {
      // The receiver is implied, so it is not in the argument list.
      args_count = arg_list_count;
    } else {
      // Subtract the receiver from the argument count.
      Node* receiver_count = Int32Constant(1);
      args_count = Int32Sub(arg_list_count, receiver_count);
    }
    Node* slot_id = BytecodeOperandIdx(3);
    Node* feedback_vector = LoadFeedbackVector();
    Node* context = GetContext();
    Node* result = CallJSWithFeedback(function, context, first_arg, args_count,
                                      slot_id, feedback_vector, receiver_mode);
    SetAccumulator(result);
    Dispatch();
  }

  // Generates code to perform a JS call with a known number of arguments that
  // collects type feedback.
  void JSCallN(int arg_count, ConvertReceiverMode receiver_mode) {
    // Indices and counts of operands on the bytecode.
    const int kFirstArgumentOperandIndex = 1;
    const int kReceiverOperandCount =
        (receiver_mode == ConvertReceiverMode::kNullOrUndefined) ? 0 : 1;
    const int kSlotOperandIndex =
        kFirstArgumentOperandIndex + kReceiverOperandCount + arg_count;
    // Indices and counts of parameters to the call stub.
    const int kBoilerplateParameterCount = 7;
    const int kReceiverParameterIndex = 5;
    const int kReceiverParameterCount = 1;
    // Only used in a DCHECK.
    USE(kReceiverParameterCount);

    Node* function_reg = BytecodeOperandReg(0);
    Node* function = LoadRegister(function_reg);
    std::array<Node*, Bytecodes::kMaxOperands + kBoilerplateParameterCount>
        temp;
    Callable call_ic = CodeFactory::CallIC(isolate());
    temp[0] = HeapConstant(call_ic.code());
    temp[1] = function;
    temp[2] = Int32Constant(arg_count);
    temp[3] = BytecodeOperandIdxInt32(kSlotOperandIndex);
    temp[4] = LoadFeedbackVector();

    int parameter_index = kReceiverParameterIndex;
    if (receiver_mode == ConvertReceiverMode::kNullOrUndefined) {
      // The first argument parameter (the receiver) is implied to be undefined.
      Node* undefined_value =
          HeapConstant(isolate()->factory()->undefined_value());
      temp[parameter_index++] = undefined_value;
    }
    // The bytecode argument operands are copied into the remaining argument
    // parameters.
    for (int i = 0; i < (kReceiverOperandCount + arg_count); ++i) {
      Node* reg = BytecodeOperandReg(kFirstArgumentOperandIndex + i);
      temp[parameter_index++] = LoadRegister(reg);
    }

    DCHECK_EQ(parameter_index,
              kReceiverParameterIndex + kReceiverParameterCount + arg_count);
    temp[parameter_index] = GetContext();

    Node* result = CallStubN(call_ic.descriptor(), 1,
                             arg_count + kBoilerplateParameterCount, &temp[0]);
    SetAccumulator(result);
    Dispatch();
  }
};

// Call <callable> <receiver> <arg_count> <feedback_slot_id>
//
// Call a JSfunction or Callable in |callable| with the |receiver| and
// |arg_count| arguments in subsequent registers. Collect type feedback
// into |feedback_slot_id|
IGNITION_HANDLER(CallAnyReceiver, InterpreterJSCallAssembler) {
  JSCall(ConvertReceiverMode::kAny);
}

IGNITION_HANDLER(CallProperty, InterpreterJSCallAssembler) {
  JSCall(ConvertReceiverMode::kNotNullOrUndefined);
}

IGNITION_HANDLER(CallProperty0, InterpreterJSCallAssembler) {
  JSCallN(0, ConvertReceiverMode::kNotNullOrUndefined);
}

IGNITION_HANDLER(CallProperty1, InterpreterJSCallAssembler) {
  JSCallN(1, ConvertReceiverMode::kNotNullOrUndefined);
}

IGNITION_HANDLER(CallProperty2, InterpreterJSCallAssembler) {
  JSCallN(2, ConvertReceiverMode::kNotNullOrUndefined);
}

IGNITION_HANDLER(CallUndefinedReceiver, InterpreterJSCallAssembler) {
  JSCall(ConvertReceiverMode::kNullOrUndefined);
}

IGNITION_HANDLER(CallUndefinedReceiver0, InterpreterJSCallAssembler) {
  JSCallN(0, ConvertReceiverMode::kNullOrUndefined);
}

IGNITION_HANDLER(CallUndefinedReceiver1, InterpreterJSCallAssembler) {
  JSCallN(1, ConvertReceiverMode::kNullOrUndefined);
}

IGNITION_HANDLER(CallUndefinedReceiver2, InterpreterJSCallAssembler) {
  JSCallN(2, ConvertReceiverMode::kNullOrUndefined);
}

// CallRuntime <function_id> <first_arg> <arg_count>
//
// Call the runtime function |function_id| with the first argument in
// register |first_arg| and |arg_count| arguments in subsequent
// registers.
IGNITION_HANDLER(CallRuntime, InterpreterAssembler) {
  Node* function_id = BytecodeOperandRuntimeId(0);
  Node* first_arg_reg = BytecodeOperandReg(1);
  Node* first_arg = RegisterLocation(first_arg_reg);
  Node* args_count = BytecodeOperandCount(2);
  Node* context = GetContext();
  Node* result = CallRuntimeN(function_id, context, first_arg, args_count);
  SetAccumulator(result);
  Dispatch();
}

// InvokeIntrinsic <function_id> <first_arg> <arg_count>
//
// Implements the semantic equivalent of calling the runtime function
// |function_id| with the first argument in |first_arg| and |arg_count|
// arguments in subsequent registers.
IGNITION_HANDLER(InvokeIntrinsic, InterpreterAssembler) {
  Node* function_id = BytecodeOperandIntrinsicId(0);
  Node* first_arg_reg = BytecodeOperandReg(1);
  Node* arg_count = BytecodeOperandCount(2);
  Node* context = GetContext();
  Node* result = GenerateInvokeIntrinsic(this, function_id, context,
                                         first_arg_reg, arg_count);
  SetAccumulator(result);
  Dispatch();
}

// CallRuntimeForPair <function_id> <first_arg> <arg_count> <first_return>
//
// Call the runtime function |function_id| which returns a pair, with the
// first argument in register |first_arg| and |arg_count| arguments in
// subsequent registers. Returns the result in <first_return> and
// <first_return + 1>
IGNITION_HANDLER(CallRuntimeForPair, InterpreterAssembler) {
  // Call the runtime function.
  Node* function_id = BytecodeOperandRuntimeId(0);
  Node* first_arg_reg = BytecodeOperandReg(1);
  Node* first_arg = RegisterLocation(first_arg_reg);
  Node* args_count = BytecodeOperandCount(2);
  Node* context = GetContext();
  Node* result_pair =
      CallRuntimeN(function_id, context, first_arg, args_count, 2);
  // Store the results in <first_return> and <first_return + 1>
  Node* first_return_reg = BytecodeOperandReg(3);
  Node* second_return_reg = NextRegister(first_return_reg);
  Node* result0 = Projection(0, result_pair);
  Node* result1 = Projection(1, result_pair);
  StoreRegister(result0, first_return_reg);
  StoreRegister(result1, second_return_reg);
  Dispatch();
}

// CallJSRuntime <context_index> <receiver> <arg_count>
//
// Call the JS runtime function that has the |context_index| with the receiver
// in register |receiver| and |arg_count| arguments in subsequent registers.
IGNITION_HANDLER(CallJSRuntime, InterpreterAssembler) {
  Node* context_index = BytecodeOperandIdx(0);
  Node* receiver_reg = BytecodeOperandReg(1);
  Node* first_arg = RegisterLocation(receiver_reg);
  Node* receiver_args_count = BytecodeOperandCount(2);
  Node* receiver_count = Int32Constant(1);
  Node* args_count = Int32Sub(receiver_args_count, receiver_count);

  // Get the function to call from the native context.
  Node* context = GetContext();
  Node* native_context = LoadNativeContext(context);
  Node* function = LoadContextElement(native_context, context_index);

  // Call the function.
  Node* result = CallJS(function, context, first_arg, args_count,
                        ConvertReceiverMode::kAny);
  SetAccumulator(result);
  Dispatch();
}

// CallWithSpread <callable> <first_arg> <arg_count>
//
// Call a JSfunction or Callable in |callable| with the receiver in
// |first_arg| and |arg_count - 1| arguments in subsequent registers. The
// final argument is always a spread.
//
IGNITION_HANDLER(CallWithSpread, InterpreterAssembler) {
  Node* callable_reg = BytecodeOperandReg(0);
  Node* callable = LoadRegister(callable_reg);
  Node* receiver_reg = BytecodeOperandReg(1);
  Node* receiver_arg = RegisterLocation(receiver_reg);
  Node* receiver_args_count = BytecodeOperandCount(2);
  Node* receiver_count = Int32Constant(1);
  Node* args_count = Int32Sub(receiver_args_count, receiver_count);
  Node* context = GetContext();

  // Call into Runtime function CallWithSpread which does everything.
  Node* result = CallJSWithSpread(callable, context, receiver_arg, args_count);
  SetAccumulator(result);
  Dispatch();
}

// ConstructWithSpread <first_arg> <arg_count>
//
// Call the constructor in |constructor| with the first argument in register
// |first_arg| and |arg_count| arguments in subsequent registers. The final
// argument is always a spread. The new.target is in the accumulator.
//
IGNITION_HANDLER(ConstructWithSpread, InterpreterAssembler) {
  Node* new_target = GetAccumulator();
  Node* constructor_reg = BytecodeOperandReg(0);
  Node* constructor = LoadRegister(constructor_reg);
  Node* first_arg_reg = BytecodeOperandReg(1);
  Node* first_arg = RegisterLocation(first_arg_reg);
  Node* args_count = BytecodeOperandCount(2);
  Node* context = GetContext();
  Node* result = ConstructWithSpread(constructor, context, new_target,
                                     first_arg, args_count);
  SetAccumulator(result);
  Dispatch();
}

// Construct <constructor> <first_arg> <arg_count>
//
// Call operator construct with |constructor| and the first argument in
// register |first_arg| and |arg_count| arguments in subsequent
// registers. The new.target is in the accumulator.
//
IGNITION_HANDLER(Construct, InterpreterAssembler) {
  Node* new_target = GetAccumulator();
  Node* constructor_reg = BytecodeOperandReg(0);
  Node* constructor = LoadRegister(constructor_reg);
  Node* first_arg_reg = BytecodeOperandReg(1);
  Node* first_arg = RegisterLocation(first_arg_reg);
  Node* args_count = BytecodeOperandCount(2);
  Node* slot_id = BytecodeOperandIdx(3);
  Node* feedback_vector = LoadFeedbackVector();
  Node* context = GetContext();
  Node* result = Construct(constructor, context, new_target, first_arg,
                           args_count, slot_id, feedback_vector);
  SetAccumulator(result);
  Dispatch();
}

class InterpreterCompareOpAssembler : public InterpreterAssembler {
 public:
  InterpreterCompareOpAssembler(CodeAssemblerState* state, Bytecode bytecode,
                                OperandScale operand_scale)
      : InterpreterAssembler(state, bytecode, operand_scale) {}

  void CompareOpWithFeedback(Token::Value compare_op) {
    Node* reg_index = BytecodeOperandReg(0);
    Node* lhs = LoadRegister(reg_index);
    Node* rhs = GetAccumulator();
    Node* context = GetContext();

    Variable var_type_feedback(this, MachineRepresentation::kTagged);
    Node* result;
    switch (compare_op) {
      case Token::EQ:
        result = Equal(lhs, rhs, context, &var_type_feedback);
        break;
      case Token::EQ_STRICT:
        result = StrictEqual(lhs, rhs, &var_type_feedback);
        break;
      case Token::LT:
        result = RelationalComparison(CodeStubAssembler::kLessThan, lhs, rhs,
                                      context, &var_type_feedback);
        break;
      case Token::GT:
        result = RelationalComparison(CodeStubAssembler::kGreaterThan, lhs, rhs,
                                      context, &var_type_feedback);
        break;
      case Token::LTE:
        result = RelationalComparison(CodeStubAssembler::kLessThanOrEqual, lhs,
                                      rhs, context, &var_type_feedback);
        break;
      case Token::GTE:
        result = RelationalComparison(CodeStubAssembler::kGreaterThanOrEqual,
                                      lhs, rhs, context, &var_type_feedback);
        break;
      default:
        UNREACHABLE();
    }

    Node* slot_index = BytecodeOperandIdx(1);
    Node* feedback_vector = LoadFeedbackVector();
    Node* function = LoadRegister(Register::function_closure());
    UpdateFeedback(var_type_feedback.value(), feedback_vector, slot_index,
                   function);
    SetAccumulator(result);
    Dispatch();
  }
};

// TestEqual <src>
//
// Test if the value in the <src> register equals the accumulator.
IGNITION_HANDLER(TestEqual, InterpreterCompareOpAssembler) {
  CompareOpWithFeedback(Token::Value::EQ);
}

// TestEqualStrict <src>
//
// Test if the value in the <src> register is strictly equal to the accumulator.
IGNITION_HANDLER(TestEqualStrict, InterpreterCompareOpAssembler) {
  CompareOpWithFeedback(Token::Value::EQ_STRICT);
}

// TestLessThan <src>
//
// Test if the value in the <src> register is less than the accumulator.
IGNITION_HANDLER(TestLessThan, InterpreterCompareOpAssembler) {
  CompareOpWithFeedback(Token::Value::LT);
}

// TestGreaterThan <src>
//
// Test if the value in the <src> register is greater than the accumulator.
IGNITION_HANDLER(TestGreaterThan, InterpreterCompareOpAssembler) {
  CompareOpWithFeedback(Token::Value::GT);
}

// TestLessThanOrEqual <src>
//
// Test if the value in the <src> register is less than or equal to the
// accumulator.
IGNITION_HANDLER(TestLessThanOrEqual, InterpreterCompareOpAssembler) {
  CompareOpWithFeedback(Token::Value::LTE);
}

// TestGreaterThanOrEqual <src>
//
// Test if the value in the <src> register is greater than or equal to the
// accumulator.
IGNITION_HANDLER(TestGreaterThanOrEqual, InterpreterCompareOpAssembler) {
  CompareOpWithFeedback(Token::Value::GTE);
}

// TestEqualStrictNoFeedback <src>
//
// Test if the value in the <src> register is strictly equal to the accumulator.
// Type feedback is not collected.
IGNITION_HANDLER(TestEqualStrictNoFeedback, InterpreterAssembler) {
  Node* reg_index = BytecodeOperandReg(0);
  Node* lhs = LoadRegister(reg_index);
  Node* rhs = GetAccumulator();
  // TODO(5310): This is called only when lhs and rhs are Smis (for ex:
  // try-finally or generators) or strings (only when visiting
  // ClassLiteralProperties). We should be able to optimize this and not perform
  // the full strict equality.
  Node* result = StrictEqual(lhs, rhs);
  SetAccumulator(result);
  Dispatch();
}

// TestIn <src>
//
// Test if the object referenced by the register operand is a property of the
// object referenced by the accumulator.
IGNITION_HANDLER(TestIn, InterpreterAssembler) {
  Node* reg_index = BytecodeOperandReg(0);
  Node* property = LoadRegister(reg_index);
  Node* object = GetAccumulator();
  Node* context = GetContext();
  SetAccumulator(HasProperty(object, property, context));
  Dispatch();
}

// TestInstanceOf <src>
//
// Test if the object referenced by the <src> register is an an instance of type
// referenced by the accumulator.
IGNITION_HANDLER(TestInstanceOf, InterpreterAssembler) {
  Node* reg_index = BytecodeOperandReg(0);
  Node* name = LoadRegister(reg_index);
  Node* object = GetAccumulator();
  Node* context = GetContext();
  SetAccumulator(InstanceOf(name, object, context));
  Dispatch();
}

// TestUndetectable
//
// Test if the value in the accumulator is undetectable (null, undefined or
// document.all).
IGNITION_HANDLER(TestUndetectable, InterpreterAssembler) {
  Label return_false(this), end(this);
  Node* object = GetAccumulator();

  // If the object is an Smi then return false.
  SetAccumulator(BooleanConstant(false));
  GotoIf(TaggedIsSmi(object), &end);

  // If it is a HeapObject, load the map and check for undetectable bit.
  Node* result = SelectBooleanConstant(IsUndetectableMap(LoadMap(object)));
  SetAccumulator(result);
  Goto(&end);

  BIND(&end);
  Dispatch();
}

// TestNull
//
// Test if the value in accumulator is strictly equal to null.
IGNITION_HANDLER(TestNull, InterpreterAssembler) {
  Node* object = GetAccumulator();
  Node* null_value = HeapConstant(isolate()->factory()->null_value());
  Node* result = SelectBooleanConstant(WordEqual(object, null_value));
  SetAccumulator(result);
  Dispatch();
}

// TestUndefined
//
// Test if the value in the accumulator is strictly equal to undefined.
IGNITION_HANDLER(TestUndefined, InterpreterAssembler) {
  Node* object = GetAccumulator();
  Node* undefined_value = HeapConstant(isolate()->factory()->undefined_value());
  Node* result = SelectBooleanConstant(WordEqual(object, undefined_value));
  SetAccumulator(result);
  Dispatch();
}

// TestTypeOf <literal_flag>
//
// Tests if the object in the <accumulator> is typeof the literal represented
// by |literal_flag|.
IGNITION_HANDLER(TestTypeOf, InterpreterAssembler) {
  Node* object = GetAccumulator();
  Node* literal_flag = BytecodeOperandFlag(0);

#define MAKE_LABEL(name, lower_case) Label if_##lower_case(this);
  TYPEOF_LITERAL_LIST(MAKE_LABEL)
#undef MAKE_LABEL

#define LABEL_POINTER(name, lower_case) &if_##lower_case,
  Label* labels[] = {TYPEOF_LITERAL_LIST(LABEL_POINTER)};
#undef LABEL_POINTER

#define CASE(name, lower_case) \
  static_cast<int32_t>(TestTypeOfFlags::LiteralFlag::k##name),
  int32_t cases[] = {TYPEOF_LITERAL_LIST(CASE)};
#undef CASE

  Label if_true(this), if_false(this), end(this), abort(this, Label::kDeferred);

  Switch(literal_flag, &abort, cases, labels, arraysize(cases));

  BIND(&abort);
  {
    Comment("Abort");
    Abort(BailoutReason::kUnexpectedTestTypeofLiteralFlag);
    Goto(&if_false);
  }
  BIND(&if_number);
  {
    Comment("IfNumber");
    GotoIfNumber(object, &if_true);
    Goto(&if_false);
  }
  BIND(&if_string);
  {
    Comment("IfString");
    GotoIf(TaggedIsSmi(object), &if_false);
    Branch(IsString(object), &if_true, &if_false);
  }
  BIND(&if_symbol);
  {
    Comment("IfSymbol");
    GotoIf(TaggedIsSmi(object), &if_false);
    Branch(IsSymbol(object), &if_true, &if_false);
  }
  BIND(&if_boolean);
  {
    Comment("IfBoolean");
    GotoIf(WordEqual(object, BooleanConstant(true)), &if_true);
    Branch(WordEqual(object, BooleanConstant(false)), &if_true, &if_false);
  }
  BIND(&if_undefined);
  {
    Comment("IfUndefined");
    GotoIf(TaggedIsSmi(object), &if_false);
    // Check it is not null and the map has the undetectable bit set.
    GotoIf(IsNull(object), &if_false);
    Branch(IsUndetectableMap(LoadMap(object)), &if_true, &if_false);
  }
  BIND(&if_function);
  {
    Comment("IfFunction");
    GotoIf(TaggedIsSmi(object), &if_false);
    // Check if callable bit is set and not undetectable.
    Node* map_bitfield = LoadMapBitField(LoadMap(object));
    Node* callable_undetectable = Word32And(
        map_bitfield,
        Int32Constant(1 << Map::kIsUndetectable | 1 << Map::kIsCallable));
    Branch(Word32Equal(callable_undetectable,
                       Int32Constant(1 << Map::kIsCallable)),
           &if_true, &if_false);
  }
  BIND(&if_object);
  {
    Comment("IfObject");
    GotoIf(TaggedIsSmi(object), &if_false);

    // If the object is null then return true.
    GotoIf(WordEqual(object, NullConstant()), &if_true);

    // Check if the object is a receiver type and is not undefined or callable.
    Node* map = LoadMap(object);
    GotoIfNot(IsJSReceiverMap(map), &if_false);
    Node* map_bitfield = LoadMapBitField(map);
    Node* callable_undetectable = Word32And(
        map_bitfield,
        Int32Constant(1 << Map::kIsUndetectable | 1 << Map::kIsCallable));
    Branch(Word32Equal(callable_undetectable, Int32Constant(0)), &if_true,
           &if_false);
  }
  BIND(&if_other);
  {
    // Typeof doesn't return any other string value.
    Goto(&if_false);
  }

  BIND(&if_false);
  {
    SetAccumulator(BooleanConstant(false));
    Goto(&end);
  }
  BIND(&if_true);
  {
    SetAccumulator(BooleanConstant(true));
    Goto(&end);
  }
  BIND(&end);
  Dispatch();
}

// Jump <imm>
//
// Jump by the number of bytes represented by the immediate operand |imm|.
IGNITION_HANDLER(Jump, InterpreterAssembler) {
  Node* relative_jump = BytecodeOperandUImmWord(0);
  Jump(relative_jump);
}

// JumpConstant <idx>
//
// Jump by the number of bytes in the Smi in the |idx| entry in the constant
// pool.
IGNITION_HANDLER(JumpConstant, InterpreterAssembler) {
  Node* index = BytecodeOperandIdx(0);
  Node* relative_jump = LoadAndUntagConstantPoolEntry(index);
  Jump(relative_jump);
}

// JumpIfTrue <imm>
//
// Jump by the number of bytes represented by an immediate operand if the
// accumulator contains true. This only works for boolean inputs, and
// will misbehave if passed arbitrary input values.
IGNITION_HANDLER(JumpIfTrue, InterpreterAssembler) {
  Node* accumulator = GetAccumulator();
  Node* relative_jump = BytecodeOperandUImmWord(0);
  Node* true_value = BooleanConstant(true);
  CSA_ASSERT(this, TaggedIsNotSmi(accumulator));
  CSA_ASSERT(this, IsBoolean(accumulator));
  JumpIfWordEqual(accumulator, true_value, relative_jump);
}

// JumpIfTrueConstant <idx>
//
// Jump by the number of bytes in the Smi in the |idx| entry in the constant
// pool if the accumulator contains true. This only works for boolean inputs,
// and will misbehave if passed arbitrary input values.
IGNITION_HANDLER(JumpIfTrueConstant, InterpreterAssembler) {
  Node* accumulator = GetAccumulator();
  Node* index = BytecodeOperandIdx(0);
  Node* relative_jump = LoadAndUntagConstantPoolEntry(index);
  Node* true_value = BooleanConstant(true);
  CSA_ASSERT(this, TaggedIsNotSmi(accumulator));
  CSA_ASSERT(this, IsBoolean(accumulator));
  JumpIfWordEqual(accumulator, true_value, relative_jump);
}

// JumpIfFalse <imm>
//
// Jump by the number of bytes represented by an immediate operand if the
// accumulator contains false. This only works for boolean inputs, and
// will misbehave if passed arbitrary input values.
IGNITION_HANDLER(JumpIfFalse, InterpreterAssembler) {
  Node* accumulator = GetAccumulator();
  Node* relative_jump = BytecodeOperandUImmWord(0);
  Node* false_value = BooleanConstant(false);
  CSA_ASSERT(this, TaggedIsNotSmi(accumulator));
  CSA_ASSERT(this, IsBoolean(accumulator));
  JumpIfWordEqual(accumulator, false_value, relative_jump);
}

// JumpIfFalseConstant <idx>
//
// Jump by the number of bytes in the Smi in the |idx| entry in the constant
// pool if the accumulator contains false. This only works for boolean inputs,
// and will misbehave if passed arbitrary input values.
IGNITION_HANDLER(JumpIfFalseConstant, InterpreterAssembler) {
  Node* accumulator = GetAccumulator();
  Node* index = BytecodeOperandIdx(0);
  Node* relative_jump = LoadAndUntagConstantPoolEntry(index);
  Node* false_value = BooleanConstant(false);
  CSA_ASSERT(this, TaggedIsNotSmi(accumulator));
  CSA_ASSERT(this, IsBoolean(accumulator));
  JumpIfWordEqual(accumulator, false_value, relative_jump);
}

// JumpIfToBooleanTrue <imm>
//
// Jump by the number of bytes represented by an immediate operand if the object
// referenced by the accumulator is true when the object is cast to boolean.
IGNITION_HANDLER(JumpIfToBooleanTrue, InterpreterAssembler) {
  Node* value = GetAccumulator();
  Node* relative_jump = BytecodeOperandUImmWord(0);
  Label if_true(this), if_false(this);
  BranchIfToBooleanIsTrue(value, &if_true, &if_false);
  BIND(&if_true);
  Jump(relative_jump);
  BIND(&if_false);
  Dispatch();
}

// JumpIfToBooleanTrueConstant <idx>
//
// Jump by the number of bytes in the Smi in the |idx| entry in the constant
// pool if the object referenced by the accumulator is true when the object is
// cast to boolean.
IGNITION_HANDLER(JumpIfToBooleanTrueConstant, InterpreterAssembler) {
  Node* value = GetAccumulator();
  Node* index = BytecodeOperandIdx(0);
  Node* relative_jump = LoadAndUntagConstantPoolEntry(index);
  Label if_true(this), if_false(this);
  BranchIfToBooleanIsTrue(value, &if_true, &if_false);
  BIND(&if_true);
  Jump(relative_jump);
  BIND(&if_false);
  Dispatch();
}

// JumpIfToBooleanFalse <imm>
//
// Jump by the number of bytes represented by an immediate operand if the object
// referenced by the accumulator is false when the object is cast to boolean.
IGNITION_HANDLER(JumpIfToBooleanFalse, InterpreterAssembler) {
  Node* value = GetAccumulator();
  Node* relative_jump = BytecodeOperandUImmWord(0);
  Label if_true(this), if_false(this);
  BranchIfToBooleanIsTrue(value, &if_true, &if_false);
  BIND(&if_true);
  Dispatch();
  BIND(&if_false);
  Jump(relative_jump);
}

// JumpIfToBooleanFalseConstant <idx>
//
// Jump by the number of bytes in the Smi in the |idx| entry in the constant
// pool if the object referenced by the accumulator is false when the object is
// cast to boolean.
IGNITION_HANDLER(JumpIfToBooleanFalseConstant, InterpreterAssembler) {
  Node* value = GetAccumulator();
  Node* index = BytecodeOperandIdx(0);
  Node* relative_jump = LoadAndUntagConstantPoolEntry(index);
  Label if_true(this), if_false(this);
  BranchIfToBooleanIsTrue(value, &if_true, &if_false);
  BIND(&if_true);
  Dispatch();
  BIND(&if_false);
  Jump(relative_jump);
}

// JumpIfNull <imm>
//
// Jump by the number of bytes represented by an immediate operand if the object
// referenced by the accumulator is the null constant.
IGNITION_HANDLER(JumpIfNull, InterpreterAssembler) {
  Node* accumulator = GetAccumulator();
  Node* null_value = HeapConstant(isolate()->factory()->null_value());
  Node* relative_jump = BytecodeOperandUImmWord(0);
  JumpIfWordEqual(accumulator, null_value, relative_jump);
}

// JumpIfNullConstant <idx>
//
// Jump by the number of bytes in the Smi in the |idx| entry in the constant
// pool if the object referenced by the accumulator is the null constant.
IGNITION_HANDLER(JumpIfNullConstant, InterpreterAssembler) {
  Node* accumulator = GetAccumulator();
  Node* null_value = HeapConstant(isolate()->factory()->null_value());
  Node* index = BytecodeOperandIdx(0);
  Node* relative_jump = LoadAndUntagConstantPoolEntry(index);
  JumpIfWordEqual(accumulator, null_value, relative_jump);
}

// JumpIfNotNull <imm>
//
// Jump by the number of bytes represented by an immediate operand if the object
// referenced by the accumulator is not the null constant.
IGNITION_HANDLER(JumpIfNotNull, InterpreterAssembler) {
  Node* accumulator = GetAccumulator();
  Node* null_value = HeapConstant(isolate()->factory()->null_value());
  Node* relative_jump = BytecodeOperandUImmWord(0);
  JumpIfWordNotEqual(accumulator, null_value, relative_jump);
}

// JumpIfNotNullConstant <idx>
//
// Jump by the number of bytes in the Smi in the |idx| entry in the constant
// pool if the object referenced by the accumulator is not the null constant.
IGNITION_HANDLER(JumpIfNotNullConstant, InterpreterAssembler) {
  Node* accumulator = GetAccumulator();
  Node* null_value = HeapConstant(isolate()->factory()->null_value());
  Node* index = BytecodeOperandIdx(0);
  Node* relative_jump = LoadAndUntagConstantPoolEntry(index);
  JumpIfWordNotEqual(accumulator, null_value, relative_jump);
}

// JumpIfUndefined <imm>
//
// Jump by the number of bytes represented by an immediate operand if the object
// referenced by the accumulator is the undefined constant.
IGNITION_HANDLER(JumpIfUndefined, InterpreterAssembler) {
  Node* accumulator = GetAccumulator();
  Node* undefined_value = HeapConstant(isolate()->factory()->undefined_value());
  Node* relative_jump = BytecodeOperandUImmWord(0);
  JumpIfWordEqual(accumulator, undefined_value, relative_jump);
}

// JumpIfUndefinedConstant <idx>
//
// Jump by the number of bytes in the Smi in the |idx| entry in the constant
// pool if the object referenced by the accumulator is the undefined constant.
IGNITION_HANDLER(JumpIfUndefinedConstant, InterpreterAssembler) {
  Node* accumulator = GetAccumulator();
  Node* undefined_value = HeapConstant(isolate()->factory()->undefined_value());
  Node* index = BytecodeOperandIdx(0);
  Node* relative_jump = LoadAndUntagConstantPoolEntry(index);
  JumpIfWordEqual(accumulator, undefined_value, relative_jump);
}

// JumpIfNotUndefined <imm>
//
// Jump by the number of bytes represented by an immediate operand if the object
// referenced by the accumulator is not the undefined constant.
IGNITION_HANDLER(JumpIfNotUndefined, InterpreterAssembler) {
  Node* accumulator = GetAccumulator();
  Node* undefined_value = HeapConstant(isolate()->factory()->undefined_value());
  Node* relative_jump = BytecodeOperandUImmWord(0);
  JumpIfWordNotEqual(accumulator, undefined_value, relative_jump);
}

// JumpIfNotUndefinedConstant <idx>
//
// Jump by the number of bytes in the Smi in the |idx| entry in the constant
// pool if the object referenced by the accumulator is not the undefined
// constant.
IGNITION_HANDLER(JumpIfNotUndefinedConstant, InterpreterAssembler) {
  Node* accumulator = GetAccumulator();
  Node* undefined_value = HeapConstant(isolate()->factory()->undefined_value());
  Node* index = BytecodeOperandIdx(0);
  Node* relative_jump = LoadAndUntagConstantPoolEntry(index);
  JumpIfWordNotEqual(accumulator, undefined_value, relative_jump);
}

// JumpIfJSReceiver <imm>
//
// Jump by the number of bytes represented by an immediate operand if the object
// referenced by the accumulator is a JSReceiver.
IGNITION_HANDLER(JumpIfJSReceiver, InterpreterAssembler) {
  Node* accumulator = GetAccumulator();
  Node* relative_jump = BytecodeOperandUImmWord(0);

  Label if_object(this), if_notobject(this, Label::kDeferred), if_notsmi(this);
  Branch(TaggedIsSmi(accumulator), &if_notobject, &if_notsmi);

  BIND(&if_notsmi);
  Branch(IsJSReceiver(accumulator), &if_object, &if_notobject);
  BIND(&if_object);
  Jump(relative_jump);

  BIND(&if_notobject);
  Dispatch();
}

// JumpIfJSReceiverConstant <idx>
//
// Jump by the number of bytes in the Smi in the |idx| entry in the constant
// pool if the object referenced by the accumulator is a JSReceiver.
IGNITION_HANDLER(JumpIfJSReceiverConstant, InterpreterAssembler) {
  Node* accumulator = GetAccumulator();
  Node* index = BytecodeOperandIdx(0);
  Node* relative_jump = LoadAndUntagConstantPoolEntry(index);

  Label if_object(this), if_notobject(this), if_notsmi(this);
  Branch(TaggedIsSmi(accumulator), &if_notobject, &if_notsmi);

  BIND(&if_notsmi);
  Branch(IsJSReceiver(accumulator), &if_object, &if_notobject);

  BIND(&if_object);
  Jump(relative_jump);

  BIND(&if_notobject);
  Dispatch();
}

// JumpLoop <imm> <loop_depth>
//
// Jump by the number of bytes represented by the immediate operand |imm|. Also
// performs a loop nesting check and potentially triggers OSR in case the
// current OSR level matches (or exceeds) the specified |loop_depth|.
IGNITION_HANDLER(JumpLoop, InterpreterAssembler) {
  Node* relative_jump = BytecodeOperandUImmWord(0);
  Node* loop_depth = BytecodeOperandImm(1);
  Node* osr_level = LoadOSRNestingLevel();

  // Check if OSR points at the given {loop_depth} are armed by comparing it to
  // the current {osr_level} loaded from the header of the BytecodeArray.
  Label ok(this), osr_armed(this, Label::kDeferred);
  Node* condition = Int32GreaterThanOrEqual(loop_depth, osr_level);
  Branch(condition, &ok, &osr_armed);

  BIND(&ok);
  JumpBackward(relative_jump);

  BIND(&osr_armed);
  {
    Callable callable = CodeFactory::InterpreterOnStackReplacement(isolate());
    Node* target = HeapConstant(callable.code());
    Node* context = GetContext();
    CallStub(callable.descriptor(), target, context);
    JumpBackward(relative_jump);
  }
}

// SwitchOnSmiNoFeedback <table_start> <table_length> <case_value_base>
//
// Jump by the number of bytes defined by a Smi in a table in the constant pool,
// where the table starts at |table_start| and has |table_length| entries.
// The table is indexed by the accumulator, minus |case_value_base|. If the
// case_value falls outside of the table |table_length|, fall-through to the
// next bytecode.
IGNITION_HANDLER(SwitchOnSmiNoFeedback, InterpreterAssembler) {
  Node* acc = GetAccumulator();
  Node* table_start = BytecodeOperandIdx(0);
  Node* table_length = BytecodeOperandUImmWord(1);
  Node* case_value_base = BytecodeOperandImmIntPtr(2);

  Label fall_through(this);

  // The accumulator must be a Smi.
  // TODO(leszeks): Add a bytecode with type feedback that allows other
  // accumulator values.
  CSA_ASSERT(this, TaggedIsSmi(acc));

  Node* case_value = IntPtrSub(SmiUntag(acc), case_value_base);
  GotoIf(IntPtrLessThan(case_value, IntPtrConstant(0)), &fall_through);
  GotoIf(IntPtrGreaterThanOrEqual(case_value, table_length), &fall_through);
  Node* entry = IntPtrAdd(table_start, case_value);
  Node* relative_jump = LoadAndUntagConstantPoolEntry(entry);
  Jump(relative_jump);

  BIND(&fall_through);
  Dispatch();
}

// CreateRegExpLiteral <pattern_idx> <literal_idx> <flags>
//
// Creates a regular expression literal for literal index <literal_idx> with
// <flags> and the pattern in <pattern_idx>.
IGNITION_HANDLER(CreateRegExpLiteral, InterpreterAssembler) {
  Node* index = BytecodeOperandIdx(0);
  Node* pattern = LoadConstantPoolEntry(index);
  Node* literal_index = BytecodeOperandIdxSmi(1);
  Node* flags = SmiFromWord32(BytecodeOperandFlag(2));
  Node* closure = LoadRegister(Register::function_closure());
  Node* context = GetContext();
  ConstructorBuiltinsAssembler constructor_assembler(state());
  Node* result = constructor_assembler.EmitFastCloneRegExp(
      closure, literal_index, pattern, flags, context);
  SetAccumulator(result);
  Dispatch();
}

// CreateArrayLiteral <element_idx> <literal_idx> <flags>
//
// Creates an array literal for literal index <literal_idx> with
// CreateArrayLiteral flags <flags> and constant elements in <element_idx>.
IGNITION_HANDLER(CreateArrayLiteral, InterpreterAssembler) {
  Node* literal_index = BytecodeOperandIdxSmi(1);
  Node* closure = LoadRegister(Register::function_closure());
  Node* context = GetContext();
  Node* bytecode_flags = BytecodeOperandFlag(2);

  Label fast_shallow_clone(this), call_runtime(this, Label::kDeferred);
  Branch(IsSetWord32<CreateArrayLiteralFlags::FastCloneSupportedBit>(
             bytecode_flags),
         &fast_shallow_clone, &call_runtime);

  BIND(&fast_shallow_clone);
  {
    ConstructorBuiltinsAssembler constructor_assembler(state());
    Node* result = constructor_assembler.EmitFastCloneShallowArray(
        closure, literal_index, context, &call_runtime, TRACK_ALLOCATION_SITE);
    SetAccumulator(result);
    Dispatch();
  }

  BIND(&call_runtime);
  {
    Node* flags_raw = DecodeWordFromWord32<CreateArrayLiteralFlags::FlagsBits>(
        bytecode_flags);
    Node* flags = SmiTag(flags_raw);
    Node* index = BytecodeOperandIdx(0);
    Node* constant_elements = LoadConstantPoolEntry(index);
    Node* result = CallRuntime(Runtime::kCreateArrayLiteral, context, closure,
                               literal_index, constant_elements, flags);
    SetAccumulator(result);
    Dispatch();
  }
}

// CreateObjectLiteral <element_idx> <literal_idx> <flags>
//
// Creates an object literal for literal index <literal_idx> with
// CreateObjectLiteralFlags <flags> and constant elements in <element_idx>.
IGNITION_HANDLER(CreateObjectLiteral, InterpreterAssembler) {
  Node* literal_index = BytecodeOperandIdxSmi(1);
  Node* bytecode_flags = BytecodeOperandFlag(2);
  Node* closure = LoadRegister(Register::function_closure());

  // Check if we can do a fast clone or have to call the runtime.
  Label if_fast_clone(this), if_not_fast_clone(this, Label::kDeferred);
  Branch(IsSetWord32<CreateObjectLiteralFlags::FastCloneSupportedBit>(
             bytecode_flags),
         &if_fast_clone, &if_not_fast_clone);

  BIND(&if_fast_clone);
  {
    // If we can do a fast clone do the fast-path in FastCloneShallowObjectStub.
    ConstructorBuiltinsAssembler constructor_assembler(state());
    Node* result = constructor_assembler.EmitFastCloneShallowObject(
        &if_not_fast_clone, closure, literal_index);
    StoreRegister(result, BytecodeOperandReg(3));
    Dispatch();
  }

  BIND(&if_not_fast_clone);
  {
    // If we can't do a fast clone, call into the runtime.
    Node* index = BytecodeOperandIdx(0);
    Node* boilerplate_description = LoadConstantPoolEntry(index);
    Node* context = GetContext();

    Node* flags_raw = DecodeWordFromWord32<CreateObjectLiteralFlags::FlagsBits>(
        bytecode_flags);
    Node* flags = SmiTag(flags_raw);

    Node* result = CallRuntime(Runtime::kCreateObjectLiteral, context, closure,
                               literal_index, boilerplate_description, flags);
    StoreRegister(result, BytecodeOperandReg(3));
    // TODO(klaasb) build a single dispatch once the call is inlined
    Dispatch();
  }
}

// CreateClosure <index> <slot> <tenured>
//
// Creates a new closure for SharedFunctionInfo at position |index| in the
// constant pool and with the PretenureFlag <tenured>.
IGNITION_HANDLER(CreateClosure, InterpreterAssembler) {
  Node* index = BytecodeOperandIdx(0);
  Node* shared = LoadConstantPoolEntry(index);
  Node* flags = BytecodeOperandFlag(2);
  Node* context = GetContext();

  Label call_runtime(this, Label::kDeferred);
  GotoIfNot(IsSetWord32<CreateClosureFlags::FastNewClosureBit>(flags),
            &call_runtime);
  ConstructorBuiltinsAssembler constructor_assembler(state());
  Node* vector_index = BytecodeOperandIdx(1);
  vector_index = SmiTag(vector_index);
  Node* feedback_vector = LoadFeedbackVector();
  SetAccumulator(constructor_assembler.EmitFastNewClosure(
      shared, feedback_vector, vector_index, context));
  Dispatch();

  BIND(&call_runtime);
  {
    Node* tenured_raw =
        DecodeWordFromWord32<CreateClosureFlags::PretenuredBit>(flags);
    Node* tenured = SmiTag(tenured_raw);
    feedback_vector = LoadFeedbackVector();
    vector_index = BytecodeOperandIdx(1);
    vector_index = SmiTag(vector_index);
    Node* result = CallRuntime(Runtime::kInterpreterNewClosure, context, shared,
                               feedback_vector, vector_index, tenured);
    SetAccumulator(result);
    Dispatch();
  }
}

// CreateBlockContext <index>
//
// Creates a new block context with the scope info constant at |index| and the
// closure in the accumulator.
IGNITION_HANDLER(CreateBlockContext, InterpreterAssembler) {
  Node* index = BytecodeOperandIdx(0);
  Node* scope_info = LoadConstantPoolEntry(index);
  Node* closure = GetAccumulator();
  Node* context = GetContext();
  SetAccumulator(
      CallRuntime(Runtime::kPushBlockContext, context, scope_info, closure));
  Dispatch();
}

// CreateCatchContext <exception> <name_idx> <scope_info_idx>
//
// Creates a new context for a catch block with the |exception| in a register,
// the variable name at |name_idx|, the ScopeInfo at |scope_info_idx|, and the
// closure in the accumulator.
IGNITION_HANDLER(CreateCatchContext, InterpreterAssembler) {
  Node* exception_reg = BytecodeOperandReg(0);
  Node* exception = LoadRegister(exception_reg);
  Node* name_idx = BytecodeOperandIdx(1);
  Node* name = LoadConstantPoolEntry(name_idx);
  Node* scope_info_idx = BytecodeOperandIdx(2);
  Node* scope_info = LoadConstantPoolEntry(scope_info_idx);
  Node* closure = GetAccumulator();
  Node* context = GetContext();
  SetAccumulator(CallRuntime(Runtime::kPushCatchContext, context, name,
                             exception, scope_info, closure));
  Dispatch();
}

// CreateFunctionContext <slots>
//
// Creates a new context with number of |slots| for the function closure.
IGNITION_HANDLER(CreateFunctionContext, InterpreterAssembler) {
  Node* closure = LoadRegister(Register::function_closure());
  Node* slots = BytecodeOperandUImm(0);
  Node* context = GetContext();
  ConstructorBuiltinsAssembler constructor_assembler(state());
  SetAccumulator(constructor_assembler.EmitFastNewFunctionContext(
      closure, slots, context, FUNCTION_SCOPE));
  Dispatch();
}

// CreateEvalContext <slots>
//
// Creates a new context with number of |slots| for an eval closure.
IGNITION_HANDLER(CreateEvalContext, InterpreterAssembler) {
  Node* closure = LoadRegister(Register::function_closure());
  Node* slots = BytecodeOperandUImm(0);
  Node* context = GetContext();
  ConstructorBuiltinsAssembler constructor_assembler(state());
  SetAccumulator(constructor_assembler.EmitFastNewFunctionContext(
      closure, slots, context, EVAL_SCOPE));
  Dispatch();
}

// CreateWithContext <register> <scope_info_idx>
//
// Creates a new context with the ScopeInfo at |scope_info_idx| for a
// with-statement with the object in |register| and the closure in the
// accumulator.
IGNITION_HANDLER(CreateWithContext, InterpreterAssembler) {
  Node* reg_index = BytecodeOperandReg(0);
  Node* object = LoadRegister(reg_index);
  Node* scope_info_idx = BytecodeOperandIdx(1);
  Node* scope_info = LoadConstantPoolEntry(scope_info_idx);
  Node* closure = GetAccumulator();
  Node* context = GetContext();
  SetAccumulator(CallRuntime(Runtime::kPushWithContext, context, object,
                             scope_info, closure));
  Dispatch();
}

// CreateMappedArguments
//
// Creates a new mapped arguments object.
IGNITION_HANDLER(CreateMappedArguments, InterpreterAssembler) {
  Node* closure = LoadRegister(Register::function_closure());
  Node* context = GetContext();

  Label if_duplicate_parameters(this, Label::kDeferred);
  Label if_not_duplicate_parameters(this);

  // Check if function has duplicate parameters.
  // TODO(rmcilroy): Remove this check when FastNewSloppyArgumentsStub supports
  // duplicate parameters.
  Node* shared_info =
      LoadObjectField(closure, JSFunction::kSharedFunctionInfoOffset);
  Node* compiler_hints =
      LoadObjectField(shared_info, SharedFunctionInfo::kCompilerHintsOffset,
                      MachineType::Uint32());
  Node* has_duplicate_parameters =
      IsSetWord32<SharedFunctionInfo::HasDuplicateParametersBit>(
          compiler_hints);
  Branch(has_duplicate_parameters, &if_duplicate_parameters,
         &if_not_duplicate_parameters);

  BIND(&if_not_duplicate_parameters);
  {
    ArgumentsBuiltinsAssembler constructor_assembler(state());
    Node* result =
        constructor_assembler.EmitFastNewSloppyArguments(context, closure);
    SetAccumulator(result);
    Dispatch();
  }

  BIND(&if_duplicate_parameters);
  {
    Node* result =
        CallRuntime(Runtime::kNewSloppyArguments_Generic, context, closure);
    SetAccumulator(result);
    Dispatch();
  }
}

// CreateUnmappedArguments
//
// Creates a new unmapped arguments object.
IGNITION_HANDLER(CreateUnmappedArguments, InterpreterAssembler) {
  Node* context = GetContext();
  Node* closure = LoadRegister(Register::function_closure());
  ArgumentsBuiltinsAssembler builtins_assembler(state());
  Node* result =
      builtins_assembler.EmitFastNewStrictArguments(context, closure);
  SetAccumulator(result);
  Dispatch();
}

// CreateRestParameter
//
// Creates a new rest parameter array.
IGNITION_HANDLER(CreateRestParameter, InterpreterAssembler) {
  Node* closure = LoadRegister(Register::function_closure());
  Node* context = GetContext();
  ArgumentsBuiltinsAssembler builtins_assembler(state());
  Node* result = builtins_assembler.EmitFastNewRestParameter(context, closure);
  SetAccumulator(result);
  Dispatch();
}

// StackCheck
//
// Performs a stack guard check.
IGNITION_HANDLER(StackCheck, InterpreterAssembler) {
  Label ok(this), stack_check_interrupt(this, Label::kDeferred);

  Node* interrupt = StackCheckTriggeredInterrupt();
  Branch(interrupt, &stack_check_interrupt, &ok);

  BIND(&ok);
  Dispatch();

  BIND(&stack_check_interrupt);
  {
    Node* context = GetContext();
    CallRuntime(Runtime::kStackGuard, context);
    Dispatch();
  }
}

// SetPendingMessage
//
// Sets the pending message to the value in the accumulator, and returns the
// previous pending message in the accumulator.
IGNITION_HANDLER(SetPendingMessage, InterpreterAssembler) {
  Node* pending_message = ExternalConstant(
      ExternalReference::address_of_pending_message_obj(isolate()));
  Node* previous_message = Load(MachineType::TaggedPointer(), pending_message);
  Node* new_message = GetAccumulator();
  StoreNoWriteBarrier(MachineRepresentation::kTaggedPointer, pending_message,
                      new_message);
  SetAccumulator(previous_message);
  Dispatch();
}

// Throw
//
// Throws the exception in the accumulator.
IGNITION_HANDLER(Throw, InterpreterAssembler) {
  Node* exception = GetAccumulator();
  Node* context = GetContext();
  CallRuntime(Runtime::kThrow, context, exception);
  // We shouldn't ever return from a throw.
  Abort(kUnexpectedReturnFromThrow);
}

// ReThrow
//
// Re-throws the exception in the accumulator.
IGNITION_HANDLER(ReThrow, InterpreterAssembler) {
  Node* exception = GetAccumulator();
  Node* context = GetContext();
  CallRuntime(Runtime::kReThrow, context, exception);
  // We shouldn't ever return from a throw.
  Abort(kUnexpectedReturnFromThrow);
}

// Return
//
// Return the value in the accumulator.
IGNITION_HANDLER(Return, InterpreterAssembler) {
  UpdateInterruptBudgetOnReturn();
  Node* accumulator = GetAccumulator();
  Return(accumulator);
}

// ThrowReferenceErrorIfHole <variable_name>
//
// Throws an exception if the value in the accumulator is TheHole.
IGNITION_HANDLER(ThrowReferenceErrorIfHole, InterpreterAssembler) {
  Node* value = GetAccumulator();
  Node* the_hole_value = HeapConstant(isolate()->factory()->the_hole_value());

  Label throw_error(this, Label::kDeferred);
  GotoIf(WordEqual(value, the_hole_value), &throw_error);
  Dispatch();

  BIND(&throw_error);
  {
    Node* name = LoadConstantPoolEntry(BytecodeOperandIdx(0));
    CallRuntime(Runtime::kThrowReferenceError, GetContext(), name);
    // We shouldn't ever return from a throw.
    Abort(kUnexpectedReturnFromThrow);
  }
}

// ThrowSuperNotCalledIfHole
//
// Throws an exception if the value in the accumulator is TheHole.
IGNITION_HANDLER(ThrowSuperNotCalledIfHole, InterpreterAssembler) {
  Node* value = GetAccumulator();
  Node* the_hole_value = HeapConstant(isolate()->factory()->the_hole_value());

  Label throw_error(this, Label::kDeferred);
  GotoIf(WordEqual(value, the_hole_value), &throw_error);
  Dispatch();

  BIND(&throw_error);
  {
    CallRuntime(Runtime::kThrowSuperNotCalled, GetContext());
    // We shouldn't ever return from a throw.
    Abort(kUnexpectedReturnFromThrow);
  }
}

// ThrowSuperAlreadyCalledIfNotHole
//
// Throws SuperAleradyCalled exception if the value in the accumulator is not
// TheHole.
IGNITION_HANDLER(ThrowSuperAlreadyCalledIfNotHole, InterpreterAssembler) {
  Node* value = GetAccumulator();
  Node* the_hole_value = HeapConstant(isolate()->factory()->the_hole_value());

  Label throw_error(this, Label::kDeferred);
  GotoIf(WordNotEqual(value, the_hole_value), &throw_error);
  Dispatch();

  BIND(&throw_error);
  {
    CallRuntime(Runtime::kThrowSuperAlreadyCalledError, GetContext());
    // We shouldn't ever return from a throw.
    Abort(kUnexpectedReturnFromThrow);
  }
}

// Debugger
//
// Call runtime to handle debugger statement.
IGNITION_HANDLER(Debugger, InterpreterAssembler) {
  Node* context = GetContext();
  CallStub(CodeFactory::HandleDebuggerStatement(isolate()), context);
  Dispatch();
}

// DebugBreak
//
// Call runtime to handle a debug break.
#define DEBUG_BREAK(Name, ...)                                             \
  IGNITION_HANDLER(Name, InterpreterAssembler) {                           \
    Node* context = GetContext();                                          \
    Node* accumulator = GetAccumulator();                                  \
    Node* original_handler =                                               \
        CallRuntime(Runtime::kDebugBreakOnBytecode, context, accumulator); \
    MaybeDropFrames(context);                                              \
    DispatchToBytecodeHandler(original_handler);                           \
  }
DEBUG_BREAK_BYTECODE_LIST(DEBUG_BREAK);
#undef DEBUG_BREAK

// IncBlockCounter <slot>
//
// Increment the execution count for the given slot. Used for block code
// coverage.
IGNITION_HANDLER(IncBlockCounter, InterpreterAssembler) {
  Node* closure = LoadRegister(Register::function_closure());
  Node* coverage_array_slot = BytecodeOperandIdxSmi(0);
  Node* context = GetContext();

  CallRuntime(Runtime::kIncBlockCounter, context, closure, coverage_array_slot);

  Dispatch();
}

class InterpreterForInPrepareAssembler : public InterpreterAssembler {
 public:
  InterpreterForInPrepareAssembler(CodeAssemblerState* state, Bytecode bytecode,
                                   OperandScale operand_scale)
      : InterpreterAssembler(state, bytecode, operand_scale) {}

  void BuildForInPrepareResult(Node* output_register, Node* cache_type,
                               Node* cache_array, Node* cache_length) {
    StoreRegister(cache_type, output_register);
    output_register = NextRegister(output_register);
    StoreRegister(cache_array, output_register);
    output_register = NextRegister(output_register);
    StoreRegister(cache_length, output_register);
  }
};

// ForInPrepare <receiver> <cache_info_triple>
//
// Returns state for for..in loop execution based on the object in the register
// |receiver|. The object must not be null or undefined and must have been
// converted to a receiver already.
// The result is output in registers |cache_info_triple| to
// |cache_info_triple + 2|, with the registers holding cache_type, cache_array,
// and cache_length respectively.
IGNITION_HANDLER(ForInPrepare, InterpreterForInPrepareAssembler) {
  Node* object_register = BytecodeOperandReg(0);
  Node* output_register = BytecodeOperandReg(1);
  Node* receiver = LoadRegister(object_register);
  Node* context = GetContext();

  Node* cache_type;
  Node* cache_array;
  Node* cache_length;
  Label call_runtime(this, Label::kDeferred),
      nothing_to_iterate(this, Label::kDeferred);

  ForInBuiltinsAssembler forin_assembler(state());
  std::tie(cache_type, cache_array, cache_length) =
      forin_assembler.EmitForInPrepare(receiver, context, &call_runtime,
                                       &nothing_to_iterate);

  BuildForInPrepareResult(output_register, cache_type, cache_array,
                          cache_length);
  Dispatch();

  BIND(&call_runtime);
  {
    Node* result_triple =
        CallRuntime(Runtime::kForInPrepare, context, receiver);
    Node* cache_type = Projection(0, result_triple);
    Node* cache_array = Projection(1, result_triple);
    Node* cache_length = Projection(2, result_triple);
    BuildForInPrepareResult(output_register, cache_type, cache_array,
                            cache_length);
    Dispatch();
  }
  BIND(&nothing_to_iterate);
  {
    // Receiver is null or undefined or descriptors are zero length.
    Node* zero = SmiConstant(0);
    BuildForInPrepareResult(output_register, zero, zero, zero);
    Dispatch();
  }
}

// ForInNext <receiver> <index> <cache_info_pair>
//
// Returns the next enumerable property in the the accumulator.
IGNITION_HANDLER(ForInNext, InterpreterAssembler) {
  Node* receiver_reg = BytecodeOperandReg(0);
  Node* receiver = LoadRegister(receiver_reg);
  Node* index_reg = BytecodeOperandReg(1);
  Node* index = LoadRegister(index_reg);
  Node* cache_type_reg = BytecodeOperandReg(2);
  Node* cache_type = LoadRegister(cache_type_reg);
  Node* cache_array_reg = NextRegister(cache_type_reg);
  Node* cache_array = LoadRegister(cache_array_reg);

  // Load the next key from the enumeration array.
  Node* key = LoadFixedArrayElement(cache_array, index, 0,
                                    CodeStubAssembler::SMI_PARAMETERS);

  // Check if we can use the for-in fast path potentially using the enum cache.
  Label if_fast(this), if_slow(this, Label::kDeferred);
  Node* receiver_map = LoadMap(receiver);
  Branch(WordEqual(receiver_map, cache_type), &if_fast, &if_slow);
  BIND(&if_fast);
  {
    // Enum cache in use for {receiver}, the {key} is definitely valid.
    SetAccumulator(key);
    Dispatch();
  }
  BIND(&if_slow);
  {
    // Record the fact that we hit the for-in slow path.
    Node* vector_index = BytecodeOperandIdx(3);
    Node* feedback_vector = LoadFeedbackVector();
    Node* megamorphic_sentinel =
        HeapConstant(FeedbackVector::MegamorphicSentinel(isolate()));
    StoreFixedArrayElement(feedback_vector, vector_index, megamorphic_sentinel,
                           SKIP_WRITE_BARRIER);

    // Need to filter the {key} for the {receiver}.
    Node* context = GetContext();
    Node* result = CallBuiltin(Builtins::kForInFilter, context, key, receiver);
    SetAccumulator(result);
    Dispatch();
  }
}

// ForInContinue <index> <cache_length>
//
// Returns false if the end of the enumerable properties has been reached.
IGNITION_HANDLER(ForInContinue, InterpreterAssembler) {
  Node* index_reg = BytecodeOperandReg(0);
  Node* index = LoadRegister(index_reg);
  Node* cache_length_reg = BytecodeOperandReg(1);
  Node* cache_length = LoadRegister(cache_length_reg);

  // Check if {index} is at {cache_length} already.
  Label if_true(this), if_false(this), end(this);
  Branch(WordEqual(index, cache_length), &if_true, &if_false);
  BIND(&if_true);
  {
    SetAccumulator(BooleanConstant(false));
    Goto(&end);
  }
  BIND(&if_false);
  {
    SetAccumulator(BooleanConstant(true));
    Goto(&end);
  }
  BIND(&end);
  Dispatch();
}

// ForInStep <index>
//
// Increments the loop counter in register |index| and stores the result
// in the accumulator.
IGNITION_HANDLER(ForInStep, InterpreterAssembler) {
  Node* index_reg = BytecodeOperandReg(0);
  Node* index = LoadRegister(index_reg);
  Node* one = SmiConstant(1);
  Node* result = SmiAdd(index, one);
  SetAccumulator(result);
  Dispatch();
}

// Wide
//
// Prefix bytecode indicating next bytecode has wide (16-bit) operands.
IGNITION_HANDLER(Wide, InterpreterAssembler) {
  DispatchWide(OperandScale::kDouble);
}

// ExtraWide
//
// Prefix bytecode indicating next bytecode has extra-wide (32-bit) operands.
IGNITION_HANDLER(ExtraWide, InterpreterAssembler) {
  DispatchWide(OperandScale::kQuadruple);
}

// Illegal
//
// An invalid bytecode aborting execution if dispatched.
IGNITION_HANDLER(Illegal, InterpreterAssembler) { Abort(kInvalidBytecode); }

// Nop
//
// No operation.
IGNITION_HANDLER(Nop, InterpreterAssembler) { Dispatch(); }

// SuspendGenerator <generator> <first input register> <register count>
//
// Exports the register file and stores it into the generator.  Also stores the
// current context, the state given in the accumulator, and the current bytecode
// offset (for debugging purposes) into the generator.
IGNITION_HANDLER(SuspendGenerator, InterpreterAssembler) {
  Node* generator_reg = BytecodeOperandReg(0);

  Node* generator = LoadRegister(generator_reg);

  Label if_stepping(this, Label::kDeferred), ok(this);
  Node* step_action_address = ExternalConstant(
      ExternalReference::debug_last_step_action_address(isolate()));
  Node* step_action = Load(MachineType::Int8(), step_action_address);
  STATIC_ASSERT(StepIn > StepNext);
  STATIC_ASSERT(LastStepAction == StepIn);
  Node* step_next = Int32Constant(StepNext);
  Branch(Int32LessThanOrEqual(step_next, step_action), &if_stepping, &ok);
  BIND(&ok);

  Node* array =
      LoadObjectField(generator, JSGeneratorObject::kRegisterFileOffset);
  Node* context = GetContext();
  Node* state = GetAccumulator();

  // Bytecode operand 1 should be always 0 (we are always store registers
  // from the beginning).
  CSA_ASSERT(this, WordEqual(BytecodeOperandReg(1),
                             IntPtrConstant(Register(0).ToOperand())));
  // Bytecode operand 2 is the number of registers to store to the generator.
  Node* register_count = ChangeUint32ToWord(BytecodeOperandCount(2));
  ExportRegisterFile(array, register_count);
  StoreObjectField(generator, JSGeneratorObject::kContextOffset, context);
  StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, state);

  // Store the bytecode offset in the [input_or_debug_pos] field, to be used by
  // the inspector.
  Node* offset = SmiTag(BytecodeOffset());
  StoreObjectField(generator, JSGeneratorObject::kInputOrDebugPosOffset,
                   offset);
  Dispatch();

  BIND(&if_stepping);
  {
    Node* context = GetContext();
    CallRuntime(Runtime::kDebugRecordGenerator, context, generator);
    Goto(&ok);
  }
}

// RestoreGeneratorState <generator>
//
// Loads the generator's state and stores it in the accumulator,
// before overwriting it with kGeneratorExecuting.
IGNITION_HANDLER(RestoreGeneratorState, InterpreterAssembler) {
  Node* generator_reg = BytecodeOperandReg(0);
  Node* generator = LoadRegister(generator_reg);

  Node* old_state =
      LoadObjectField(generator, JSGeneratorObject::kContinuationOffset);
  Node* new_state = Int32Constant(JSGeneratorObject::kGeneratorExecuting);
  StoreObjectField(generator, JSGeneratorObject::kContinuationOffset,
                   SmiTag(new_state));
  SetAccumulator(old_state);

  Dispatch();
}

// RestoreGeneratorRegisters <generator> <first output register> <register
// count>
//
// Imports the register file stored in the generator.
IGNITION_HANDLER(RestoreGeneratorRegisters, InterpreterAssembler) {
  Node* generator_reg = BytecodeOperandReg(0);
  // Bytecode operand 1 is the start register. It should always be 0, so let's
  // ignore it.
  CSA_ASSERT(this, WordEqual(BytecodeOperandReg(1),
                             IntPtrConstant(Register(0).ToOperand())));
  // Bytecode operand 2 is the number of registers to store to the generator.
  Node* register_count = ChangeUint32ToWord(BytecodeOperandCount(2));

  Node* generator = LoadRegister(generator_reg);

  ImportRegisterFile(
      LoadObjectField(generator, JSGeneratorObject::kRegisterFileOffset),
      register_count);

  Dispatch();
}

}  // namespace

Handle<Code> GenerateBytecodeHandler(Isolate* isolate, Bytecode bytecode,
                                     OperandScale operand_scale) {
  Zone zone(isolate->allocator(), ZONE_NAME);
  InterpreterDispatchDescriptor descriptor(isolate);
  compiler::CodeAssemblerState state(
      isolate, &zone, descriptor, Code::ComputeFlags(Code::BYTECODE_HANDLER),
      Bytecodes::ToString(bytecode), Bytecodes::ReturnCount(bytecode));

  switch (bytecode) {
#define CALL_GENERATOR(Name, ...)                     \
  case Bytecode::k##Name:                             \
    Name##Assembler::Generate(&state, operand_scale); \
    break;
    BYTECODE_LIST(CALL_GENERATOR);
#undef CALL_GENERATOR
  }

  Handle<Code> code = compiler::CodeAssembler::GenerateCode(&state);
  PROFILE(isolate, CodeCreateEvent(
                       CodeEventListener::BYTECODE_HANDLER_TAG,
                       AbstractCode::cast(*code),
                       Bytecodes::ToString(bytecode, operand_scale).c_str()));
#ifdef ENABLE_DISASSEMBLER
  if (FLAG_trace_ignition_codegen) {
    OFStream os(stdout);
    code->Disassemble(Bytecodes::ToString(bytecode), os);
    os << std::flush;
  }
#endif  // ENABLE_DISASSEMBLER
  return code;
}

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