// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include <setjmp.h>  // NOLINT
#include <stdlib.h>

#include "vm/globals.h"
#if !defined(DART_PRECOMPILED_RUNTIME)

#include "vm/interpreter.h"

#include "vm/compiler/assembler/assembler.h"
#include "vm/compiler/assembler/disassembler_kbc.h"
#include "vm/compiler/jit/compiler.h"
#include "vm/cpu.h"
#include "vm/dart_entry.h"
#include "vm/debugger.h"
#include "vm/lockers.h"
#include "vm/native_arguments.h"
#include "vm/native_entry.h"
#include "vm/object.h"
#include "vm/object_store.h"
#include "vm/os_thread.h"
#include "vm/stack_frame_kbc.h"
#include "vm/symbols.h"

namespace dart {

DEFINE_FLAG(uint64_t,
            trace_interpreter_after,
            ULLONG_MAX,
            "Trace interpreter execution after instruction count reached.");
DEFINE_FLAG(charp,
            interpreter_trace_file,
            NULL,
            "File to write a dynamic instruction trace to.");
DEFINE_FLAG(uint64_t,
            interpreter_trace_file_max_bytes,
            100 * MB,
            "Maximum size in bytes of the interpreter trace file");

// InterpreterSetjmpBuffer are linked together, and the last created one
// is referenced by the Interpreter. When an exception is thrown, the exception
// runtime looks at where to jump and finds the corresponding
// InterpreterSetjmpBuffer based on the stack pointer of the exception handler.
// The runtime then does a Longjmp on that buffer to return to the interpreter.
class InterpreterSetjmpBuffer {
 public:
  void Longjmp() {
    // "This" is now the last setjmp buffer.
    interpreter_->set_last_setjmp_buffer(this);
    longjmp(buffer_, 1);
  }

  explicit InterpreterSetjmpBuffer(Interpreter* interpreter) {
    interpreter_ = interpreter;
    link_ = interpreter->last_setjmp_buffer();
    interpreter->set_last_setjmp_buffer(this);
    fp_ = interpreter->fp_;
  }

  ~InterpreterSetjmpBuffer() {
    ASSERT(interpreter_->last_setjmp_buffer() == this);
    interpreter_->set_last_setjmp_buffer(link_);
  }

  InterpreterSetjmpBuffer* link() const { return link_; }

  uword fp() const { return reinterpret_cast<uword>(fp_); }

  jmp_buf buffer_;

 private:
  RawObject** fp_;
  Interpreter* interpreter_;
  InterpreterSetjmpBuffer* link_;

  friend class Interpreter;

  DISALLOW_ALLOCATION();
  DISALLOW_COPY_AND_ASSIGN(InterpreterSetjmpBuffer);
};

DART_FORCE_INLINE static RawObject** SavedCallerFP(RawObject** FP) {
  return reinterpret_cast<RawObject**>(FP[kKBCSavedCallerFpSlotFromFp]);
}

DART_FORCE_INLINE static RawObject** FrameArguments(RawObject** FP,
                                                    intptr_t argc) {
  return FP - (kKBCDartFrameFixedSize + argc);
}

#define RAW_CAST(Type, val) (InterpreterHelpers::CastTo##Type(val))

class InterpreterHelpers {
 public:
#define DEFINE_CASTS(Type)                                                     \
  DART_FORCE_INLINE static Raw##Type* CastTo##Type(RawObject* obj) {           \
    ASSERT((k##Type##Cid == kSmiCid)                                           \
               ? !obj->IsHeapObject()                                          \
               : (k##Type##Cid == kIntegerCid)                                 \
                     ? (!obj->IsHeapObject() || obj->IsMint())                 \
                     : obj->Is##Type());                                       \
    return reinterpret_cast<Raw##Type*>(obj);                                  \
  }
  CLASS_LIST(DEFINE_CASTS)
#undef DEFINE_CASTS

  DART_FORCE_INLINE static RawSmi* GetClassIdAsSmi(RawObject* obj) {
    return Smi::New(obj->IsHeapObject() ? obj->GetClassId()
                                        : static_cast<intptr_t>(kSmiCid));
  }

  DART_FORCE_INLINE static intptr_t GetClassId(RawObject* obj) {
    return obj->IsHeapObject() ? obj->GetClassId()
                               : static_cast<intptr_t>(kSmiCid);
  }

  // The usage counter is actually a 'hotness' counter.
  // For an instance call, both the usage counters of the caller and of the
  // calle will get incremented, as well as the ICdata counter at the call site.
  DART_FORCE_INLINE static void IncrementUsageCounter(RawFunction* f) {
    f->ptr()->usage_counter_++;
  }

  DART_FORCE_INLINE static void IncrementICUsageCount(RawObject** entries,
                                                      intptr_t offset,
                                                      intptr_t args_tested) {
    const intptr_t count_offset = ICData::CountIndexFor(args_tested);
    const intptr_t raw_smi_old =
        reinterpret_cast<intptr_t>(entries[offset + count_offset]);
    const intptr_t raw_smi_new = raw_smi_old + Smi::RawValue(1);
    *reinterpret_cast<intptr_t*>(&entries[offset + count_offset]) = raw_smi_new;
  }

  DART_FORCE_INLINE static bool IsStrictEqualWithNumberCheck(RawObject* lhs,
                                                             RawObject* rhs) {
    if (lhs == rhs) {
      return true;
    }

    if (lhs->IsHeapObject() && rhs->IsHeapObject()) {
      const intptr_t lhs_cid = lhs->GetClassId();
      const intptr_t rhs_cid = rhs->GetClassId();
      if (lhs_cid == rhs_cid) {
        switch (lhs_cid) {
          case kDoubleCid:
            return (bit_cast<uint64_t, double>(
                        static_cast<RawDouble*>(lhs)->ptr()->value_) ==
                    bit_cast<uint64_t, double>(
                        static_cast<RawDouble*>(rhs)->ptr()->value_));

          case kMintCid:
            return (static_cast<RawMint*>(lhs)->ptr()->value_ ==
                    static_cast<RawMint*>(rhs)->ptr()->value_);
        }
      }
    }

    return false;
  }

  template <typename T>
  DART_FORCE_INLINE static T* Untag(T* tagged) {
    return tagged->ptr();
  }

  DART_FORCE_INLINE static bool CheckIndex(RawSmi* index, RawSmi* length) {
    return !index->IsHeapObject() && (reinterpret_cast<intptr_t>(index) >= 0) &&
           (reinterpret_cast<intptr_t>(index) <
            reinterpret_cast<intptr_t>(length));
  }

  DART_FORCE_INLINE static intptr_t ArgDescTypeArgsLen(RawArray* argdesc) {
    return Smi::Value(*reinterpret_cast<RawSmi**>(
        reinterpret_cast<uword>(argdesc->ptr()) +
        Array::element_offset(ArgumentsDescriptor::kTypeArgsLenIndex)));
  }

  DART_FORCE_INLINE static intptr_t ArgDescArgCount(RawArray* argdesc) {
    return Smi::Value(*reinterpret_cast<RawSmi**>(
        reinterpret_cast<uword>(argdesc->ptr()) +
        Array::element_offset(ArgumentsDescriptor::kCountIndex)));
  }

  DART_FORCE_INLINE static intptr_t ArgDescPosCount(RawArray* argdesc) {
    return Smi::Value(*reinterpret_cast<RawSmi**>(
        reinterpret_cast<uword>(argdesc->ptr()) +
        Array::element_offset(ArgumentsDescriptor::kPositionalCountIndex)));
  }

  static bool ObjectArraySetIndexed(Thread* thread,
                                    RawObject** FP,
                                    RawObject** result) {
    return ObjectArraySetIndexedUnchecked(thread, FP, result);
  }

  static bool ObjectArraySetIndexedUnchecked(Thread* thread,
                                             RawObject** FP,
                                             RawObject** result) {
    RawObject** args = FrameArguments(FP, 3);
    RawSmi* index = static_cast<RawSmi*>(args[1]);
    RawArray* array = static_cast<RawArray*>(args[0]);
    if (CheckIndex(index, array->ptr()->length_)) {
      array->StorePointer(array->ptr()->data() + Smi::Value(index), args[2],
                          thread);
      return true;
    }
    return false;
  }

  static bool ObjectArrayGetIndexed(Thread* thread,
                                    RawObject** FP,
                                    RawObject** result) {
    RawObject** args = FrameArguments(FP, 2);
    RawSmi* index = static_cast<RawSmi*>(args[1]);
    RawArray* array = static_cast<RawArray*>(args[0]);
    if (CheckIndex(index, array->ptr()->length_)) {
      *result = array->ptr()->data()[Smi::Value(index)];
      return true;
    }
    return false;
  }

  static bool GrowableArraySetIndexed(Thread* thread,
                                      RawObject** FP,
                                      RawObject** result) {
    return GrowableArraySetIndexedUnchecked(thread, FP, result);
  }

  static bool GrowableArraySetIndexedUnchecked(Thread* thread,
                                               RawObject** FP,
                                               RawObject** result) {
    RawObject** args = FrameArguments(FP, 3);
    RawSmi* index = static_cast<RawSmi*>(args[1]);
    RawGrowableObjectArray* array =
        static_cast<RawGrowableObjectArray*>(args[0]);
    if (CheckIndex(index, array->ptr()->length_)) {
      RawArray* data = array->ptr()->data_;
      data->StorePointer(data->ptr()->data() + Smi::Value(index), args[2],
                         thread);
      return true;
    }
    return false;
  }

  static bool GrowableArrayGetIndexed(Thread* thread,
                                      RawObject** FP,
                                      RawObject** result) {
    RawObject** args = FrameArguments(FP, 2);
    RawSmi* index = static_cast<RawSmi*>(args[1]);
    RawGrowableObjectArray* array =
        static_cast<RawGrowableObjectArray*>(args[0]);
    if (CheckIndex(index, array->ptr()->length_)) {
      *result = array->ptr()->data_->ptr()->data()[Smi::Value(index)];
      return true;
    }
    return false;
  }

  static bool Double_getIsNan(Thread* thread,
                              RawObject** FP,
                              RawObject** result) {
    RawObject** args = FrameArguments(FP, 1);
    RawDouble* d = static_cast<RawDouble*>(args[0]);
    *result =
        isnan(d->ptr()->value_) ? Bool::True().raw() : Bool::False().raw();
    return true;
  }

  static bool Double_getIsInfinite(Thread* thread,
                                   RawObject** FP,
                                   RawObject** result) {
    RawObject** args = FrameArguments(FP, 1);
    RawDouble* d = static_cast<RawDouble*>(args[0]);
    *result =
        isinf(d->ptr()->value_) ? Bool::True().raw() : Bool::False().raw();
    return true;
  }

  static bool ObjectEquals(Thread* thread, RawObject** FP, RawObject** result) {
    RawObject** args = FrameArguments(FP, 2);
    *result = args[0] == args[1] ? Bool::True().raw() : Bool::False().raw();
    return true;
  }

  static bool ObjectRuntimeType(Thread* thread,
                                RawObject** FP,
                                RawObject** result) {
    RawObject** args = FrameArguments(FP, 1);
    const intptr_t cid = GetClassId(args[0]);
    if (cid == kClosureCid) {
      return false;
    }
    if (cid < kNumPredefinedCids) {
      if (cid == kDoubleCid) {
        *result = thread->isolate()->object_store()->double_type();
        return true;
      } else if (RawObject::IsStringClassId(cid)) {
        *result = thread->isolate()->object_store()->string_type();
        return true;
      } else if (RawObject::IsIntegerClassId(cid)) {
        *result = thread->isolate()->object_store()->int_type();
        return true;
      }
    }
    RawClass* cls = thread->isolate()->class_table()->At(cid);
    if (cls->ptr()->num_type_arguments_ != 0) {
      return false;
    }
    RawType* typ = cls->ptr()->canonical_type_;
    if (typ == Object::null()) {
      return false;
    }
    *result = static_cast<RawObject*>(typ);
    return true;
  }

  static bool GetDoubleOperands(RawObject** args, double* d1, double* d2) {
    RawObject* obj2 = args[1];
    if (!obj2->IsHeapObject()) {
      *d2 =
          static_cast<double>(reinterpret_cast<intptr_t>(obj2) >> kSmiTagSize);
    } else if (obj2->GetClassId() == kDoubleCid) {
      RawDouble* obj2d = static_cast<RawDouble*>(obj2);
      *d2 = obj2d->ptr()->value_;
    } else {
      return false;
    }
    RawDouble* obj1 = static_cast<RawDouble*>(args[0]);
    *d1 = obj1->ptr()->value_;
    return true;
  }

  static RawObject* AllocateDouble(Thread* thread, double value) {
    const intptr_t instance_size = Double::InstanceSize();
    const uword start =
        thread->heap()->new_space()->TryAllocateInTLAB(thread, instance_size);
    if (LIKELY(start != 0)) {
      uword tags = 0;
      tags = RawObject::ClassIdTag::update(kDoubleCid, tags);
      tags = RawObject::SizeTag::update(instance_size, tags);
      tags = RawObject::NewBit::update(true, tags);
      // Also writes zero in the hash_ field.
      *reinterpret_cast<uword*>(start + Double::tags_offset()) = tags;
      *reinterpret_cast<double*>(start + Double::value_offset()) = value;
      return reinterpret_cast<RawObject*>(start + kHeapObjectTag);
    }
    return NULL;
  }

  static bool Double_add(Thread* thread, RawObject** FP, RawObject** result) {
    double d1, d2;
    if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) {
      return false;
    }
    RawObject* new_double = AllocateDouble(thread, d1 + d2);
    if (new_double != NULL) {
      *result = new_double;
      return true;
    }
    return false;
  }

  static bool Double_mul(Thread* thread, RawObject** FP, RawObject** result) {
    double d1, d2;
    if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) {
      return false;
    }
    RawObject* new_double = AllocateDouble(thread, d1 * d2);
    if (new_double != NULL) {
      *result = new_double;
      return true;
    }
    return false;
  }

  static bool Double_sub(Thread* thread, RawObject** FP, RawObject** result) {
    double d1, d2;
    if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) {
      return false;
    }
    RawObject* new_double = AllocateDouble(thread, d1 - d2);
    if (new_double != NULL) {
      *result = new_double;
      return true;
    }
    return false;
  }

  static bool Double_div(Thread* thread, RawObject** FP, RawObject** result) {
    double d1, d2;
    if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) {
      return false;
    }
    RawObject* new_double = AllocateDouble(thread, d1 / d2);
    if (new_double != NULL) {
      *result = new_double;
      return true;
    }
    return false;
  }

  static bool Double_greaterThan(Thread* thread,
                                 RawObject** FP,
                                 RawObject** result) {
    double d1, d2;
    if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) {
      return false;
    }
    *result = d1 > d2 ? Bool::True().raw() : Bool::False().raw();
    return true;
  }

  static bool Double_greaterEqualThan(Thread* thread,
                                      RawObject** FP,
                                      RawObject** result) {
    double d1, d2;
    if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) {
      return false;
    }
    *result = d1 >= d2 ? Bool::True().raw() : Bool::False().raw();
    return true;
  }

  static bool Double_lessThan(Thread* thread,
                              RawObject** FP,
                              RawObject** result) {
    double d1, d2;
    if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) {
      return false;
    }
    *result = d1 < d2 ? Bool::True().raw() : Bool::False().raw();
    return true;
  }

  static bool Double_equal(Thread* thread, RawObject** FP, RawObject** result) {
    double d1, d2;
    if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) {
      return false;
    }
    *result = d1 == d2 ? Bool::True().raw() : Bool::False().raw();
    return true;
  }

  static bool Double_lessEqualThan(Thread* thread,
                                   RawObject** FP,
                                   RawObject** result) {
    double d1, d2;
    if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) {
      return false;
    }
    *result = d1 <= d2 ? Bool::True().raw() : Bool::False().raw();
    return true;
  }

  static bool ClearAsyncThreadStack(Thread* thread,
                                    RawObject** FP,
                                    RawObject** result) {
    thread->clear_async_stack_trace();
    *result = Object::null();
    return true;
  }

  static bool SetAsyncThreadStackTrace(Thread* thread,
                                       RawObject** FP,
                                       RawObject** result) {
    RawObject** args = FrameArguments(FP, 1);
    thread->set_raw_async_stack_trace(
        reinterpret_cast<RawStackTrace*>(args[0]));
    *result = Object::null();
    return true;
  }

  DART_FORCE_INLINE static RawBytecode* FrameBytecode(RawObject** FP) {
    ASSERT(GetClassId(FP[kKBCPcMarkerSlotFromFp]) == kBytecodeCid);
    return static_cast<RawBytecode*>(FP[kKBCPcMarkerSlotFromFp]);
  }

  DART_FORCE_INLINE static uint8_t* GetTypedData(RawObject* obj,
                                                 RawObject* index) {
    ASSERT(RawObject::IsTypedDataClassId(obj->GetClassId()));
    RawTypedData* array = reinterpret_cast<RawTypedData*>(obj);
    const intptr_t byte_offset = Smi::Value(RAW_CAST(Smi, index));
    ASSERT(byte_offset >= 0);
    return array->ptr()->data() + byte_offset;
  }
};

DART_FORCE_INLINE static uint32_t* SavedCallerPC(RawObject** FP) {
  return reinterpret_cast<uint32_t*>(FP[kKBCSavedCallerPcSlotFromFp]);
}

DART_FORCE_INLINE static RawFunction* FrameFunction(RawObject** FP) {
  RawFunction* function = static_cast<RawFunction*>(FP[kKBCFunctionSlotFromFp]);
  ASSERT(InterpreterHelpers::GetClassId(function) == kFunctionCid ||
         InterpreterHelpers::GetClassId(function) == kNullCid);
  return function;
}

IntrinsicHandler Interpreter::intrinsics_[Interpreter::kIntrinsicCount];

// Synchronization primitives support.
void Interpreter::InitOnce() {
  for (intptr_t i = 0; i < kIntrinsicCount; i++) {
    intrinsics_[i] = 0;
  }

  intrinsics_[kObjectArraySetIndexedIntrinsic] =
      InterpreterHelpers::ObjectArraySetIndexed;
  intrinsics_[kObjectArraySetIndexedUncheckedIntrinsic] =
      InterpreterHelpers::ObjectArraySetIndexedUnchecked;
  intrinsics_[kObjectArrayGetIndexedIntrinsic] =
      InterpreterHelpers::ObjectArrayGetIndexed;
  intrinsics_[kGrowableArraySetIndexedIntrinsic] =
      InterpreterHelpers::GrowableArraySetIndexed;
  intrinsics_[kGrowableArraySetIndexedUncheckedIntrinsic] =
      InterpreterHelpers::GrowableArraySetIndexedUnchecked;
  intrinsics_[kGrowableArrayGetIndexedIntrinsic] =
      InterpreterHelpers::GrowableArrayGetIndexed;
  intrinsics_[kObjectEqualsIntrinsic] = InterpreterHelpers::ObjectEquals;
  intrinsics_[kObjectRuntimeTypeIntrinsic] =
      InterpreterHelpers::ObjectRuntimeType;

  intrinsics_[kDouble_getIsNaNIntrinsic] = InterpreterHelpers::Double_getIsNan;
  intrinsics_[kDouble_getIsInfiniteIntrinsic] =
      InterpreterHelpers::Double_getIsInfinite;
  intrinsics_[kDouble_addIntrinsic] = InterpreterHelpers::Double_add;
  intrinsics_[kDouble_mulIntrinsic] = InterpreterHelpers::Double_mul;
  intrinsics_[kDouble_subIntrinsic] = InterpreterHelpers::Double_sub;
  intrinsics_[kDouble_divIntrinsic] = InterpreterHelpers::Double_div;
  intrinsics_[kDouble_greaterThanIntrinsic] =
      InterpreterHelpers::Double_greaterThan;
  intrinsics_[kDouble_greaterEqualThanIntrinsic] =
      InterpreterHelpers::Double_greaterEqualThan;
  intrinsics_[kDouble_lessThanIntrinsic] = InterpreterHelpers::Double_lessThan;
  intrinsics_[kDouble_equalIntrinsic] = InterpreterHelpers::Double_equal;
  intrinsics_[kDouble_lessEqualThanIntrinsic] =
      InterpreterHelpers::Double_lessEqualThan;
  intrinsics_[kClearAsyncThreadStackTraceIntrinsic] =
      InterpreterHelpers::ClearAsyncThreadStack;
  intrinsics_[kSetAsyncThreadStackTraceIntrinsic] =
      InterpreterHelpers::SetAsyncThreadStackTrace;
}

Interpreter::Interpreter()
    : stack_(NULL), fp_(NULL), pp_(NULL), argdesc_(NULL) {
  // Setup interpreter support first. Some of this information is needed to
  // setup the architecture state.
  // We allocate the stack here, the size is computed as the sum of
  // the size specified by the user and the buffer space needed for
  // handling stack overflow exceptions. To be safe in potential
  // stack underflows we also add some underflow buffer space.
  stack_ = new uintptr_t[(OSThread::GetSpecifiedStackSize() +
                          OSThread::kStackSizeBuffer +
                          kInterpreterStackUnderflowSize) /
                         sizeof(uintptr_t)];
  // Low address.
  stack_base_ =
      reinterpret_cast<uword>(stack_) + kInterpreterStackUnderflowSize;
  // Limit for StackOverflowError.
  overflow_stack_limit_ = stack_base_ + OSThread::GetSpecifiedStackSize();
  // High address.
  stack_limit_ = overflow_stack_limit_ + OSThread::kStackSizeBuffer;

  last_setjmp_buffer_ = NULL;

  DEBUG_ONLY(icount_ = 1);  // So that tracing after 0 traces first bytecode.

#if defined(DEBUG)
  trace_file_bytes_written_ = 0;
  trace_file_ = NULL;
  if (FLAG_interpreter_trace_file != NULL) {
    Dart_FileOpenCallback file_open = Dart::file_open_callback();
    if (file_open != NULL) {
      trace_file_ = file_open(FLAG_interpreter_trace_file, /* write */ true);
      trace_buffer_ = new KBCInstr[kTraceBufferInstrs];
      trace_buffer_idx_ = 0;
    }
  }
#endif
}

Interpreter::~Interpreter() {
  delete[] stack_;
#if defined(DEBUG)
  if (trace_file_ != NULL) {
    FlushTraceBuffer();
    // Close the file.
    Dart_FileCloseCallback file_close = Dart::file_close_callback();
    if (file_close != NULL) {
      file_close(trace_file_);
      trace_file_ = NULL;
      delete[] trace_buffer_;
      trace_buffer_ = NULL;
    }
  }
#endif
}

// Get the active Interpreter for the current isolate.
Interpreter* Interpreter::Current() {
  Interpreter* interpreter = Thread::Current()->interpreter();
  if (interpreter == NULL) {
    interpreter = new Interpreter();
    Thread::Current()->set_interpreter(interpreter);
  }
  return interpreter;
}

#if defined(DEBUG)
// Returns true if tracing of executed instructions is enabled.
// May be called on entry, when icount_ has not been incremented yet.
DART_FORCE_INLINE bool Interpreter::IsTracingExecution() const {
  return icount_ > FLAG_trace_interpreter_after;
}

// Prints bytecode instruction at given pc for instruction tracing.
DART_NOINLINE void Interpreter::TraceInstruction(uint32_t* pc) const {
  THR_Print("%" Pu64 " ", icount_);
  if (FLAG_support_disassembler) {
    KernelBytecodeDisassembler::Disassemble(reinterpret_cast<uword>(pc),
                                            reinterpret_cast<uword>(pc + 1));
  } else {
    THR_Print("Disassembler not supported in this mode.\n");
  }
}

DART_FORCE_INLINE bool Interpreter::IsWritingTraceFile() const {
  return (trace_file_ != NULL) &&
         (trace_file_bytes_written_ < FLAG_interpreter_trace_file_max_bytes);
}

void Interpreter::FlushTraceBuffer() {
  Dart_FileWriteCallback file_write = Dart::file_write_callback();
  if (file_write == NULL) {
    return;
  }
  if (trace_file_bytes_written_ >= FLAG_interpreter_trace_file_max_bytes) {
    return;
  }
  const intptr_t bytes_to_write = Utils::Minimum(
      static_cast<uint64_t>(trace_buffer_idx_ * sizeof(KBCInstr)),
      FLAG_interpreter_trace_file_max_bytes - trace_file_bytes_written_);
  if (bytes_to_write == 0) {
    return;
  }
  file_write(trace_buffer_, bytes_to_write, trace_file_);
  trace_file_bytes_written_ += bytes_to_write;
  trace_buffer_idx_ = 0;
}

DART_NOINLINE void Interpreter::WriteInstructionToTrace(uint32_t* pc) {
  Dart_FileWriteCallback file_write = Dart::file_write_callback();
  if (file_write == NULL) {
    return;
  }
  if (trace_buffer_idx_ < kTraceBufferInstrs) {
    trace_buffer_[trace_buffer_idx_++] = static_cast<KBCInstr>(*pc);
  }
  if (trace_buffer_idx_ == kTraceBufferInstrs) {
    FlushTraceBuffer();
  }
}

#endif  // defined(DEBUG)

// Calls into the Dart runtime are based on this interface.
typedef void (*InterpreterRuntimeCall)(NativeArguments arguments);

// Calls to leaf Dart runtime functions are based on this interface.
typedef intptr_t (*InterpreterLeafRuntimeCall)(intptr_t r0,
                                               intptr_t r1,
                                               intptr_t r2,
                                               intptr_t r3);

// Calls to leaf float Dart runtime functions are based on this interface.
typedef double (*InterpreterLeafFloatRuntimeCall)(double d0, double d1);

void Interpreter::Exit(Thread* thread,
                       RawObject** base,
                       RawObject** frame,
                       uint32_t* pc) {
  frame[0] = Function::null();
  frame[1] = Bytecode::null();
  frame[2] = reinterpret_cast<RawObject*>(pc);
  frame[3] = reinterpret_cast<RawObject*>(base);
  fp_ = frame + kKBCDartFrameFixedSize;
  thread->set_top_exit_frame_info(reinterpret_cast<uword>(fp_));
#if defined(DEBUG)
  if (IsTracingExecution()) {
    THR_Print("%" Pu64 " ", icount_);
    THR_Print("Exiting interpreter 0x%" Px " at fp_ 0x%" Px "\n",
              reinterpret_cast<uword>(this), reinterpret_cast<uword>(fp_));
  }
#endif
}

void Interpreter::CallRuntime(Thread* thread,
                              RawObject** base,
                              RawObject** exit_frame,
                              uint32_t* pc,
                              intptr_t argc_tag,
                              RawObject** args,
                              RawObject** result,
                              uword target) {
  Exit(thread, base, exit_frame, pc);
  NativeArguments native_args(thread, argc_tag, args, result);
  reinterpret_cast<RuntimeFunction>(target)(native_args);
}

// Calling into runtime may trigger garbage collection and relocate objects,
// so all RawObject* pointers become outdated and should not be used across
// runtime calls.
// Note: functions below are marked DART_NOINLINE to recover performance on
// ARM where inlining these functions into the interpreter loop seemed to cause
// some code quality issues.
static DART_NOINLINE bool InvokeRuntime(Thread* thread,
                                        Interpreter* interpreter,
                                        RuntimeFunction drt,
                                        const NativeArguments& args) {
  InterpreterSetjmpBuffer buffer(interpreter);
  if (!setjmp(buffer.buffer_)) {
    thread->set_vm_tag(reinterpret_cast<uword>(drt));
    drt(args);
    thread->set_vm_tag(VMTag::kDartInterpretedTagId);
    thread->set_top_exit_frame_info(0);
    return true;
  } else {
    return false;
  }
}

static DART_NOINLINE bool InvokeNative(Thread* thread,
                                       Interpreter* interpreter,
                                       NativeFunctionWrapper wrapper,
                                       Dart_NativeFunction function,
                                       Dart_NativeArguments args) {
  InterpreterSetjmpBuffer buffer(interpreter);
  if (!setjmp(buffer.buffer_)) {
    thread->set_vm_tag(reinterpret_cast<uword>(function));
    wrapper(args, function);
    thread->set_vm_tag(VMTag::kDartInterpretedTagId);
    thread->set_top_exit_frame_info(0);
    return true;
  } else {
    return false;
  }
}

DART_NOINLINE bool Interpreter::InvokeCompiled(Thread* thread,
                                               RawFunction* function,
                                               RawObject** call_base,
                                               RawObject** call_top,
                                               uint32_t** pc,
                                               RawObject*** FP,
                                               RawObject*** SP) {
#if defined(USING_SIMULATOR) || defined(TARGET_ARCH_DBC)
  // TODO(regis): Revisit.
  UNIMPLEMENTED();
#endif
  ASSERT(Function::HasCode(function));
  RawCode* volatile code = function->ptr()->code_;
  ASSERT(code != StubCode::LazyCompile().raw());
  // TODO(regis): Once we share the same stack, try to invoke directly.
#if defined(DEBUG)
  if (IsTracingExecution()) {
    THR_Print("%" Pu64 " ", icount_);
    THR_Print("invoking compiled %s\n", Function::Handle(function).ToCString());
  }
#endif
  // On success, returns a RawInstance.  On failure, a RawError.
  typedef RawObject* (*invokestub)(RawCode * code, RawArray * argdesc,
                                   RawObject * *arg0, Thread * thread);
  invokestub volatile entrypoint = reinterpret_cast<invokestub>(
      StubCode::InvokeDartCodeFromBytecode().EntryPoint());
  RawObject* volatile result;
  Exit(thread, *FP, call_top + 1, *pc);
  {
    InterpreterSetjmpBuffer buffer(this);
    if (!setjmp(buffer.buffer_)) {
      result = entrypoint(code, argdesc_, call_base, thread);
      thread->set_top_exit_frame_info(0);
      ASSERT(thread->vm_tag() == VMTag::kDartInterpretedTagId);
      ASSERT(thread->execution_state() == Thread::kThreadInGenerated);
    } else {
      return false;
    }
  }
  // Pop args and push result.
  *SP = call_base;
  **SP = result;
  pp_ = InterpreterHelpers::FrameBytecode(*FP)->ptr()->object_pool_;

  // If the result is an error (not a Dart instance), it must either be rethrown
  // (in the case of an unhandled exception) or it must be returned to the
  // caller of the interpreter to be propagated.
  if (result->IsHeapObject()) {
    const intptr_t result_cid = result->GetClassId();
    if (result_cid == kUnhandledExceptionCid) {
      (*SP)[0] = UnhandledException::RawCast(result)->ptr()->exception_;
      (*SP)[1] = UnhandledException::RawCast(result)->ptr()->stacktrace_;
      (*SP)[2] = 0;  // Space for result.
      Exit(thread, *FP, *SP + 3, *pc);
      NativeArguments args(thread, 2, *SP, *SP + 2);
      if (!InvokeRuntime(thread, this, DRT_ReThrow, args)) {
        return false;
      }
      UNREACHABLE();
    }
    if (RawObject::IsErrorClassId(result_cid)) {
      // Unwind to entry frame.
      fp_ = *FP;
      pc_ = reinterpret_cast<uword>(SavedCallerPC(fp_));
      while (!IsEntryFrameMarker(pc_)) {
        fp_ = SavedCallerFP(fp_);
        pc_ = reinterpret_cast<uword>(SavedCallerPC(fp_));
      }
      // Pop entry frame.
      fp_ = SavedCallerFP(fp_);
      special_[KernelBytecode::kExceptionSpecialIndex] = result;
      return false;
    }
  }
  return true;
}

DART_NOINLINE bool Interpreter::ProcessInvocation(bool* invoked,
                                                  Thread* thread,
                                                  RawFunction* function,
                                                  RawObject** call_base,
                                                  RawObject** call_top,
                                                  uint32_t** pc,
                                                  RawObject*** FP,
                                                  RawObject*** SP) {
  ASSERT(!Function::HasCode(function) && !Function::HasBytecode(function));
  ASSERT(function == call_top[0]);
  // If the function is an implicit getter or setter, process its invocation
  // here without code or bytecode.
  RawFunction::Kind kind = Function::kind(function);
  switch (kind) {
    case RawFunction::kImplicitGetter: {
      // Field object is cached in function's data_.
      RawInstance* instance = reinterpret_cast<RawInstance*>(*call_base);
      RawField* field = reinterpret_cast<RawField*>(function->ptr()->data_);
      intptr_t offset_in_words = Smi::Value(field->ptr()->value_.offset_);
      *SP = call_base;
      **SP = reinterpret_cast<RawObject**>(instance->ptr())[offset_in_words];
      *invoked = true;
      return true;
    }
    case RawFunction::kImplicitSetter: {
      // Field object is cached in function's data_.
      RawInstance* instance = reinterpret_cast<RawInstance*>(call_base[0]);
      RawField* field = reinterpret_cast<RawField*>(function->ptr()->data_);
      intptr_t offset_in_words = Smi::Value(field->ptr()->value_.offset_);
      RawAbstractType* field_type = field->ptr()->type_;
      classid_t cid;
      if (field_type->GetClassId() == kTypeCid) {
        cid = Smi::Value(reinterpret_cast<RawSmi*>(
            Type::RawCast(field_type)->ptr()->type_class_id_));
      } else {
        cid = kIllegalCid;  // Not really illegal, but not a Type to skip.
      }
      // Perform type test of value if field type is not one of dynamic, object,
      // or void, and if the value is not null.
      RawObject* null_value = Object::null();
      RawObject* value = call_base[1];
      if (cid != kDynamicCid && cid != kInstanceCid && cid != kVoidCid &&
          value != null_value) {
        RawSubtypeTestCache* cache = field->ptr()->type_test_cache_;
        if (cache->GetClassId() != kSubtypeTestCacheCid) {
          // Allocate new cache.
          call_top[1] = null_value;  // Result.
          Exit(thread, *FP, call_top + 2, *pc);
          NativeArguments native_args(thread, 0, call_top + 1, call_top + 1);
          if (!InvokeRuntime(thread, this, DRT_AllocateSubtypeTestCache,
                             native_args)) {
            *invoked = true;
            return false;
          }
          // Reload objects after the call which may trigger GC.
          function = reinterpret_cast<RawFunction*>(call_top[0]);
          field = reinterpret_cast<RawField*>(function->ptr()->data_);
          field_type = field->ptr()->type_;
          instance = reinterpret_cast<RawInstance*>(call_base[0]);
          value = call_base[1];
          cache = reinterpret_cast<RawSubtypeTestCache*>(call_top[1]);
          field->ptr()->type_test_cache_ = cache;
        }
        // Push arguments of type test.
        call_top[1] = value;
        call_top[2] = field_type;
        // Provide type arguments of instance as instantiator.
        RawClass* instance_class = thread->isolate()->class_table()->At(
            InterpreterHelpers::GetClassId(instance));
        call_top[3] =
            instance_class->ptr()->num_type_arguments_ > 0
                ? reinterpret_cast<RawObject**>(
                      instance
                          ->ptr())[instance_class->ptr()
                                       ->type_arguments_field_offset_in_words_]
                : null_value;
        call_top[4] = null_value;  // Implicit setters cannot be generic.
        call_top[5] = field->ptr()->name_;
        if (!AssertAssignable(thread, *pc, *FP, call_top + 5, call_top + 1,
                              cache)) {
          *invoked = true;
          return false;
        }
        // Reload objects after the call which may trigger GC.
        function = reinterpret_cast<RawFunction*>(call_top[0]);
        field = reinterpret_cast<RawField*>(function->ptr()->data_);
        instance = reinterpret_cast<RawInstance*>(call_base[0]);
        value = call_base[1];
      }
      if (thread->isolate()->use_field_guards()) {
        // Check value cid according to field.guarded_cid().
        // The interpreter should never see a cloned field.
        ASSERT(field->ptr()->owner_->GetClassId() != kFieldCid);
        const classid_t field_guarded_cid = field->ptr()->guarded_cid_;
        const classid_t field_nullability_cid = field->ptr()->is_nullable_;
        const classid_t value_cid = InterpreterHelpers::GetClassId(value);
        if (value_cid != field_guarded_cid &&
            value_cid != field_nullability_cid) {
          if (Smi::Value(field->ptr()->guarded_list_length_) <
                  Field::kUnknownFixedLength &&
              field_guarded_cid == kIllegalCid) {
            field->ptr()->guarded_cid_ = value_cid;
            field->ptr()->is_nullable_ = value_cid;
          } else if (field_guarded_cid != kDynamicCid) {
            call_top[1] = 0;  // Unused result of runtime call.
            call_top[2] = field;
            call_top[3] = value;
            Exit(thread, *FP, call_top + 4, *pc);
            NativeArguments native_args(thread, 2, call_top + 2, call_top + 1);
            if (!InvokeRuntime(thread, this, DRT_UpdateFieldCid, native_args)) {
              *invoked = true;
              return false;
            }
            // Reload objects after the call which may trigger GC.
            instance = reinterpret_cast<RawInstance*>(call_base[0]);
            value = call_base[1];
          }
        }
      }
      instance->StorePointer(
          reinterpret_cast<RawObject**>(instance->ptr()) + offset_in_words,
          value, thread);
      *SP = call_base;
      **SP = null_value;
      *invoked = true;
      return true;
    }
    case RawFunction::kImplicitStaticFinalGetter: {
      // Field object is cached in function's data_.
      RawField* field = reinterpret_cast<RawField*>(function->ptr()->data_);
      RawInstance* value = field->ptr()->value_.static_value_;
      if (value == Object::sentinel().raw() ||
          value == Object::transition_sentinel().raw()) {
        call_top[1] = 0;  // Unused result of invoking the initializer.
        call_top[2] = field;
        Exit(thread, *FP, call_top + 3, *pc);
        NativeArguments native_args(thread, 1, call_top + 2, call_top + 1);
        if (!InvokeRuntime(thread, this, DRT_InitStaticField, native_args)) {
          *invoked = true;
          return false;
        }
        // Reload objects after the call which may trigger GC.
        function = reinterpret_cast<RawFunction*>(call_top[0]);
        field = reinterpret_cast<RawField*>(function->ptr()->data_);
        pp_ = InterpreterHelpers::FrameBytecode(*FP)->ptr()->object_pool_;
        // The field is initialized by the runtime call, but not returned.
        value = field->ptr()->value_.static_value_;
      }
      // Field was initialized. Return its value.
      *SP = call_base;
      **SP = value;
      *invoked = true;
      return true;
    }
    case RawFunction::kMethodExtractor: {
      ASSERT(InterpreterHelpers::ArgDescTypeArgsLen(argdesc_) == 0);
      call_top[1] = 0;                       // Result of runtime call.
      call_top[2] = *call_base;              // Receiver.
      call_top[3] = function->ptr()->data_;  // Method.
      Exit(thread, *FP, call_top + 4, *pc);
      NativeArguments native_args(thread, 2, call_top + 2, call_top + 1);
      if (!InvokeRuntime(thread, this, DRT_ExtractMethod, native_args)) {
        return false;
      }
      *SP = call_base;
      **SP = call_top[1];
      *invoked = true;
      return true;
    }
    case RawFunction::kInvokeFieldDispatcher: {
      const intptr_t type_args_len =
          InterpreterHelpers::ArgDescTypeArgsLen(argdesc_);
      const intptr_t receiver_idx = type_args_len > 0 ? 1 : 0;
      RawObject* receiver = call_base[receiver_idx];
      RawObject** callee_fp = call_top + kKBCDartFrameFixedSize;
      ASSERT(function == FrameFunction(callee_fp));
      RawFunction* call_function = Function::null();
      if (function->ptr()->name_ == Symbols::Call().raw()) {
        RawObject* owner = function->ptr()->owner_;
        if (owner->GetClassId() == kPatchClassCid) {
          owner = PatchClass::RawCast(owner)->ptr()->patched_class_;
        }
        if (owner == thread->isolate()->object_store()->closure_class()) {
          // Closure call.
          call_function = Closure::RawCast(receiver)->ptr()->function_;
        }
      }
      if (call_function == Function::null()) {
        // Invoke field getter on receiver.
        call_top[1] = 0;                       // Result of runtime call.
        call_top[2] = receiver;                // Receiver.
        call_top[3] = function->ptr()->name_;  // Field name.
        Exit(thread, *FP, call_top + 4, *pc);
        NativeArguments native_args(thread, 2, call_top + 2, call_top + 1);
        if (!InvokeRuntime(thread, this, DRT_GetFieldForDispatch,
                           native_args)) {
          return false;
        }
        // If the field value is a closure, no need to resolve 'call' function.
        // Otherwise, call runtime to resolve 'call' function.
        if (InterpreterHelpers::GetClassId(call_top[1]) == kClosureCid) {
          // Closure call.
          call_function = Closure::RawCast(call_top[1])->ptr()->function_;
        } else {
          // Resolve and invoke the 'call' function.
          call_top[2] = 0;  // Result of runtime call.
          Exit(thread, *FP, call_top + 3, *pc);
          NativeArguments native_args(thread, 1, call_top + 1, call_top + 2);
          if (!InvokeRuntime(thread, this, DRT_ResolveCallFunction,
                             native_args)) {
            return false;
          }
          call_function = Function::RawCast(call_top[2]);
          if (call_function == Function::null()) {
            // 'Call' could not be resolved. TODO(regis): Can this happen?
            // Fall back to jitting the field dispatcher function.
            break;
          }
        }
        // Replace receiver with field value, keep all other arguments, and
        // invoke 'call' function.
        call_base[receiver_idx] = call_top[1];
      }
      ASSERT(call_function != Function::null());
      // Patch field dispatcher in callee frame with call function.
      callee_fp[kKBCFunctionSlotFromFp] = call_function;
      // Do not compile function if it has code or bytecode.
      if (Function::HasCode(call_function)) {
        *invoked = true;
        return InvokeCompiled(thread, call_function, call_base, call_top, pc,
                              FP, SP);
      }
      if (Function::HasBytecode(call_function)) {
        *invoked = false;
        return true;
      }
      function = call_function;
      break;  // Compile and invoke the function.
    }
    case RawFunction::kNoSuchMethodDispatcher:
      // TODO(regis): Implement. For now, use jitted version.
      break;
    case RawFunction::kDynamicInvocationForwarder:
      // TODO(regis): Implement. For now, use jitted version.
      break;
    default:
      break;
  }
  // Compile the function to either generate code or load bytecode.
  call_top[1] = 0;  // Code result.
  call_top[2] = function;
  Exit(thread, *FP, call_top + 3, *pc);
  NativeArguments native_args(thread, 1, call_top + 2, call_top + 1);
  if (!InvokeRuntime(thread, this, DRT_CompileFunction, native_args)) {
    return false;
  }
  // Reload objects after the call which may trigger GC.
  function = Function::RawCast(call_top[2]);
  if (Function::HasCode(function)) {
    *invoked = true;
    return InvokeCompiled(thread, function, call_base, call_top, pc, FP, SP);
  }
  ASSERT(Function::HasBytecode(function));
  // Bytecode was loaded in the above compilation step.
  // The caller will dispatch to the function's bytecode.
  *invoked = false;
  ASSERT(thread->vm_tag() == VMTag::kDartInterpretedTagId);
  ASSERT(thread->top_exit_frame_info() == 0);
  return true;
}

DART_FORCE_INLINE bool Interpreter::Invoke(Thread* thread,
                                           RawObject** call_base,
                                           RawObject** call_top,
                                           uint32_t** pc,
                                           RawObject*** FP,
                                           RawObject*** SP) {
  RawObject** callee_fp = call_top + kKBCDartFrameFixedSize;

  RawFunction* function = FrameFunction(callee_fp);
  if (Function::HasCode(function)) {
    return InvokeCompiled(thread, function, call_base, call_top, pc, FP, SP);
  }
  if (!Function::HasBytecode(function)) {
    bool invoked = false;
    bool result = ProcessInvocation(&invoked, thread, function, call_base,
                                    call_top, pc, FP, SP);
    if (invoked || !result) {
      return result;
    }
    function = FrameFunction(callee_fp);  // Function may have been patched.
    ASSERT(Function::HasBytecode(function));
  }
#if defined(DEBUG)
  if (IsTracingExecution()) {
    THR_Print("%" Pu64 " ", icount_);
    THR_Print("invoking %s\n",
              Function::Handle(function).ToFullyQualifiedCString());
  }
#endif
  RawBytecode* bytecode = function->ptr()->bytecode_;
  callee_fp[kKBCPcMarkerSlotFromFp] = bytecode;
  callee_fp[kKBCSavedCallerPcSlotFromFp] = reinterpret_cast<RawObject*>(*pc);
  callee_fp[kKBCSavedCallerFpSlotFromFp] = reinterpret_cast<RawObject*>(*FP);
  pp_ = bytecode->ptr()->object_pool_;
  *pc =
      reinterpret_cast<uint32_t*>(bytecode->ptr()->instructions_->ptr()->data_);
  pc_ = reinterpret_cast<uword>(*pc);  // For the profiler.
  *FP = callee_fp;
  fp_ = callee_fp;  // For the profiler.
  *SP = *FP - 1;
  return true;
}

void Interpreter::InlineCacheMiss(int checked_args,
                                  Thread* thread,
                                  RawICData* icdata,
                                  RawObject** args,
                                  RawObject** top,
                                  uint32_t* pc,
                                  RawObject** FP,
                                  RawObject** SP) {
  RawObject** result = top;
  top[0] = 0;  // Clean up result slot.
  RawObject** miss_handler_args = top + 1;
  for (intptr_t i = 0; i < checked_args; i++) {
    miss_handler_args[i] = args[i];
  }
  miss_handler_args[checked_args] = icdata;
  RuntimeFunction handler = NULL;
  switch (checked_args) {
    case 1:
      handler = DRT_InlineCacheMissHandlerOneArg;
      break;
    case 2:
      handler = DRT_InlineCacheMissHandlerTwoArgs;
      break;
    default:
      UNREACHABLE();
      break;
  }

  // Handler arguments: arguments to check and an ICData object.
  const intptr_t miss_handler_argc = checked_args + 1;
  RawObject** exit_frame = miss_handler_args + miss_handler_argc;
  CallRuntime(thread, FP, exit_frame, pc, miss_handler_argc, miss_handler_args,
              result, reinterpret_cast<uword>(handler));
}

DART_FORCE_INLINE bool Interpreter::InstanceCall1(Thread* thread,
                                                  RawICData* icdata,
                                                  RawObject** call_base,
                                                  RawObject** top,
                                                  uint32_t** pc,
                                                  RawObject*** FP,
                                                  RawObject*** SP,
                                                  bool optimized) {
  ASSERT(icdata->GetClassId() == kICDataCid);

  const intptr_t kCheckedArgs = 1;
  RawObject** args = call_base;
  RawArray* cache = icdata->ptr()->ic_data_->ptr();

  const intptr_t type_args_len =
      InterpreterHelpers::ArgDescTypeArgsLen(icdata->ptr()->args_descriptor_);
  const intptr_t receiver_idx = type_args_len > 0 ? 1 : 0;
  RawSmi* receiver_cid =
      InterpreterHelpers::GetClassIdAsSmi(args[receiver_idx]);

  bool found = false;
  const intptr_t length = Smi::Value(cache->length_);
  intptr_t i;
  for (i = 0; i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) {
    if (cache->data()[i + 0] == receiver_cid) {
      top[0] = cache->data()[i + kCheckedArgs];
      found = true;
      break;
    }
  }

  argdesc_ = icdata->ptr()->args_descriptor_;

  if (found) {
    if (!optimized) {
      InterpreterHelpers::IncrementICUsageCount(cache->data(), i, kCheckedArgs);
    }
  } else {
    InlineCacheMiss(kCheckedArgs, thread, icdata, call_base + receiver_idx, top,
                    *pc, *FP, *SP);
  }

  return Invoke(thread, call_base, top, pc, FP, SP);
}

DART_FORCE_INLINE bool Interpreter::InstanceCall2(Thread* thread,
                                                  RawICData* icdata,
                                                  RawObject** call_base,
                                                  RawObject** top,
                                                  uint32_t** pc,
                                                  RawObject*** FP,
                                                  RawObject*** SP,
                                                  bool optimized) {
  ASSERT(icdata->GetClassId() == kICDataCid);

  const intptr_t kCheckedArgs = 2;
  RawObject** args = call_base;
  RawArray* cache = icdata->ptr()->ic_data_->ptr();

  const intptr_t type_args_len =
      InterpreterHelpers::ArgDescTypeArgsLen(icdata->ptr()->args_descriptor_);
  const intptr_t receiver_idx = type_args_len > 0 ? 1 : 0;
  RawSmi* receiver_cid =
      InterpreterHelpers::GetClassIdAsSmi(args[receiver_idx]);
  RawSmi* arg0_cid =
      InterpreterHelpers::GetClassIdAsSmi(args[receiver_idx + 1]);

  bool found = false;
  const intptr_t length = Smi::Value(cache->length_);
  intptr_t i;
  for (i = 0; i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) {
    if ((cache->data()[i + 0] == receiver_cid) &&
        (cache->data()[i + 1] == arg0_cid)) {
      top[0] = cache->data()[i + kCheckedArgs];
      found = true;
      break;
    }
  }

  argdesc_ = icdata->ptr()->args_descriptor_;

  if (found) {
    if (!optimized) {
      InterpreterHelpers::IncrementICUsageCount(cache->data(), i, kCheckedArgs);
    }
  } else {
    InlineCacheMiss(kCheckedArgs, thread, icdata, call_base + receiver_idx, top,
                    *pc, *FP, *SP);
  }

  return Invoke(thread, call_base, top, pc, FP, SP);
}

// Note:
// All macro helpers are intended to be used only inside Interpreter::Call.

// Counts and prints executed bytecode instructions (in DEBUG mode).
#if defined(DEBUG)
#define TRACE_INSTRUCTION                                                      \
  if (IsTracingExecution()) {                                                  \
    TraceInstruction(pc - 1);                                                  \
  }                                                                            \
  if (IsWritingTraceFile()) {                                                  \
    WriteInstructionToTrace(pc - 1);                                           \
  }                                                                            \
  icount_++;
#else
#define TRACE_INSTRUCTION
#endif  // defined(DEBUG)

// Decode opcode and A part of the given value and dispatch to the
// corresponding bytecode handler.
#ifdef DART_HAS_COMPUTED_GOTO
#define DISPATCH_OP(val)                                                       \
  do {                                                                         \
    op = (val);                                                                \
    rA = ((op >> 8) & 0xFF);                                                   \
    TRACE_INSTRUCTION                                                          \
    goto* dispatch[op & 0xFF];                                                 \
  } while (0)
#else
#define DISPATCH_OP(val)                                                       \
  do {                                                                         \
    op = (val);                                                                \
    rA = ((op >> 8) & 0xFF);                                                   \
    TRACE_INSTRUCTION                                                          \
    goto SwitchDispatch;                                                       \
  } while (0)
#endif

// Fetch next operation from PC, increment program counter and dispatch.
#define DISPATCH() DISPATCH_OP(*pc++)

// Load target of a jump instruction into PC.
#define LOAD_JUMP_TARGET() pc += ((static_cast<int32_t>(op) >> 8) - 1)

// Define entry point that handles bytecode Name with the given operand format.
#define BYTECODE(Name, Operands)                                               \
  BYTECODE_HEADER(Name, DECLARE_##Operands, DECODE_##Operands)

#define BYTECODE_HEADER(Name, Declare, Decode)                                 \
  Declare;                                                                     \
  bc##Name : Decode

// Helpers to decode common instruction formats. Used in conjunction with
// BYTECODE() macro.
#define DECLARE_A_B_C                                                          \
  uint16_t rB, rC;                                                             \
  USE(rB);                                                                     \
  USE(rC)
#define DECODE_A_B_C                                                           \
  rB = ((op >> KernelBytecode::kBShift) & KernelBytecode::kBMask);             \
  rC = ((op >> KernelBytecode::kCShift) & KernelBytecode::kCMask);

#define DECLARE_A_B_Y                                                          \
  uint16_t rB;                                                                 \
  int8_t rY;                                                                   \
  USE(rB);                                                                     \
  USE(rY)
#define DECODE_A_B_Y                                                           \
  rB = ((op >> KernelBytecode::kBShift) & KernelBytecode::kBMask);             \
  rY = ((op >> KernelBytecode::kYShift) & KernelBytecode::kYMask);

#define DECLARE_0
#define DECODE_0

#define DECLARE_A
#define DECODE_A

#define DECLARE___D                                                            \
  uint32_t rD;                                                                 \
  USE(rD)
#define DECODE___D rD = (op >> KernelBytecode::kDShift);

#define DECLARE_A_D DECLARE___D
#define DECODE_A_D DECODE___D

#define DECLARE_A_X                                                            \
  int32_t rD;                                                                  \
  USE(rD)
#define DECODE_A_X rD = (static_cast<int32_t>(op) >> KernelBytecode::kDShift);


// Exception handling helper. Gets handler FP and PC from the Interpreter where
// they were stored by Interpreter::Longjmp and proceeds to execute the handler.
// Corner case: handler PC can be a fake marker that marks entry frame, which
// means exception was not handled in the Dart code. In this case we return
// caught exception from Interpreter::Call.
#if defined(DEBUG)

#define HANDLE_EXCEPTION                                                       \
  do {                                                                         \
    FP = reinterpret_cast<RawObject**>(fp_);                                   \
    pc = reinterpret_cast<uint32_t*>(pc_);                                     \
    if (IsEntryFrameMarker(reinterpret_cast<uword>(pc))) {                     \
      pp_ = reinterpret_cast<RawObjectPool*>(fp_[kKBCSavedPpSlotFromEntryFp]); \
      argdesc_ =                                                               \
          reinterpret_cast<RawArray*>(fp_[kKBCSavedArgDescSlotFromEntryFp]);   \
      uword exit_fp =                                                          \
          reinterpret_cast<uword>(fp_[kKBCExitLinkSlotFromEntryFp]);           \
      thread->set_top_exit_frame_info(exit_fp);                                \
      thread->set_top_resource(top_resource);                                  \
      thread->set_vm_tag(vm_tag);                                              \
      if (IsTracingExecution()) {                                              \
        THR_Print("%" Pu64 " ", icount_);                                      \
        THR_Print("Returning exception from interpreter 0x%" Px                \
                  " at fp_ 0x%" Px " exit 0x%" Px "\n",                        \
                  reinterpret_cast<uword>(this), reinterpret_cast<uword>(fp_), \
                  exit_fp);                                                    \
      }                                                                        \
      ASSERT(HasFrame(reinterpret_cast<uword>(fp_)));                          \
      return special_[KernelBytecode::kExceptionSpecialIndex];                 \
    }                                                                          \
    goto DispatchAfterException;                                               \
  } while (0)

#else  // !defined(DEBUG)

#define HANDLE_EXCEPTION                                                       \
  do {                                                                         \
    FP = reinterpret_cast<RawObject**>(fp_);                                   \
    pc = reinterpret_cast<uint32_t*>(pc_);                                     \
    if (IsEntryFrameMarker(reinterpret_cast<uword>(pc))) {                     \
      pp_ = reinterpret_cast<RawObjectPool*>(fp_[kKBCSavedPpSlotFromEntryFp]); \
      argdesc_ =                                                               \
          reinterpret_cast<RawArray*>(fp_[kKBCSavedArgDescSlotFromEntryFp]);   \
      uword exit_fp =                                                          \
          reinterpret_cast<uword>(fp_[kKBCExitLinkSlotFromEntryFp]);           \
      thread->set_top_exit_frame_info(exit_fp);                                \
      thread->set_top_resource(top_resource);                                  \
      thread->set_vm_tag(vm_tag);                                              \
      return special_[KernelBytecode::kExceptionSpecialIndex];                 \
    }                                                                          \
    goto DispatchAfterException;                                               \
  } while (0)

#endif  // !defined(DEBUG)

#define HANDLE_RETURN                                                          \
  do {                                                                         \
    pp_ = InterpreterHelpers::FrameBytecode(FP)->ptr()->object_pool_;          \
    fp_ = FP; /* For the profiler. */                                          \
  } while (0)

// Runtime call helpers: handle invocation and potential exception after return.
#define INVOKE_RUNTIME(Func, Args)                                             \
  if (!InvokeRuntime(thread, this, Func, Args)) {                              \
    HANDLE_EXCEPTION;                                                          \
  } else {                                                                     \
    HANDLE_RETURN;                                                             \
  }

#define INVOKE_NATIVE(Wrapper, Func, Args)                                     \
  if (!InvokeNative(thread, this, Wrapper, Func, Args)) {                      \
    HANDLE_EXCEPTION;                                                          \
  } else {                                                                     \
    HANDLE_RETURN;                                                             \
  }

#define LOAD_CONSTANT(index) (pp_->ptr()->data()[(index)].raw_obj_)

#define UNBOX_INT64(value, obj, selector)                                      \
  int64_t value;                                                               \
  {                                                                            \
    word raw_value = reinterpret_cast<word>(obj);                              \
    if (LIKELY((raw_value & kSmiTagMask) == kSmiTag)) {                        \
      value = raw_value >> kSmiTagShift;                                       \
    } else {                                                                   \
      if (UNLIKELY(obj == null_value)) {                                       \
        SP[0] = selector.raw();                                                \
        goto ThrowNullError;                                                   \
      }                                                                        \
      value = Integer::GetInt64Value(RAW_CAST(Integer, obj));                  \
    }                                                                          \
  }

#define BOX_INT64_RESULT(result)                                               \
  if (LIKELY(Smi::IsValid(result))) {                                          \
    SP[0] = Smi::New(static_cast<intptr_t>(result));                           \
  } else if (!AllocateInt64Box(thread, result, pc, FP, SP)) {                  \
    HANDLE_EXCEPTION;                                                          \
  }                                                                            \
  ASSERT(Integer::GetInt64Value(RAW_CAST(Integer, SP[0])) == result);

bool Interpreter::AssertAssignable(Thread* thread,
                                   uint32_t* pc,
                                   RawObject** FP,
                                   RawObject** call_top,
                                   RawObject** args,
                                   RawSubtypeTestCache* cache) {
  RawObject* null_value = Object::null();
  if (cache != null_value) {
    RawInstance* instance = static_cast<RawInstance*>(args[0]);
    RawTypeArguments* instantiator_type_arguments =
        static_cast<RawTypeArguments*>(args[2]);
    RawTypeArguments* function_type_arguments =
        static_cast<RawTypeArguments*>(args[3]);

    const intptr_t cid = InterpreterHelpers::GetClassId(instance);

    RawTypeArguments* instance_type_arguments =
        static_cast<RawTypeArguments*>(null_value);
    RawObject* instance_cid_or_function;

    RawTypeArguments* parent_function_type_arguments;
    RawTypeArguments* delayed_function_type_arguments;
    if (cid == kClosureCid) {
      RawClosure* closure = static_cast<RawClosure*>(instance);
      instance_type_arguments = closure->ptr()->instantiator_type_arguments_;
      parent_function_type_arguments = closure->ptr()->function_type_arguments_;
      delayed_function_type_arguments = closure->ptr()->delayed_type_arguments_;
      instance_cid_or_function = closure->ptr()->function_;
    } else {
      instance_cid_or_function = Smi::New(cid);

      RawClass* instance_class = thread->isolate()->class_table()->At(cid);
      if (instance_class->ptr()->num_type_arguments_ < 0) {
        goto AssertAssignableCallRuntime;
      } else if (instance_class->ptr()->num_type_arguments_ > 0) {
        instance_type_arguments = reinterpret_cast<RawTypeArguments**>(
            instance->ptr())[instance_class->ptr()
                                 ->type_arguments_field_offset_in_words_];
      }
      parent_function_type_arguments =
          static_cast<RawTypeArguments*>(null_value);
      delayed_function_type_arguments =
          static_cast<RawTypeArguments*>(null_value);
    }

    for (RawObject** entries = cache->ptr()->cache_->ptr()->data();
         entries[0] != null_value;
         entries += SubtypeTestCache::kTestEntryLength) {
      if ((entries[SubtypeTestCache::kInstanceClassIdOrFunction] ==
           instance_cid_or_function) &&
          (entries[SubtypeTestCache::kInstanceTypeArguments] ==
           instance_type_arguments) &&
          (entries[SubtypeTestCache::kInstantiatorTypeArguments] ==
           instantiator_type_arguments) &&
          (entries[SubtypeTestCache::kFunctionTypeArguments] ==
           function_type_arguments) &&
          (entries[SubtypeTestCache::kInstanceParentFunctionTypeArguments] ==
           parent_function_type_arguments) &&
          (entries[SubtypeTestCache::kInstanceDelayedFunctionTypeArguments] ==
           delayed_function_type_arguments)) {
        if (Bool::True().raw() == entries[SubtypeTestCache::kTestResult]) {
          return true;
        } else {
          break;
        }
      }
    }
  }

AssertAssignableCallRuntime:
  // args[0]: Instance.
  // args[1]: Type.
  // args[2]: Instantiator type args.
  // args[3]: Function type args.
  // args[4]: Name.
  args[5] = cache;
  args[6] = Smi::New(kTypeCheckFromInline);
  args[7] = 0;  // Unused result.
  Exit(thread, FP, args + 8, pc);
  NativeArguments native_args(thread, 7, args, args + 7);
  return InvokeRuntime(thread, this, DRT_TypeCheck, native_args);
}

RawObject* Interpreter::Call(const Function& function,
                             const Array& arguments_descriptor,
                             const Array& arguments,
                             Thread* thread) {
  return Call(function.raw(), arguments_descriptor.raw(), arguments.Length(),
              arguments.raw_ptr()->data(), thread);
}

// Allocate _Mint box for the given int64_t value and puts it into SP[0].
// Returns false on exception.
DART_NOINLINE bool Interpreter::AllocateInt64Box(Thread* thread,
                                                 int64_t value,
                                                 uint32_t* pc,
                                                 RawObject** FP,
                                                 RawObject** SP) {
  ASSERT(!Smi::IsValid(value));
  const intptr_t instance_size = Mint::InstanceSize();
  const uword start =
      thread->heap()->new_space()->TryAllocateInTLAB(thread, instance_size);
  if (LIKELY(start != 0)) {
    uword tags = 0;
    tags = RawObject::ClassIdTag::update(kMintCid, tags);
    tags = RawObject::SizeTag::update(instance_size, tags);
    tags = RawObject::NewBit::update(true, tags);
    // Also writes zero in the hash_ field.
    *reinterpret_cast<uword*>(start + Mint::tags_offset()) = tags;
    *reinterpret_cast<int64_t*>(start + Mint::value_offset()) = value;
    SP[0] = reinterpret_cast<RawObject*>(start + kHeapObjectTag);
    return true;
  } else {
    SP[0] = 0;  // Space for the result.
    SP[1] = thread->isolate()->object_store()->mint_class();  // Class object.
    SP[2] = Object::null();                                  // Type arguments.
    Exit(thread, FP, SP + 3, pc);
    NativeArguments args(thread, 2, SP + 1, SP);
    if (!InvokeRuntime(thread, this, DRT_AllocateObject, args)) {
      return false;
    }
    *reinterpret_cast<int64_t*>(reinterpret_cast<uword>(SP[0]) -
                                kHeapObjectTag + Mint::value_offset()) = value;
    return true;
  }
}

RawObject* Interpreter::Call(RawFunction* function,
                             RawArray* argdesc,
                             intptr_t argc,
                             RawObject* const* argv,
                             Thread* thread) {
  // Interpreter state (see constants_kbc.h for high-level overview).
  uint32_t* pc;    // Program Counter: points to the next op to execute.
  RawObject** FP;  // Frame Pointer.
  RawObject** SP;  // Stack Pointer.

  uint32_t op;  // Currently executing op.
  uint16_t rA;  // A component of the currently executing op.

  bool reentering = fp_ != NULL;
  if (!reentering) {
    fp_ = reinterpret_cast<RawObject**>(stack_base_);
  }
#if defined(DEBUG)
  if (IsTracingExecution()) {
    THR_Print("%" Pu64 " ", icount_);
    THR_Print("%s interpreter 0x%" Px " at fp_ 0x%" Px " exit 0x%" Px " %s\n",
              reentering ? "Re-entering" : "Entering",
              reinterpret_cast<uword>(this), reinterpret_cast<uword>(fp_),
              thread->top_exit_frame_info(),
              Function::Handle(function).ToCString());
  }
#endif

  // Setup entry frame:
  //
  //                        ^
  //                        |  previous Dart frames
  //                        |
  //       | ........... | -+
  // fp_ > | exit fp_    |     saved top_exit_frame_info
  //       | argdesc_    |     saved argdesc_ (for reentering interpreter)
  //       | pp_         |     saved pp_ (for reentering interpreter)
  //       | arg 0       | -+
  //       | arg 1       |  |
  //         ...            |
  //                         > incoming arguments
  //                        |
  //       | arg argc-1  | -+
  //       | function    | -+
  //       | code        |  |
  //       | caller PC   | ---> special fake PC marking an entry frame
  //  SP > | fp_         |  |
  //  FP > | ........... |   > normal Dart frame (see stack_frame_kbc.h)
  //                        |
  //                        v
  //
  // A negative argc indicates reverse memory order of arguments.
  const intptr_t arg_count = argc < 0 ? -argc : argc;
  FP = fp_ + kKBCEntrySavedSlots + arg_count + kKBCDartFrameFixedSize;
  SP = FP - 1;

  // Save outer top_exit_frame_info, current argdesc, and current pp.
  fp_[kKBCExitLinkSlotFromEntryFp] =
      reinterpret_cast<RawObject*>(thread->top_exit_frame_info());
  thread->set_top_exit_frame_info(0);
  fp_[kKBCSavedArgDescSlotFromEntryFp] = reinterpret_cast<RawObject*>(argdesc_);
  fp_[kKBCSavedPpSlotFromEntryFp] = reinterpret_cast<RawObject*>(pp_);

  // Copy arguments and setup the Dart frame.
  for (intptr_t i = 0; i < arg_count; i++) {
    fp_[kKBCEntrySavedSlots + i] = argv[argc < 0 ? -i : i];
  }

  RawBytecode* bytecode = function->ptr()->bytecode_;
  FP[kKBCFunctionSlotFromFp] = function;
  FP[kKBCPcMarkerSlotFromFp] = bytecode;
  FP[kKBCSavedCallerPcSlotFromFp] =
      reinterpret_cast<RawObject*>((arg_count << 2) | 2);
  FP[kKBCSavedCallerFpSlotFromFp] = reinterpret_cast<RawObject*>(fp_);

  // Load argument descriptor.
  argdesc_ = argdesc;

  // Ready to start executing bytecode. Load entry point and corresponding
  // object pool.
  pc =
      reinterpret_cast<uint32_t*>(bytecode->ptr()->instructions_->ptr()->data_);
  pc_ = reinterpret_cast<uword>(pc);  // For the profiler.
  fp_ = FP;                           // For the profiler.
  pp_ = bytecode->ptr()->object_pool_;

  // Save current VM tag and mark thread as executing Dart code. For the
  // profiler, do this *after* setting up the entry frame (compare the machine
  // code entry stubs).
  const uword vm_tag = thread->vm_tag();
  thread->set_vm_tag(VMTag::kDartInterpretedTagId);

  // Save current top stack resource and reset the list.
  StackResource* top_resource = thread->top_resource();
  thread->set_top_resource(NULL);

  // Cache some frequently used values in the frame.
  RawBool* true_value = Bool::True().raw();
  RawBool* false_value = Bool::False().raw();
  RawObject* null_value = Object::null();

#if defined(DEBUG)
  Function& function_h = Function::Handle();
#endif

#ifdef DART_HAS_COMPUTED_GOTO
  static const void* dispatch[] = {
#define TARGET(name, fmt, fmta, fmtb, fmtc) &&bc##name,
      KERNEL_BYTECODES_LIST(TARGET)
#undef TARGET
  };
  DISPATCH();  // Enter the dispatch loop.
#else
  DISPATCH();  // Enter the dispatch loop.
SwitchDispatch:
  switch (op & 0xFF) {
#define TARGET(name, fmt, fmta, fmtb, fmtc)                                    \
  case KernelBytecode::k##name:                                                \
    goto bc##name;
    KERNEL_BYTECODES_LIST(TARGET)
#undef TARGET
    default:
      FATAL1("Undefined opcode: %d\n", op);
  }
#endif

  // KernelBytecode handlers (see constants_kbc.h for bytecode descriptions).
  {
    BYTECODE(Entry, A_D);
    const uint16_t num_locals = rD;

    // Initialize locals with null & set SP.
    for (intptr_t i = 0; i < num_locals; i++) {
      FP[i] = null_value;
    }
    SP = FP + num_locals - 1;

    DISPATCH();
  }

  {
    BYTECODE(EntryFixed, A_D);
    const uint16_t num_fixed_params = rA;
    const uint16_t num_locals = rD;

    const intptr_t arg_count = InterpreterHelpers::ArgDescArgCount(argdesc_);
    const intptr_t pos_count = InterpreterHelpers::ArgDescPosCount(argdesc_);
    if ((arg_count != num_fixed_params) || (pos_count != num_fixed_params)) {
      goto ClosureNoSuchMethod;
    }

    // Initialize locals with null & set SP.
    for (intptr_t i = 0; i < num_locals; i++) {
      FP[i] = null_value;
    }
    SP = FP + num_locals - 1;

    DISPATCH();
  }

  {
    BYTECODE(EntryOptional, A_B_C);
    const uint16_t num_fixed_params = rA;
    const uint16_t num_opt_pos_params = rB;
    const uint16_t num_opt_named_params = rC;
    const intptr_t min_num_pos_args = num_fixed_params;
    const intptr_t max_num_pos_args = num_fixed_params + num_opt_pos_params;

    // Decode arguments descriptor.
    const intptr_t arg_count = InterpreterHelpers::ArgDescArgCount(argdesc_);
    const intptr_t pos_count = InterpreterHelpers::ArgDescPosCount(argdesc_);
    const intptr_t named_count = (arg_count - pos_count);

    // Check that got the right number of positional parameters.
    if ((min_num_pos_args > pos_count) || (pos_count > max_num_pos_args)) {
      goto ClosureNoSuchMethod;
    }

    // Copy all passed position arguments.
    RawObject** first_arg = FrameArguments(FP, arg_count);
    memmove(FP, first_arg, pos_count * kWordSize);

    if (num_opt_named_params != 0) {
      // This is a function with named parameters.
      // Walk the list of named parameters and their
      // default values encoded as pairs of LoadConstant instructions that
      // follows the entry point and find matching values via arguments
      // descriptor.
      RawObject** argdesc_data = argdesc_->ptr()->data();

      intptr_t i = named_count - 1;           // argument position
      intptr_t j = num_opt_named_params - 1;  // parameter position
      while ((j >= 0) && (i >= 0)) {
        // Fetch formal parameter information: name, default value, target slot.
        const uint32_t load_name = pc[2 * j];
        const uint32_t load_value = pc[2 * j + 1];
        ASSERT(KernelBytecode::DecodeOpcode(load_name) ==
               KernelBytecode::kLoadConstant);
        ASSERT(KernelBytecode::DecodeOpcode(load_value) ==
               KernelBytecode::kLoadConstant);
        const uint8_t reg = KernelBytecode::DecodeA(load_name);
        ASSERT(reg == KernelBytecode::DecodeA(load_value));

        RawString* name = static_cast<RawString*>(
            LOAD_CONSTANT(KernelBytecode::DecodeD(load_name)));
        if (name == argdesc_data[ArgumentsDescriptor::name_index(i)]) {
          // Parameter was passed. Fetch passed value.
          const intptr_t arg_index = Smi::Value(static_cast<RawSmi*>(
              argdesc_data[ArgumentsDescriptor::position_index(i)]));
          FP[reg] = first_arg[arg_index];
          i--;  // Consume passed argument.
        } else {
          // Parameter was not passed. Fetch default value.
          FP[reg] = LOAD_CONSTANT(KernelBytecode::DecodeD(load_value));
        }
        j--;  // Next formal parameter.
      }

      // If we have unprocessed formal parameters then initialize them all
      // using default values.
      while (j >= 0) {
        const uint32_t load_name = pc[2 * j];
        const uint32_t load_value = pc[2 * j + 1];
        ASSERT(KernelBytecode::DecodeOpcode(load_name) ==
               KernelBytecode::kLoadConstant);
        ASSERT(KernelBytecode::DecodeOpcode(load_value) ==
               KernelBytecode::kLoadConstant);
        const uint8_t reg = KernelBytecode::DecodeA(load_name);
        ASSERT(reg == KernelBytecode::DecodeA(load_value));

        FP[reg] = LOAD_CONSTANT(KernelBytecode::DecodeD(load_value));
        j--;
      }

      // If we have unprocessed passed arguments that means we have mismatch
      // between formal parameters and concrete arguments. This can only
      // occur if the current function is a closure.
      if (i != -1) {
        goto ClosureNoSuchMethod;
      }

      // Skip LoadConstant-s encoding information about named parameters.
      pc += num_opt_named_params * 2;

      // SP points past copied arguments.
      SP = FP + num_fixed_params + num_opt_named_params - 1;
    } else {
      ASSERT(num_opt_pos_params != 0);
      if (named_count != 0) {
        // Function can't have both named and optional positional parameters.
        // This kind of mismatch can only occur if the current function
        // is a closure.
        goto ClosureNoSuchMethod;
      }

      // Process the list of default values encoded as a sequence of
      // LoadConstant instructions after EntryOpt bytecode.
      // Execute only those that correspond to parameters that were not passed.
      for (intptr_t i = pos_count - num_fixed_params; i < num_opt_pos_params;
           i++) {
        const uint32_t load_value = pc[i];
        ASSERT(KernelBytecode::DecodeOpcode(load_value) ==
               KernelBytecode::kLoadConstant);
#if defined(DEBUG)
        const uint8_t reg = KernelBytecode::DecodeA(load_value);
        ASSERT((num_fixed_params + i) == reg);
#endif
        FP[num_fixed_params + i] =
            LOAD_CONSTANT(KernelBytecode::DecodeD(load_value));
      }

      // Skip LoadConstant-s encoding default values for optional positional
      // parameters.
      pc += num_opt_pos_params;

      // SP points past the last copied parameter.
      SP = FP + max_num_pos_args - 1;
    }

    DISPATCH();
  }

  {
    BYTECODE(Frame, A_D);
    // Initialize locals with null and increment SP.
    const uint16_t num_locals = rD;
    for (intptr_t i = 1; i <= num_locals; i++) {
      SP[i] = null_value;
    }
    SP += num_locals;

    DISPATCH();
  }

  {
    BYTECODE(SetFrame, A);
    SP = FP + rA - 1;
    DISPATCH();
  }

  {
    BYTECODE(CheckStack, A);
    {
      // Check the interpreter's own stack limit for actual interpreter's stack
      // overflows, and also the thread's stack limit for scheduled interrupts.
      if (reinterpret_cast<uword>(SP) >= overflow_stack_limit() ||
          thread->HasScheduledInterrupts()) {
        Exit(thread, FP, SP + 1, pc);
        NativeArguments args(thread, 0, NULL, NULL);
        INVOKE_RUNTIME(DRT_StackOverflow, args);
      }
    }
    RawFunction* function = FrameFunction(FP);
    int32_t counter = ++(function->ptr()->usage_counter_);
    if (UNLIKELY(FLAG_compilation_counter_threshold >= 0 &&
                 counter >= FLAG_compilation_counter_threshold &&
                 !Function::HasCode(function))) {
      SP[1] = 0;  // Unused code result.
      SP[2] = function;
      Exit(thread, FP, SP + 3, pc);
      NativeArguments native_args(thread, 1, SP + 2, SP + 1);
      INVOKE_RUNTIME(DRT_OptimizeInvokedFunction, native_args);
    }
    DISPATCH();
  }

  {
    BYTECODE(CheckFunctionTypeArgs, A_D);
    const uint16_t declared_type_args_len = rA;
    const uint16_t first_stack_local_index = rD;

    // Decode arguments descriptor's type args len.
    const intptr_t type_args_len =
        InterpreterHelpers::ArgDescTypeArgsLen(argdesc_);
    if ((type_args_len != declared_type_args_len) && (type_args_len != 0)) {
      goto ClosureNoSuchMethod;
    }
    if (type_args_len > 0) {
      // Decode arguments descriptor's argument count (excluding type args).
      const intptr_t arg_count = InterpreterHelpers::ArgDescArgCount(argdesc_);
      // Copy passed-in type args to first local slot.
      FP[first_stack_local_index] = *FrameArguments(FP, arg_count + 1);
    } else if (declared_type_args_len > 0) {
      FP[first_stack_local_index] = Object::null();
    }
    DISPATCH();
  }

  {
    BYTECODE(InstantiateType, A_D);
    // Stack: instantiator type args, function type args
    RawObject* type = LOAD_CONSTANT(rD);
    SP[1] = type;
    SP[2] = SP[-1];
    SP[3] = SP[0];
    Exit(thread, FP, SP + 4, pc);
    {
      NativeArguments args(thread, 3, SP + 1, SP - 1);
      INVOKE_RUNTIME(DRT_InstantiateType, args);
    }
    SP -= 1;
    DISPATCH();
  }

  {
    BYTECODE(InstantiateTypeArgumentsTOS, A_D);
    // Stack: instantiator type args, function type args
    RawTypeArguments* type_arguments =
        static_cast<RawTypeArguments*>(LOAD_CONSTANT(rD));

    RawObject* instantiator_type_args = SP[-1];
    RawObject* function_type_args = SP[0];
    // If both instantiators are null and if the type argument vector
    // instantiated from null becomes a vector of dynamic, then use null as
    // the type arguments.
    if ((rA == 0) || (null_value != instantiator_type_args) ||
        (null_value != function_type_args)) {
      // First lookup in the cache.
      RawArray* instantiations = type_arguments->ptr()->instantiations_;
      for (intptr_t i = 0;
           instantiations->ptr()->data()[i] != NULL;  // kNoInstantiator
           i += 3) {  // kInstantiationSizeInWords
        if ((instantiations->ptr()->data()[i] == instantiator_type_args) &&
            (instantiations->ptr()->data()[i + 1] == function_type_args)) {
          // Found in the cache.
          SP[-1] = instantiations->ptr()->data()[i + 2];
          goto InstantiateTypeArgumentsTOSDone;
        }
      }

      // Cache lookup failed, call runtime.
      SP[1] = type_arguments;
      SP[2] = instantiator_type_args;
      SP[3] = function_type_args;

      Exit(thread, FP, SP + 4, pc);
      NativeArguments args(thread, 3, SP + 1, SP - 1);
      INVOKE_RUNTIME(DRT_InstantiateTypeArguments, args);
    }

  InstantiateTypeArgumentsTOSDone:
    SP -= 1;
    DISPATCH();
  }

  {
    BYTECODE(Throw, A);
    {
      SP[1] = 0;  // Space for result.
      Exit(thread, FP, SP + 2, pc);
      if (rA == 0) {  // Throw
        NativeArguments args(thread, 1, SP, SP + 1);
        INVOKE_RUNTIME(DRT_Throw, args);
      } else {  // ReThrow
        NativeArguments args(thread, 2, SP - 1, SP + 1);
        INVOKE_RUNTIME(DRT_ReThrow, args);
      }
    }
    DISPATCH();
  }

  {
    BYTECODE(Drop1, 0);
    SP--;
    DISPATCH();
  }

  {
    BYTECODE(LoadConstant, A_D);
    FP[rA] = LOAD_CONSTANT(rD);
    DISPATCH();
  }

  {
    BYTECODE(PushConstant, __D);
    *++SP = LOAD_CONSTANT(rD);
    DISPATCH();
  }

  {
    BYTECODE(PushNull, 0);
    *++SP = null_value;
    DISPATCH();
  }

  {
    BYTECODE(PushTrue, 0);
    *++SP = true_value;
    DISPATCH();
  }

  {
    BYTECODE(PushFalse, 0);
    *++SP = false_value;
    DISPATCH();
  }

  {
    BYTECODE(PushInt, A_X);
    *++SP = Smi::New(rD);
    DISPATCH();
  }

  {
    BYTECODE(Push, A_X);
    *++SP = FP[rD];
    DISPATCH();
  }

  {
    BYTECODE(StoreLocal, A_X);
    FP[rD] = *SP;
    DISPATCH();
  }

  {
    BYTECODE(PopLocal, A_X);
    FP[rD] = *SP--;
    DISPATCH();
  }

  {
    BYTECODE(MoveSpecial, A_X);
    ASSERT(rA < KernelBytecode::kSpecialIndexCount);
    FP[rD] = special_[rA];
    DISPATCH();
  }

  {
    BYTECODE(BooleanNegateTOS, 0);
    SP[0] = (SP[0] == true_value) ? false_value : true_value;
    DISPATCH();
  }

  {
    BYTECODE(IndirectStaticCall, A_D);

    // Check if single stepping.
    if (thread->isolate()->single_step()) {
      Exit(thread, FP, SP + 1, pc);
      NativeArguments args(thread, 0, NULL, NULL);
      INVOKE_RUNTIME(DRT_SingleStepHandler, args);
    }

    // Invoke target function.
    {
      const uint16_t argc = rA;
      // Look up the function in the ICData.
      RawObject* ic_data_obj = SP[0];
      RawICData* ic_data = RAW_CAST(ICData, ic_data_obj);
      RawObject** data = ic_data->ptr()->ic_data_->ptr()->data();
      InterpreterHelpers::IncrementICUsageCount(data, 0, 0);
      SP[0] = data[ICData::TargetIndexFor(ic_data->ptr()->state_bits_ & 0x3)];
      RawObject** call_base = SP - argc;
      RawObject** call_top = SP;  // *SP contains function
      argdesc_ = static_cast<RawArray*>(LOAD_CONSTANT(rD));
      if (!Invoke(thread, call_base, call_top, &pc, &FP, &SP)) {
        HANDLE_EXCEPTION;
      }
    }

    DISPATCH();
  }

  {
    BYTECODE(InstanceCall, A_D);

    // Check if single stepping.
    if (thread->isolate()->single_step()) {
      Exit(thread, FP, SP + 1, pc);
      NativeArguments args(thread, 0, NULL, NULL);
      INVOKE_RUNTIME(DRT_SingleStepHandler, args);
    }

    {
      const uint16_t argc = rA;
      const uint16_t kidx = rD;

      RawObject** call_base = SP - argc + 1;
      RawObject** call_top = SP + 1;

      RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx));
      InterpreterHelpers::IncrementUsageCounter(
          RAW_CAST(Function, icdata->ptr()->owner_));
      if (ICData::NumArgsTestedBits::decode(icdata->ptr()->state_bits_) == 1) {
        if (!InstanceCall1(thread, icdata, call_base, call_top, &pc, &FP, &SP,
                           false /* optimized */)) {
          HANDLE_EXCEPTION;
        }
      } else {
        ASSERT(ICData::NumArgsTestedBits::decode(icdata->ptr()->state_bits_) ==
               2);
        if (!InstanceCall2(thread, icdata, call_base, call_top, &pc, &FP, &SP,
                           false /* optimized */)) {
          HANDLE_EXCEPTION;
        }
      }
    }

    DISPATCH();
  }

  {
    BYTECODE(NativeCall, __D);
    RawTypedData* data = static_cast<RawTypedData*>(LOAD_CONSTANT(rD));
    MethodRecognizer::Kind kind = NativeEntryData::GetKind(data);
    switch (kind) {
      case MethodRecognizer::kObjectEquals: {
        SP[-1] = SP[-1] == SP[0] ? Bool::True().raw() : Bool::False().raw();
        SP--;
      } break;
      case MethodRecognizer::kStringBaseLength:
      case MethodRecognizer::kStringBaseIsEmpty: {
        RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
        SP[0] = reinterpret_cast<RawObject**>(
            instance->ptr())[String::length_offset() / kWordSize];
        if (kind == MethodRecognizer::kStringBaseIsEmpty) {
          SP[0] =
              SP[0] == Smi::New(0) ? Bool::True().raw() : Bool::False().raw();
        }
      } break;
      case MethodRecognizer::kGrowableArrayLength: {
        RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
        SP[0] = reinterpret_cast<RawObject**>(
            instance->ptr())[GrowableObjectArray::length_offset() / kWordSize];
      } break;
      case MethodRecognizer::kObjectArrayLength:
      case MethodRecognizer::kImmutableArrayLength: {
        RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
        SP[0] = reinterpret_cast<RawObject**>(
            instance->ptr())[Array::length_offset() / kWordSize];
      } break;
      case MethodRecognizer::kTypedDataLength: {
        RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
        SP[0] = reinterpret_cast<RawObject**>(
            instance->ptr())[TypedData::length_offset() / kWordSize];
      } break;
      case MethodRecognizer::kClassIDgetID: {
        SP[0] = InterpreterHelpers::GetClassIdAsSmi(SP[0]);
      } break;
      case MethodRecognizer::kGrowableArrayCapacity: {
        RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
        instance = reinterpret_cast<RawInstance**>(
            instance->ptr())[GrowableObjectArray::data_offset() / kWordSize];
        SP[0] = reinterpret_cast<RawObject**>(
            instance->ptr())[Array::length_offset() / kWordSize];
      } break;
      case MethodRecognizer::kListFactory: {
        // factory List<E>([int length]) {
        //   return (:arg_desc.positional_count == 2) ? new _List<E>(length)
        //                                            : new _GrowableList<E>(0);
        // }
        if (InterpreterHelpers::ArgDescPosCount(argdesc_) == 2) {
          SP[1] = SP[0];   // length
          SP[2] = SP[-1];  // type
          Exit(thread, FP, SP + 3, pc);
          NativeArguments native_args(thread, 2, SP + 1, SP - 1);
          INVOKE_RUNTIME(DRT_AllocateArray, native_args);
          SP -= 1;  // Result is in SP - 1.
        } else {
          ASSERT(InterpreterHelpers::ArgDescPosCount(argdesc_) == 1);
          // SP[-1] is type.
          // The native wrapper pushed null as the optional length argument.
          ASSERT(SP[0] == null_value);
          SP[0] = Smi::New(0);  // Patch null length with zero length.
          SP[1] = thread->isolate()->object_store()->growable_list_factory();
          // Change the ArgumentsDescriptor of the call with a new cached one.
          argdesc_ = ArgumentsDescriptor::New(
              0, KernelBytecode::kNativeCallToGrowableListArgc);
          // Note the special handling of the return of this call in DecodeArgc.
          if (!Invoke(thread, SP - 1, SP + 1, &pc, &FP, &SP)) {
            HANDLE_EXCEPTION;
          }
        }
      } break;
      case MethodRecognizer::kObjectArrayAllocate: {
        SP[1] = SP[0];   // length
        SP[2] = SP[-1];  // type
        Exit(thread, FP, SP + 3, pc);
        NativeArguments native_args(thread, 2, SP + 1, SP - 1);
        INVOKE_RUNTIME(DRT_AllocateArray, native_args);
        SP -= 1;  // Result is in SP - 1.
      } break;
      case MethodRecognizer::kLinkedHashMap_getIndex: {
        RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
        SP[0] = reinterpret_cast<RawObject**>(
            instance->ptr())[LinkedHashMap::index_offset() / kWordSize];
      } break;
      case MethodRecognizer::kLinkedHashMap_setIndex: {
        RawInstance* instance = reinterpret_cast<RawInstance*>(SP[-1]);
        instance->StorePointer(reinterpret_cast<RawObject**>(instance->ptr()) +
                                   LinkedHashMap::index_offset() / kWordSize,
                               SP[0]);
        *--SP = null_value;
      } break;
      case MethodRecognizer::kLinkedHashMap_getData: {
        RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
        SP[0] = reinterpret_cast<RawObject**>(
            instance->ptr())[LinkedHashMap::data_offset() / kWordSize];
      } break;
      case MethodRecognizer::kLinkedHashMap_setData: {
        RawInstance* instance = reinterpret_cast<RawInstance*>(SP[-1]);
        instance->StorePointer(reinterpret_cast<RawObject**>(instance->ptr()) +
                                   LinkedHashMap::data_offset() / kWordSize,
                               SP[0]);
        *--SP = null_value;
      } break;
      case MethodRecognizer::kLinkedHashMap_getHashMask: {
        RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
        SP[0] = reinterpret_cast<RawObject**>(
            instance->ptr())[LinkedHashMap::hash_mask_offset() / kWordSize];
      } break;
      case MethodRecognizer::kLinkedHashMap_setHashMask: {
        RawInstance* instance = reinterpret_cast<RawInstance*>(SP[-1]);
        ASSERT(!SP[0]->IsHeapObject());
        reinterpret_cast<RawObject**>(
            instance->ptr())[LinkedHashMap::hash_mask_offset() / kWordSize] =
            SP[0];
        *--SP = null_value;
      } break;
      case MethodRecognizer::kLinkedHashMap_getUsedData: {
        RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
        SP[0] = reinterpret_cast<RawObject**>(
            instance->ptr())[LinkedHashMap::used_data_offset() / kWordSize];
      } break;
      case MethodRecognizer::kLinkedHashMap_setUsedData: {
        RawInstance* instance = reinterpret_cast<RawInstance*>(SP[-1]);
        ASSERT(!SP[0]->IsHeapObject());
        reinterpret_cast<RawObject**>(
            instance->ptr())[LinkedHashMap::used_data_offset() / kWordSize] =
            SP[0];
        *--SP = null_value;
      } break;
      case MethodRecognizer::kLinkedHashMap_getDeletedKeys: {
        RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
        SP[0] = reinterpret_cast<RawObject**>(
            instance->ptr())[LinkedHashMap::deleted_keys_offset() / kWordSize];
      } break;
      case MethodRecognizer::kLinkedHashMap_setDeletedKeys: {
        RawInstance* instance = reinterpret_cast<RawInstance*>(SP[-1]);
        ASSERT(!SP[0]->IsHeapObject());
        reinterpret_cast<RawObject**>(
            instance->ptr())[LinkedHashMap::deleted_keys_offset() / kWordSize] =
            SP[0];
        *--SP = null_value;
      } break;
      default: {
        NativeEntryData::Payload* payload =
            NativeEntryData::FromTypedArray(data);
        intptr_t argc_tag = NativeEntryData::GetArgcTag(data);
        const intptr_t num_arguments =
            NativeArguments::ArgcBits::decode(argc_tag);

        if (payload->trampoline == NULL) {
          ASSERT(payload->native_function == NULL);
          payload->trampoline = &NativeEntry::BootstrapNativeCallWrapper;
          payload->native_function =
              reinterpret_cast<NativeFunction>(&NativeEntry::LinkNativeCall);
        }

        *++SP = null_value;  // Result slot.

        RawObject** incoming_args = SP - num_arguments;
        RawObject** return_slot = SP;
        Exit(thread, FP, SP + 1, pc);
        NativeArguments args(thread, argc_tag, incoming_args, return_slot);
        INVOKE_NATIVE(
            payload->trampoline,
            reinterpret_cast<Dart_NativeFunction>(payload->native_function),
            reinterpret_cast<Dart_NativeArguments>(&args));

        *(SP - num_arguments) = *return_slot;
        SP -= num_arguments;
      }
    }
    DISPATCH();
  }

  // Return and return like instructions (Intrinsic).
  {
    RawObject* result;  // result to return to the caller.

    BYTECODE(ReturnTOS, 0);
    result = *SP;
    // Restore caller PC.
    pc = SavedCallerPC(FP);
    pc_ = reinterpret_cast<uword>(pc);  // For the profiler.

    // Check if it is a fake PC marking the entry frame.
    if (IsEntryFrameMarker(reinterpret_cast<uword>(pc))) {
      // Pop entry frame.
      fp_ = SavedCallerFP(FP);
      // Restore exit frame info saved in entry frame.
      pp_ = reinterpret_cast<RawObjectPool*>(fp_[kKBCSavedPpSlotFromEntryFp]);
      argdesc_ =
          reinterpret_cast<RawArray*>(fp_[kKBCSavedArgDescSlotFromEntryFp]);
      uword exit_fp = reinterpret_cast<uword>(fp_[kKBCExitLinkSlotFromEntryFp]);
      thread->set_top_exit_frame_info(exit_fp);
      thread->set_top_resource(top_resource);
      thread->set_vm_tag(vm_tag);
#if defined(DEBUG)
      if (IsTracingExecution()) {
        THR_Print("%" Pu64 " ", icount_);
        THR_Print("Returning from interpreter 0x%" Px " at fp_ 0x%" Px
                  " exit 0x%" Px "\n",
                  reinterpret_cast<uword>(this), reinterpret_cast<uword>(fp_),
                  exit_fp);
      }
      ASSERT(HasFrame(reinterpret_cast<uword>(fp_)));
      const intptr_t argc = reinterpret_cast<uword>(pc) >> 2;
      ASSERT(fp_ == FrameArguments(FP, argc + kKBCEntrySavedSlots));
      // Exception propagation should have been done.
      ASSERT(!result->IsHeapObject() ||
             result->GetClassId() != kUnhandledExceptionCid);
#endif
      return result;
    }

    // Look at the caller to determine how many arguments to pop.
    const uint8_t argc = KernelBytecode::DecodeArgc(pc[-1]);

    // Restore SP, FP and PP. Push result and dispatch.
    SP = FrameArguments(FP, argc);
    FP = SavedCallerFP(FP);
    fp_ = FP;  // For the profiler.
    pp_ = InterpreterHelpers::FrameBytecode(FP)->ptr()->object_pool_;
    *SP = result;
    DISPATCH();
  }

  {
    BYTECODE(StoreStaticTOS, A_D);
    RawField* field = reinterpret_cast<RawField*>(LOAD_CONSTANT(rD));
    RawInstance* value = static_cast<RawInstance*>(*SP--);
    field->StorePointer(&field->ptr()->value_.static_value_, value, thread);
    DISPATCH();
  }

  {
    BYTECODE(PushStatic, A_D);
    RawField* field = reinterpret_cast<RawField*>(LOAD_CONSTANT(rD));
    // Note: field is also on the stack, hence no increment.
    *SP = field->ptr()->value_.static_value_;
    DISPATCH();
  }

  {
    BYTECODE(StoreFieldTOS, __D);
    const uword offset_in_words =
        static_cast<uword>(Smi::Value(RAW_CAST(Smi, LOAD_CONSTANT(rD))));
    RawInstance* instance = reinterpret_cast<RawInstance*>(SP[-1]);
    RawObject* value = reinterpret_cast<RawObject*>(SP[0]);
    SP -= 2;  // Drop instance and value.

    // TODO(regis): Implement cid guard.
    ASSERT(!thread->isolate()->use_field_guards());

    instance->StorePointer(
        reinterpret_cast<RawObject**>(instance->ptr()) + offset_in_words, value,
        thread);

    DISPATCH();
  }

  {
    BYTECODE(StoreContextParent, 0);
    const uword offset_in_words =
        static_cast<uword>(Context::parent_offset() / kWordSize);
    RawContext* instance = reinterpret_cast<RawContext*>(SP[-1]);
    RawContext* value = reinterpret_cast<RawContext*>(SP[0]);
    SP -= 2;  // Drop instance and value.

    instance->StorePointer(
        reinterpret_cast<RawContext**>(instance->ptr()) + offset_in_words,
        value, thread);

    DISPATCH();
  }

  {
    BYTECODE(StoreContextVar, __D);
    const uword offset_in_words =
        static_cast<uword>(Context::variable_offset(rD) / kWordSize);
    RawContext* instance = reinterpret_cast<RawContext*>(SP[-1]);
    RawObject* value = reinterpret_cast<RawContext*>(SP[0]);
    SP -= 2;  // Drop instance and value.
    ASSERT(rD < static_cast<uint32_t>(instance->ptr()->num_variables_));
    instance->StorePointer(
        reinterpret_cast<RawObject**>(instance->ptr()) + offset_in_words, value,
        thread);

    DISPATCH();
  }

  {
    BYTECODE(LoadFieldTOS, __D);
    const uword offset_in_words =
        static_cast<uword>(Smi::Value(RAW_CAST(Smi, LOAD_CONSTANT(rD))));
    RawInstance* instance = static_cast<RawInstance*>(SP[0]);
    SP[0] = reinterpret_cast<RawObject**>(instance->ptr())[offset_in_words];
    DISPATCH();
  }

  {
    BYTECODE(LoadTypeArgumentsField, __D);
    const uword offset_in_words =
        static_cast<uword>(Smi::Value(RAW_CAST(Smi, LOAD_CONSTANT(rD))));
    RawInstance* instance = static_cast<RawInstance*>(SP[0]);
    SP[0] = reinterpret_cast<RawObject**>(instance->ptr())[offset_in_words];
    DISPATCH();
  }

  {
    BYTECODE(LoadContextParent, 0);
    const uword offset_in_words =
        static_cast<uword>(Context::parent_offset() / kWordSize);
    RawContext* instance = static_cast<RawContext*>(SP[0]);
    SP[0] = reinterpret_cast<RawObject**>(instance->ptr())[offset_in_words];
    DISPATCH();
  }

  {
    BYTECODE(LoadContextVar, __D);
    const uword offset_in_words =
        static_cast<uword>(Context::variable_offset(rD) / kWordSize);
    RawContext* instance = static_cast<RawContext*>(SP[0]);
    ASSERT(rD < static_cast<uint32_t>(instance->ptr()->num_variables_));
    SP[0] = reinterpret_cast<RawObject**>(instance->ptr())[offset_in_words];
    DISPATCH();
  }

  // TODO(vegorov) allocation bytecodes can benefit from the new-space
  // allocation fast-path that does not transition into the runtime system.
  {
    BYTECODE(AllocateContext, A_D);
    const uint16_t num_context_variables = rD;
    {
      *++SP = 0;
      SP[1] = Smi::New(num_context_variables);
      Exit(thread, FP, SP + 2, pc);
      NativeArguments args(thread, 1, SP + 1, SP);
      INVOKE_RUNTIME(DRT_AllocateContext, args);
    }
    DISPATCH();
  }

  {
    BYTECODE(CloneContext, A);
    {
      SP[1] = SP[0];  // Context to clone.
      Exit(thread, FP, SP + 2, pc);
      NativeArguments args(thread, 1, SP + 1, SP);
      INVOKE_RUNTIME(DRT_CloneContext, args);
    }
    DISPATCH();
  }

  {
    BYTECODE(Allocate, A_D);
    SP[1] = 0;                  // Space for the result.
    SP[2] = LOAD_CONSTANT(rD);  // Class object.
    SP[3] = null_value;         // Type arguments.
    Exit(thread, FP, SP + 4, pc);
    NativeArguments args(thread, 2, SP + 2, SP + 1);
    INVOKE_RUNTIME(DRT_AllocateObject, args);
    SP++;  // Result is in SP[1].
    DISPATCH();
  }

  {
    BYTECODE(AllocateT, 0);
    SP[1] = SP[-0];  // Class object.
    SP[2] = SP[-1];  // Type arguments
    Exit(thread, FP, SP + 3, pc);
    NativeArguments args(thread, 2, SP + 1, SP - 1);
    INVOKE_RUNTIME(DRT_AllocateObject, args);
    SP -= 1;  // Result is in SP - 1.
    DISPATCH();
  }

  {
    BYTECODE(CreateArrayTOS, 0);
    SP[1] = SP[-0];  // Length.
    SP[2] = SP[-1];  // Type.
    Exit(thread, FP, SP + 3, pc);
    NativeArguments args(thread, 2, SP + 1, SP - 1);
    INVOKE_RUNTIME(DRT_AllocateArray, args);
    SP -= 1;
    DISPATCH();
  }

  {
    BYTECODE(AssertAssignable, A_D);
    // Stack: instance, type, instantiator type args, function type args, name
    RawObject** args = SP - 4;
    const bool may_be_smi = (rA == 1);
    const bool is_smi =
        ((reinterpret_cast<intptr_t>(args[0]) & kSmiTagMask) == kSmiTag);
    const bool smi_ok = is_smi && may_be_smi;
    if (!smi_ok && (args[0] != null_value)) {
      RawSubtypeTestCache* cache =
          static_cast<RawSubtypeTestCache*>(LOAD_CONSTANT(rD));

      if (!AssertAssignable(thread, pc, FP, SP, args, cache)) {
        HANDLE_EXCEPTION;
      }
    }

    SP -= 4;  // Instance remains on stack.
    DISPATCH();
  }

  {
    BYTECODE(AssertSubtype, A);
    RawObject** args = SP - 4;

    // TODO(kustermann): Implement fast case for common arguments.

    // The arguments on the stack look like:
    //     args[0]  instantiator type args
    //     args[1]  function type args
    //     args[2]  sub_type
    //     args[3]  super_type
    //     args[4]  name

    // This is unused, since the negative case throws an exception.
    SP++;
    RawObject** result_slot = SP;

    Exit(thread, FP, SP + 1, pc);
    NativeArguments native_args(thread, 5, args, result_slot);
    INVOKE_RUNTIME(DRT_SubtypeCheck, native_args);

    // Result slot not used anymore.
    SP--;

    // Drop all arguments.
    SP -= 5;

    DISPATCH();
  }

  {
    BYTECODE(AssertBoolean, A);
    RawObject* value = SP[0];
    if (rA) {  // Should we perform type check?
      if ((value == true_value) || (value == false_value)) {
        goto AssertBooleanOk;
      }
    } else if (value != null_value) {
      goto AssertBooleanOk;
    }

    // Assertion failed.
    {
      SP[1] = SP[0];  // instance
      Exit(thread, FP, SP + 2, pc);
      NativeArguments args(thread, 1, SP + 1, SP);
      INVOKE_RUNTIME(DRT_NonBoolTypeError, args);
    }

  AssertBooleanOk:
    DISPATCH();
  }

  {
    BYTECODE(Jump, 0);
    LOAD_JUMP_TARGET();
    DISPATCH();
  }

  {
    BYTECODE(JumpIfNoAsserts, 0);
    if (!thread->isolate()->asserts()) {
      LOAD_JUMP_TARGET();
    }
    DISPATCH();
  }

  {
    BYTECODE(JumpIfNotZeroTypeArgs, 0);
    if (InterpreterHelpers::ArgDescTypeArgsLen(argdesc_) != 0) {
      LOAD_JUMP_TARGET();
    }
    DISPATCH();
  }

  {
    BYTECODE(JumpIfEqStrict, 0);
    SP -= 2;
    if (SP[1] == SP[2]) {
      LOAD_JUMP_TARGET();
    }
    DISPATCH();
  }

  {
    BYTECODE(JumpIfNeStrict, 0);
    SP -= 2;
    if (SP[1] != SP[2]) {
      LOAD_JUMP_TARGET();
    }
    DISPATCH();
  }

  {
    BYTECODE(JumpIfTrue, 0);
    SP -= 1;
    if (SP[1] == true_value) {
      LOAD_JUMP_TARGET();
    }
    DISPATCH();
  }

  {
    BYTECODE(JumpIfFalse, 0);
    SP -= 1;
    if (SP[1] == false_value) {
      LOAD_JUMP_TARGET();
    }
    DISPATCH();
  }

  {
    BYTECODE(JumpIfNull, 0);
    SP -= 1;
    if (SP[1] == null_value) {
      LOAD_JUMP_TARGET();
    }
    DISPATCH();
  }

  {
    BYTECODE(JumpIfNotNull, 0);
    SP -= 1;
    if (SP[1] != null_value) {
      LOAD_JUMP_TARGET();
    }
    DISPATCH();
  }

  {
    BYTECODE(StoreIndexedTOS, 0);
    SP -= 3;
    RawArray* array = RAW_CAST(Array, SP[1]);
    RawSmi* index = RAW_CAST(Smi, SP[2]);
    RawObject* value = SP[3];
    ASSERT(InterpreterHelpers::CheckIndex(index, array->ptr()->length_));
    array->StorePointer(array->ptr()->data() + Smi::Value(index), value,
                        thread);
    DISPATCH();
  }

  {
    BYTECODE(EqualsNull, 0);
    SP[0] = (SP[0] == null_value) ? true_value : false_value;
    DISPATCH();
  }

  {
    BYTECODE(NegateInt, 0);
    UNBOX_INT64(value, SP[0], Symbols::UnaryMinus());
    int64_t result = Utils::SubWithWrapAround(0, value);
    BOX_INT64_RESULT(result);
    DISPATCH();
  }

  {
    BYTECODE(AddInt, 0);
    SP -= 1;
    UNBOX_INT64(a, SP[0], Symbols::Plus());
    UNBOX_INT64(b, SP[1], Symbols::Plus());
    int64_t result = Utils::AddWithWrapAround(a, b);
    BOX_INT64_RESULT(result);
    DISPATCH();
  }

  {
    BYTECODE(SubInt, 0);
    SP -= 1;
    UNBOX_INT64(a, SP[0], Symbols::Minus());
    UNBOX_INT64(b, SP[1], Symbols::Minus());
    int64_t result = Utils::SubWithWrapAround(a, b);
    BOX_INT64_RESULT(result);
    DISPATCH();
  }

  {
    BYTECODE(MulInt, 0);
    SP -= 1;
    UNBOX_INT64(a, SP[0], Symbols::Star());
    UNBOX_INT64(b, SP[1], Symbols::Star());
    int64_t result = Utils::MulWithWrapAround(a, b);
    BOX_INT64_RESULT(result);
    DISPATCH();
  }

  {
    BYTECODE(TruncDivInt, 0);
    SP -= 1;
    UNBOX_INT64(a, SP[0], Symbols::TruncDivOperator());
    UNBOX_INT64(b, SP[1], Symbols::TruncDivOperator());
    if (UNLIKELY(b == 0)) {
      goto ThrowIntegerDivisionByZeroException;
    }
    int64_t result;
    if (UNLIKELY((a == Mint::kMinValue) && (b == -1))) {
      result = Mint::kMinValue;
    } else {
      result = a / b;
    }
    BOX_INT64_RESULT(result);
    DISPATCH();
  }

  {
    BYTECODE(ModInt, 0);
    SP -= 1;
    UNBOX_INT64(a, SP[0], Symbols::Percent());
    UNBOX_INT64(b, SP[1], Symbols::Percent());
    if (UNLIKELY(b == 0)) {
      goto ThrowIntegerDivisionByZeroException;
    }
    int64_t result;
    if (UNLIKELY((a == Mint::kMinValue) && (b == -1))) {
      result = 0;
    } else {
      result = a % b;
      if (result < 0) {
        if (b < 0) {
          result -= b;
        } else {
          result += b;
        }
      }
    }
    BOX_INT64_RESULT(result);
    DISPATCH();
  }

  {
    BYTECODE(BitAndInt, 0);
    SP -= 1;
    UNBOX_INT64(a, SP[0], Symbols::Ampersand());
    UNBOX_INT64(b, SP[1], Symbols::Ampersand());
    int64_t result = a & b;
    BOX_INT64_RESULT(result);
    DISPATCH();
  }

  {
    BYTECODE(BitOrInt, 0);
    SP -= 1;
    UNBOX_INT64(a, SP[0], Symbols::BitOr());
    UNBOX_INT64(b, SP[1], Symbols::BitOr());
    int64_t result = a | b;
    BOX_INT64_RESULT(result);
    DISPATCH();
  }

  {
    BYTECODE(BitXorInt, 0);
    SP -= 1;
    UNBOX_INT64(a, SP[0], Symbols::Caret());
    UNBOX_INT64(b, SP[1], Symbols::Caret());
    int64_t result = a ^ b;
    BOX_INT64_RESULT(result);
    DISPATCH();
  }

  {
    BYTECODE(ShlInt, 0);
    SP -= 1;
    UNBOX_INT64(a, SP[0], Symbols::LeftShiftOperator());
    UNBOX_INT64(b, SP[1], Symbols::LeftShiftOperator());
    if (b < 0) {
      SP[0] = SP[1];
      goto ThrowArgumentError;
    }
    int64_t result = Utils::ShiftLeftWithTruncation(a, b);
    BOX_INT64_RESULT(result);
    DISPATCH();
  }

  {
    BYTECODE(ShrInt, 0);
    SP -= 1;
    UNBOX_INT64(a, SP[0], Symbols::RightShiftOperator());
    UNBOX_INT64(b, SP[1], Symbols::RightShiftOperator());
    if (b < 0) {
      SP[0] = SP[1];
      goto ThrowArgumentError;
    }
    int64_t result = a >> Utils::Minimum<int64_t>(b, Mint::kBits);
    BOX_INT64_RESULT(result);
    DISPATCH();
  }

  {
    BYTECODE(CompareIntEq, 0);
    SP -= 1;
    if (SP[0] == SP[1]) {
      SP[0] = true_value;
    } else if (!SP[0]->IsHeapObject() || !SP[1]->IsHeapObject() ||
               (SP[0] == null_value) || (SP[1] == null_value)) {
      SP[0] = false_value;
    } else {
      int64_t a = Integer::GetInt64Value(RAW_CAST(Integer, SP[0]));
      int64_t b = Integer::GetInt64Value(RAW_CAST(Integer, SP[1]));
      SP[0] = (a == b) ? true_value : false_value;
    }
    DISPATCH();
  }

  {
    BYTECODE(CompareIntGt, 0);
    SP -= 1;
    UNBOX_INT64(a, SP[0], Symbols::RAngleBracket());
    UNBOX_INT64(b, SP[1], Symbols::RAngleBracket());
    SP[0] = (a > b) ? true_value : false_value;
    DISPATCH();
  }

  {
    BYTECODE(CompareIntLt, 0);
    SP -= 1;
    UNBOX_INT64(a, SP[0], Symbols::LAngleBracket());
    UNBOX_INT64(b, SP[1], Symbols::LAngleBracket());
    SP[0] = (a < b) ? true_value : false_value;
    DISPATCH();
  }

  {
    BYTECODE(CompareIntGe, 0);
    SP -= 1;
    UNBOX_INT64(a, SP[0], Symbols::GreaterEqualOperator());
    UNBOX_INT64(b, SP[1], Symbols::GreaterEqualOperator());
    SP[0] = (a >= b) ? true_value : false_value;
    DISPATCH();
  }

  {
    BYTECODE(CompareIntLe, 0);
    SP -= 1;
    UNBOX_INT64(a, SP[0], Symbols::LessEqualOperator());
    UNBOX_INT64(b, SP[1], Symbols::LessEqualOperator());
    SP[0] = (a <= b) ? true_value : false_value;
    DISPATCH();
  }

  {
    BYTECODE(Trap, 0);
    UNIMPLEMENTED();
    DISPATCH();
  }

  // Helper used to handle noSuchMethod on closures.
  {
  ClosureNoSuchMethod:
#if defined(DEBUG)
    function_h ^= FrameFunction(FP);
    ASSERT(function_h.IsNull() || function_h.IsClosureFunction());
#endif

    // Restore caller context as we are going to throw NoSuchMethod.
    pc = SavedCallerPC(FP);

    const bool has_dart_caller =
        !IsEntryFrameMarker(reinterpret_cast<uword>(pc));
    const intptr_t argc = has_dart_caller ? KernelBytecode::DecodeArgc(pc[-1])
                                          : (reinterpret_cast<uword>(pc) >> 2);
    const intptr_t type_args_len =
        InterpreterHelpers::ArgDescTypeArgsLen(argdesc_);
    const intptr_t receiver_idx = type_args_len > 0 ? 1 : 0;

    SP = FrameArguments(FP, 0);
    RawObject** args = SP - argc;
    FP = SavedCallerFP(FP);
    fp_ = FP;  // For the profiler.
    if (has_dart_caller) {
      pp_ = InterpreterHelpers::FrameBytecode(FP)->ptr()->object_pool_;
    }

    *++SP = null_value;
    *++SP = args[receiver_idx];  // Closure object.
    *++SP = argdesc_;
    *++SP = null_value;  // Array of arguments (will be filled).

    // Allocate array of arguments.
    {
      SP[1] = Smi::New(argc);  // length
      SP[2] = null_value;      // type
      Exit(thread, FP, SP + 3, pc);
      NativeArguments native_args(thread, 2, SP + 1, SP);
      if (!InvokeRuntime(thread, this, DRT_AllocateArray, native_args)) {
        HANDLE_EXCEPTION;
      } else if (has_dart_caller) {
        HANDLE_RETURN;
      }

      // Copy arguments into the newly allocated array.
      RawArray* array = static_cast<RawArray*>(SP[0]);
      ASSERT(array->GetClassId() == kArrayCid);
      for (intptr_t i = 0; i < argc; i++) {
        array->ptr()->data()[i] = args[i];
      }
    }

    // Invoke noSuchMethod passing down closure, argument descriptor and
    // array of arguments.
    {
      Exit(thread, FP, SP + 1, pc);
      NativeArguments native_args(thread, 3, SP - 2, SP - 3);
      INVOKE_RUNTIME(DRT_InvokeClosureNoSuchMethod, native_args);
      UNREACHABLE();
    }

    DISPATCH();
  }

  {
  ThrowNullError:
    // SP[0] contains selector.
    SP[1] = 0;  // Unused space for result.
    Exit(thread, FP, SP + 2, pc);
    NativeArguments args(thread, 1, SP, SP + 1);
    INVOKE_RUNTIME(DRT_NullErrorWithSelector, args);
    UNREACHABLE();
  }

  {
  ThrowIntegerDivisionByZeroException:
    SP[0] = 0;  // Unused space for result.
    Exit(thread, FP, SP + 1, pc);
    NativeArguments args(thread, 0, SP, SP);
    INVOKE_RUNTIME(DRT_IntegerDivisionByZeroException, args);
    UNREACHABLE();
  }

  {
  ThrowArgumentError:
    // SP[0] contains value.
    SP[1] = 0;  // Unused space for result.
    Exit(thread, FP, SP + 2, pc);
    NativeArguments args(thread, 1, SP, SP + 1);
    INVOKE_RUNTIME(DRT_ArgumentError, args);
    UNREACHABLE();
  }

  // Single dispatch point used by exception handling macros.
  {
  DispatchAfterException:
    pp_ = InterpreterHelpers::FrameBytecode(FP)->ptr()->object_pool_;
    DISPATCH();
  }

  UNREACHABLE();
  return 0;
}

void Interpreter::JumpToFrame(uword pc, uword sp, uword fp, Thread* thread) {
  // Walk over all setjmp buffers (simulated --> C++ transitions)
  // and try to find the setjmp associated with the simulated frame pointer.
  InterpreterSetjmpBuffer* buf = last_setjmp_buffer();
  while ((buf->link() != NULL) && (buf->link()->fp() > fp)) {
    buf = buf->link();
  }
  ASSERT(buf != NULL);
  ASSERT(last_setjmp_buffer() == buf);

  // The C++ caller has not cleaned up the stack memory of C++ frames.
  // Prepare for unwinding frames by destroying all the stack resources
  // in the previous C++ frames.
  StackResource::Unwind(thread);

  fp_ = reinterpret_cast<RawObject**>(fp);

  if (pc == StubCode::RunExceptionHandler().EntryPoint()) {
    // The RunExceptionHandler stub is a placeholder.  We implement
    // its behavior here.
    RawObject* raw_exception = thread->active_exception();
    RawObject* raw_stacktrace = thread->active_stacktrace();
    ASSERT(raw_exception != Object::null());
    thread->set_active_exception(Object::null_object());
    thread->set_active_stacktrace(Object::null_object());
    special_[KernelBytecode::kExceptionSpecialIndex] = raw_exception;
    special_[KernelBytecode::kStackTraceSpecialIndex] = raw_stacktrace;
    pc_ = thread->resume_pc();
  } else {
    pc_ = pc;
  }

  // Set the tag.
  thread->set_vm_tag(VMTag::kDartInterpretedTagId);
  // Clear top exit frame.
  thread->set_top_exit_frame_info(0);

  buf->Longjmp();
  UNREACHABLE();
}

void Interpreter::VisitObjectPointers(ObjectPointerVisitor* visitor) {
  visitor->VisitPointer(reinterpret_cast<RawObject**>(&pp_));
  visitor->VisitPointer(reinterpret_cast<RawObject**>(&argdesc_));
}

}  // namespace dart

#endif  // !defined(DART_PRECOMPILED_RUNTIME)
