// Copyright (c) 2013, 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 "include/dart_api.h"
#include "include/dart_native_api.h"

#include "lib/stacktrace.h"
#include "platform/assert.h"
#include "vm/class_finalizer.h"
#include "vm/clustered_snapshot.h"
#include "vm/compilation_trace.h"
#include "vm/compiler/jit/compiler.h"
#include "vm/dart.h"
#include "vm/dart_api_impl.h"
#include "vm/dart_api_message.h"
#include "vm/dart_api_state.h"
#include "vm/dart_entry.h"
#include "vm/debugger.h"
#if !defined(DART_PRECOMPILED_RUNTIME)
#include "vm/kernel_loader.h"
#endif
#include "vm/compiler/aot/precompiler.h"
#include "vm/exceptions.h"
#include "vm/flags.h"
#include "vm/growable_array.h"
#include "vm/image_snapshot.h"
#include "vm/isolate_reload.h"
#include "vm/kernel_isolate.h"
#include "vm/lockers.h"
#include "vm/message.h"
#include "vm/message_handler.h"
#include "vm/native_entry.h"
#include "vm/object.h"
#include "vm/object_store.h"
#include "vm/os.h"
#include "vm/os_thread.h"
#include "vm/port.h"
#include "vm/profiler.h"
#include "vm/program_visitor.h"
#include "vm/resolver.h"
#include "vm/reusable_handles.h"
#include "vm/service.h"
#include "vm/service_event.h"
#include "vm/service_isolate.h"
#include "vm/stack_frame.h"
#include "vm/symbols.h"
#include "vm/tags.h"
#include "vm/thread_registry.h"
#include "vm/timer.h"
#include "vm/unicode.h"
#include "vm/uri.h"
#include "vm/verifier.h"
#include "vm/version.h"

namespace dart {

// Facilitate quick access to the current zone once we have the current thread.
#define Z (T->zone())

DECLARE_FLAG(bool, print_class_table);
DECLARE_FLAG(bool, verify_handles);
#if defined(DART_NO_SNAPSHOT)
DEFINE_FLAG(bool,
            check_function_fingerprints,
            true,
            "Check function fingerprints");
#endif  // defined(DART_NO_SNAPSHOT).
DEFINE_FLAG(bool,
            verify_acquired_data,
            false,
            "Verify correct API acquire/release of typed data.");

ThreadLocalKey Api::api_native_key_ = kUnsetThreadLocalKey;
Dart_Handle Api::true_handle_ = NULL;
Dart_Handle Api::false_handle_ = NULL;
Dart_Handle Api::null_handle_ = NULL;
Dart_Handle Api::empty_string_handle_ = NULL;

const char* CanonicalFunction(const char* func) {
  if (strncmp(func, "dart::", 6) == 0) {
    return func + 6;
  } else {
    return func;
  }
}

#if defined(DEBUG)
// An object visitor which will iterate over all the function objects in the
// heap and check if the result type and parameter types are canonicalized
// or not. An assertion is raised if a type is not canonicalized.
class CheckFunctionTypesVisitor : public ObjectVisitor {
 public:
  explicit CheckFunctionTypesVisitor(Thread* thread)
      : classHandle_(Class::Handle(thread->zone())),
        funcHandle_(Function::Handle(thread->zone())),
        typeHandle_(AbstractType::Handle(thread->zone())) {}

  void VisitObject(RawObject* obj) {
    if (obj->IsFunction()) {
      funcHandle_ ^= obj;
      classHandle_ ^= funcHandle_.Owner();
      // Signature functions get created, but not canonicalized, when function
      // types get instantiated during run time type tests.
      if (funcHandle_.IsSignatureFunction()) {
        return;
      }
      // Verify that the result type of a function is canonical or a
      // TypeParameter.
      typeHandle_ ^= funcHandle_.result_type();
      ASSERT(typeHandle_.IsMalformed() || !typeHandle_.IsResolved() ||
             typeHandle_.IsTypeParameter() || typeHandle_.IsCanonical());
      // Verify that the types in the function signature are all canonical or
      // a TypeParameter.
      const intptr_t num_parameters = funcHandle_.NumParameters();
      for (intptr_t i = 0; i < num_parameters; i++) {
        typeHandle_ = funcHandle_.ParameterTypeAt(i);
        ASSERT(typeHandle_.IsMalformed() || !typeHandle_.IsResolved() ||
               typeHandle_.IsTypeParameter() || typeHandle_.IsCanonical());
      }
    }
  }

 private:
  Class& classHandle_;
  Function& funcHandle_;
  AbstractType& typeHandle_;
};
#endif  // #if defined(DEBUG).

static RawInstance* GetListInstance(Zone* zone, const Object& obj) {
  if (obj.IsInstance()) {
    const Library& core_lib = Library::Handle(zone, Library::CoreLibrary());
    const Class& list_class =
        Class::Handle(zone, core_lib.LookupClass(Symbols::List()));
    ASSERT(!list_class.IsNull());
    const Instance& instance = Instance::Cast(obj);
    const Class& obj_class = Class::Handle(zone, obj.clazz());
    Error& malformed_type_error = Error::Handle(zone);
    if (obj_class.IsSubtypeOf(Object::null_type_arguments(), list_class,
                              Object::null_type_arguments(),
                              &malformed_type_error, NULL, Heap::kNew)) {
      ASSERT(malformed_type_error.IsNull());  // Type is a raw List.
      return instance.raw();
    }
  }
  return Instance::null();
}

static RawInstance* GetMapInstance(Zone* zone, const Object& obj) {
  if (obj.IsInstance()) {
    const Library& core_lib = Library::Handle(zone, Library::CoreLibrary());
    const Class& map_class =
        Class::Handle(core_lib.LookupClass(Symbols::Map()));
    ASSERT(!map_class.IsNull());
    const Instance& instance = Instance::Cast(obj);
    const Class& obj_class = Class::Handle(zone, obj.clazz());
    Error& malformed_type_error = Error::Handle(zone);
    if (obj_class.IsSubtypeOf(Object::null_type_arguments(), map_class,
                              Object::null_type_arguments(),
                              &malformed_type_error, NULL, Heap::kNew)) {
      ASSERT(malformed_type_error.IsNull());  // Type is a raw Map.
      return instance.raw();
    }
  }
  return Instance::null();
}

static bool IsCompiletimeErrorObject(Zone* zone, const Object& obj) {
#if defined(DART_PRECOMPILED_RUNTIME)
  // All compile-time errors were handled at snapshot generation time and
  // compiletime_error_class was removed.
  return false;
#else
  Isolate* I = Thread::Current()->isolate();
  const Class& error_class =
      Class::Handle(zone, I->object_store()->compiletime_error_class());
  ASSERT(!error_class.IsNull());
  return (obj.GetClassId() == error_class.id());
#endif
}

static bool GetNativeStringArgument(NativeArguments* arguments,
                                    int arg_index,
                                    Dart_Handle* str,
                                    void** peer) {
  ASSERT(peer != NULL);
  if (Api::StringGetPeerHelper(arguments, arg_index, peer)) {
    *str = NULL;
    return true;
  }
  Thread* thread = arguments->thread();
  ASSERT(thread == Thread::Current());
  *peer = NULL;
  REUSABLE_OBJECT_HANDLESCOPE(thread);
  Object& obj = thread->ObjectHandle();
  obj = arguments->NativeArgAt(arg_index);
  if (RawObject::IsStringClassId(obj.GetClassId())) {
    ASSERT(thread->api_top_scope() != NULL);
    *str = Api::NewHandle(thread, obj.raw());
    return true;
  }
  if (obj.IsNull()) {
    *str = Api::Null();
    return true;
  }
  return false;
}

static bool GetNativeIntegerArgument(NativeArguments* arguments,
                                     int arg_index,
                                     int64_t* value) {
  ASSERT(value != NULL);
  return Api::GetNativeIntegerArgument(arguments, arg_index, value);
}

static bool GetNativeUnsignedIntegerArgument(NativeArguments* arguments,
                                             int arg_index,
                                             uint64_t* value) {
  ASSERT(value != NULL);
  int64_t arg_value = 0;
  if (Api::GetNativeIntegerArgument(arguments, arg_index, &arg_value)) {
    *value = static_cast<uint64_t>(arg_value);
    return true;
  }
  return false;
}

static bool GetNativeDoubleArgument(NativeArguments* arguments,
                                    int arg_index,
                                    double* value) {
  ASSERT(value != NULL);
  return Api::GetNativeDoubleArgument(arguments, arg_index, value);
}

static Dart_Handle GetNativeFieldsOfArgument(NativeArguments* arguments,
                                             int arg_index,
                                             int num_fields,
                                             intptr_t* field_values,
                                             const char* current_func) {
  ASSERT(field_values != NULL);
  if (Api::GetNativeFieldsOfArgument(arguments, arg_index, num_fields,
                                     field_values)) {
    return Api::Success();
  }
  Thread* thread = arguments->thread();
  ASSERT(thread == Thread::Current());
  REUSABLE_OBJECT_HANDLESCOPE(thread);
  Object& obj = thread->ObjectHandle();
  obj = arguments->NativeArgAt(arg_index);
  if (obj.IsNull()) {
    memset(field_values, 0, (num_fields * sizeof(field_values[0])));
    return Api::Success();
  }
  // We did not succeed in extracting the native fields report the
  // appropriate error.
  if (!obj.IsInstance()) {
    return Api::NewError(
        "%s expects argument at index '%d' to be of"
        " type Instance.",
        current_func, arg_index);
  }
  const Instance& instance = Instance::Cast(obj);
  int field_count = instance.NumNativeFields();
  ASSERT(num_fields != field_count);
  return Api::NewError("%s: expected %d 'num_fields' but was passed in %d.",
                       current_func, field_count, num_fields);
}

Heap::Space SpaceForExternal(Thread* thread, intptr_t size) {
  Heap* heap = thread->heap();
  // If 'size' would be a significant fraction of new space, then use old.
  static const int kExtNewRatio = 16;
  if (size > (heap->CapacityInWords(Heap::kNew) * kWordSize) / kExtNewRatio) {
    return Heap::kOld;
  } else {
    return Heap::kNew;
  }
}

static RawObject* Send0Arg(const Instance& receiver, const String& selector) {
  const intptr_t kTypeArgsLen = 0;
  const intptr_t kNumArgs = 1;
  ArgumentsDescriptor args_desc(
      Array::Handle(ArgumentsDescriptor::New(kTypeArgsLen, kNumArgs)));
  const Function& function =
      Function::Handle(Resolver::ResolveDynamic(receiver, selector, args_desc));
  if (function.IsNull()) {
    return ApiError::New(String::Handle(String::New("")));
  }
  const Array& args = Array::Handle(Array::New(kNumArgs));
  args.SetAt(0, receiver);
  return DartEntry::InvokeFunction(function, args);
}

static RawObject* Send1Arg(const Instance& receiver,
                           const String& selector,
                           const Instance& argument) {
  const intptr_t kTypeArgsLen = 0;
  const intptr_t kNumArgs = 2;
  ArgumentsDescriptor args_desc(
      Array::Handle(ArgumentsDescriptor::New(kTypeArgsLen, kNumArgs)));
  const Function& function =
      Function::Handle(Resolver::ResolveDynamic(receiver, selector, args_desc));
  if (function.IsNull()) {
    return ApiError::New(String::Handle(String::New("")));
  }
  const Array& args = Array::Handle(Array::New(kNumArgs));
  args.SetAt(0, receiver);
  args.SetAt(1, argument);
  return DartEntry::InvokeFunction(function, args);
}

static const char* GetErrorString(Thread* thread, const Object& obj) {
  // This function requires an API scope to be present.
  if (obj.IsError()) {
    ASSERT(thread->api_top_scope() != NULL);
    const Error& error = Error::Cast(obj);
    const char* str = error.ToErrorCString();
    intptr_t len = strlen(str) + 1;
    char* str_copy = Api::TopScope(thread)->zone()->Alloc<char>(len);
    strncpy(str_copy, str, len);
    // Strip a possible trailing '\n'.
    if ((len > 1) && (str_copy[len - 2] == '\n')) {
      str_copy[len - 2] = '\0';
    }
    return str_copy;
  } else {
    return "";
  }
}

Dart_Handle Api::InitNewHandle(Thread* thread, RawObject* raw) {
  LocalHandles* local_handles = Api::TopScope(thread)->local_handles();
  ASSERT(local_handles != NULL);
  LocalHandle* ref = local_handles->AllocateHandle();
  ref->set_raw(raw);
  return ref->apiHandle();
}

Dart_Handle Api::NewHandle(Thread* thread, RawObject* raw) {
  if (raw == Object::null()) {
    return Null();
  }
  if (raw == Bool::True().raw()) {
    return True();
  }
  if (raw == Bool::False().raw()) {
    return False();
  }
  return InitNewHandle(thread, raw);
}

RawObject* Api::UnwrapHandle(Dart_Handle object) {
#if defined(DEBUG)
  Thread* thread = Thread::Current();
  ASSERT(thread->IsMutatorThread());
  ASSERT(thread->isolate() != NULL);
  ASSERT(!FLAG_verify_handles || thread->IsValidLocalHandle(object) ||
         thread->isolate()->api_state()->IsActivePersistentHandle(
             reinterpret_cast<Dart_PersistentHandle>(object)) ||
         Dart::IsReadOnlyApiHandle(object));
  ASSERT(FinalizablePersistentHandle::raw_offset() == 0 &&
         PersistentHandle::raw_offset() == 0 && LocalHandle::raw_offset() == 0);
#endif
  return (reinterpret_cast<LocalHandle*>(object))->raw();
}

#define DEFINE_UNWRAP(type)                                                    \
  const type& Api::Unwrap##type##Handle(Zone* zone, Dart_Handle dart_handle) { \
    const Object& obj = Object::Handle(zone, Api::UnwrapHandle(dart_handle));  \
    if (obj.Is##type()) {                                                      \
      return type::Cast(obj);                                                  \
    }                                                                          \
    return type::Handle(zone);                                                 \
  }
CLASS_LIST_FOR_HANDLES(DEFINE_UNWRAP)
#undef DEFINE_UNWRAP

const String& Api::UnwrapStringHandle(const ReusableObjectHandleScope& reuse,
                                      Dart_Handle dart_handle) {
  Object& ref = reuse.Handle();
  ref = Api::UnwrapHandle(dart_handle);
  if (ref.IsString()) {
    return String::Cast(ref);
  }
  return Object::null_string();
}

const Instance& Api::UnwrapInstanceHandle(
    const ReusableObjectHandleScope& reuse,
    Dart_Handle dart_handle) {
  Object& ref = reuse.Handle();
  ref = Api::UnwrapHandle(dart_handle);
  if (ref.IsInstance()) {
    return Instance::Cast(ref);
  }
  return Object::null_instance();
}

Dart_Handle Api::CheckAndFinalizePendingClasses(Thread* thread) {
  Isolate* isolate = thread->isolate();
  if (!isolate->AllowClassFinalization()) {
    // Class finalization is blocked for the isolate. Do nothing.
    return Api::Success();
  }
  if (ClassFinalizer::ProcessPendingClasses()) {
    return Api::Success();
  }
  ASSERT(thread->sticky_error() != Object::null());
  return Api::NewHandle(thread, thread->sticky_error());
}

Dart_Isolate Api::CastIsolate(Isolate* isolate) {
  return reinterpret_cast<Dart_Isolate>(isolate);
}

Dart_Handle Api::NewError(const char* format, ...) {
  Thread* T = Thread::Current();
  CHECK_API_SCOPE(T);
  HANDLESCOPE(T);
  CHECK_CALLBACK_STATE(T);
  // Ensure we transition safepoint state to VM if we are not already in
  // that state.
  TransitionToVM transition(T);

  va_list args;
  va_start(args, format);
  intptr_t len = Utils::VSNPrint(NULL, 0, format, args);
  va_end(args);

  char* buffer = Z->Alloc<char>(len + 1);
  va_list args2;
  va_start(args2, format);
  Utils::VSNPrint(buffer, (len + 1), format, args2);
  va_end(args2);

  const String& message = String::Handle(Z, String::New(buffer));
  return Api::NewHandle(T, ApiError::New(message));
}

void Api::SetupAcquiredError(Isolate* isolate) {
  ASSERT(isolate != NULL);
  ApiState* state = isolate->api_state();
  ASSERT(state != NULL);
  state->SetupAcquiredError();
}

Dart_Handle Api::AcquiredError(Isolate* isolate) {
  ASSERT(isolate != NULL);
  ApiState* state = isolate->api_state();
  ASSERT(state != NULL);
  PersistentHandle* acquired_error_handle = state->AcquiredError();
  return reinterpret_cast<Dart_Handle>(acquired_error_handle);
}

bool Api::IsValid(Dart_Handle handle) {
  Isolate* isolate = Isolate::Current();
  Thread* thread = Thread::Current();
  ASSERT(thread->IsMutatorThread());
  CHECK_ISOLATE(isolate);

  // Check against all of the handles in the current isolate as well as the
  // read-only handles.
  return thread->IsValidHandle(handle) ||
         isolate->api_state()->IsActivePersistentHandle(
             reinterpret_cast<Dart_PersistentHandle>(handle)) ||
         isolate->api_state()->IsActiveWeakPersistentHandle(
             reinterpret_cast<Dart_WeakPersistentHandle>(handle)) ||
         Dart::IsReadOnlyApiHandle(handle) ||
         Dart::IsReadOnlyHandle(reinterpret_cast<uword>(handle));
}

ApiLocalScope* Api::TopScope(Thread* thread) {
  ASSERT(thread != NULL);
  ApiLocalScope* scope = thread->api_top_scope();
  ASSERT(scope != NULL);
  return scope;
}

void Api::InitOnce() {
  ASSERT(api_native_key_ == kUnsetThreadLocalKey);
  api_native_key_ = OSThread::CreateThreadLocal();
  ASSERT(api_native_key_ != kUnsetThreadLocalKey);
}

static Dart_Handle InitNewReadOnlyApiHandle(RawObject* raw) {
  ASSERT(raw->IsVMHeapObject());
  LocalHandle* ref = Dart::AllocateReadOnlyApiHandle();
  ref->set_raw(raw);
  return ref->apiHandle();
}

void Api::InitHandles() {
  Isolate* isolate = Isolate::Current();
  ASSERT(isolate != NULL);
  ASSERT(isolate == Dart::vm_isolate());
  ApiState* state = isolate->api_state();
  ASSERT(state != NULL);

  ASSERT(true_handle_ == NULL);
  true_handle_ = InitNewReadOnlyApiHandle(Bool::True().raw());

  ASSERT(false_handle_ == NULL);
  false_handle_ = InitNewReadOnlyApiHandle(Bool::False().raw());

  ASSERT(null_handle_ == NULL);
  null_handle_ = InitNewReadOnlyApiHandle(Object::null());

  ASSERT(empty_string_handle_ == NULL);
  empty_string_handle_ = InitNewReadOnlyApiHandle(Symbols::Empty().raw());
}

bool Api::StringGetPeerHelper(NativeArguments* arguments,
                              int arg_index,
                              void** peer) {
  NoSafepointScope no_safepoint_scope;
  RawObject* raw_obj = arguments->NativeArgAt(arg_index);
  if (!raw_obj->IsHeapObject()) {
    return false;
  }
  intptr_t cid = raw_obj->GetClassId();
  if (cid == kExternalOneByteStringCid) {
    RawExternalOneByteString* raw_string =
        reinterpret_cast<RawExternalOneByteString*>(raw_obj);
    *peer = raw_string->ptr()->peer_;
    return true;
  }
  if (cid == kOneByteStringCid || cid == kTwoByteStringCid) {
    Isolate* isolate = arguments->thread()->isolate();
    *peer = isolate->heap()->GetPeer(raw_obj);
    return (*peer != 0);
  }
  if (cid == kExternalTwoByteStringCid) {
    RawExternalTwoByteString* raw_string =
        reinterpret_cast<RawExternalTwoByteString*>(raw_obj);
    *peer = raw_string->ptr()->peer_;
    return true;
  }
  return false;
}

bool Api::GetNativeReceiver(NativeArguments* arguments, intptr_t* value) {
  NoSafepointScope no_safepoint_scope;
  RawObject* raw_obj = arguments->NativeArg0();
  if (raw_obj->IsHeapObject()) {
    intptr_t cid = raw_obj->GetClassId();
    if (cid >= kNumPredefinedCids) {
      ASSERT(Instance::Cast(Object::Handle(raw_obj)).IsValidNativeIndex(0));
      RawTypedData* native_fields = *reinterpret_cast<RawTypedData**>(
          RawObject::ToAddr(raw_obj) + sizeof(RawObject));
      if (native_fields == TypedData::null()) {
        *value = 0;
      } else {
        *value = *bit_cast<intptr_t*, uint8_t*>(native_fields->ptr()->data());
      }
      return true;
    }
  }
  return false;
}

bool Api::GetNativeBooleanArgument(NativeArguments* arguments,
                                   int arg_index,
                                   bool* value) {
  NoSafepointScope no_safepoint_scope;
  RawObject* raw_obj = arguments->NativeArgAt(arg_index);
  if (raw_obj->IsHeapObject()) {
    intptr_t cid = raw_obj->GetClassId();
    if (cid == kBoolCid) {
      *value = (raw_obj == Object::bool_true().raw());
      return true;
    }
    if (cid == kNullCid) {
      *value = false;
      return true;
    }
  }
  return false;
}

bool Api::GetNativeIntegerArgument(NativeArguments* arguments,
                                   int arg_index,
                                   int64_t* value) {
  NoSafepointScope no_safepoint_scope;
  RawObject* raw_obj = arguments->NativeArgAt(arg_index);
  if (raw_obj->IsHeapObject()) {
    intptr_t cid = raw_obj->GetClassId();
    if (cid == kMintCid) {
      *value = reinterpret_cast<RawMint*>(raw_obj)->ptr()->value_;
      return true;
    }
    return false;
  }
  *value = Smi::Value(reinterpret_cast<RawSmi*>(raw_obj));
  return true;
}

bool Api::GetNativeDoubleArgument(NativeArguments* arguments,
                                  int arg_index,
                                  double* value) {
  NoSafepointScope no_safepoint_scope;
  RawObject* raw_obj = arguments->NativeArgAt(arg_index);
  if (raw_obj->IsHeapObject()) {
    intptr_t cid = raw_obj->GetClassId();
    if (cid == kDoubleCid) {
      *value = reinterpret_cast<RawDouble*>(raw_obj)->ptr()->value_;
      return true;
    }
    if (cid == kMintCid) {
      *value = static_cast<double>(
          reinterpret_cast<RawMint*>(raw_obj)->ptr()->value_);
      return true;
    }
    return false;
  }
  *value = static_cast<double>(Smi::Value(reinterpret_cast<RawSmi*>(raw_obj)));
  return true;
}

bool Api::GetNativeFieldsOfArgument(NativeArguments* arguments,
                                    int arg_index,
                                    int num_fields,
                                    intptr_t* field_values) {
  NoSafepointScope no_safepoint_scope;
  RawObject* raw_obj = arguments->NativeArgAt(arg_index);
  if (raw_obj->IsHeapObject()) {
    intptr_t cid = raw_obj->GetClassId();
    if (cid >= kNumPredefinedCids) {
      RawTypedData* native_fields = *reinterpret_cast<RawTypedData**>(
          RawObject::ToAddr(raw_obj) + sizeof(RawObject));
      if (native_fields == TypedData::null()) {
        memset(field_values, 0, (num_fields * sizeof(field_values[0])));
      } else if (num_fields == Smi::Value(native_fields->ptr()->length_)) {
        intptr_t* native_values =
            bit_cast<intptr_t*, uint8_t*>(native_fields->ptr()->data());
        memmove(field_values, native_values,
                (num_fields * sizeof(field_values[0])));
      }
      return true;
    }
  }
  return false;
}

void Api::SetWeakHandleReturnValue(NativeArguments* args,
                                   Dart_WeakPersistentHandle retval) {
  args->SetReturnUnsafe(FinalizablePersistentHandle::Cast(retval)->raw());
}

PersistentHandle* PersistentHandle::Cast(Dart_PersistentHandle handle) {
  ASSERT(Isolate::Current()->api_state()->IsValidPersistentHandle(handle));
  return reinterpret_cast<PersistentHandle*>(handle);
}

FinalizablePersistentHandle* FinalizablePersistentHandle::Cast(
    Dart_WeakPersistentHandle handle) {
#if defined(DEBUG)
  ApiState* state = Isolate::Current()->api_state();
  ASSERT(state->IsValidWeakPersistentHandle(handle));
#endif
  return reinterpret_cast<FinalizablePersistentHandle*>(handle);
}

void FinalizablePersistentHandle::Finalize(
    Isolate* isolate,
    FinalizablePersistentHandle* handle) {
  if (!handle->raw()->IsHeapObject()) {
    return;  // Free handle.
  }
  Dart_WeakPersistentHandleFinalizer callback = handle->callback();
  ASSERT(callback != NULL);
  void* peer = handle->peer();
  Dart_WeakPersistentHandle object = handle->apiHandle();
  (*callback)(isolate->init_callback_data(), object, peer);
  ApiState* state = isolate->api_state();
  ASSERT(state != NULL);
  state->weak_persistent_handles().FreeHandle(handle);
}

// --- Handles ---

DART_EXPORT bool Dart_IsError(Dart_Handle handle) {
  return Api::IsError(handle);
}

DART_EXPORT bool Dart_IsApiError(Dart_Handle object) {
  return Api::ClassId(object) == kApiErrorCid;
}

DART_EXPORT bool Dart_IsUnhandledExceptionError(Dart_Handle object) {
  return Api::ClassId(object) == kUnhandledExceptionCid;
}

DART_EXPORT bool Dart_IsCompilationError(Dart_Handle object) {
  if (::Dart_IsUnhandledExceptionError(object)) {
    DARTSCOPE(Thread::Current());
    const UnhandledException& error =
        UnhandledException::Cast(Object::Handle(Z, Api::UnwrapHandle(object)));
    const Instance& exc = Instance::Handle(Z, error.exception());
    return IsCompiletimeErrorObject(Z, exc);
  }
  return Api::ClassId(object) == kLanguageErrorCid;
}

DART_EXPORT bool Dart_IsFatalError(Dart_Handle object) {
  return Api::ClassId(object) == kUnwindErrorCid;
}

DART_EXPORT const char* Dart_GetError(Dart_Handle handle) {
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  const Object& obj = Object::Handle(Z, Api::UnwrapHandle(handle));
  return GetErrorString(T, obj);
}

DART_EXPORT bool Dart_ErrorHasException(Dart_Handle handle) {
  DARTSCOPE(Thread::Current());
  const Object& obj = Object::Handle(Z, Api::UnwrapHandle(handle));
  return obj.IsUnhandledException();
}

DART_EXPORT Dart_Handle Dart_ErrorGetException(Dart_Handle handle) {
  DARTSCOPE(Thread::Current());
  const Object& obj = Object::Handle(Z, Api::UnwrapHandle(handle));
  if (obj.IsUnhandledException()) {
    const UnhandledException& error = UnhandledException::Cast(obj);
    return Api::NewHandle(T, error.exception());
  } else if (obj.IsError()) {
    return Api::NewError("This error is not an unhandled exception error.");
  } else {
    return Api::NewError("Can only get exceptions from error handles.");
  }
}

DART_EXPORT Dart_Handle Dart_ErrorGetStackTrace(Dart_Handle handle) {
  DARTSCOPE(Thread::Current());
  const Object& obj = Object::Handle(Z, Api::UnwrapHandle(handle));
  if (obj.IsUnhandledException()) {
    const UnhandledException& error = UnhandledException::Cast(obj);
    return Api::NewHandle(T, error.stacktrace());
  } else if (obj.IsError()) {
    return Api::NewError("This error is not an unhandled exception error.");
  } else {
    return Api::NewError("Can only get stacktraces from error handles.");
  }
}

DART_EXPORT Dart_Handle Dart_NewApiError(const char* error) {
  DARTSCOPE(Thread::Current());
  CHECK_CALLBACK_STATE(T);

  const String& message = String::Handle(Z, String::New(error));
  return Api::NewHandle(T, ApiError::New(message));
}

DART_EXPORT Dart_Handle Dart_NewCompilationError(const char* error) {
  DARTSCOPE(Thread::Current());
  CHECK_CALLBACK_STATE(T);

  const String& message = String::Handle(Z, String::New(error));
  return Api::NewHandle(T, LanguageError::New(message));
}

DART_EXPORT Dart_Handle Dart_NewUnhandledExceptionError(Dart_Handle exception) {
  DARTSCOPE(Thread::Current());
  CHECK_CALLBACK_STATE(T);

  Instance& obj = Instance::Handle(Z);
  intptr_t class_id = Api::ClassId(exception);
  if ((class_id == kApiErrorCid) || (class_id == kLanguageErrorCid)) {
    const Object& excp = Object::Handle(Z, Api::UnwrapHandle(exception));
    obj = String::New(GetErrorString(T, excp));
  } else {
    obj = Api::UnwrapInstanceHandle(Z, exception).raw();
    if (obj.IsNull()) {
      RETURN_TYPE_ERROR(Z, exception, Instance);
    }
  }
  const StackTrace& stacktrace = StackTrace::Handle(Z);
  return Api::NewHandle(T, UnhandledException::New(obj, stacktrace));
}

DART_EXPORT Dart_Handle Dart_PropagateError(Dart_Handle handle) {
  Thread* thread = Thread::Current();
  TransitionNativeToVM transition(thread);
  const Object& obj = Object::Handle(thread->zone(), Api::UnwrapHandle(handle));
  if (!obj.IsError()) {
    return Api::NewError(
        "%s expects argument 'handle' to be an error handle.  "
        "Did you forget to check Dart_IsError first?",
        CURRENT_FUNC);
  }
  if (thread->top_exit_frame_info() == 0) {
    // There are no dart frames on the stack so it would be illegal to
    // propagate an error here.
    return Api::NewError("No Dart frames on stack, cannot propagate error.");
  }
  // Unwind all the API scopes till the exit frame before propagating.
  const Error* error;
  {
    // We need to preserve the error object across the destruction of zones
    // when the ApiScopes are unwound.  By using NoSafepointScope, we can ensure
    // that GC won't touch the raw error object before creating a valid
    // handle for it in the surviving zone.
    NoSafepointScope no_safepoint;
    RawError* raw_error = Api::UnwrapErrorHandle(thread->zone(), handle).raw();
    thread->UnwindScopes(thread->top_exit_frame_info());
    // Note that thread's zone is different here than at the beginning of this
    // function.
    error = &Error::Handle(thread->zone(), raw_error);
  }
  Exceptions::PropagateError(*error);
  UNREACHABLE();
  return Api::NewError("Cannot reach here.  Internal error.");
}

DART_EXPORT void _Dart_ReportErrorHandle(const char* file,
                                         int line,
                                         const char* handle,
                                         const char* message) {
  fprintf(stderr, "%s:%d: error handle: '%s':\n    '%s'\n", file, line, handle,
          message);
  OS::Abort();
}

DART_EXPORT Dart_Handle Dart_ToString(Dart_Handle object) {
  DARTSCOPE(Thread::Current());
  const Object& obj = Object::Handle(Z, Api::UnwrapHandle(object));
  if (obj.IsString()) {
    return Api::NewHandle(T, obj.raw());
  } else if (obj.IsInstance()) {
    CHECK_CALLBACK_STATE(T);
    const Instance& receiver = Instance::Cast(obj);
    return Api::NewHandle(T, DartLibraryCalls::ToString(receiver));
  } else {
    CHECK_CALLBACK_STATE(T);
    // This is a VM internal object. Call the C++ method of printing.
    return Api::NewHandle(T, String::New(obj.ToCString()));
  }
}

DART_EXPORT bool Dart_IdentityEquals(Dart_Handle obj1, Dart_Handle obj2) {
  DARTSCOPE(Thread::Current());
  {
    NoSafepointScope no_safepoint_scope;
    if (Api::UnwrapHandle(obj1) == Api::UnwrapHandle(obj2)) {
      return true;
    }
  }
  const Object& object1 = Object::Handle(Z, Api::UnwrapHandle(obj1));
  const Object& object2 = Object::Handle(Z, Api::UnwrapHandle(obj2));
  if (object1.IsInstance() && object2.IsInstance()) {
    return Instance::Cast(object1).IsIdenticalTo(Instance::Cast(object2));
  }
  return false;
}

DART_EXPORT Dart_Handle
Dart_HandleFromPersistent(Dart_PersistentHandle object) {
  Thread* thread = Thread::Current();
  Isolate* isolate = thread->isolate();
  CHECK_ISOLATE(isolate);
  NoSafepointScope no_safepoint_scope;
  ApiState* state = isolate->api_state();
  ASSERT(state != NULL);
  PersistentHandle* ref = PersistentHandle::Cast(object);
  return Api::NewHandle(thread, ref->raw());
}

DART_EXPORT Dart_Handle
Dart_HandleFromWeakPersistent(Dart_WeakPersistentHandle object) {
  Thread* thread = Thread::Current();
  Isolate* isolate = thread->isolate();
  CHECK_ISOLATE(isolate);
  NoSafepointScope no_safepoint_scope;
  ApiState* state = isolate->api_state();
  ASSERT(state != NULL);
  FinalizablePersistentHandle* weak_ref =
      FinalizablePersistentHandle::Cast(object);
  return Api::NewHandle(thread, weak_ref->raw());
}

DART_EXPORT Dart_PersistentHandle Dart_NewPersistentHandle(Dart_Handle object) {
  DARTSCOPE(Thread::Current());
  Isolate* I = T->isolate();
  ApiState* state = I->api_state();
  ASSERT(state != NULL);
  const Object& old_ref = Object::Handle(Z, Api::UnwrapHandle(object));
  PersistentHandle* new_ref = state->persistent_handles().AllocateHandle();
  new_ref->set_raw(old_ref);
  return new_ref->apiHandle();
}

DART_EXPORT void Dart_SetPersistentHandle(Dart_PersistentHandle obj1,
                                          Dart_Handle obj2) {
  DARTSCOPE(Thread::Current());
  Isolate* I = T->isolate();
  ApiState* state = I->api_state();
  ASSERT(state != NULL);
  ASSERT(state->IsValidPersistentHandle(obj1));
  const Object& obj2_ref = Object::Handle(Z, Api::UnwrapHandle(obj2));
  PersistentHandle* obj1_ref = PersistentHandle::Cast(obj1);
  obj1_ref->set_raw(obj2_ref);
}

static Dart_WeakPersistentHandle AllocateFinalizableHandle(
    Thread* thread,
    const Object& ref,
    void* peer,
    intptr_t external_allocation_size,
    Dart_WeakPersistentHandleFinalizer callback) {
  if (!ref.raw()->IsHeapObject()) {
    return NULL;
  }
  FinalizablePersistentHandle* finalizable_ref =
      FinalizablePersistentHandle::New(thread->isolate(), ref, peer, callback,
                                       external_allocation_size);
  return finalizable_ref->apiHandle();
}

static Dart_WeakPersistentHandle AllocateFinalizableHandle(
    Thread* thread,
    Dart_Handle object,
    void* peer,
    intptr_t external_allocation_size,
    Dart_WeakPersistentHandleFinalizer callback) {
  REUSABLE_OBJECT_HANDLESCOPE(thread);
  Object& ref = thread->ObjectHandle();
  ref = Api::UnwrapHandle(object);
  return AllocateFinalizableHandle(thread, ref, peer, external_allocation_size,
                                   callback);
}

DART_EXPORT Dart_WeakPersistentHandle
Dart_NewWeakPersistentHandle(Dart_Handle object,
                             void* peer,
                             intptr_t external_allocation_size,
                             Dart_WeakPersistentHandleFinalizer callback) {
  Thread* thread = Thread::Current();
  CHECK_ISOLATE(thread->isolate());
  if (callback == NULL) {
    return NULL;
  }
  TransitionNativeToVM transition(thread);
  return AllocateFinalizableHandle(thread, object, peer,
                                   external_allocation_size, callback);
}

DART_EXPORT void Dart_DeletePersistentHandle(Dart_PersistentHandle object) {
  Isolate* isolate = Isolate::Current();
  CHECK_ISOLATE(isolate);
  NoSafepointScope no_safepoint_scope;
  ApiState* state = isolate->api_state();
  ASSERT(state != NULL);
  PersistentHandle* ref = PersistentHandle::Cast(object);
  ASSERT(!state->IsProtectedHandle(ref));
  if (!state->IsProtectedHandle(ref)) {
    state->persistent_handles().FreeHandle(ref);
  }
}

DART_EXPORT void Dart_DeleteWeakPersistentHandle(
    Dart_Isolate current_isolate,
    Dart_WeakPersistentHandle object) {
  Isolate* isolate = reinterpret_cast<Isolate*>(current_isolate);
  CHECK_ISOLATE(isolate);
  NoSafepointScope no_safepoint_scope;
  ASSERT(isolate == Isolate::Current());
  ApiState* state = isolate->api_state();
  ASSERT(state != NULL);
  FinalizablePersistentHandle* weak_ref =
      FinalizablePersistentHandle::Cast(object);
  weak_ref->EnsureFreeExternal(isolate);
  state->weak_persistent_handles().FreeHandle(weak_ref);
}

// --- Initialization and Globals ---

DART_EXPORT const char* Dart_VersionString() {
  return Version::String();
}

DART_EXPORT char* Dart_Initialize(Dart_InitializeParams* params) {
  if (params == NULL) {
    return strdup(
        "Dart_Initialize: "
        "Dart_InitializeParams is null.");
  }

  if (params->version != DART_INITIALIZE_PARAMS_CURRENT_VERSION) {
    return strdup(
        "Dart_Initialize: "
        "Invalid Dart_InitializeParams version.");
  }

  return Dart::InitOnce(
      params->vm_snapshot_data, params->vm_snapshot_instructions,
      params->create, params->shutdown, params->cleanup, params->thread_exit,
      params->file_open, params->file_read, params->file_write,
      params->file_close, params->entropy_source, params->get_service_assets,
      params->start_kernel_isolate);
}

DART_EXPORT char* Dart_Cleanup() {
  CHECK_NO_ISOLATE(Isolate::Current());
  const char* err_msg = Dart::Cleanup();
  if (err_msg != NULL) {
    return strdup(err_msg);
  }
  return NULL;
}

DART_EXPORT char* Dart_SetVMFlags(int argc, const char** argv) {
  return Flags::ProcessCommandLineFlags(argc, argv);
}

DART_EXPORT bool Dart_IsVMFlagSet(const char* flag_name) {
  return Flags::IsSet(flag_name);
}

// --- Isolates ---

static char* BuildIsolateName(const char* script_uri, const char* main) {
  if (script_uri == NULL) {
    // Just use the main as the name.
    if (main == NULL) {
      return strdup("isolate");
    } else {
      return strdup(main);
    }
  }

  if (ServiceIsolate::NameEquals(script_uri) ||
      (strcmp(script_uri, DART_KERNEL_ISOLATE_NAME) == 0)) {
    return strdup(script_uri);
  }

  // Skip past any slashes and backslashes in the script uri.
  const char* last_slash = strrchr(script_uri, '/');
  if (last_slash != NULL) {
    script_uri = last_slash + 1;
  }
  const char* last_backslash = strrchr(script_uri, '\\');
  if (last_backslash != NULL) {
    script_uri = last_backslash + 1;
  }
  if (main == NULL) {
    main = "main";
  }

  char* chars = NULL;
  intptr_t len = Utils::SNPrint(NULL, 0, "%s:%s()", script_uri, main) + 1;
  chars = reinterpret_cast<char*>(malloc(len));
  Utils::SNPrint(chars, len, "%s:%s()", script_uri, main);
  return chars;
}

static Dart_Isolate CreateIsolate(const char* script_uri,
                                  const char* main,
                                  const uint8_t* snapshot_data,
                                  const uint8_t* snapshot_instructions,
                                  const uint8_t* shared_data,
                                  const uint8_t* shared_instructions,
                                  const uint8_t* kernel_buffer,
                                  intptr_t kernel_buffer_size,
                                  Dart_IsolateFlags* flags,
                                  void* callback_data,
                                  char** error) {
  CHECK_NO_ISOLATE(Isolate::Current());
  char* isolate_name = BuildIsolateName(script_uri, main);

  // Setup default flags in case none were passed.
  Dart_IsolateFlags api_flags;
  if (flags == NULL) {
    Isolate::FlagsInitialize(&api_flags);
    flags = &api_flags;
  }
  Isolate* I = Dart::CreateIsolate(isolate_name, *flags);
  free(isolate_name);
  if (I == NULL) {
    if (error != NULL) {
      *error = strdup("Isolate creation failed");
    }
    return reinterpret_cast<Dart_Isolate>(NULL);
  }
  {
    Thread* T = Thread::Current();
    StackZone zone(T);
    HANDLESCOPE(T);
    // We enter an API scope here as InitializeIsolate could compile some
    // bootstrap library files which call out to a tag handler that may create
    // Api Handles when an error is encountered.
    Dart_EnterScope();
    const Error& error_obj = Error::Handle(
        Z,
        Dart::InitializeIsolate(snapshot_data, snapshot_instructions,
                                shared_data, shared_instructions, kernel_buffer,
                                kernel_buffer_size, callback_data));
    if (error_obj.IsNull()) {
#if defined(DART_NO_SNAPSHOT) && !defined(PRODUCT)
      if (FLAG_check_function_fingerprints && kernel_buffer == NULL) {
        Library::CheckFunctionFingerprints();
      }
#endif  // defined(DART_NO_SNAPSHOT) && !defined(PRODUCT).
      // We exit the API scope entered above.
      Dart_ExitScope();
      // A Thread structure has been associated to the thread, we do the
      // safepoint transition explicitly here instead of using the
      // TransitionXXX scope objects as the reverse transition happens
      // outside this scope in Dart_ShutdownIsolate/Dart_ExitIsolate.
      T->set_execution_state(Thread::kThreadInNative);
      T->EnterSafepoint();
      if (error != NULL) {
        *error = NULL;
      }
      return Api::CastIsolate(I);
    }
    if (error != NULL) {
      *error = strdup(error_obj.ToErrorCString());
    }
    // We exit the API scope entered above.
    Dart_ExitScope();
  }
  Dart::ShutdownIsolate();
  return reinterpret_cast<Dart_Isolate>(NULL);
}

DART_EXPORT void Dart_IsolateFlagsInitialize(Dart_IsolateFlags* flags) {
  Isolate::FlagsInitialize(flags);
}

DART_EXPORT Dart_Isolate
Dart_CreateIsolate(const char* script_uri,
                   const char* main,
                   const uint8_t* snapshot_data,
                   const uint8_t* snapshot_instructions,
                   const uint8_t* shared_data,
                   const uint8_t* shared_instructions,
                   Dart_IsolateFlags* flags,
                   void* callback_data,
                   char** error) {
  API_TIMELINE_DURATION(Thread::Current());
  return CreateIsolate(script_uri, main, snapshot_data, snapshot_instructions,
                       shared_data, shared_instructions, NULL, 0, flags,
                       callback_data, error);
}

DART_EXPORT Dart_Isolate
Dart_CreateIsolateFromKernel(const char* script_uri,
                             const char* main,
                             const uint8_t* kernel_buffer,
                             intptr_t kernel_buffer_size,
                             Dart_IsolateFlags* flags,
                             void* callback_data,
                             char** error) {
  API_TIMELINE_DURATION(Thread::Current());
  // Setup default flags in case none were passed.
  Dart_IsolateFlags api_flags;
  if (flags == NULL) {
    Isolate::FlagsInitialize(&api_flags);
    flags = &api_flags;
  }
  flags->use_dart_frontend = true;
  return CreateIsolate(script_uri, main, NULL, NULL, NULL, NULL, kernel_buffer,
                       kernel_buffer_size, flags, callback_data, error);
}

DART_EXPORT void Dart_ShutdownIsolate() {
  Thread* T = Thread::Current();
  Isolate* I = T->isolate();
  CHECK_ISOLATE(I);
  I->WaitForOutstandingSpawns();

  // Release any remaining API scopes.
  ApiLocalScope* scope = T->api_top_scope();
  while (scope != NULL) {
    ApiLocalScope* previous = scope->previous();
    delete scope;
    scope = previous;
  }
  T->set_api_top_scope(NULL);

  {
    StackZone zone(T);
    HandleScope handle_scope(T);
    Dart::RunShutdownCallback();
    // The Thread structure is disassociated from the isolate, we do the
    // safepoint transition explicitly here instead of using the TransitionXXX
    // scope objects as the original transition happened outside this scope in
    // Dart_EnterIsolate/Dart_CreateIsolate.
    T->ExitSafepoint();
    T->set_execution_state(Thread::kThreadInVM);
    ServiceIsolate::SendIsolateShutdownMessage();
  }
  Dart::ShutdownIsolate();
}

DART_EXPORT Dart_Isolate Dart_CurrentIsolate() {
  return Api::CastIsolate(Isolate::Current());
}

DART_EXPORT void* Dart_CurrentIsolateData() {
  Isolate* isolate = Isolate::Current();
  CHECK_ISOLATE(isolate);
  NoSafepointScope no_safepoint_scope;
  return isolate->init_callback_data();
}

DART_EXPORT void* Dart_IsolateData(Dart_Isolate isolate) {
  if (isolate == NULL) {
    FATAL1("%s expects argument 'isolate' to be non-null.", CURRENT_FUNC);
  }
  // TODO(16615): Validate isolate parameter.
  Isolate* iso = reinterpret_cast<Isolate*>(isolate);
  return iso->init_callback_data();
}

DART_EXPORT Dart_Handle Dart_DebugName() {
  DARTSCOPE(Thread::Current());
  Isolate* I = T->isolate();
  return Api::NewHandle(
      T, String::NewFormatted("(%" Pd64 ") '%s'",
                              static_cast<int64_t>(I->main_port()), I->name()));
}

DART_EXPORT void Dart_EnterIsolate(Dart_Isolate isolate) {
  CHECK_NO_ISOLATE(Isolate::Current());
  // TODO(16615): Validate isolate parameter.
  Isolate* iso = reinterpret_cast<Isolate*>(isolate);
  if (!Thread::EnterIsolate(iso)) {
    FATAL(
        "Unable to Enter Isolate : "
        "Multiple mutators entering an isolate / "
        "Dart VM is shutting down");
  }
  // A Thread structure has been associated to the thread, we do the
  // safepoint transition explicitly here instead of using the
  // TransitionXXX scope objects as the reverse transition happens
  // outside this scope in Dart_ExitIsolate/Dart_ShutdownIsolate.
  Thread* T = Thread::Current();
  T->set_execution_state(Thread::kThreadInNative);
  T->EnterSafepoint();
}

DART_EXPORT void Dart_ThreadDisableProfiling() {
  OSThread* os_thread = OSThread::Current();
  if (os_thread == NULL) {
    return;
  }
  os_thread->DisableThreadInterrupts();
}

DART_EXPORT void Dart_ThreadEnableProfiling() {
  OSThread* os_thread = OSThread::Current();
  if (os_thread == NULL) {
    return;
  }
  os_thread->EnableThreadInterrupts();
}

DART_EXPORT bool Dart_ShouldPauseOnStart() {
#if defined(PRODUCT)
  return false;
#else
  Isolate* isolate = Isolate::Current();
  CHECK_ISOLATE(isolate);
  NoSafepointScope no_safepoint_scope;
  return isolate->message_handler()->should_pause_on_start();
#endif
}

DART_EXPORT void Dart_SetShouldPauseOnStart(bool should_pause) {
#if defined(PRODUCT)
  if (should_pause) {
    FATAL1("%s(true) is not supported in a PRODUCT build", CURRENT_FUNC);
  }
#else
  Isolate* isolate = Isolate::Current();
  CHECK_ISOLATE(isolate);
  NoSafepointScope no_safepoint_scope;
  if (isolate->is_runnable()) {
    FATAL1("%s expects the current isolate to not be runnable yet.",
           CURRENT_FUNC);
  }
  isolate->message_handler()->set_should_pause_on_start(should_pause);
#endif
}

DART_EXPORT bool Dart_IsPausedOnStart() {
#if defined(PRODUCT)
  return false;
#else
  Isolate* isolate = Isolate::Current();
  CHECK_ISOLATE(isolate);
  NoSafepointScope no_safepoint_scope;
  return isolate->message_handler()->is_paused_on_start();
#endif
}

DART_EXPORT void Dart_SetPausedOnStart(bool paused) {
#if defined(PRODUCT)
  if (paused) {
    FATAL1("%s(true) is not supported in a PRODUCT build", CURRENT_FUNC);
  }
#else
  Isolate* isolate = Isolate::Current();
  CHECK_ISOLATE(isolate);
  NoSafepointScope no_safepoint_scope;
  if (isolate->message_handler()->is_paused_on_start() != paused) {
    isolate->message_handler()->PausedOnStart(paused);
  }
#endif
}

DART_EXPORT bool Dart_ShouldPauseOnExit() {
#if defined(PRODUCT)
  return false;
#else
  Isolate* isolate = Isolate::Current();
  CHECK_ISOLATE(isolate);
  NoSafepointScope no_safepoint_scope;
  return isolate->message_handler()->should_pause_on_exit();
#endif
}

DART_EXPORT void Dart_SetShouldPauseOnExit(bool should_pause) {
#if defined(PRODUCT)
  if (should_pause) {
    FATAL1("%s(true) is not supported in a PRODUCT build", CURRENT_FUNC);
  }
#else
  Isolate* isolate = Isolate::Current();
  CHECK_ISOLATE(isolate);
  NoSafepointScope no_safepoint_scope;
  isolate->message_handler()->set_should_pause_on_exit(should_pause);
#endif
}

DART_EXPORT bool Dart_IsPausedOnExit() {
#if defined(PRODUCT)
  return false;
#else
  Isolate* isolate = Isolate::Current();
  CHECK_ISOLATE(isolate);
  NoSafepointScope no_safepoint_scope;
  return isolate->message_handler()->is_paused_on_exit();
#endif
}

DART_EXPORT void Dart_SetPausedOnExit(bool paused) {
#if defined(PRODUCT)
  if (paused) {
    FATAL1("%s(true) is not supported in a PRODUCT build", CURRENT_FUNC);
  }
#else
  Isolate* isolate = Isolate::Current();
  CHECK_ISOLATE(isolate);
  NoSafepointScope no_safepoint_scope;
  if (isolate->message_handler()->is_paused_on_exit() != paused) {
    isolate->message_handler()->PausedOnExit(paused);
  }
#endif
}

DART_EXPORT void Dart_SetStickyError(Dart_Handle error) {
  Thread* thread = Thread::Current();
  DARTSCOPE(thread);
  Isolate* isolate = thread->isolate();
  CHECK_ISOLATE(isolate);
  NoSafepointScope no_safepoint_scope;
  if ((isolate->sticky_error() != Error::null()) && !::Dart_IsNull(error)) {
    FATAL1("%s expects there to be no sticky error.", CURRENT_FUNC);
  }
  if (!::Dart_IsUnhandledExceptionError(error) && !::Dart_IsNull(error)) {
    FATAL1("%s expects the error to be an unhandled exception error or null.",
           CURRENT_FUNC);
  }
  isolate->SetStickyError(Api::UnwrapErrorHandle(Z, error).raw());
}

DART_EXPORT bool Dart_HasStickyError() {
  Thread* T = Thread::Current();
  Isolate* isolate = T->isolate();
  CHECK_ISOLATE(isolate);
  NoSafepointScope no_safepoint_scope;
  return isolate->sticky_error() != Error::null();
}

DART_EXPORT Dart_Handle Dart_GetStickyError() {
  Thread* T = Thread::Current();
  Isolate* I = T->isolate();
  CHECK_ISOLATE(I);
  NoSafepointScope no_safepoint_scope;
  if (I->sticky_error() != Error::null()) {
    Dart_Handle error = Api::NewHandle(T, I->sticky_error());
    return error;
  }
  return Dart_Null();
}

DART_EXPORT void Dart_NotifyIdle(int64_t deadline) {
  Thread* T = Thread::Current();
  CHECK_ISOLATE(T->isolate());
  API_TIMELINE_BEGIN_END(T);
  TransitionNativeToVM transition(T);
  T->isolate()->NotifyIdle(deadline);
}

DART_EXPORT void Dart_NotifyLowMemory() {
  API_TIMELINE_BEGIN_END(Thread::Current());
  Isolate::NotifyLowMemory();
}

DART_EXPORT void Dart_ExitIsolate() {
  Thread* T = Thread::Current();
  CHECK_ISOLATE(T->isolate());
  // The Thread structure is disassociated from the isolate, we do the
  // safepoint transition explicitly here instead of using the TransitionXXX
  // scope objects as the original transition happened outside this scope in
  // Dart_EnterIsolate/Dart_CreateIsolate.
  ASSERT(T->execution_state() == Thread::kThreadInNative);
  T->ExitSafepoint();
  T->set_execution_state(Thread::kThreadInVM);
  Thread::ExitIsolate();
}

static uint8_t* ApiReallocate(uint8_t* ptr,
                              intptr_t old_size,
                              intptr_t new_size) {
  return Api::TopScope(Thread::Current())
      ->zone()
      ->Realloc<uint8_t>(ptr, old_size, new_size);
}

DART_EXPORT Dart_Handle
Dart_CreateSnapshot(uint8_t** vm_snapshot_data_buffer,
                    intptr_t* vm_snapshot_data_size,
                    uint8_t** isolate_snapshot_data_buffer,
                    intptr_t* isolate_snapshot_data_size) {
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  Isolate* I = T->isolate();
  if (!FLAG_load_deferred_eagerly) {
    return Api::NewError(
        "Creating full snapshots requires --load_deferred_eagerly");
  }
  if (vm_snapshot_data_buffer != NULL && vm_snapshot_data_size == NULL) {
    RETURN_NULL_ERROR(vm_snapshot_data_size);
  }
  CHECK_NULL(isolate_snapshot_data_buffer);
  CHECK_NULL(isolate_snapshot_data_size);
  // Finalize all classes if needed.
  Dart_Handle state = Api::CheckAndFinalizePendingClasses(T);
  if (::Dart_IsError(state)) {
    return state;
  }
  BackgroundCompiler::Stop(I);

#if defined(DEBUG)
  I->heap()->CollectAllGarbage();
  {
    HeapIterationScope iteration(T);
    CheckFunctionTypesVisitor check_canonical(T);
    iteration.IterateObjects(&check_canonical);
  }
#endif  // #if defined(DEBUG)

  Symbols::Compact(I);

  FullSnapshotWriter writer(Snapshot::kFull, vm_snapshot_data_buffer,
                            isolate_snapshot_data_buffer, ApiReallocate,
                            NULL /* vm_image_writer */,
                            NULL /* isolate_image_writer */);
  writer.WriteFullSnapshot();
  if (vm_snapshot_data_buffer != NULL) {
    *vm_snapshot_data_size = writer.VmIsolateSnapshotSize();
  }
  *isolate_snapshot_data_size = writer.IsolateSnapshotSize();
  return Api::Success();
}

DART_EXPORT Dart_Handle
Dart_CreateScriptSnapshot(uint8_t** script_snapshot_buffer,
                          intptr_t* script_snapshot_size) {
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  Isolate* I = T->isolate();
  CHECK_NULL(script_snapshot_buffer);
  CHECK_NULL(script_snapshot_size);
  if (I->strong()) {
    return Api::NewError("Script snapshots are not supported in Dart 2");
  }
  // Finalize all classes if needed.
  Dart_Handle state = Api::CheckAndFinalizePendingClasses(T);
  if (::Dart_IsError(state)) {
    return state;
  }
  Library& lib = Library::Handle(Z, I->object_store()->root_library());

#if defined(DEBUG)
  I->heap()->CollectAllGarbage();
  {
    HeapIterationScope iteration(T);
    CheckFunctionTypesVisitor check_canonical(T);
    iteration.IterateObjects(&check_canonical);
  }
#endif  // #if defined(DEBUG)

  ScriptSnapshotWriter writer(ApiReallocate);
  writer.WriteScriptSnapshot(lib);
  *script_snapshot_buffer = writer.buffer();
  *script_snapshot_size = writer.BytesWritten();
  return Api::Success();
}

DART_EXPORT bool Dart_IsSnapshot(const uint8_t* buffer, intptr_t buffer_size) {
  if (buffer_size < Snapshot::kHeaderSize) {
    return false;
  }
  return Snapshot::SetupFromBuffer(buffer) != NULL;
}

DART_EXPORT bool Dart_IsKernel(const uint8_t* buffer, intptr_t buffer_size) {
  if (buffer_size < 4) {
    return false;
  }
  return (buffer[0] == 0x90) && (buffer[1] == 0xab) && (buffer[2] == 0xcd) &&
         (buffer[3] == 0xef);
}

DART_EXPORT bool Dart_IsDart2Snapshot(const uint8_t* snapshot_buffer) {
  if (snapshot_buffer == NULL) {
    return false;
  }
  const Snapshot* snapshot = Snapshot::SetupFromBuffer(snapshot_buffer);
  if (snapshot == NULL) {
    return false;
  }
  const intptr_t snapshot_size = snapshot->length();
  const char* expected_version = Version::SnapshotString();
  ASSERT(expected_version != NULL);
  const intptr_t version_len = strlen(expected_version);
  if (snapshot_size < version_len) {
    return false;
  }

  const char* version = reinterpret_cast<const char*>(snapshot->content());
  ASSERT(version != NULL);
  if (strncmp(version, expected_version, version_len)) {
    return false;
  }
  const char* features = version + version_len;
  ASSERT(features != NULL);
  intptr_t pending_len = snapshot_size - version_len;
  intptr_t buffer_len = Utils::StrNLen(features, pending_len);
  // if buffer_len is less than pending_len it means we have a null terminated
  // string and we can safely execute 'strstr' on it.
  if ((buffer_len < pending_len)) {
    if (strstr(features, "no-strong")) {
      return false;
    } else if (strstr(features, "strong")) {
      return true;
    }
  }
  return false;
}

DART_EXPORT char* Dart_IsolateMakeRunnable(Dart_Isolate isolate) {
  CHECK_NO_ISOLATE(Isolate::Current());
  API_TIMELINE_DURATION(Thread::Current());
  if (isolate == NULL) {
    FATAL1("%s expects argument 'isolate' to be non-null.", CURRENT_FUNC);
  }
  // TODO(16615): Validate isolate parameter.
  Isolate* iso = reinterpret_cast<Isolate*>(isolate);
  const char* error;
  if (iso->object_store()->root_library() == Library::null()) {
    // The embedder should have called Dart_LoadScript by now.
    error = "Missing root library";
  } else {
    error = iso->MakeRunnable();
  }
  if (error != NULL) {
    return strdup(error);
  }
  return NULL;
}

// --- Messages and Ports ---

DART_EXPORT void Dart_SetMessageNotifyCallback(
    Dart_MessageNotifyCallback message_notify_callback) {
  Isolate* isolate = Isolate::Current();
  CHECK_ISOLATE(isolate);
  NoSafepointScope no_safepoint_scope;
  isolate->set_message_notify_callback(message_notify_callback);
}

DART_EXPORT Dart_MessageNotifyCallback Dart_GetMessageNotifyCallback() {
  Isolate* isolate = Isolate::Current();
  CHECK_ISOLATE(isolate);
  NoSafepointScope no_safepoint_scope;
  return isolate->message_notify_callback();
}

struct RunLoopData {
  Monitor* monitor;
  bool done;
};

static void RunLoopDone(uword param) {
  RunLoopData* data = reinterpret_cast<RunLoopData*>(param);
  ASSERT(data->monitor != NULL);
  MonitorLocker ml(data->monitor);
  data->done = true;
  ml.Notify();
}

DART_EXPORT Dart_Handle Dart_RunLoop() {
  Isolate* I;
  {
    Thread* T = Thread::Current();
    I = T->isolate();
    CHECK_API_SCOPE(T);
    CHECK_CALLBACK_STATE(T);
  }
  API_TIMELINE_BEGIN_END(Thread::Current());
  // The message handler run loop does not expect to have a current isolate
  // so we exit the isolate here and enter it again after the runloop is done.
  ::Dart_ExitIsolate();
  {
    Monitor monitor;
    MonitorLocker ml(&monitor);
    RunLoopData data;
    data.monitor = &monitor;
    data.done = false;
    I->message_handler()->Run(Dart::thread_pool(), NULL, RunLoopDone,
                              reinterpret_cast<uword>(&data));
    while (!data.done) {
      ml.Wait();
    }
  }
  ::Dart_EnterIsolate(Api::CastIsolate(I));
  if (I->sticky_error() != Object::null()) {
    Dart_Handle error = Api::NewHandle(Thread::Current(), I->sticky_error());
    I->clear_sticky_error();
    return error;
  }
  if (FLAG_print_class_table) {
    HANDLESCOPE(Thread::Current());
    I->class_table()->Print();
  }
  return Api::Success();
}

DART_EXPORT Dart_Handle Dart_HandleMessage() {
  Thread* T = Thread::Current();
  Isolate* I = T->isolate();
  CHECK_API_SCOPE(T);
  CHECK_CALLBACK_STATE(T);
  API_TIMELINE_BEGIN_END_BASIC(T);
  TransitionNativeToVM transition(T);
  if (I->message_handler()->HandleNextMessage() != MessageHandler::kOK) {
    Dart_Handle error = Api::NewHandle(T, T->sticky_error());
    T->clear_sticky_error();
    return error;
  }
  return Api::Success();
}

DART_EXPORT Dart_Handle Dart_WaitForEvent(int64_t timeout_millis) {
  Thread* T = Thread::Current();
  Isolate* I = T->isolate();
  CHECK_API_SCOPE(T);
  CHECK_CALLBACK_STATE(T);
  API_TIMELINE_BEGIN_END_BASIC(T);
  TransitionNativeToVM transition(T);
  if (I->message_notify_callback() != NULL) {
    return Api::NewError("waitForEventSync is not supported by this embedder");
  }
  Object& result =
      Object::Handle(Z, DartLibraryCalls::EnsureScheduleImmediate());
  if (result.IsError()) {
    return Api::NewHandle(T, result.raw());
  }

  // Drain the microtask queue. Propagate any errors to the entry frame.
  result = DartLibraryCalls::DrainMicrotaskQueue();
  if (result.IsError()) {
    // Persist the error across unwiding scopes before propagating.
    const Error* error;
    {
      NoSafepointScope no_safepoint;
      RawError* raw_error = Error::Cast(result).raw();
      T->UnwindScopes(T->top_exit_frame_info());
      error = &Error::Handle(T->zone(), raw_error);
    }
    Exceptions::PropagateToEntry(*error);
    UNREACHABLE();
    return Api::NewError("Unreachable");
  }

  // Block to wait for messages and then handle them. Propagate any errors to
  // the entry frame.
  if (I->message_handler()->PauseAndHandleAllMessages(timeout_millis) !=
      MessageHandler::kOK) {
    // Persist the error across unwiding scopes before propagating.
    const Error* error;
    {
      NoSafepointScope no_safepoint;
      RawError* raw_error = T->get_and_clear_sticky_error();
      T->UnwindScopes(T->top_exit_frame_info());
      error = &Error::Handle(T->zone(), raw_error);
    }
    Exceptions::PropagateToEntry(*error);
    UNREACHABLE();
    return Api::NewError("Unreachable");
  }
  return Api::Success();
}

DART_EXPORT bool Dart_HandleServiceMessages() {
#if defined(PRODUCT)
  return true;
#else
  Thread* T = Thread::Current();
  Isolate* I = T->isolate();
  CHECK_API_SCOPE(T);
  CHECK_CALLBACK_STATE(T);
  API_TIMELINE_DURATION(T);
  TransitionNativeToVM transition(T);
  ASSERT(I->GetAndClearResumeRequest() == false);
  MessageHandler::MessageStatus status =
      I->message_handler()->HandleOOBMessages();
  bool resume = I->GetAndClearResumeRequest();
  return (status != MessageHandler::kOK) || resume;
#endif
}

DART_EXPORT bool Dart_HasServiceMessages() {
#if defined(PRODUCT)
  return false;
#else
  Isolate* isolate = Isolate::Current();
  ASSERT(isolate);
  NoSafepointScope no_safepoint_scope;
  return isolate->message_handler()->HasOOBMessages();
#endif
}

DART_EXPORT bool Dart_HasLivePorts() {
  Isolate* isolate = Isolate::Current();
  ASSERT(isolate);
  NoSafepointScope no_safepoint_scope;
  return isolate->message_handler()->HasLivePorts();
}

DART_EXPORT bool Dart_Post(Dart_Port port_id, Dart_Handle handle) {
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  NoSafepointScope no_safepoint_scope;
  if (port_id == ILLEGAL_PORT) {
    return false;
  }

  // Smis and null can be sent without serialization.
  RawObject* raw_obj = Api::UnwrapHandle(handle);
  if (ApiObjectConverter::CanConvert(raw_obj)) {
    return PortMap::PostMessage(
        new Message(port_id, raw_obj, Message::kNormalPriority));
  }

  const Object& object = Object::Handle(Z, raw_obj);
  MessageWriter writer(false);
  return PortMap::PostMessage(
      writer.WriteMessage(object, port_id, Message::kNormalPriority));
}

DART_EXPORT Dart_Handle Dart_NewSendPort(Dart_Port port_id) {
  DARTSCOPE(Thread::Current());
  CHECK_CALLBACK_STATE(T);
  if (port_id == ILLEGAL_PORT) {
    return Api::NewError("%s: illegal port_id %" Pd64 ".", CURRENT_FUNC,
                         port_id);
  }
  return Api::NewHandle(T, SendPort::New(port_id));
}

DART_EXPORT Dart_Handle Dart_SendPortGetId(Dart_Handle port,
                                           Dart_Port* port_id) {
  DARTSCOPE(Thread::Current());
  CHECK_CALLBACK_STATE(T);
  API_TIMELINE_DURATION(T);
  const SendPort& send_port = Api::UnwrapSendPortHandle(Z, port);
  if (send_port.IsNull()) {
    RETURN_TYPE_ERROR(Z, port, SendPort);
  }
  if (port_id == NULL) {
    RETURN_NULL_ERROR(port_id);
  }
  *port_id = send_port.Id();
  return Api::Success();
}

DART_EXPORT Dart_Port Dart_GetMainPortId() {
  Isolate* isolate = Isolate::Current();
  CHECK_ISOLATE(isolate);
  return isolate->main_port();
}

// --- Scopes ----

DART_EXPORT void Dart_EnterScope() {
  Thread* thread = Thread::Current();
  Isolate* isolate = thread->isolate();
  CHECK_ISOLATE(isolate);
  NoSafepointScope no_safepoint_scope;
  ApiLocalScope* new_scope = thread->api_reusable_scope();
  if (new_scope == NULL) {
    new_scope = new ApiLocalScope(thread->api_top_scope(),
                                  thread->top_exit_frame_info());
    ASSERT(new_scope != NULL);
  } else {
    new_scope->Reinit(thread, thread->api_top_scope(),
                      thread->top_exit_frame_info());
    thread->set_api_reusable_scope(NULL);
  }
  thread->set_api_top_scope(new_scope);  // New scope is now the top scope.
}

DART_EXPORT void Dart_ExitScope() {
  Thread* T = Thread::Current();
  CHECK_API_SCOPE(T);
  NoSafepointScope no_safepoint_scope;
  ApiLocalScope* scope = T->api_top_scope();
  ApiLocalScope* reusable_scope = T->api_reusable_scope();
  T->set_api_top_scope(scope->previous());  // Reset top scope to previous.
  if (reusable_scope == NULL) {
    scope->Reset(T);  // Reset the old scope which we just exited.
    T->set_api_reusable_scope(scope);
  } else {
    ASSERT(reusable_scope != scope);
    delete scope;
  }
}

DART_EXPORT uint8_t* Dart_ScopeAllocate(intptr_t size) {
  Zone* zone;
  Thread* thread = Thread::Current();
  if (thread != NULL) {
    ApiLocalScope* scope = thread->api_top_scope();
    zone = scope->zone();
  } else {
    ApiNativeScope* scope = ApiNativeScope::Current();
    if (scope == NULL) return NULL;
    zone = scope->zone();
  }
  return reinterpret_cast<uint8_t*>(zone->AllocUnsafe(size));
}

// --- Objects ----

DART_EXPORT Dart_Handle Dart_Null() {
  ASSERT(Isolate::Current() != NULL);
  return Api::Null();
}

DART_EXPORT Dart_Handle Dart_EmptyString() {
  ASSERT(Isolate::Current() != NULL);
  return Api::EmptyString();
}

DART_EXPORT bool Dart_IsNull(Dart_Handle object) {
  return Api::UnwrapHandle(object) == Object::null();
}

DART_EXPORT Dart_Handle Dart_ObjectEquals(Dart_Handle obj1,
                                          Dart_Handle obj2,
                                          bool* value) {
  DARTSCOPE(Thread::Current());
  CHECK_CALLBACK_STATE(T);
  const Instance& expected =
      Instance::CheckedHandle(Z, Api::UnwrapHandle(obj1));
  const Instance& actual = Instance::CheckedHandle(Z, Api::UnwrapHandle(obj2));
  const Object& result =
      Object::Handle(Z, DartLibraryCalls::Equals(expected, actual));
  if (result.IsBool()) {
    *value = Bool::Cast(result).value();
    return Api::Success();
  } else if (result.IsError()) {
    return Api::NewHandle(T, result.raw());
  } else {
    return Api::NewError("Expected boolean result from ==");
  }
}

// TODO(iposva): This call actually implements IsInstanceOfClass.
// Do we also need a real Dart_IsInstanceOf, which should take an instance
// rather than an object?
DART_EXPORT Dart_Handle Dart_ObjectIsType(Dart_Handle object,
                                          Dart_Handle type,
                                          bool* value) {
  DARTSCOPE(Thread::Current());

  const Type& type_obj = Api::UnwrapTypeHandle(Z, type);
  if (type_obj.IsNull()) {
    *value = false;
    RETURN_TYPE_ERROR(Z, type, Type);
  }
  if (!type_obj.IsFinalized()) {
    return Api::NewError(
        "%s expects argument 'type' to be a fully resolved type.",
        CURRENT_FUNC);
  }
  if (object == Api::Null()) {
    *value = false;
    return Api::Success();
  }
  const Instance& instance = Api::UnwrapInstanceHandle(Z, object);
  if (instance.IsNull()) {
    *value = false;
    RETURN_TYPE_ERROR(Z, object, Instance);
  }
  CHECK_CALLBACK_STATE(T);
  Error& malformed_type_error = Error::Handle(Z);
  *value = instance.IsInstanceOf(type_obj, Object::null_type_arguments(),
                                 Object::null_type_arguments(),
                                 &malformed_type_error);
  ASSERT(malformed_type_error.IsNull());  // Type was created from a class.
  return Api::Success();
}

DART_EXPORT bool Dart_IsInstance(Dart_Handle object) {
  Thread* thread = Thread::Current();
  CHECK_ISOLATE(thread->isolate());
  REUSABLE_OBJECT_HANDLESCOPE(thread);
  Object& ref = thread->ObjectHandle();
  ref = Api::UnwrapHandle(object);
  return ref.IsInstance();
}

DART_EXPORT bool Dart_IsNumber(Dart_Handle object) {
  return RawObject::IsNumberClassId(Api::ClassId(object));
}

DART_EXPORT bool Dart_IsInteger(Dart_Handle object) {
  return RawObject::IsIntegerClassId(Api::ClassId(object));
}

DART_EXPORT bool Dart_IsDouble(Dart_Handle object) {
  return Api::ClassId(object) == kDoubleCid;
}

DART_EXPORT bool Dart_IsBoolean(Dart_Handle object) {
  return Api::ClassId(object) == kBoolCid;
}

DART_EXPORT bool Dart_IsString(Dart_Handle object) {
  return RawObject::IsStringClassId(Api::ClassId(object));
}

DART_EXPORT bool Dart_IsStringLatin1(Dart_Handle object) {
  return RawObject::IsOneByteStringClassId(Api::ClassId(object));
}

DART_EXPORT bool Dart_IsExternalString(Dart_Handle object) {
  return RawObject::IsExternalStringClassId(Api::ClassId(object));
}

DART_EXPORT bool Dart_IsList(Dart_Handle object) {
  if (RawObject::IsBuiltinListClassId(Api::ClassId(object))) {
    return true;
  }

  DARTSCOPE(Thread::Current());
  const Object& obj = Object::Handle(Z, Api::UnwrapHandle(object));
  return GetListInstance(Z, obj) != Instance::null();
}

DART_EXPORT bool Dart_IsMap(Dart_Handle object) {
  DARTSCOPE(Thread::Current());
  const Object& obj = Object::Handle(Z, Api::UnwrapHandle(object));
  return GetMapInstance(Z, obj) != Instance::null();
}

DART_EXPORT bool Dart_IsLibrary(Dart_Handle object) {
  return Api::ClassId(object) == kLibraryCid;
}

DART_EXPORT bool Dart_IsType(Dart_Handle handle) {
  return Api::ClassId(handle) == kTypeCid;
}

DART_EXPORT bool Dart_IsFunction(Dart_Handle handle) {
  return Api::ClassId(handle) == kFunctionCid;
}

DART_EXPORT bool Dart_IsVariable(Dart_Handle handle) {
  return Api::ClassId(handle) == kFieldCid;
}

DART_EXPORT bool Dart_IsTypeVariable(Dart_Handle handle) {
  return Api::ClassId(handle) == kTypeParameterCid;
}

DART_EXPORT bool Dart_IsClosure(Dart_Handle object) {
  return Api::ClassId(object) == kClosureCid;
}

DART_EXPORT bool Dart_IsTypedData(Dart_Handle handle) {
  intptr_t cid = Api::ClassId(handle);
  return RawObject::IsTypedDataClassId(cid) ||
         RawObject::IsExternalTypedDataClassId(cid) ||
         RawObject::IsTypedDataViewClassId(cid);
}

DART_EXPORT bool Dart_IsByteBuffer(Dart_Handle handle) {
  return Api::ClassId(handle) == kByteBufferCid;
}

DART_EXPORT bool Dart_IsFuture(Dart_Handle handle) {
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  Isolate* I = T->isolate();
  const Object& obj = Object::Handle(Z, Api::UnwrapHandle(handle));
  if (obj.IsInstance()) {
    const Class& future_class =
        Class::Handle(I->object_store()->future_class());
    ASSERT(!future_class.IsNull());
    const Class& obj_class = Class::Handle(Z, obj.clazz());
    Error& malformed_type_error = Error::Handle(Z);
    bool is_future = obj_class.IsSubtypeOf(
        Object::null_type_arguments(), future_class,
        Object::null_type_arguments(), &malformed_type_error, NULL, Heap::kNew);
    ASSERT(malformed_type_error.IsNull());  // Type is a raw Future.
    return is_future;
  }
  return false;
}

// --- Instances ----

DART_EXPORT Dart_Handle Dart_InstanceGetType(Dart_Handle instance) {
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  Isolate* I = T->isolate();
  const Object& obj = Object::Handle(Z, Api::UnwrapHandle(instance));
  if (obj.IsNull()) {
    return Api::NewHandle(T, I->object_store()->null_type());
  }
  if (!obj.IsInstance()) {
    RETURN_TYPE_ERROR(Z, instance, Instance);
  }
  const AbstractType& type =
      AbstractType::Handle(Instance::Cast(obj).GetType(Heap::kNew));
  return Api::NewHandle(T, type.Canonicalize());
}

// --- Numbers, Integers and Doubles ----

DART_EXPORT Dart_Handle Dart_IntegerFitsIntoInt64(Dart_Handle integer,
                                                  bool* fits) {
  // Fast path for Smis and Mints.
  Thread* thread = Thread::Current();
  API_TIMELINE_DURATION(thread);
  Isolate* isolate = thread->isolate();
  CHECK_ISOLATE(isolate);
  intptr_t class_id = Api::ClassId(integer);
  if (class_id == kSmiCid || class_id == kMintCid) {
    *fits = true;
    return Api::Success();
  }
  // Slow path for type error.
  DARTSCOPE(thread);
  const Integer& int_obj = Api::UnwrapIntegerHandle(Z, integer);
  ASSERT(int_obj.IsNull());
  RETURN_TYPE_ERROR(Z, integer, Integer);
}

DART_EXPORT Dart_Handle Dart_IntegerFitsIntoUint64(Dart_Handle integer,
                                                   bool* fits) {
  // Fast path for Smis.
  Thread* thread = Thread::Current();
  Isolate* isolate = thread->isolate();
  CHECK_ISOLATE(isolate);
  API_TIMELINE_DURATION(thread);
  if (Api::IsSmi(integer)) {
    *fits = (Api::SmiValue(integer) >= 0);
    return Api::Success();
  }
  // Slow path for Mints.
  DARTSCOPE(thread);
  const Integer& int_obj = Api::UnwrapIntegerHandle(Z, integer);
  if (int_obj.IsNull()) {
    RETURN_TYPE_ERROR(Z, integer, Integer);
  }
  ASSERT(int_obj.IsMint());
  *fits = !int_obj.IsNegative();
  return Api::Success();
}

DART_EXPORT Dart_Handle Dart_NewInteger(int64_t value) {
  // Fast path for Smis.
  Thread* thread = Thread::Current();
  Isolate* isolate = thread->isolate();
  CHECK_ISOLATE(isolate);
  API_TIMELINE_DURATION(thread);
  if (Smi::IsValid(value)) {
    NOHANDLESCOPE(thread);
    return Api::NewHandle(thread, Smi::New(static_cast<intptr_t>(value)));
  }
  // Slow path for Mints.
  DARTSCOPE(thread);
  CHECK_CALLBACK_STATE(thread);
  return Api::NewHandle(thread, Integer::New(value));
}

DART_EXPORT Dart_Handle Dart_NewIntegerFromUint64(uint64_t value) {
  DARTSCOPE(Thread::Current());
  CHECK_CALLBACK_STATE(T);
  API_TIMELINE_DURATION(T);
  if (Integer::IsValueInRange(value)) {
    return Api::NewHandle(T, Integer::NewFromUint64(value));
  }
  return Api::NewError("%s: Cannot create Dart integer from value %" Pu64,
                       CURRENT_FUNC, value);
}

DART_EXPORT Dart_Handle Dart_NewIntegerFromHexCString(const char* str) {
  DARTSCOPE(Thread::Current());
  CHECK_CALLBACK_STATE(T);
  API_TIMELINE_DURATION(T);
  const String& str_obj = String::Handle(Z, String::New(str));
  RawInteger* integer = Integer::New(str_obj);
  if (integer == Integer::null()) {
    return Api::NewError("%s: Cannot create Dart integer from string %s",
                         CURRENT_FUNC, str);
  }
  return Api::NewHandle(T, integer);
}

DART_EXPORT Dart_Handle Dart_IntegerToInt64(Dart_Handle integer,
                                            int64_t* value) {
  // Fast path for Smis.
  Thread* thread = Thread::Current();
  Isolate* isolate = thread->isolate();
  CHECK_ISOLATE(isolate);
  if (Api::IsSmi(integer)) {
    *value = Api::SmiValue(integer);
    return Api::Success();
  }
  // Slow path for Mints.
  DARTSCOPE(thread);
  const Integer& int_obj = Api::UnwrapIntegerHandle(Z, integer);
  if (int_obj.IsNull()) {
    RETURN_TYPE_ERROR(Z, integer, Integer);
  }
  ASSERT(int_obj.IsMint());
  *value = int_obj.AsInt64Value();
  return Api::Success();
}

DART_EXPORT Dart_Handle Dart_IntegerToUint64(Dart_Handle integer,
                                             uint64_t* value) {
  // Fast path for Smis.
  Thread* thread = Thread::Current();
  Isolate* isolate = thread->isolate();
  CHECK_ISOLATE(isolate);
  if (Api::IsSmi(integer)) {
    intptr_t smi_value = Api::SmiValue(integer);
    if (smi_value >= 0) {
      *value = smi_value;
      return Api::Success();
    }
  }
  // Slow path for Mints.
  DARTSCOPE(thread);
  const Integer& int_obj = Api::UnwrapIntegerHandle(Z, integer);
  if (int_obj.IsNull()) {
    RETURN_TYPE_ERROR(Z, integer, Integer);
  }
  if (int_obj.IsSmi()) {
    ASSERT(int_obj.IsNegative());
  } else {
    ASSERT(int_obj.IsMint());
    if (!int_obj.IsNegative()) {
      *value = int_obj.AsInt64Value();
      return Api::Success();
    }
  }
  return Api::NewError("%s: Integer %s cannot be represented as a uint64_t.",
                       CURRENT_FUNC, int_obj.ToCString());
}

DART_EXPORT Dart_Handle Dart_IntegerToHexCString(Dart_Handle integer,
                                                 const char** value) {
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  const Integer& int_obj = Api::UnwrapIntegerHandle(Z, integer);
  if (int_obj.IsNull()) {
    RETURN_TYPE_ERROR(Z, integer, Integer);
  }
  Zone* scope_zone = Api::TopScope(Thread::Current())->zone();
  *value = int_obj.ToHexCString(scope_zone);
  return Api::Success();
}

DART_EXPORT Dart_Handle Dart_NewDouble(double value) {
  DARTSCOPE(Thread::Current());
  CHECK_CALLBACK_STATE(T);
  return Api::NewHandle(T, Double::New(value));
}

DART_EXPORT Dart_Handle Dart_DoubleValue(Dart_Handle double_obj,
                                         double* value) {
  DARTSCOPE(Thread::Current());
  const Double& obj = Api::UnwrapDoubleHandle(Z, double_obj);
  if (obj.IsNull()) {
    RETURN_TYPE_ERROR(Z, double_obj, Double);
  }
  *value = obj.value();
  return Api::Success();
}

DART_EXPORT Dart_Handle Dart_GetClosure(Dart_Handle library,
                                        Dart_Handle function_name) {
  DARTSCOPE(Thread::Current());
  const Library& lib = Api::UnwrapLibraryHandle(Z, library);
  if (lib.IsNull()) {
    RETURN_TYPE_ERROR(Z, library, Library);
  }
  const String& name = Api::UnwrapStringHandle(Z, function_name);
  if (name.IsNull()) {
    RETURN_TYPE_ERROR(Z, function_name, String);
  }
  return Api::NewHandle(T, lib.GetFunctionClosure(name));
}

// --- Booleans ----

DART_EXPORT Dart_Handle Dart_True() {
  ASSERT(Isolate::Current() != NULL);
  return Api::True();
}

DART_EXPORT Dart_Handle Dart_False() {
  ASSERT(Isolate::Current() != NULL);
  return Api::False();
}

DART_EXPORT Dart_Handle Dart_NewBoolean(bool value) {
  Isolate* isolate = Isolate::Current();
  CHECK_ISOLATE(isolate);
  return value ? Api::True() : Api::False();
}

DART_EXPORT Dart_Handle Dart_BooleanValue(Dart_Handle boolean_obj,
                                          bool* value) {
  DARTSCOPE(Thread::Current());
  const Bool& obj = Api::UnwrapBoolHandle(Z, boolean_obj);
  if (obj.IsNull()) {
    RETURN_TYPE_ERROR(Z, boolean_obj, Bool);
  }
  *value = obj.value();
  return Api::Success();
}

// --- Strings ---

DART_EXPORT Dart_Handle Dart_StringLength(Dart_Handle str, intptr_t* len) {
  Thread* thread = Thread::Current();
  CHECK_ISOLATE(thread->isolate());
  ReusableObjectHandleScope reused_obj_handle(thread);
  const String& str_obj = Api::UnwrapStringHandle(reused_obj_handle, str);
  if (str_obj.IsNull()) {
    RETURN_TYPE_ERROR(thread->zone(), str, String);
  }
  *len = str_obj.Length();
  return Api::Success();
}

DART_EXPORT Dart_Handle Dart_NewStringFromCString(const char* str) {
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  if (str == NULL) {
    RETURN_NULL_ERROR(str);
  }
  CHECK_CALLBACK_STATE(T);
  return Api::NewHandle(T, String::New(str));
}

DART_EXPORT Dart_Handle Dart_NewStringFromUTF8(const uint8_t* utf8_array,
                                               intptr_t length) {
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  if (utf8_array == NULL && length != 0) {
    RETURN_NULL_ERROR(utf8_array);
  }
  CHECK_LENGTH(length, String::kMaxElements);
  if (!Utf8::IsValid(utf8_array, length)) {
    return Api::NewError("%s expects argument 'str' to be valid UTF-8.",
                         CURRENT_FUNC);
  }
  CHECK_CALLBACK_STATE(T);
  return Api::NewHandle(T, String::FromUTF8(utf8_array, length));
}

DART_EXPORT Dart_Handle Dart_NewStringFromUTF16(const uint16_t* utf16_array,
                                                intptr_t length) {
  DARTSCOPE(Thread::Current());
  if (utf16_array == NULL && length != 0) {
    RETURN_NULL_ERROR(utf16_array);
  }
  CHECK_LENGTH(length, String::kMaxElements);
  CHECK_CALLBACK_STATE(T);
  return Api::NewHandle(T, String::FromUTF16(utf16_array, length));
}

DART_EXPORT Dart_Handle Dart_NewStringFromUTF32(const int32_t* utf32_array,
                                                intptr_t length) {
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  if (utf32_array == NULL && length != 0) {
    RETURN_NULL_ERROR(utf32_array);
  }
  CHECK_LENGTH(length, String::kMaxElements);
  CHECK_CALLBACK_STATE(T);
  return Api::NewHandle(T, String::FromUTF32(utf32_array, length));
}

DART_EXPORT Dart_Handle
Dart_NewExternalLatin1String(const uint8_t* latin1_array,
                             intptr_t length,
                             void* peer,
                             intptr_t external_allocation_size,
                             Dart_WeakPersistentHandleFinalizer callback) {
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  if (latin1_array == NULL && length != 0) {
    RETURN_NULL_ERROR(latin1_array);
  }
  if (callback == NULL) {
    RETURN_NULL_ERROR(callback);
  }
  CHECK_LENGTH(length, String::kMaxElements);
  CHECK_CALLBACK_STATE(T);
  return Api::NewHandle(
      T,
      String::NewExternal(latin1_array, length, peer, external_allocation_size,
                          callback, SpaceForExternal(T, length)));
}

DART_EXPORT Dart_Handle
Dart_NewExternalUTF16String(const uint16_t* utf16_array,
                            intptr_t length,
                            void* peer,
                            intptr_t external_allocation_size,
                            Dart_WeakPersistentHandleFinalizer callback) {
  DARTSCOPE(Thread::Current());
  if (utf16_array == NULL && length != 0) {
    RETURN_NULL_ERROR(utf16_array);
  }
  if (callback == NULL) {
    RETURN_NULL_ERROR(callback);
  }
  CHECK_LENGTH(length, String::kMaxElements);
  CHECK_CALLBACK_STATE(T);
  intptr_t bytes = length * sizeof(*utf16_array);
  return Api::NewHandle(
      T,
      String::NewExternal(utf16_array, length, peer, external_allocation_size,
                          callback, SpaceForExternal(T, bytes)));
}

DART_EXPORT Dart_Handle Dart_StringToCString(Dart_Handle object,
                                             const char** cstr) {
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  if (cstr == NULL) {
    RETURN_NULL_ERROR(cstr);
  }
  const String& str_obj = Api::UnwrapStringHandle(Z, object);
  if (str_obj.IsNull()) {
    RETURN_TYPE_ERROR(Z, object, String);
  }
  intptr_t string_length = Utf8::Length(str_obj);
  char* res = Api::TopScope(T)->zone()->Alloc<char>(string_length + 1);
  if (res == NULL) {
    return Api::NewError("Unable to allocate memory");
  }
  const char* string_value = str_obj.ToCString();
  memmove(res, string_value, string_length + 1);
  ASSERT(res[string_length] == '\0');
  *cstr = res;
  return Api::Success();
}

DART_EXPORT Dart_Handle Dart_StringToUTF8(Dart_Handle str,
                                          uint8_t** utf8_array,
                                          intptr_t* length) {
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  if (utf8_array == NULL) {
    RETURN_NULL_ERROR(utf8_array);
  }
  if (length == NULL) {
    RETURN_NULL_ERROR(length);
  }
  const String& str_obj = Api::UnwrapStringHandle(Z, str);
  if (str_obj.IsNull()) {
    RETURN_TYPE_ERROR(Z, str, String);
  }
  intptr_t str_len = Utf8::Length(str_obj);
  *utf8_array = Api::TopScope(T)->zone()->Alloc<uint8_t>(str_len);
  if (*utf8_array == NULL) {
    return Api::NewError("Unable to allocate memory");
  }
  str_obj.ToUTF8(*utf8_array, str_len);
  *length = str_len;
  return Api::Success();
}

DART_EXPORT Dart_Handle Dart_StringToLatin1(Dart_Handle str,
                                            uint8_t* latin1_array,
                                            intptr_t* length) {
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  if (latin1_array == NULL) {
    RETURN_NULL_ERROR(latin1_array);
  }
  if (length == NULL) {
    RETURN_NULL_ERROR(length);
  }
  const String& str_obj = Api::UnwrapStringHandle(Z, str);
  if (str_obj.IsNull() || !str_obj.IsOneByteString()) {
    RETURN_TYPE_ERROR(Z, str, String);
  }
  intptr_t str_len = str_obj.Length();
  intptr_t copy_len = (str_len > *length) ? *length : str_len;

  // We have already asserted that the string object is a Latin-1 string
  // so we can copy the characters over using a simple loop.
  for (intptr_t i = 0; i < copy_len; i++) {
    latin1_array[i] = str_obj.CharAt(i);
  }
  *length = copy_len;
  return Api::Success();
}

DART_EXPORT Dart_Handle Dart_StringToUTF16(Dart_Handle str,
                                           uint16_t* utf16_array,
                                           intptr_t* length) {
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  const String& str_obj = Api::UnwrapStringHandle(Z, str);
  if (str_obj.IsNull()) {
    RETURN_TYPE_ERROR(Z, str, String);
  }
  intptr_t str_len = str_obj.Length();
  intptr_t copy_len = (str_len > *length) ? *length : str_len;
  for (intptr_t i = 0; i < copy_len; i++) {
    utf16_array[i] = str_obj.CharAt(i);
  }
  *length = copy_len;
  return Api::Success();
}

DART_EXPORT Dart_Handle Dart_StringStorageSize(Dart_Handle str,
                                               intptr_t* size) {
  Thread* thread = Thread::Current();
  CHECK_ISOLATE(thread->isolate());
  ReusableObjectHandleScope reused_obj_handle(thread);
  const String& str_obj = Api::UnwrapStringHandle(reused_obj_handle, str);
  if (str_obj.IsNull()) {
    RETURN_TYPE_ERROR(thread->zone(), str, String);
  }
  if (size == NULL) {
    RETURN_NULL_ERROR(size);
  }
  *size = (str_obj.Length() * str_obj.CharSize());
  return Api::Success();
}

DART_EXPORT Dart_Handle Dart_StringGetProperties(Dart_Handle object,
                                                 intptr_t* char_size,
                                                 intptr_t* str_len,
                                                 void** peer) {
  Thread* thread = Thread::Current();
  CHECK_ISOLATE(thread->isolate());
  ReusableObjectHandleScope reused_obj_handle(thread);
  const String& str = Api::UnwrapStringHandle(reused_obj_handle, object);
  if (str.IsNull()) {
    RETURN_TYPE_ERROR(thread->zone(), object, String);
  }
  if (str.IsExternal()) {
    *peer = str.GetPeer();
    ASSERT(*peer != NULL);
  } else {
    NoSafepointScope no_safepoint_scope;
    *peer = thread->isolate()->heap()->GetPeer(str.raw());
  }
  *char_size = str.CharSize();
  *str_len = str.Length();
  return Api::Success();
}

// --- Lists ---

DART_EXPORT Dart_Handle Dart_NewList(intptr_t length) {
  return Dart_NewListOf(Dart_CoreType_Dynamic, length);
}

static RawTypeArguments* TypeArgumentsForElementType(
    ObjectStore* store,
    Dart_CoreType_Id element_type_id) {
  switch (element_type_id) {
    case Dart_CoreType_Dynamic:
      return TypeArguments::null();
    case Dart_CoreType_Int:
      return store->type_argument_int();
    case Dart_CoreType_String:
      return store->type_argument_string();
  }
  UNREACHABLE();
  return NULL;
}

DART_EXPORT Dart_Handle Dart_NewListOf(Dart_CoreType_Id element_type_id,
                                       intptr_t length) {
  DARTSCOPE(Thread::Current());
  CHECK_LENGTH(length, Array::kMaxElements);
  CHECK_CALLBACK_STATE(T);
  const Array& arr = Array::Handle(Z, Array::New(length));
  if (element_type_id != Dart_CoreType_Dynamic) {
    arr.SetTypeArguments(TypeArguments::Handle(
        Z, TypeArgumentsForElementType(T->isolate()->object_store(),
                                       element_type_id)));
  }
  return Api::NewHandle(T, arr.raw());
}

DART_EXPORT Dart_Handle Dart_NewListOfType(Dart_Handle element_type,
                                           intptr_t length) {
  DARTSCOPE(Thread::Current());
  CHECK_LENGTH(length, Array::kMaxElements);
  CHECK_CALLBACK_STATE(T);
  const Type& type = Api::UnwrapTypeHandle(Z, element_type);
  if (type.IsNull()) {
    RETURN_TYPE_ERROR(Z, element_type, Type);
  }
  if (!type.IsFinalized()) {
    return Api::NewError(
        "%s expects argument 'type' to be a fully resolved type.",
        CURRENT_FUNC);
  }
  return Api::NewHandle(T, Array::New(length, type));
}

#define GET_LIST_LENGTH(zone, type, obj, len)                                  \
  type& array = type::Handle(zone);                                            \
  array ^= obj.raw();                                                          \
  *len = array.Length();                                                       \
  return Api::Success();

DART_EXPORT Dart_Handle Dart_ListLength(Dart_Handle list, intptr_t* len) {
  DARTSCOPE(Thread::Current());
  const Object& obj = Object::Handle(Z, Api::UnwrapHandle(list));
  if (obj.IsError()) {
    // Pass through errors.
    return list;
  }
  if (obj.IsTypedData()) {
    GET_LIST_LENGTH(Z, TypedData, obj, len);
  }
  if (obj.IsArray()) {
    GET_LIST_LENGTH(Z, Array, obj, len);
  }
  if (obj.IsGrowableObjectArray()) {
    GET_LIST_LENGTH(Z, GrowableObjectArray, obj, len);
  }
  if (obj.IsExternalTypedData()) {
    GET_LIST_LENGTH(Z, ExternalTypedData, obj, len);
  }
  CHECK_CALLBACK_STATE(T);

  // Now check and handle a dart object that implements the List interface.
  const Instance& instance = Instance::Handle(Z, GetListInstance(Z, obj));
  if (instance.IsNull()) {
    return Api::NewError("Object does not implement the List interface");
  }
  const String& name = String::Handle(Z, Field::GetterName(Symbols::Length()));
  const int kTypeArgsLen = 0;
  const int kNumArgs = 1;
  ArgumentsDescriptor args_desc(
      Array::Handle(Z, ArgumentsDescriptor::New(kTypeArgsLen, kNumArgs)));
  const Function& function =
      Function::Handle(Z, Resolver::ResolveDynamic(instance, name, args_desc));
  if (function.IsNull()) {
    return Api::NewError("List object does not have a 'length' field.");
  }

  const Array& args = Array::Handle(Z, Array::New(kNumArgs));
  args.SetAt(0, instance);  // Set up the receiver as the first argument.
  const Object& retval =
      Object::Handle(Z, DartEntry::InvokeFunction(function, args));
  if (retval.IsSmi()) {
    *len = Smi::Cast(retval).Value();
    return Api::Success();
  } else if (retval.IsMint()) {
    int64_t mint_value = Mint::Cast(retval).value();
    if (mint_value >= kIntptrMin && mint_value <= kIntptrMax) {
      *len = static_cast<intptr_t>(mint_value);
      return Api::Success();
    }
    return Api::NewError(
        "Length of List object is greater than the "
        "maximum value that 'len' parameter can hold");
  } else if (retval.IsError()) {
    return Api::NewHandle(T, retval.raw());
  } else {
    return Api::NewError("Length of List object is not an integer");
  }
}

#define GET_LIST_ELEMENT(thread, type, obj, index)                             \
  const type& array_obj = type::Cast(obj);                                     \
  if ((index >= 0) && (index < array_obj.Length())) {                          \
    return Api::NewHandle(thread, array_obj.At(index));                        \
  }                                                                            \
  return Api::NewError("Invalid index passed in to access list element");

DART_EXPORT Dart_Handle Dart_ListGetAt(Dart_Handle list, intptr_t index) {
  DARTSCOPE(Thread::Current());
  const Object& obj = Object::Handle(Z, Api::UnwrapHandle(list));
  if (obj.IsArray()) {
    GET_LIST_ELEMENT(T, Array, obj, index);
  } else if (obj.IsGrowableObjectArray()) {
    GET_LIST_ELEMENT(T, GrowableObjectArray, obj, index);
  } else if (obj.IsError()) {
    return list;
  } else {
    CHECK_CALLBACK_STATE(T);
    // Check and handle a dart object that implements the List interface.
    const Instance& instance = Instance::Handle(Z, GetListInstance(Z, obj));
    if (!instance.IsNull()) {
      return Api::NewHandle(T,
                            Send1Arg(instance, Symbols::IndexToken(),
                                     Instance::Handle(Z, Integer::New(index))));
    }
    return Api::NewError("Object does not implement the 'List' interface");
  }
}

#define GET_LIST_RANGE(thread, type, obj, offset, length)                      \
  const type& array_obj = type::Cast(obj);                                     \
  if ((offset >= 0) && (offset + length <= array_obj.Length())) {              \
    for (intptr_t index = 0; index < length; ++index) {                        \
      result[index] = Api::NewHandle(thread, array_obj.At(index + offset));    \
    }                                                                          \
    return Api::Success();                                                     \
  }                                                                            \
  return Api::NewError("Invalid offset/length passed in to access list");

DART_EXPORT Dart_Handle Dart_ListGetRange(Dart_Handle list,
                                          intptr_t offset,
                                          intptr_t length,
                                          Dart_Handle* result) {
  DARTSCOPE(Thread::Current());
  if (result == NULL) {
    RETURN_NULL_ERROR(result);
  }
  const Object& obj = Object::Handle(Z, Api::UnwrapHandle(list));
  if (obj.IsArray()) {
    GET_LIST_RANGE(T, Array, obj, offset, length);
  } else if (obj.IsGrowableObjectArray()) {
    GET_LIST_RANGE(T, GrowableObjectArray, obj, offset, length);
  } else if (obj.IsError()) {
    return list;
  } else {
    CHECK_CALLBACK_STATE(T);
    // Check and handle a dart object that implements the List interface.
    const Instance& instance = Instance::Handle(Z, GetListInstance(Z, obj));
    if (!instance.IsNull()) {
      const intptr_t kTypeArgsLen = 0;
      const intptr_t kNumArgs = 2;
      ArgumentsDescriptor args_desc(
          Array::Handle(ArgumentsDescriptor::New(kTypeArgsLen, kNumArgs)));
      const Function& function = Function::Handle(
          Z, Resolver::ResolveDynamic(instance, Symbols::AssignIndexToken(),
                                      args_desc));
      if (!function.IsNull()) {
        const Array& args = Array::Handle(Array::New(kNumArgs));
        args.SetAt(0, instance);
        Instance& index = Instance::Handle(Z);
        for (intptr_t i = 0; i < length; ++i) {
          index = Integer::New(i);
          args.SetAt(1, index);
          Dart_Handle value =
              Api::NewHandle(T, DartEntry::InvokeFunction(function, args));
          if (::Dart_IsError(value)) return value;
          result[i] = value;
        }
        return Api::Success();
      }
    }
    return Api::NewError("Object does not implement the 'List' interface");
  }
}

#define SET_LIST_ELEMENT(type, obj, index, value)                              \
  const type& array = type::Cast(obj);                                         \
  const Object& value_obj = Object::Handle(Z, Api::UnwrapHandle(value));       \
  if (!value_obj.IsNull() && !value_obj.IsInstance()) {                        \
    RETURN_TYPE_ERROR(Z, value, Instance);                                     \
  }                                                                            \
  if ((index >= 0) && (index < array.Length())) {                              \
    array.SetAt(index, value_obj);                                             \
    return Api::Success();                                                     \
  }                                                                            \
  return Api::NewError("Invalid index passed in to set list element");

DART_EXPORT Dart_Handle Dart_ListSetAt(Dart_Handle list,
                                       intptr_t index,
                                       Dart_Handle value) {
  DARTSCOPE(Thread::Current());
  const Object& obj = Object::Handle(Z, Api::UnwrapHandle(list));
  // If the list is immutable we call into Dart for the indexed setter to
  // get the unsupported operation exception as the result.
  if (obj.IsArray() && !Array::Cast(obj).IsImmutable()) {
    SET_LIST_ELEMENT(Array, obj, index, value);
  } else if (obj.IsGrowableObjectArray()) {
    SET_LIST_ELEMENT(GrowableObjectArray, obj, index, value);
  } else if (obj.IsError()) {
    return list;
  } else {
    CHECK_CALLBACK_STATE(T);

    // Check and handle a dart object that implements the List interface.
    const Instance& instance = Instance::Handle(Z, GetListInstance(Z, obj));
    if (!instance.IsNull()) {
      const intptr_t kTypeArgsLen = 0;
      const intptr_t kNumArgs = 3;
      ArgumentsDescriptor args_desc(
          Array::Handle(ArgumentsDescriptor::New(kTypeArgsLen, kNumArgs)));
      const Function& function = Function::Handle(
          Z, Resolver::ResolveDynamic(instance, Symbols::AssignIndexToken(),
                                      args_desc));
      if (!function.IsNull()) {
        const Integer& index_obj = Integer::Handle(Z, Integer::New(index));
        const Object& value_obj = Object::Handle(Z, Api::UnwrapHandle(value));
        if (!value_obj.IsNull() && !value_obj.IsInstance()) {
          RETURN_TYPE_ERROR(Z, value, Instance);
        }
        const Array& args = Array::Handle(Z, Array::New(kNumArgs));
        args.SetAt(0, instance);
        args.SetAt(1, index_obj);
        args.SetAt(2, value_obj);
        return Api::NewHandle(T, DartEntry::InvokeFunction(function, args));
      }
    }
    return Api::NewError("Object does not implement the 'List' interface");
  }
}

static RawObject* ResolveConstructor(const char* current_func,
                                     const Class& cls,
                                     const String& class_name,
                                     const String& dotted_name,
                                     int num_args);

static RawObject* ThrowArgumentError(const char* exception_message) {
  Thread* thread = Thread::Current();
  Zone* zone = thread->zone();
  // Lookup the class ArgumentError in dart:core.
  const String& lib_url = String::Handle(String::New("dart:core"));
  const String& class_name = String::Handle(String::New("ArgumentError"));
  const Library& lib =
      Library::Handle(zone, Library::LookupLibrary(thread, lib_url));
  if (lib.IsNull()) {
    const String& message = String::Handle(String::NewFormatted(
        "%s: library '%s' not found.", CURRENT_FUNC, lib_url.ToCString()));
    return ApiError::New(message);
  }
  const Class& cls =
      Class::Handle(zone, lib.LookupClassAllowPrivate(class_name));
  ASSERT(!cls.IsNull());
  Object& result = Object::Handle(zone);
  String& dot_name = String::Handle(String::New("."));
  String& constr_name = String::Handle(String::Concat(class_name, dot_name));
  result = ResolveConstructor(CURRENT_FUNC, cls, class_name, constr_name, 1);
  if (result.IsError()) return result.raw();
  ASSERT(result.IsFunction());
  Function& constructor = Function::Handle(zone);
  constructor ^= result.raw();
  if (!constructor.IsGenerativeConstructor()) {
    const String& message = String::Handle(
        String::NewFormatted("%s: class '%s' is not a constructor.",
                             CURRENT_FUNC, class_name.ToCString()));
    return ApiError::New(message);
  }
  Instance& exception = Instance::Handle(zone);
  exception = Instance::New(cls);
  const Array& args = Array::Handle(zone, Array::New(2));
  args.SetAt(0, exception);
  args.SetAt(1, String::Handle(String::New(exception_message)));
  result = DartEntry::InvokeFunction(constructor, args);
  if (result.IsError()) return result.raw();
  ASSERT(result.IsNull());

  if (thread->top_exit_frame_info() == 0) {
    // There are no dart frames on the stack so it would be illegal to
    // throw an exception here.
    const String& message = String::Handle(
        String::New("No Dart frames on stack, cannot throw exception"));
    return ApiError::New(message);
  }
  // Unwind all the API scopes till the exit frame before throwing an
  // exception.
  const Instance* saved_exception;
  {
    NoSafepointScope no_safepoint;
    RawInstance* raw_exception = exception.raw();
    thread->UnwindScopes(thread->top_exit_frame_info());
    saved_exception = &Instance::Handle(raw_exception);
  }
  Exceptions::Throw(thread, *saved_exception);
  const String& message =
      String::Handle(String::New("Exception was not thrown, internal error"));
  return ApiError::New(message);
}

// TODO(sgjesse): value should always be smaller then 0xff. Add error handling.
#define GET_LIST_ELEMENT_AS_BYTES(type, obj, native_array, offset, length)     \
  const type& array = type::Cast(obj);                                         \
  if (Utils::RangeCheck(offset, length, array.Length())) {                     \
    Object& element = Object::Handle(Z);                                       \
    for (int i = 0; i < length; i++) {                                         \
      element = array.At(offset + i);                                          \
      if (!element.IsInteger()) {                                              \
        return Api::NewHandle(                                                 \
            T, ThrowArgumentError("List contains non-int elements"));          \
      }                                                                        \
      const Integer& integer = Integer::Cast(element);                         \
      native_array[i] = static_cast<uint8_t>(integer.AsInt64Value() & 0xff);   \
      ASSERT(integer.AsInt64Value() <= 0xff);                                  \
    }                                                                          \
    return Api::Success();                                                     \
  }                                                                            \
  return Api::NewError("Invalid length passed in to access array elements");

template <typename T>
static Dart_Handle CopyBytes(const T& array,
                             intptr_t offset,
                             uint8_t* native_array,
                             intptr_t length) {
  ASSERT(array.ElementSizeInBytes() == 1);
  NoSafepointScope no_safepoint;
  memmove(native_array, reinterpret_cast<uint8_t*>(array.DataAddr(offset)),
          length);
  return Api::Success();
}

DART_EXPORT Dart_Handle Dart_ListGetAsBytes(Dart_Handle list,
                                            intptr_t offset,
                                            uint8_t* native_array,
                                            intptr_t length) {
  DARTSCOPE(Thread::Current());
  const Object& obj = Object::Handle(Z, Api::UnwrapHandle(list));
  if (obj.IsTypedData()) {
    const TypedData& array = TypedData::Cast(obj);
    if (array.ElementSizeInBytes() == 1) {
      if (!Utils::RangeCheck(offset, length, array.Length())) {
        return Api::NewError(
            "Invalid length passed in to access list elements");
      }
      return CopyBytes(array, offset, native_array, length);
    }
  }
  if (obj.IsExternalTypedData()) {
    const ExternalTypedData& external_array = ExternalTypedData::Cast(obj);
    if (external_array.ElementSizeInBytes() == 1) {
      if (!Utils::RangeCheck(offset, length, external_array.Length())) {
        return Api::NewError(
            "Invalid length passed in to access list elements");
      }
      return CopyBytes(external_array, offset, native_array, length);
    }
  }
  if (RawObject::IsTypedDataViewClassId(obj.GetClassId())) {
    const Instance& view = Instance::Cast(obj);
    if (TypedDataView::ElementSizeInBytes(view) == 1) {
      intptr_t view_length = Smi::Value(TypedDataView::Length(view));
      if (!Utils::RangeCheck(offset, length, view_length)) {
        return Api::NewError(
            "Invalid length passed in to access list elements");
      }
      const Instance& data = Instance::Handle(TypedDataView::Data(view));
      if (data.IsTypedData()) {
        const TypedData& array = TypedData::Cast(data);
        if (array.ElementSizeInBytes() == 1) {
          intptr_t data_offset =
              Smi::Value(TypedDataView::OffsetInBytes(view)) + offset;
          // Range check already performed on the view object.
          ASSERT(Utils::RangeCheck(data_offset, length, array.Length()));
          return CopyBytes(array, data_offset, native_array, length);
        }
      }
    }
  }
  if (obj.IsArray()) {
    GET_LIST_ELEMENT_AS_BYTES(Array, obj, native_array, offset, length);
  }
  if (obj.IsGrowableObjectArray()) {
    GET_LIST_ELEMENT_AS_BYTES(GrowableObjectArray, obj, native_array, offset,
                              length);
  }
  if (obj.IsError()) {
    return list;
  }
  CHECK_CALLBACK_STATE(T);

  // Check and handle a dart object that implements the List interface.
  const Instance& instance = Instance::Handle(Z, GetListInstance(Z, obj));
  if (!instance.IsNull()) {
    const int kTypeArgsLen = 0;
    const int kNumArgs = 2;
    ArgumentsDescriptor args_desc(
        Array::Handle(ArgumentsDescriptor::New(kTypeArgsLen, kNumArgs)));
    const Function& function = Function::Handle(
        Z,
        Resolver::ResolveDynamic(instance, Symbols::IndexToken(), args_desc));
    if (!function.IsNull()) {
      Object& result = Object::Handle(Z);
      Integer& intobj = Integer::Handle(Z);
      const Array& args = Array::Handle(Z, Array::New(kNumArgs));
      args.SetAt(0, instance);  // Set up the receiver as the first argument.
      for (int i = 0; i < length; i++) {
        HANDLESCOPE(T);
        intobj = Integer::New(offset + i);
        args.SetAt(1, intobj);
        result = DartEntry::InvokeFunction(function, args);
        if (result.IsError()) {
          return Api::NewHandle(T, result.raw());
        }
        if (!result.IsInteger()) {
          return Api::NewError(
              "%s expects the argument 'list' to be "
              "a List of int",
              CURRENT_FUNC);
        }
        const Integer& integer_result = Integer::Cast(result);
        ASSERT(integer_result.AsInt64Value() <= 0xff);
        // TODO(hpayer): value should always be smaller then 0xff. Add error
        // handling.
        native_array[i] =
            static_cast<uint8_t>(integer_result.AsInt64Value() & 0xff);
      }
      return Api::Success();
    }
  }
  return Api::NewError("Object does not implement the 'List' interface");
}

#define SET_LIST_ELEMENT_AS_BYTES(type, obj, native_array, offset, length)     \
  const type& array = type::Cast(obj);                                         \
  Integer& integer = Integer::Handle(Z);                                       \
  if (Utils::RangeCheck(offset, length, array.Length())) {                     \
    for (int i = 0; i < length; i++) {                                         \
      integer = Integer::New(native_array[i]);                                 \
      array.SetAt(offset + i, integer);                                        \
    }                                                                          \
    return Api::Success();                                                     \
  }                                                                            \
  return Api::NewError("Invalid length passed in to set array elements");

DART_EXPORT Dart_Handle Dart_ListSetAsBytes(Dart_Handle list,
                                            intptr_t offset,
                                            const uint8_t* native_array,
                                            intptr_t length) {
  DARTSCOPE(Thread::Current());
  const Object& obj = Object::Handle(Z, Api::UnwrapHandle(list));
  if (obj.IsTypedData()) {
    const TypedData& array = TypedData::Cast(obj);
    if (array.ElementSizeInBytes() == 1) {
      if (Utils::RangeCheck(offset, length, array.Length())) {
        NoSafepointScope no_safepoint;
        memmove(reinterpret_cast<uint8_t*>(array.DataAddr(offset)),
                native_array, length);
        return Api::Success();
      }
      return Api::NewError("Invalid length passed in to access list elements");
    }
  }
  if (obj.IsArray() && !Array::Cast(obj).IsImmutable()) {
    // If the list is immutable we call into Dart for the indexed setter to
    // get the unsupported operation exception as the result.
    SET_LIST_ELEMENT_AS_BYTES(Array, obj, native_array, offset, length);
  }
  if (obj.IsGrowableObjectArray()) {
    SET_LIST_ELEMENT_AS_BYTES(GrowableObjectArray, obj, native_array, offset,
                              length);
  }
  if (obj.IsError()) {
    return list;
  }
  CHECK_CALLBACK_STATE(T);

  // Check and handle a dart object that implements the List interface.
  const Instance& instance = Instance::Handle(Z, GetListInstance(Z, obj));
  if (!instance.IsNull()) {
    const int kTypeArgsLen = 0;
    const int kNumArgs = 3;
    ArgumentsDescriptor args_desc(
        Array::Handle(Z, ArgumentsDescriptor::New(kTypeArgsLen, kNumArgs)));
    const Function& function = Function::Handle(
        Z, Resolver::ResolveDynamic(instance, Symbols::AssignIndexToken(),
                                    args_desc));
    if (!function.IsNull()) {
      Integer& indexobj = Integer::Handle(Z);
      Integer& valueobj = Integer::Handle(Z);
      const Array& args = Array::Handle(Z, Array::New(kNumArgs));
      args.SetAt(0, instance);  // Set up the receiver as the first argument.
      for (int i = 0; i < length; i++) {
        indexobj = Integer::New(offset + i);
        valueobj = Integer::New(native_array[i]);
        args.SetAt(1, indexobj);
        args.SetAt(2, valueobj);
        const Object& result =
            Object::Handle(Z, DartEntry::InvokeFunction(function, args));
        if (result.IsError()) {
          return Api::NewHandle(T, result.raw());
        }
      }
      return Api::Success();
    }
  }
  return Api::NewError("Object does not implement the 'List' interface");
}

// --- Maps ---

DART_EXPORT Dart_Handle Dart_MapGetAt(Dart_Handle map, Dart_Handle key) {
  DARTSCOPE(Thread::Current());
  CHECK_CALLBACK_STATE(T);
  const Object& obj = Object::Handle(Z, Api::UnwrapHandle(map));
  const Instance& instance = Instance::Handle(Z, GetMapInstance(Z, obj));
  if (!instance.IsNull()) {
    const Object& key_obj = Object::Handle(Api::UnwrapHandle(key));
    if (!(key_obj.IsInstance() || key_obj.IsNull())) {
      return Api::NewError("Key is not an instance");
    }
    return Api::NewHandle(
        T, Send1Arg(instance, Symbols::IndexToken(), Instance::Cast(key_obj)));
  }
  return Api::NewError("Object does not implement the 'Map' interface");
}

DART_EXPORT Dart_Handle Dart_MapContainsKey(Dart_Handle map, Dart_Handle key) {
  DARTSCOPE(Thread::Current());
  CHECK_CALLBACK_STATE(T);
  const Object& obj = Object::Handle(Z, Api::UnwrapHandle(map));
  const Instance& instance = Instance::Handle(Z, GetMapInstance(Z, obj));
  if (!instance.IsNull()) {
    const Object& key_obj = Object::Handle(Z, Api::UnwrapHandle(key));
    if (!(key_obj.IsInstance() || key_obj.IsNull())) {
      return Api::NewError("Key is not an instance");
    }
    return Api::NewHandle(
        T, Send1Arg(instance, String::Handle(Z, String::New("containsKey")),
                    Instance::Cast(key_obj)));
  }
  return Api::NewError("Object does not implement the 'Map' interface");
}

DART_EXPORT Dart_Handle Dart_MapKeys(Dart_Handle map) {
  DARTSCOPE(Thread::Current());
  CHECK_CALLBACK_STATE(T);
  Object& obj = Object::Handle(Z, Api::UnwrapHandle(map));
  Instance& instance = Instance::Handle(Z, GetMapInstance(Z, obj));
  if (!instance.IsNull()) {
    const Object& iterator = Object::Handle(
        Send0Arg(instance, String::Handle(Z, String::New("get:keys"))));
    if (!iterator.IsInstance()) {
      return Api::NewHandle(T, iterator.raw());
    }
    return Api::NewHandle(T, Send0Arg(Instance::Cast(iterator),
                                      String::Handle(String::New("toList"))));
  }
  return Api::NewError("Object does not implement the 'Map' interface");
}

// --- Typed Data ---

// Helper method to get the type of a TypedData object.
static Dart_TypedData_Type GetType(intptr_t class_id) {
  Dart_TypedData_Type type;
  switch (class_id) {
    case kByteDataViewCid:
      type = Dart_TypedData_kByteData;
      break;
    case kTypedDataInt8ArrayCid:
    case kTypedDataInt8ArrayViewCid:
    case kExternalTypedDataInt8ArrayCid:
      type = Dart_TypedData_kInt8;
      break;
    case kTypedDataUint8ArrayCid:
    case kTypedDataUint8ArrayViewCid:
    case kExternalTypedDataUint8ArrayCid:
      type = Dart_TypedData_kUint8;
      break;
    case kTypedDataUint8ClampedArrayCid:
    case kTypedDataUint8ClampedArrayViewCid:
    case kExternalTypedDataUint8ClampedArrayCid:
      type = Dart_TypedData_kUint8Clamped;
      break;
    case kTypedDataInt16ArrayCid:
    case kTypedDataInt16ArrayViewCid:
    case kExternalTypedDataInt16ArrayCid:
      type = Dart_TypedData_kInt16;
      break;
    case kTypedDataUint16ArrayCid:
    case kTypedDataUint16ArrayViewCid:
    case kExternalTypedDataUint16ArrayCid:
      type = Dart_TypedData_kUint16;
      break;
    case kTypedDataInt32ArrayCid:
    case kTypedDataInt32ArrayViewCid:
    case kExternalTypedDataInt32ArrayCid:
      type = Dart_TypedData_kInt32;
      break;
    case kTypedDataUint32ArrayCid:
    case kTypedDataUint32ArrayViewCid:
    case kExternalTypedDataUint32ArrayCid:
      type = Dart_TypedData_kUint32;
      break;
    case kTypedDataInt64ArrayCid:
    case kTypedDataInt64ArrayViewCid:
    case kExternalTypedDataInt64ArrayCid:
      type = Dart_TypedData_kInt64;
      break;
    case kTypedDataUint64ArrayCid:
    case kTypedDataUint64ArrayViewCid:
    case kExternalTypedDataUint64ArrayCid:
      type = Dart_TypedData_kUint64;
      break;
    case kTypedDataFloat32ArrayCid:
    case kTypedDataFloat32ArrayViewCid:
    case kExternalTypedDataFloat32ArrayCid:
      type = Dart_TypedData_kFloat32;
      break;
    case kTypedDataFloat64ArrayCid:
    case kTypedDataFloat64ArrayViewCid:
    case kExternalTypedDataFloat64ArrayCid:
      type = Dart_TypedData_kFloat64;
      break;
    case kTypedDataFloat32x4ArrayCid:
    case kTypedDataFloat32x4ArrayViewCid:
    case kExternalTypedDataFloat32x4ArrayCid:
      type = Dart_TypedData_kFloat32x4;
      break;
    default:
      type = Dart_TypedData_kInvalid;
      break;
  }
  return type;
}

DART_EXPORT Dart_TypedData_Type Dart_GetTypeOfTypedData(Dart_Handle object) {
  API_TIMELINE_DURATION(Thread::Current());
  intptr_t class_id = Api::ClassId(object);
  if (RawObject::IsTypedDataClassId(class_id) ||
      RawObject::IsTypedDataViewClassId(class_id)) {
    return GetType(class_id);
  }
  return Dart_TypedData_kInvalid;
}

DART_EXPORT Dart_TypedData_Type
Dart_GetTypeOfExternalTypedData(Dart_Handle object) {
  API_TIMELINE_DURATION(Thread::Current());
  intptr_t class_id = Api::ClassId(object);
  if (RawObject::IsExternalTypedDataClassId(class_id)) {
    return GetType(class_id);
  }
  if (RawObject::IsTypedDataViewClassId(class_id)) {
    // Check if data object of the view is external.
    Zone* zone = Thread::Current()->zone();
    const Instance& view_obj = Api::UnwrapInstanceHandle(zone, object);
    ASSERT(!view_obj.IsNull());
    const Instance& data_obj =
        Instance::Handle(zone, TypedDataView::Data(view_obj));
    if (ExternalTypedData::IsExternalTypedData(data_obj)) {
      return GetType(class_id);
    }
  }
  return Dart_TypedData_kInvalid;
}

static RawObject* GetByteDataConstructor(Thread* thread,
                                         const String& constructor_name,
                                         intptr_t num_args) {
  const Library& lib =
      Library::Handle(thread->isolate()->object_store()->typed_data_library());
  ASSERT(!lib.IsNull());
  const Class& cls = Class::Handle(
      thread->zone(), lib.LookupClassAllowPrivate(Symbols::ByteData()));
  ASSERT(!cls.IsNull());
  return ResolveConstructor(CURRENT_FUNC, cls, Symbols::ByteData(),
                            constructor_name, num_args);
}

static Dart_Handle NewByteData(Thread* thread, intptr_t length) {
  CHECK_LENGTH(length, TypedData::MaxElements(kTypedDataInt8ArrayCid));
  Zone* zone = thread->zone();
  Object& result = Object::Handle(zone);
  result = GetByteDataConstructor(thread, Symbols::ByteDataDot(), 1);
  ASSERT(!result.IsNull());
  ASSERT(result.IsFunction());
  const Function& factory = Function::Cast(result);
  ASSERT(!factory.IsGenerativeConstructor());

  // Create the argument list.
  const Array& args = Array::Handle(zone, Array::New(2));
  // Factories get type arguments.
  args.SetAt(0, Object::null_type_arguments());
  args.SetAt(1, Smi::Handle(zone, Smi::New(length)));

  // Invoke the constructor and return the new object.
  result = DartEntry::InvokeFunction(factory, args);
  ASSERT(result.IsInstance() || result.IsNull() || result.IsError());
  return Api::NewHandle(thread, result.raw());
}

static Dart_Handle NewTypedData(Thread* thread, intptr_t cid, intptr_t length) {
  CHECK_LENGTH(length, TypedData::MaxElements(cid));
  return Api::NewHandle(thread, TypedData::New(cid, length));
}

static Dart_Handle NewExternalTypedData(
    Thread* thread,
    intptr_t cid,
    void* data,
    intptr_t length,
    void* peer,
    intptr_t external_allocation_size,
    Dart_WeakPersistentHandleFinalizer callback) {
  CHECK_LENGTH(length, ExternalTypedData::MaxElements(cid));
  Zone* zone = thread->zone();
  intptr_t bytes = length * ExternalTypedData::ElementSizeInBytes(cid);
  const ExternalTypedData& result = ExternalTypedData::Handle(
      zone, ExternalTypedData::New(cid, reinterpret_cast<uint8_t*>(data),
                                   length, SpaceForExternal(thread, bytes)));
  if (callback != NULL) {
    AllocateFinalizableHandle(thread, result, peer, external_allocation_size,
                              callback);
  }
  return Api::NewHandle(thread, result.raw());
}

static Dart_Handle NewExternalByteData(
    Thread* thread,
    void* data,
    intptr_t length,
    void* peer,
    intptr_t external_allocation_size,
    Dart_WeakPersistentHandleFinalizer callback) {
  Zone* zone = thread->zone();
  Dart_Handle ext_data =
      NewExternalTypedData(thread, kExternalTypedDataUint8ArrayCid, data,
                           length, peer, external_allocation_size, callback);
  if (::Dart_IsError(ext_data)) {
    return ext_data;
  }
  Object& result = Object::Handle(zone);
  result = GetByteDataConstructor(thread, Symbols::ByteDataDot_view(), 3);
  ASSERT(!result.IsNull());
  ASSERT(result.IsFunction());
  const Function& factory = Function::Cast(result);
  ASSERT(!factory.IsGenerativeConstructor());

  // Create the argument list.
  const intptr_t num_args = 3;
  const Array& args = Array::Handle(zone, Array::New(num_args + 1));
  // Factories get type arguments.
  args.SetAt(0, Object::null_type_arguments());
  const ExternalTypedData& array =
      Api::UnwrapExternalTypedDataHandle(zone, ext_data);
  args.SetAt(1, array);
  Smi& smi = Smi::Handle(zone);
  smi = Smi::New(0);
  args.SetAt(2, smi);
  smi = Smi::New(length);
  args.SetAt(3, smi);

  // Invoke the constructor and return the new object.
  result = DartEntry::InvokeFunction(factory, args);
  ASSERT(result.IsNull() || result.IsInstance() || result.IsError());
  return Api::NewHandle(thread, result.raw());
}

DART_EXPORT Dart_Handle Dart_NewTypedData(Dart_TypedData_Type type,
                                          intptr_t length) {
  DARTSCOPE(Thread::Current());
  CHECK_CALLBACK_STATE(T);
  switch (type) {
    case Dart_TypedData_kByteData:
      return NewByteData(T, length);
    case Dart_TypedData_kInt8:
      return NewTypedData(T, kTypedDataInt8ArrayCid, length);
    case Dart_TypedData_kUint8:
      return NewTypedData(T, kTypedDataUint8ArrayCid, length);
    case Dart_TypedData_kUint8Clamped:
      return NewTypedData(T, kTypedDataUint8ClampedArrayCid, length);
    case Dart_TypedData_kInt16:
      return NewTypedData(T, kTypedDataInt16ArrayCid, length);
    case Dart_TypedData_kUint16:
      return NewTypedData(T, kTypedDataUint16ArrayCid, length);
    case Dart_TypedData_kInt32:
      return NewTypedData(T, kTypedDataInt32ArrayCid, length);
    case Dart_TypedData_kUint32:
      return NewTypedData(T, kTypedDataUint32ArrayCid, length);
    case Dart_TypedData_kInt64:
      return NewTypedData(T, kTypedDataInt64ArrayCid, length);
    case Dart_TypedData_kUint64:
      return NewTypedData(T, kTypedDataUint64ArrayCid, length);
    case Dart_TypedData_kFloat32:
      return NewTypedData(T, kTypedDataFloat32ArrayCid, length);
    case Dart_TypedData_kFloat64:
      return NewTypedData(T, kTypedDataFloat64ArrayCid, length);
    case Dart_TypedData_kFloat32x4:
      return NewTypedData(T, kTypedDataFloat32x4ArrayCid, length);
    default:
      return Api::NewError("%s expects argument 'type' to be of 'TypedData'",
                           CURRENT_FUNC);
  }
  UNREACHABLE();
  return Api::Null();
}

DART_EXPORT Dart_Handle Dart_NewExternalTypedData(Dart_TypedData_Type type,
                                                  void* data,
                                                  intptr_t length) {
  return Dart_NewExternalTypedDataWithFinalizer(type, data, length, NULL, 0,
                                                NULL);
}

DART_EXPORT Dart_Handle Dart_NewExternalTypedDataWithFinalizer(
    Dart_TypedData_Type type,
    void* data,
    intptr_t length,
    void* peer,
    intptr_t external_allocation_size,
    Dart_WeakPersistentHandleFinalizer callback) {
  DARTSCOPE(Thread::Current());
  if (data == NULL && length != 0) {
    RETURN_NULL_ERROR(data);
  }
  CHECK_CALLBACK_STATE(T);
  switch (type) {
    case Dart_TypedData_kByteData:
      return NewExternalByteData(T, data, length, peer,
                                 external_allocation_size, callback);
    case Dart_TypedData_kInt8:
      return NewExternalTypedData(T, kExternalTypedDataInt8ArrayCid, data,
                                  length, peer, external_allocation_size,
                                  callback);
    case Dart_TypedData_kUint8:
      return NewExternalTypedData(T, kExternalTypedDataUint8ArrayCid, data,
                                  length, peer, external_allocation_size,
                                  callback);
    case Dart_TypedData_kUint8Clamped:
      return NewExternalTypedData(T, kExternalTypedDataUint8ClampedArrayCid,
                                  data, length, peer, external_allocation_size,
                                  callback);
    case Dart_TypedData_kInt16:
      return NewExternalTypedData(T, kExternalTypedDataInt16ArrayCid, data,
                                  length, peer, external_allocation_size,
                                  callback);
    case Dart_TypedData_kUint16:
      return NewExternalTypedData(T, kExternalTypedDataUint16ArrayCid, data,
                                  length, peer, external_allocation_size,
                                  callback);
    case Dart_TypedData_kInt32:
      return NewExternalTypedData(T, kExternalTypedDataInt32ArrayCid, data,
                                  length, peer, external_allocation_size,
                                  callback);
    case Dart_TypedData_kUint32:
      return NewExternalTypedData(T, kExternalTypedDataUint32ArrayCid, data,
                                  length, peer, external_allocation_size,
                                  callback);
    case Dart_TypedData_kInt64:
      return NewExternalTypedData(T, kExternalTypedDataInt64ArrayCid, data,
                                  length, peer, external_allocation_size,
                                  callback);
    case Dart_TypedData_kUint64:
      return NewExternalTypedData(T, kExternalTypedDataUint64ArrayCid, data,
                                  length, peer, external_allocation_size,
                                  callback);
    case Dart_TypedData_kFloat32:
      return NewExternalTypedData(T, kExternalTypedDataFloat32ArrayCid, data,
                                  length, peer, external_allocation_size,
                                  callback);
    case Dart_TypedData_kFloat64:
      return NewExternalTypedData(T, kExternalTypedDataFloat64ArrayCid, data,
                                  length, peer, external_allocation_size,
                                  callback);
    case Dart_TypedData_kFloat32x4:
      return NewExternalTypedData(T, kExternalTypedDataFloat32x4ArrayCid, data,
                                  length, peer, external_allocation_size,
                                  callback);
    default:
      return Api::NewError(
          "%s expects argument 'type' to be of"
          " 'external TypedData'",
          CURRENT_FUNC);
  }
  UNREACHABLE();
  return Api::Null();
}

static RawObject* GetByteBufferConstructor(Thread* thread,
                                           const String& class_name,
                                           const String& constructor_name,
                                           intptr_t num_args) {
  const Library& lib =
      Library::Handle(thread->isolate()->object_store()->typed_data_library());
  ASSERT(!lib.IsNull());
  const Class& cls =
      Class::Handle(thread->zone(), lib.LookupClassAllowPrivate(class_name));
  ASSERT(!cls.IsNull());
  return ResolveConstructor(CURRENT_FUNC, cls, class_name, constructor_name,
                            num_args);
}

DART_EXPORT Dart_Handle Dart_NewByteBuffer(Dart_Handle typed_data) {
  DARTSCOPE(Thread::Current());
  intptr_t class_id = Api::ClassId(typed_data);
  if (!RawObject::IsExternalTypedDataClassId(class_id) &&
      !RawObject::IsTypedDataViewClassId(class_id) &&
      !RawObject::IsTypedDataClassId(class_id)) {
    RETURN_TYPE_ERROR(Z, typed_data, 'TypedData');
  }
  Object& result = Object::Handle(Z);
  result = GetByteBufferConstructor(T, Symbols::_ByteBuffer(),
                                    Symbols::_ByteBufferDot_New(), 1);
  ASSERT(!result.IsNull());
  ASSERT(result.IsFunction());
  const Function& factory = Function::Cast(result);
  ASSERT(!factory.IsGenerativeConstructor());

  // Create the argument list.
  const Array& args = Array::Handle(Z, Array::New(2));
  // Factories get type arguments.
  args.SetAt(0, Object::null_type_arguments());
  const Object& obj = Object::Handle(Z, Api::UnwrapHandle(typed_data));
  args.SetAt(1, obj);

  // Invoke the factory constructor and return the new object.
  result = DartEntry::InvokeFunction(factory, args);
  ASSERT(result.IsInstance() || result.IsNull() || result.IsError());
  return Api::NewHandle(T, result.raw());
}

// Structure to record acquired typed data for verification purposes.
class AcquiredData {
 public:
  AcquiredData(void* data, intptr_t size_in_bytes, bool copy)
      : size_in_bytes_(size_in_bytes), data_(data), data_copy_(NULL) {
    if (copy) {
      data_copy_ = malloc(size_in_bytes_);
      memmove(data_copy_, data_, size_in_bytes_);
    }
  }

  // The pointer to hand out via the API.
  void* GetData() const { return data_copy_ != NULL ? data_copy_ : data_; }

  // Writes back and deletes/zaps, if a copy was made.
  ~AcquiredData() {
    if (data_copy_ != NULL) {
      memmove(data_, data_copy_, size_in_bytes_);
      memset(data_copy_, kZapReleasedByte, size_in_bytes_);
      free(data_copy_);
    }
  }

 private:
  static const uint8_t kZapReleasedByte = 0xda;
  intptr_t size_in_bytes_;
  void* data_;
  void* data_copy_;

  DISALLOW_COPY_AND_ASSIGN(AcquiredData);
};

DART_EXPORT Dart_Handle Dart_TypedDataAcquireData(Dart_Handle object,
                                                  Dart_TypedData_Type* type,
                                                  void** data,
                                                  intptr_t* len) {
  DARTSCOPE(Thread::Current());
  Isolate* I = T->isolate();
  intptr_t class_id = Api::ClassId(object);
  if (!RawObject::IsExternalTypedDataClassId(class_id) &&
      !RawObject::IsTypedDataViewClassId(class_id) &&
      !RawObject::IsTypedDataClassId(class_id)) {
    RETURN_TYPE_ERROR(Z, object, 'TypedData');
  }
  if (type == NULL) {
    RETURN_NULL_ERROR(type);
  }
  if (data == NULL) {
    RETURN_NULL_ERROR(data);
  }
  if (len == NULL) {
    RETURN_NULL_ERROR(len);
  }
  // Get the type of typed data object.
  *type = GetType(class_id);
  intptr_t length = 0;
  intptr_t size_in_bytes = 0;
  void* data_tmp = NULL;
  bool external = false;
  // If it is an external typed data object just return the data field.
  if (RawObject::IsExternalTypedDataClassId(class_id)) {
    const ExternalTypedData& obj =
        Api::UnwrapExternalTypedDataHandle(Z, object);
    ASSERT(!obj.IsNull());
    length = obj.Length();
    size_in_bytes = length * ExternalTypedData::ElementSizeInBytes(class_id);
    data_tmp = obj.DataAddr(0);
    external = true;
  } else if (RawObject::IsTypedDataClassId(class_id)) {
    // Regular typed data object, set up some GC and API callback guards.
    const TypedData& obj = Api::UnwrapTypedDataHandle(Z, object);
    ASSERT(!obj.IsNull());
    length = obj.Length();
    size_in_bytes = length * TypedData::ElementSizeInBytes(class_id);
    T->IncrementNoSafepointScopeDepth();
    START_NO_CALLBACK_SCOPE(T);
    data_tmp = obj.DataAddr(0);
  } else {
    ASSERT(RawObject::IsTypedDataViewClassId(class_id));
    const Instance& view_obj = Api::UnwrapInstanceHandle(Z, object);
    ASSERT(!view_obj.IsNull());
    Smi& val = Smi::Handle();
    val ^= TypedDataView::Length(view_obj);
    length = val.Value();
    size_in_bytes = length * TypedDataView::ElementSizeInBytes(class_id);
    val ^= TypedDataView::OffsetInBytes(view_obj);
    intptr_t offset_in_bytes = val.Value();
    const Instance& obj = Instance::Handle(TypedDataView::Data(view_obj));
    T->IncrementNoSafepointScopeDepth();
    START_NO_CALLBACK_SCOPE(T);
    if (TypedData::IsTypedData(obj)) {
      const TypedData& data_obj = TypedData::Cast(obj);
      data_tmp = data_obj.DataAddr(offset_in_bytes);
    } else {
      ASSERT(ExternalTypedData::IsExternalTypedData(obj));
      const ExternalTypedData& data_obj = ExternalTypedData::Cast(obj);
      data_tmp = data_obj.DataAddr(offset_in_bytes);
      external = true;
    }
  }
  if (FLAG_verify_acquired_data) {
    if (external) {
      ASSERT(!I->heap()->Contains(reinterpret_cast<uword>(data_tmp)));
    } else {
      ASSERT(I->heap()->Contains(reinterpret_cast<uword>(data_tmp)));
    }
    const Object& obj = Object::Handle(Z, Api::UnwrapHandle(object));
    WeakTable* table = I->api_state()->acquired_table();
    intptr_t current = table->GetValue(obj.raw());
    if (current != 0) {
      return Api::NewError("Data was already acquired for this object.");
    }
    // Do not make a copy if the data is external. Some callers expect external
    // data to remain in place, even though the API spec doesn't guarantee it.
    // TODO(koda/asiva): Make final decision and document it.
    AcquiredData* ad = new AcquiredData(data_tmp, size_in_bytes, !external);
    table->SetValue(obj.raw(), reinterpret_cast<intptr_t>(ad));
    data_tmp = ad->GetData();
  }
  *data = data_tmp;
  *len = length;
  return Api::Success();
}

DART_EXPORT Dart_Handle Dart_TypedDataReleaseData(Dart_Handle object) {
  DARTSCOPE(Thread::Current());
  Isolate* I = T->isolate();
  intptr_t class_id = Api::ClassId(object);
  if (!RawObject::IsExternalTypedDataClassId(class_id) &&
      !RawObject::IsTypedDataViewClassId(class_id) &&
      !RawObject::IsTypedDataClassId(class_id)) {
    RETURN_TYPE_ERROR(Z, object, 'TypedData');
  }
  if (!RawObject::IsExternalTypedDataClassId(class_id)) {
    T->DecrementNoSafepointScopeDepth();
    END_NO_CALLBACK_SCOPE(T);
  }
  if (FLAG_verify_acquired_data) {
    const Object& obj = Object::Handle(Z, Api::UnwrapHandle(object));
    WeakTable* table = I->api_state()->acquired_table();
    intptr_t current = table->GetValue(obj.raw());
    if (current == 0) {
      return Api::NewError("Data was not acquired for this object.");
    }
    AcquiredData* ad = reinterpret_cast<AcquiredData*>(current);
    table->SetValue(obj.raw(), 0);  // Delete entry from table.
    delete ad;
  }
  return Api::Success();
}

DART_EXPORT Dart_Handle Dart_GetDataFromByteBuffer(Dart_Handle object) {
  Thread* thread = Thread::Current();
  Zone* zone = thread->zone();
  Isolate* isolate = thread->isolate();
  CHECK_ISOLATE(isolate);
  intptr_t class_id = Api::ClassId(object);
  if (class_id != kByteBufferCid) {
    RETURN_TYPE_ERROR(zone, object, 'ByteBuffer');
  }
  const Instance& instance = Api::UnwrapInstanceHandle(zone, object);
  ASSERT(!instance.IsNull());
  return Api::NewHandle(thread, ByteBuffer::Data(instance));
}

// ---  Invoking Constructors, Methods, and Field accessors ---

static RawObject* ResolveConstructor(const char* current_func,
                                     const Class& cls,
                                     const String& class_name,
                                     const String& constr_name,
                                     int num_args) {
  // The constructor must be present in the interface.
  const Function& constructor =
      Function::Handle(cls.LookupFunctionAllowPrivate(constr_name));
  if (constructor.IsNull() ||
      (!constructor.IsGenerativeConstructor() && !constructor.IsFactory())) {
    const String& lookup_class_name = String::Handle(cls.Name());
    if (!class_name.Equals(lookup_class_name)) {
      // When the class name used to build the constructor name is
      // different than the name of the class in which we are doing
      // the lookup, it can be confusing to the user to figure out
      // what's going on.  Be a little more explicit for these error
      // messages.
      const String& message = String::Handle(String::NewFormatted(
          "%s: could not find factory '%s' in class '%s'.", current_func,
          constr_name.ToCString(), lookup_class_name.ToCString()));
      return ApiError::New(message);
    } else {
      const String& message = String::Handle(
          String::NewFormatted("%s: could not find constructor '%s'.",
                               current_func, constr_name.ToCString()));
      return ApiError::New(message);
    }
  }
  const int kTypeArgsLen = 0;
  const int extra_args = 1;
  String& error_message = String::Handle();
  if (!constructor.AreValidArgumentCounts(kTypeArgsLen, num_args + extra_args,
                                          0, &error_message)) {
    const String& message = String::Handle(String::NewFormatted(
        "%s: wrong argument count for "
        "constructor '%s': %s.",
        current_func, constr_name.ToCString(), error_message.ToCString()));
    return ApiError::New(message);
  }
  return constructor.raw();
}

DART_EXPORT Dart_Handle Dart_New(Dart_Handle type,
                                 Dart_Handle constructor_name,
                                 int number_of_arguments,
                                 Dart_Handle* arguments) {
  DARTSCOPE(Thread::Current());
  CHECK_CALLBACK_STATE(T);
  Object& result = Object::Handle(Z);

  if (number_of_arguments < 0) {
    return Api::NewError(
        "%s expects argument 'number_of_arguments' to be non-negative.",
        CURRENT_FUNC);
  }

  // Get the class to instantiate.
  Object& unchecked_type = Object::Handle(Api::UnwrapHandle(type));
  if (unchecked_type.IsNull() || !unchecked_type.IsType()) {
    RETURN_TYPE_ERROR(Z, type, Type);
  }
  Type& type_obj = Type::Handle();
  type_obj ^= unchecked_type.raw();
  if (!type_obj.IsFinalized()) {
    return Api::NewError(
        "%s expects argument 'type' to be a fully resolved type.",
        CURRENT_FUNC);
  }
  Class& cls = Class::Handle(Z, type_obj.type_class());
  TypeArguments& type_arguments =
      TypeArguments::Handle(Z, type_obj.arguments());

  const String& base_constructor_name = String::Handle(Z, cls.Name());

  // And get the name of the constructor to invoke.
  String& dot_name = String::Handle(Z);
  result = Api::UnwrapHandle(constructor_name);
  if (result.IsNull()) {
    dot_name = Symbols::Dot().raw();
  } else if (result.IsString()) {
    dot_name = String::Concat(Symbols::Dot(), String::Cast(result));
  } else {
    RETURN_TYPE_ERROR(Z, constructor_name, String);
  }

  // Resolve the constructor.
  String& constr_name =
      String::Handle(String::Concat(base_constructor_name, dot_name));
  result = ResolveConstructor("Dart_New", cls, base_constructor_name,
                              constr_name, number_of_arguments);
  if (result.IsError()) {
    return Api::NewHandle(T, result.raw());
  }
  ASSERT(result.IsFunction());
  Function& constructor = Function::Handle(Z);
  constructor ^= result.raw();

  Instance& new_object = Instance::Handle(Z);
  if (constructor.IsRedirectingFactory()) {
    ClassFinalizer::ResolveRedirectingFactory(cls, constructor);
    Type& redirect_type = Type::Handle(constructor.RedirectionType());
    constructor = constructor.RedirectionTarget();
    if (constructor.IsNull()) {
      ASSERT(redirect_type.IsMalformed());
      return Api::NewHandle(T, redirect_type.error());
    }

    if (!redirect_type.IsInstantiated()) {
      // The type arguments of the redirection type are instantiated from the
      // type arguments of the type argument.
      // We do not support generic constructors.
      ASSERT(redirect_type.IsInstantiated(kFunctions));
      Error& bound_error = Error::Handle();
      redirect_type ^= redirect_type.InstantiateFrom(
          type_arguments, Object::null_type_arguments(), kNoneFree,
          &bound_error, NULL, NULL, Heap::kNew);
      if (!bound_error.IsNull()) {
        return Api::NewHandle(T, bound_error.raw());
      }
      redirect_type ^= redirect_type.Canonicalize();
    }

    type_obj = redirect_type.raw();
    type_arguments = redirect_type.arguments();

    cls = type_obj.type_class();
  }
  if (constructor.IsGenerativeConstructor()) {
#if defined(DEBUG)
    if (!cls.is_allocated() &&
        (Dart::vm_snapshot_kind() == Snapshot::kFullAOT)) {
      return Api::NewError("Precompilation dropped '%s'", cls.ToCString());
    }
#endif
    // Create the new object.
    new_object = Instance::New(cls);
  }

  // Create the argument list.
  intptr_t arg_index = 0;
  int extra_args = 1;
  const Array& args =
      Array::Handle(Z, Array::New(number_of_arguments + extra_args));
  if (constructor.IsGenerativeConstructor()) {
    // Constructors get the uninitialized object.
    if (!type_arguments.IsNull()) {
      // The type arguments will be null if the class has no type parameters, in
      // which case the following call would fail because there is no slot
      // reserved in the object for the type vector.
      new_object.SetTypeArguments(type_arguments);
    }
    args.SetAt(arg_index++, new_object);
  } else {
    // Factories get type arguments.
    args.SetAt(arg_index++, type_arguments);
  }
  Object& argument = Object::Handle(Z);
  for (int i = 0; i < number_of_arguments; i++) {
    argument = Api::UnwrapHandle(arguments[i]);
    if (!argument.IsNull() && !argument.IsInstance()) {
      if (argument.IsError()) {
        return Api::NewHandle(T, argument.raw());
      } else {
        return Api::NewError(
            "%s expects arguments[%d] to be an Instance handle.", CURRENT_FUNC,
            i);
      }
    }
    args.SetAt(arg_index++, argument);
  }

  // Invoke the constructor and return the new object.
  result = DartEntry::InvokeFunction(constructor, args);
  if (result.IsError()) {
    return Api::NewHandle(T, result.raw());
  }

  if (constructor.IsGenerativeConstructor()) {
    ASSERT(result.IsNull());
  } else {
    ASSERT(result.IsNull() || result.IsInstance());
    new_object ^= result.raw();
  }
  return Api::NewHandle(T, new_object.raw());
}

static RawInstance* AllocateObject(Thread* thread, const Class& cls) {
  if (!cls.is_fields_marked_nullable()) {
    // Mark all fields as nullable.
    Zone* zone = thread->zone();
    Class& iterate_cls = Class::Handle(zone, cls.raw());
    Field& field = Field::Handle(zone);
    Array& fields = Array::Handle(zone);
    while (!iterate_cls.IsNull()) {
      ASSERT(iterate_cls.is_finalized());
      iterate_cls.set_is_fields_marked_nullable();
      fields = iterate_cls.fields();
      iterate_cls = iterate_cls.SuperClass();
      for (int field_num = 0; field_num < fields.Length(); field_num++) {
        field ^= fields.At(field_num);
        if (field.is_static()) {
          continue;
        }
        field.RecordStore(Object::null_object());
      }
    }
  }

  // Allocate an object for the given class.
  return Instance::New(cls);
}

DART_EXPORT Dart_Handle Dart_Allocate(Dart_Handle type) {
  DARTSCOPE(Thread::Current());
  CHECK_CALLBACK_STATE(T);

  const Type& type_obj = Api::UnwrapTypeHandle(Z, type);
  // Get the class to instantiate.
  if (type_obj.IsNull()) {
    RETURN_TYPE_ERROR(Z, type, Type);
  }
  const Class& cls = Class::Handle(Z, type_obj.type_class());
#if defined(DEBUG)
  if (!cls.is_allocated() && (Dart::vm_snapshot_kind() == Snapshot::kFullAOT)) {
    return Api::NewError("Precompilation dropped '%s'", cls.ToCString());
  }
#endif
  const Error& error = Error::Handle(Z, cls.EnsureIsFinalized(T));
  if (!error.IsNull()) {
    // An error occurred, return error object.
    return Api::NewHandle(T, error.raw());
  }
  return Api::NewHandle(T, AllocateObject(T, cls));
}

DART_EXPORT Dart_Handle
Dart_AllocateWithNativeFields(Dart_Handle type,
                              intptr_t num_native_fields,
                              const intptr_t* native_fields) {
  DARTSCOPE(Thread::Current());
  CHECK_CALLBACK_STATE(T);

  const Type& type_obj = Api::UnwrapTypeHandle(Z, type);
  // Get the class to instantiate.
  if (type_obj.IsNull()) {
    RETURN_TYPE_ERROR(Z, type, Type);
  }
  if (native_fields == NULL) {
    RETURN_NULL_ERROR(native_fields);
  }
  const Class& cls = Class::Handle(Z, type_obj.type_class());
#if defined(DEBUG)
  if (!cls.is_allocated() && (Dart::vm_snapshot_kind() == Snapshot::kFullAOT)) {
    return Api::NewError("Precompilation dropped '%s'", cls.ToCString());
  }
#endif
  const Error& error = Error::Handle(Z, cls.EnsureIsFinalized(T));
  if (!error.IsNull()) {
    // An error occurred, return error object.
    return Api::NewHandle(T, error.raw());
  }
  if (num_native_fields != cls.num_native_fields()) {
    return Api::NewError(
        "%s: invalid number of native fields %" Pd " passed in, expected %d",
        CURRENT_FUNC, num_native_fields, cls.num_native_fields());
  }
  const Instance& instance = Instance::Handle(Z, AllocateObject(T, cls));
  instance.SetNativeFields(num_native_fields, native_fields);
  return Api::NewHandle(T, instance.raw());
}

static Dart_Handle SetupArguments(Thread* thread,
                                  int num_args,
                                  Dart_Handle* arguments,
                                  int extra_args,
                                  Array* args) {
  Zone* zone = thread->zone();
  // Check for malformed arguments in the arguments list.
  *args = Array::New(num_args + extra_args);
  Object& arg = Object::Handle(zone);
  for (int i = 0; i < num_args; i++) {
    arg = Api::UnwrapHandle(arguments[i]);
    if (!arg.IsNull() && !arg.IsInstance()) {
      *args = Array::null();
      if (arg.IsError()) {
        return Api::NewHandle(thread, arg.raw());
      } else {
        return Api::NewError(
            "%s expects arguments[%d] to be an Instance handle.", "Dart_Invoke",
            i);
      }
    }
    args->SetAt((i + extra_args), arg);
  }
  return Api::Success();
}

DART_EXPORT Dart_Handle Dart_InvokeConstructor(Dart_Handle object,
                                               Dart_Handle name,
                                               int number_of_arguments,
                                               Dart_Handle* arguments) {
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  CHECK_CALLBACK_STATE(T);

  if (number_of_arguments < 0) {
    return Api::NewError(
        "%s expects argument 'number_of_arguments' to be non-negative.",
        CURRENT_FUNC);
  }
  const Instance& instance = Api::UnwrapInstanceHandle(Z, object);
  if (instance.IsNull()) {
    RETURN_TYPE_ERROR(Z, object, Instance);
  }

  // Since we have allocated an object it would mean that the type
  // is finalized.
  // TODO(asiva): How do we ensure that a constructor is not called more than
  // once for the same object.

  // Construct name of the constructor to invoke.
  const String& constructor_name = Api::UnwrapStringHandle(Z, name);
  const AbstractType& type_obj =
      AbstractType::Handle(Z, instance.GetType(Heap::kNew));
  const Class& cls = Class::Handle(Z, type_obj.type_class());
  const String& class_name = String::Handle(Z, cls.Name());
  const Array& strings = Array::Handle(Z, Array::New(3));
  strings.SetAt(0, class_name);
  strings.SetAt(1, Symbols::Dot());
  if (constructor_name.IsNull()) {
    strings.SetAt(2, Symbols::Empty());
  } else {
    strings.SetAt(2, constructor_name);
  }
  const String& dot_name = String::Handle(Z, String::ConcatAll(strings));
  const TypeArguments& type_arguments =
      TypeArguments::Handle(Z, type_obj.arguments());
  const Function& constructor =
      Function::Handle(Z, cls.LookupFunctionAllowPrivate(dot_name));
  const int kTypeArgsLen = 0;
  const int extra_args = 1;
  if (!constructor.IsNull() && constructor.IsGenerativeConstructor() &&
      constructor.AreValidArgumentCounts(
          kTypeArgsLen, number_of_arguments + extra_args, 0, NULL)) {
    // Create the argument list.
    // Constructors get the uninitialized object.
    if (!type_arguments.IsNull()) {
      // The type arguments will be null if the class has no type
      // parameters, in which case the following call would fail
      // because there is no slot reserved in the object for the
      // type vector.
      instance.SetTypeArguments(type_arguments);
    }
    Dart_Handle result;
    Array& args = Array::Handle(Z);
    result =
        SetupArguments(T, number_of_arguments, arguments, extra_args, &args);
    if (!::Dart_IsError(result)) {
      args.SetAt(0, instance);
      const Object& retval =
          Object::Handle(Z, DartEntry::InvokeFunction(constructor, args));
      if (retval.IsError()) {
        result = Api::NewHandle(T, retval.raw());
      } else {
        result = Api::NewHandle(T, instance.raw());
      }
    }
    return result;
  }
  return Api::NewError("%s expects argument 'name' to be a valid constructor.",
                       CURRENT_FUNC);
}

DART_EXPORT Dart_Handle Dart_Invoke(Dart_Handle target,
                                    Dart_Handle name,
                                    int number_of_arguments,
                                    Dart_Handle* arguments) {
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  CHECK_CALLBACK_STATE(T);

  const String& function_name = Api::UnwrapStringHandle(Z, name);
  if (function_name.IsNull()) {
    RETURN_TYPE_ERROR(Z, name, String);
  }
  if (number_of_arguments < 0) {
    return Api::NewError(
        "%s expects argument 'number_of_arguments' to be non-negative.",
        CURRENT_FUNC);
  }
  const Object& obj = Object::Handle(Z, Api::UnwrapHandle(target));
  if (obj.IsError()) {
    return target;
  }
  Dart_Handle result;
  Array& args = Array::Handle(Z);
  const intptr_t kTypeArgsLen = 0;
  if (obj.IsType()) {
    if (!Type::Cast(obj).IsFinalized()) {
      return Api::NewError(
          "%s expects argument 'target' to be a fully resolved type.",
          CURRENT_FUNC);
    }

    const Class& cls = Class::Handle(Z, Type::Cast(obj).type_class());
    const Function& function =
        Function::Handle(Z, Resolver::ResolveStaticAllowPrivate(
                                cls, function_name, kTypeArgsLen,
                                number_of_arguments, Object::empty_array()));
    if (function.IsNull()) {
      const String& cls_name = String::Handle(Z, cls.Name());
      return Api::NewError("%s: did not find static method '%s.%s'.",
                           CURRENT_FUNC, cls_name.ToCString(),
                           function_name.ToCString());
    }
#if !defined(PRODUCT)
    if (tds.enabled()) {
      const String& cls_name = String::Handle(Z, cls.Name());
      tds.SetNumArguments(1);
      tds.FormatArgument(0, "name", "%s.%s", cls_name.ToCString(),
                         function_name.ToCString());
    }
#endif  // !defined(PRODUCT)
    // Setup args and check for malformed arguments in the arguments list.
    result = SetupArguments(T, number_of_arguments, arguments, 0, &args);
    if (!::Dart_IsError(result)) {
      result = Api::NewHandle(T, DartEntry::InvokeFunction(function, args));
    }
    return result;
  } else if (obj.IsNull() || obj.IsInstance()) {
    // Since we have allocated an object it would mean that the type of the
    // receiver is already resolved and finalized, hence it is not necessary
    // to check here.
    Instance& instance = Instance::Handle(Z);
    instance ^= obj.raw();
    ArgumentsDescriptor args_desc(Array::Handle(
        Z, ArgumentsDescriptor::New(kTypeArgsLen, number_of_arguments + 1)));
    const Function& function = Function::Handle(
        Z, Resolver::ResolveDynamic(instance, function_name, args_desc));
    if (function.IsNull()) {
      // Setup args and check for malformed arguments in the arguments list.
      result = SetupArguments(T, number_of_arguments, arguments, 1, &args);
      if (!::Dart_IsError(result)) {
        args.SetAt(0, instance);
        const Array& args_descriptor = Array::Handle(
            Z, ArgumentsDescriptor::New(kTypeArgsLen, args.Length()));
        result = Api::NewHandle(
            T, DartEntry::InvokeNoSuchMethod(instance, function_name, args,
                                             args_descriptor));
      }
      return result;
    }
#if !defined(PRODUCT)
    if (tds.enabled()) {
      const Class& cls = Class::Handle(Z, instance.clazz());
      ASSERT(!cls.IsNull());
      const String& cls_name = String::Handle(Z, cls.Name());
      tds.SetNumArguments(1);
      tds.FormatArgument(0, "name", "%s.%s", cls_name.ToCString(),
                         function_name.ToCString());
    }
#endif  // !defined(PRODUCT)
    // Setup args and check for malformed arguments in the arguments list.
    result = SetupArguments(T, number_of_arguments, arguments, 1, &args);
    if (!::Dart_IsError(result)) {
      args.SetAt(0, instance);
      result = Api::NewHandle(T, DartEntry::InvokeFunction(function, args));
    }
    return result;
  } else if (obj.IsLibrary()) {
    // Check whether class finalization is needed.
    const Library& lib = Library::Cast(obj);

    // Check that the library is loaded.
    if (!lib.Loaded()) {
      return Api::NewError("%s expects library argument 'target' to be loaded.",
                           CURRENT_FUNC);
    }

    const Function& function =
        Function::Handle(Z, lib.LookupFunctionAllowPrivate(function_name));
    if (function.IsNull()) {
      return Api::NewError("%s: did not find top-level function '%s'.",
                           CURRENT_FUNC, function_name.ToCString());
    }

#if !defined(PRODUCT)
    if (tds.enabled()) {
      const String& lib_name = String::Handle(Z, lib.url());
      tds.SetNumArguments(1);
      tds.FormatArgument(0, "name", "%s.%s", lib_name.ToCString(),
                         function_name.ToCString());
    }
#endif  // !defined(PRODUCT)

    // LookupFunctionAllowPrivate does not check argument arity, so we
    // do it here.
    String& error_message = String::Handle(Z);
    if (!function.AreValidArgumentCounts(kTypeArgsLen, number_of_arguments, 0,
                                         &error_message)) {
      return Api::NewError("%s: wrong argument count for function '%s': %s.",
                           CURRENT_FUNC, function_name.ToCString(),
                           error_message.ToCString());
    }
    // Setup args and check for malformed arguments in the arguments list.
    result = SetupArguments(T, number_of_arguments, arguments, 0, &args);
    if (!::Dart_IsError(result)) {
      result = Api::NewHandle(T, DartEntry::InvokeFunction(function, args));
    }
    return result;
  } else {
    return Api::NewError(
        "%s expects argument 'target' to be an object, type, or library.",
        CURRENT_FUNC);
  }
}

DART_EXPORT Dart_Handle Dart_InvokeClosure(Dart_Handle closure,
                                           int number_of_arguments,
                                           Dart_Handle* arguments) {
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  CHECK_CALLBACK_STATE(T);
  const Instance& closure_obj = Api::UnwrapInstanceHandle(Z, closure);
  if (closure_obj.IsNull() || !closure_obj.IsCallable(NULL)) {
    RETURN_TYPE_ERROR(Z, closure, Instance);
  }
  if (number_of_arguments < 0) {
    return Api::NewError(
        "%s expects argument 'number_of_arguments' to be non-negative.",
        CURRENT_FUNC);
  }

  // Set up arguments to include the closure as the first argument.
  const Array& args = Array::Handle(Z, Array::New(number_of_arguments + 1));
  Object& obj = Object::Handle(Z);
  args.SetAt(0, closure_obj);
  for (int i = 0; i < number_of_arguments; i++) {
    obj = Api::UnwrapHandle(arguments[i]);
    if (!obj.IsNull() && !obj.IsInstance()) {
      RETURN_TYPE_ERROR(Z, arguments[i], Instance);
    }
    args.SetAt(i + 1, obj);
  }
  // Now try to invoke the closure.
  return Api::NewHandle(T, DartEntry::InvokeClosure(args));
}

DART_EXPORT Dart_Handle Dart_GetField(Dart_Handle container, Dart_Handle name) {
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  CHECK_CALLBACK_STATE(T);

  const String& field_name = Api::UnwrapStringHandle(Z, name);
  if (field_name.IsNull()) {
    RETURN_TYPE_ERROR(Z, name, String);
  }

  Field& field = Field::Handle(Z);
  Function& getter = Function::Handle(Z);
  const Object& obj = Object::Handle(Z, Api::UnwrapHandle(container));
  if (obj.IsNull()) {
    return Api::NewError("%s expects argument 'container' to be non-null.",
                         CURRENT_FUNC);
  } else if (obj.IsType()) {
    if (!Type::Cast(obj).IsFinalized()) {
      return Api::NewError(
          "%s expects argument 'container' to be a fully resolved type.",
          CURRENT_FUNC);
    }
    // To access a static field we may need to use the Field or the
    // getter Function.
    Class& cls = Class::Handle(Z, Type::Cast(obj).type_class());

    field = cls.LookupStaticFieldAllowPrivate(field_name);
    if (field.IsNull() || field.IsUninitialized()) {
      const String& getter_name =
          String::Handle(Z, Field::GetterName(field_name));
      getter = cls.LookupStaticFunctionAllowPrivate(getter_name);
    }

#if !defined(PRODUCT)
    if (tds.enabled()) {
      const String& cls_name = String::Handle(cls.Name());
      tds.SetNumArguments(1);
      tds.FormatArgument(0, "name", "%s.%s", cls_name.ToCString(),
                         field_name.ToCString());
    }
#endif  // !defined(PRODUCT)

    if (!getter.IsNull()) {
      // Invoke the getter and return the result.
      return Api::NewHandle(
          T, DartEntry::InvokeFunction(getter, Object::empty_array()));
    } else if (!field.IsNull()) {
      return Api::NewHandle(T, field.StaticValue());
    } else {
      return Api::NewError("%s: did not find static field '%s'.", CURRENT_FUNC,
                           field_name.ToCString());
    }

  } else if (obj.IsInstance()) {
    // Every instance field has a getter Function.  Try to find the
    // getter in any superclass and use that function to access the
    // field.
    const Instance& instance = Instance::Cast(obj);
    Class& cls = Class::Handle(Z, instance.clazz());
    String& getter_name = String::Handle(Z, Field::GetterName(field_name));
    while (!cls.IsNull()) {
      getter = cls.LookupDynamicFunctionAllowPrivate(getter_name);
      if (!getter.IsNull()) {
        break;
      }
      cls = cls.SuperClass();
    }

#if !defined(PRODUCT)
    if (tds.enabled()) {
      const String& cls_name = String::Handle(cls.Name());
      tds.SetNumArguments(1);
      tds.FormatArgument(0, "name", "%s.%s", cls_name.ToCString(),
                         field_name.ToCString());
    }
#endif  // !defined(PRODUCT)

    // Invoke the getter and return the result.
    const int kTypeArgsLen = 0;
    const int kNumArgs = 1;
    const Array& args = Array::Handle(Z, Array::New(kNumArgs));
    args.SetAt(0, instance);
    if (getter.IsNull()) {
      const Array& args_descriptor = Array::Handle(
          Z, ArgumentsDescriptor::New(kTypeArgsLen, args.Length()));
      return Api::NewHandle(
          T, DartEntry::InvokeNoSuchMethod(instance, getter_name, args,
                                           args_descriptor));
    }
    return Api::NewHandle(T, DartEntry::InvokeFunction(getter, args));

  } else if (obj.IsLibrary()) {
    // To access a top-level we may need to use the Field or the
    // getter Function.  The getter function may either be in the
    // library or in the field's owner class, depending.
    const Library& lib = Library::Cast(obj);
    // Check that the library is loaded.
    if (!lib.Loaded()) {
      return Api::NewError(
          "%s expects library argument 'container' to be loaded.",
          CURRENT_FUNC);
    }
    field = lib.LookupFieldAllowPrivate(field_name);
    if (field.IsNull()) {
      // No field found and no ambiguity error.  Check for a getter in the lib.
      const String& getter_name =
          String::Handle(Z, Field::GetterName(field_name));
      getter = lib.LookupFunctionAllowPrivate(getter_name);
    } else if (!field.IsNull() && field.IsUninitialized()) {
      // A field was found.  Check for a getter in the field's owner class.
      const Class& cls = Class::Handle(Z, field.Owner());
      const String& getter_name =
          String::Handle(Z, Field::GetterName(field_name));
      getter = cls.LookupStaticFunctionAllowPrivate(getter_name);
    }

#if !defined(PRODUCT)
    if (tds.enabled()) {
      const String& lib_name = String::Handle(lib.url());
      tds.SetNumArguments(1);
      tds.FormatArgument(0, "name", "%s.%s", lib_name.ToCString(),
                         field_name.ToCString());
    }
#endif  // !defined(PRODUCT)

    if (!getter.IsNull()) {
      // Invoke the getter and return the result.
      return Api::NewHandle(
          T, DartEntry::InvokeFunction(getter, Object::empty_array()));
    }
    if (!field.IsNull()) {
      return Api::NewHandle(T, field.StaticValue());
    }
    return Api::NewError("%s: did not find top-level variable '%s'.",
                         CURRENT_FUNC, field_name.ToCString());

  } else if (obj.IsError()) {
    return container;
  } else {
    return Api::NewError(
        "%s expects argument 'container' to be an object, type, or library.",
        CURRENT_FUNC);
  }
}

DART_EXPORT Dart_Handle Dart_SetField(Dart_Handle container,
                                      Dart_Handle name,
                                      Dart_Handle value) {
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  CHECK_CALLBACK_STATE(T);

  const String& field_name = Api::UnwrapStringHandle(Z, name);
  if (field_name.IsNull()) {
    RETURN_TYPE_ERROR(Z, name, String);
  }

  // Since null is allowed for value, we don't use UnwrapInstanceHandle.
  const Object& value_obj = Object::Handle(Z, Api::UnwrapHandle(value));
  if (!value_obj.IsNull() && !value_obj.IsInstance()) {
    RETURN_TYPE_ERROR(Z, value, Instance);
  }
  Instance& value_instance = Instance::Handle(Z);
  value_instance ^= value_obj.raw();

  Field& field = Field::Handle(Z);
  Function& setter = Function::Handle(Z);
  const Object& obj = Object::Handle(Z, Api::UnwrapHandle(container));
  if (obj.IsNull()) {
    return Api::NewError("%s expects argument 'container' to be non-null.",
                         CURRENT_FUNC);
  } else if (obj.IsType()) {
    if (!Type::Cast(obj).IsFinalized()) {
      return Api::NewError(
          "%s expects argument 'container' to be a fully resolved type.",
          CURRENT_FUNC);
    }

    // To access a static field we may need to use the Field or the
    // setter Function.
    Class& cls = Class::Handle(Z, Type::Cast(obj).type_class());

    field = cls.LookupStaticFieldAllowPrivate(field_name);
    if (field.IsNull()) {
      String& setter_name = String::Handle(Z, Field::SetterName(field_name));
      setter = cls.LookupStaticFunctionAllowPrivate(setter_name);
    }

    if (!setter.IsNull()) {
      // Invoke the setter and return the result.
      const int kNumArgs = 1;
      const Array& args = Array::Handle(Z, Array::New(kNumArgs));
      args.SetAt(0, value_instance);
      const Object& result =
          Object::Handle(Z, DartEntry::InvokeFunction(setter, args));
      if (result.IsError()) {
        return Api::NewHandle(T, result.raw());
      } else {
        return Api::Success();
      }
    } else if (!field.IsNull()) {
      if (field.is_final()) {
        return Api::NewError("%s: cannot set final field '%s'.", CURRENT_FUNC,
                             field_name.ToCString());
      } else {
        field.SetStaticValue(value_instance);
        return Api::Success();
      }
    } else {
      return Api::NewError("%s: did not find static field '%s'.", CURRENT_FUNC,
                           field_name.ToCString());
    }

  } else if (obj.IsInstance()) {
    // Every instance field has a setter Function.  Try to find the
    // setter in any superclass and use that function to access the
    // field.
    const Instance& instance = Instance::Cast(obj);
    Class& cls = Class::Handle(Z, instance.clazz());
    String& setter_name = String::Handle(Z, Field::SetterName(field_name));
    while (!cls.IsNull()) {
      field = cls.LookupInstanceFieldAllowPrivate(field_name);
      if (!field.IsNull() && field.is_final()) {
        return Api::NewError("%s: cannot set final field '%s'.", CURRENT_FUNC,
                             field_name.ToCString());
      }
      setter = cls.LookupDynamicFunctionAllowPrivate(setter_name);
      if (!setter.IsNull()) {
        break;
      }
      cls = cls.SuperClass();
    }

    // Invoke the setter and return the result.
    const int kTypeArgsLen = 0;
    const int kNumArgs = 2;
    const Array& args = Array::Handle(Z, Array::New(kNumArgs));
    args.SetAt(0, instance);
    args.SetAt(1, value_instance);
    if (setter.IsNull()) {
      const Array& args_descriptor = Array::Handle(
          Z, ArgumentsDescriptor::New(kTypeArgsLen, args.Length()));
      return Api::NewHandle(
          T, DartEntry::InvokeNoSuchMethod(instance, setter_name, args,
                                           args_descriptor));
    }
    return Api::NewHandle(T, DartEntry::InvokeFunction(setter, args));

  } else if (obj.IsLibrary()) {
    // To access a top-level we may need to use the Field or the
    // setter Function.  The setter function may either be in the
    // library or in the field's owner class, depending.
    const Library& lib = Library::Cast(obj);
    // Check that the library is loaded.
    if (!lib.Loaded()) {
      return Api::NewError(
          "%s expects library argument 'container' to be loaded.",
          CURRENT_FUNC);
    }
    field = lib.LookupFieldAllowPrivate(field_name);
    if (field.IsNull()) {
      const String& setter_name =
          String::Handle(Z, Field::SetterName(field_name));
      setter ^= lib.LookupFunctionAllowPrivate(setter_name);
    }

    if (!setter.IsNull()) {
      // Invoke the setter and return the result.
      const int kNumArgs = 1;
      const Array& args = Array::Handle(Z, Array::New(kNumArgs));
      args.SetAt(0, value_instance);
      const Object& result =
          Object::Handle(Z, DartEntry::InvokeFunction(setter, args));
      if (result.IsError()) {
        return Api::NewHandle(T, result.raw());
      }
      return Api::Success();
    }
    if (!field.IsNull()) {
      if (field.is_final()) {
        return Api::NewError("%s: cannot set final top-level variable '%s'.",
                             CURRENT_FUNC, field_name.ToCString());
      }
      field.SetStaticValue(value_instance);
      return Api::Success();
    }
    return Api::NewError("%s: did not find top-level variable '%s'.",
                         CURRENT_FUNC, field_name.ToCString());

  } else if (obj.IsError()) {
    return container;
  }
  return Api::NewError(
      "%s expects argument 'container' to be an object, type, or library.",
      CURRENT_FUNC);
}

// --- Exceptions ----

DART_EXPORT Dart_Handle Dart_ThrowException(Dart_Handle exception) {
  Thread* thread = Thread::Current();
  Zone* zone = thread->zone();
  Isolate* isolate = thread->isolate();
  CHECK_ISOLATE(isolate);
  CHECK_CALLBACK_STATE(thread);
  if (Api::IsError(exception)) {
    ::Dart_PropagateError(exception);
  }
  TransitionNativeToVM transition(thread);
  const Instance& excp = Api::UnwrapInstanceHandle(zone, exception);
  if (excp.IsNull()) {
    RETURN_TYPE_ERROR(zone, exception, Instance);
  }
  if (thread->top_exit_frame_info() == 0) {
    // There are no dart frames on the stack so it would be illegal to
    // throw an exception here.
    return Api::NewError("No Dart frames on stack, cannot throw exception");
  }
  // Unwind all the API scopes till the exit frame before throwing an
  // exception.
  const Instance* saved_exception;
  {
    NoSafepointScope no_safepoint;
    RawInstance* raw_exception =
        Api::UnwrapInstanceHandle(zone, exception).raw();
    thread->UnwindScopes(thread->top_exit_frame_info());
    saved_exception = &Instance::Handle(raw_exception);
  }
  Exceptions::Throw(thread, *saved_exception);
  return Api::NewError("Exception was not thrown, internal error");
}

DART_EXPORT Dart_Handle Dart_ReThrowException(Dart_Handle exception,
                                              Dart_Handle stacktrace) {
  Thread* thread = Thread::Current();
  Zone* zone = thread->zone();
  Isolate* isolate = thread->isolate();
  CHECK_ISOLATE(isolate);
  CHECK_CALLBACK_STATE(thread);
  TransitionNativeToVM transition(thread);
  {
    const Instance& excp = Api::UnwrapInstanceHandle(zone, exception);
    if (excp.IsNull()) {
      RETURN_TYPE_ERROR(zone, exception, Instance);
    }
    const Instance& stk = Api::UnwrapInstanceHandle(zone, stacktrace);
    if (stk.IsNull()) {
      RETURN_TYPE_ERROR(zone, stacktrace, Instance);
    }
  }
  if (thread->top_exit_frame_info() == 0) {
    // There are no dart frames on the stack so it would be illegal to
    // throw an exception here.
    return Api::NewError("No Dart frames on stack, cannot throw exception");
  }
  // Unwind all the API scopes till the exit frame before throwing an
  // exception.
  const Instance* saved_exception;
  const StackTrace* saved_stacktrace;
  {
    NoSafepointScope no_safepoint;
    RawInstance* raw_exception =
        Api::UnwrapInstanceHandle(zone, exception).raw();
    RawStackTrace* raw_stacktrace =
        Api::UnwrapStackTraceHandle(zone, stacktrace).raw();
    thread->UnwindScopes(thread->top_exit_frame_info());
    saved_exception = &Instance::Handle(raw_exception);
    saved_stacktrace = &StackTrace::Handle(raw_stacktrace);
  }
  Exceptions::ReThrow(thread, *saved_exception, *saved_stacktrace);
  return Api::NewError("Exception was not re thrown, internal error");
}

// --- Native fields and functions ---

DART_EXPORT Dart_Handle Dart_CreateNativeWrapperClass(Dart_Handle library,
                                                      Dart_Handle name,
                                                      int field_count) {
#if defined(DART_PRECOMPILED_RUNTIME)
  return Api::NewError("%s: Cannot compile on an AOT runtime.", CURRENT_FUNC);
#else
  DARTSCOPE(Thread::Current());
  const String& cls_name = Api::UnwrapStringHandle(Z, name);
  if (cls_name.IsNull()) {
    RETURN_TYPE_ERROR(Z, name, String);
  }
  const Library& lib = Api::UnwrapLibraryHandle(Z, library);
  if (lib.IsNull()) {
    RETURN_TYPE_ERROR(Z, library, Library);
  }
  if (!Utils::IsUint(16, field_count)) {
    return Api::NewError(
        "Invalid field_count passed to Dart_CreateNativeWrapperClass");
  }
  CHECK_CALLBACK_STATE(T);

  String& cls_symbol = String::Handle(Z, Symbols::New(T, cls_name));
  const Class& cls =
      Class::Handle(Z, Class::NewNativeWrapper(lib, cls_symbol, field_count));
  if (cls.IsNull()) {
    return Api::NewError(
        "Unable to create native wrapper class : already exists");
  }
  return Api::NewHandle(T, cls.RareType());
#endif  // defined(DART_PRECOMPILED_RUNTIME)
}

DART_EXPORT Dart_Handle Dart_GetNativeInstanceFieldCount(Dart_Handle obj,
                                                         int* count) {
  Thread* thread = Thread::Current();
  CHECK_ISOLATE(thread->isolate());
  ReusableObjectHandleScope reused_obj_handle(thread);
  const Instance& instance = Api::UnwrapInstanceHandle(reused_obj_handle, obj);
  if (instance.IsNull()) {
    RETURN_TYPE_ERROR(thread->zone(), obj, Instance);
  }
  *count = instance.NumNativeFields();
  return Api::Success();
}

DART_EXPORT Dart_Handle Dart_GetNativeInstanceField(Dart_Handle obj,
                                                    int index,
                                                    intptr_t* value) {
  Thread* thread = Thread::Current();
  CHECK_ISOLATE(thread->isolate());
  ReusableObjectHandleScope reused_obj_handle(thread);
  const Instance& instance = Api::UnwrapInstanceHandle(reused_obj_handle, obj);
  if (instance.IsNull()) {
    RETURN_TYPE_ERROR(thread->zone(), obj, Instance);
  }
  if (!instance.IsValidNativeIndex(index)) {
    return Api::NewError(
        "%s: invalid index %d passed in to access native instance field",
        CURRENT_FUNC, index);
  }
  *value = instance.GetNativeField(index);
  return Api::Success();
}

DART_EXPORT Dart_Handle Dart_SetNativeInstanceField(Dart_Handle obj,
                                                    int index,
                                                    intptr_t value) {
  DARTSCOPE(Thread::Current());
  const Instance& instance = Api::UnwrapInstanceHandle(Z, obj);
  if (instance.IsNull()) {
    RETURN_TYPE_ERROR(Z, obj, Instance);
  }
  if (!instance.IsValidNativeIndex(index)) {
    return Api::NewError(
        "%s: invalid index %d passed in to set native instance field",
        CURRENT_FUNC, index);
  }
  instance.SetNativeField(index, value);
  return Api::Success();
}

DART_EXPORT void* Dart_GetNativeIsolateData(Dart_NativeArguments args) {
  NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
  Isolate* isolate = arguments->thread()->isolate();
  ASSERT(isolate == Isolate::Current());
  return isolate->init_callback_data();
}

DART_EXPORT Dart_Handle Dart_GetNativeArguments(
    Dart_NativeArguments args,
    int num_arguments,
    const Dart_NativeArgument_Descriptor* argument_descriptors,
    Dart_NativeArgument_Value* arg_values) {
  NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
  ASSERT(arguments->thread()->isolate() == Isolate::Current());
  if (arg_values == NULL) {
    RETURN_NULL_ERROR(arg_values);
  }
  for (int i = 0; i < num_arguments; i++) {
    Dart_NativeArgument_Descriptor desc = argument_descriptors[i];
    Dart_NativeArgument_Type arg_type =
        static_cast<Dart_NativeArgument_Type>(desc.type);
    int arg_index = desc.index;
    ASSERT(arg_index >= 0 && arg_index < arguments->NativeArgCount());
    Dart_NativeArgument_Value* native_value = &(arg_values[i]);
    switch (arg_type) {
      case Dart_NativeArgument_kBool:
        if (!Api::GetNativeBooleanArgument(arguments, arg_index,
                                           &(native_value->as_bool))) {
          return Api::NewError(
              "%s: expects argument at index %d to be of"
              " type Boolean.",
              CURRENT_FUNC, i);
        }
        break;

      case Dart_NativeArgument_kInt32: {
        int64_t value = 0;
        if (!GetNativeIntegerArgument(arguments, arg_index, &value)) {
          return Api::NewError(
              "%s: expects argument at index %d to be of"
              " type Integer.",
              CURRENT_FUNC, i);
        }
        if (value < INT_MIN || value > INT_MAX) {
          return Api::NewError("%s: argument value at index %d is out of range",
                               CURRENT_FUNC, i);
        }
        native_value->as_int32 = static_cast<int32_t>(value);
        break;
      }

      case Dart_NativeArgument_kUint32: {
        int64_t value = 0;
        if (!GetNativeIntegerArgument(arguments, arg_index, &value)) {
          return Api::NewError(
              "%s: expects argument at index %d to be of"
              " type Integer.",
              CURRENT_FUNC, i);
        }
        if (value < 0 || value > UINT_MAX) {
          return Api::NewError("%s: argument value at index %d is out of range",
                               CURRENT_FUNC, i);
        }
        native_value->as_uint32 = static_cast<uint32_t>(value);
        break;
      }

      case Dart_NativeArgument_kInt64: {
        int64_t value = 0;
        if (!GetNativeIntegerArgument(arguments, arg_index, &value)) {
          return Api::NewError(
              "%s: expects argument at index %d to be of"
              " type Integer.",
              CURRENT_FUNC, i);
        }
        native_value->as_int64 = value;
        break;
      }

      case Dart_NativeArgument_kUint64: {
        uint64_t value = 0;
        if (!GetNativeUnsignedIntegerArgument(arguments, arg_index, &value)) {
          return Api::NewError(
              "%s: expects argument at index %d to be of"
              " type Integer.",
              CURRENT_FUNC, i);
        }
        native_value->as_uint64 = value;
        break;
      }

      case Dart_NativeArgument_kDouble:
        if (!GetNativeDoubleArgument(arguments, arg_index,
                                     &(native_value->as_double))) {
          return Api::NewError(
              "%s: expects argument at index %d to be of"
              " type Double.",
              CURRENT_FUNC, i);
        }
        break;

      case Dart_NativeArgument_kString:
        if (!GetNativeStringArgument(arguments, arg_index,
                                     &(native_value->as_string.dart_str),
                                     &(native_value->as_string.peer))) {
          return Api::NewError(
              "%s: expects argument at index %d to be of"
              " type String.",
              CURRENT_FUNC, i);
        }
        break;

      case Dart_NativeArgument_kNativeFields: {
        Dart_Handle result = GetNativeFieldsOfArgument(
            arguments, arg_index, native_value->as_native_fields.num_fields,
            native_value->as_native_fields.values, CURRENT_FUNC);
        if (result != Api::Success()) {
          return result;
        }
        break;
      }

      case Dart_NativeArgument_kInstance: {
        ASSERT(arguments->thread() == Thread::Current());
        ASSERT(arguments->thread()->api_top_scope() != NULL);
        native_value->as_instance = Api::NewHandle(
            arguments->thread(), arguments->NativeArgAt(arg_index));
        break;
      }

      default:
        return Api::NewError("%s: invalid argument type %d.", CURRENT_FUNC,
                             arg_type);
    }
  }
  return Api::Success();
}

DART_EXPORT Dart_Handle Dart_GetNativeArgument(Dart_NativeArguments args,
                                               int index) {
  NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
  if ((index < 0) || (index >= arguments->NativeArgCount())) {
    return Api::NewError(
        "%s: argument 'index' out of range. Expected 0..%d but saw %d.",
        CURRENT_FUNC, arguments->NativeArgCount() - 1, index);
  }
  return Api::NewHandle(arguments->thread(), arguments->NativeArgAt(index));
}

DART_EXPORT int Dart_GetNativeArgumentCount(Dart_NativeArguments args) {
  NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
  return arguments->NativeArgCount();
}

DART_EXPORT Dart_Handle
Dart_GetNativeFieldsOfArgument(Dart_NativeArguments args,
                               int arg_index,
                               int num_fields,
                               intptr_t* field_values) {
  NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
  if ((arg_index < 0) || (arg_index >= arguments->NativeArgCount())) {
    return Api::NewError(
        "%s: argument 'arg_index' out of range. Expected 0..%d but saw %d.",
        CURRENT_FUNC, arguments->NativeArgCount() - 1, arg_index);
  }
  if (field_values == NULL) {
    RETURN_NULL_ERROR(field_values);
  }
  return GetNativeFieldsOfArgument(arguments, arg_index, num_fields,
                                   field_values, CURRENT_FUNC);
}

DART_EXPORT Dart_Handle Dart_GetNativeReceiver(Dart_NativeArguments args,
                                               intptr_t* value) {
  NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
  ASSERT(arguments->thread()->isolate() == Isolate::Current());
  if (value == NULL) {
    RETURN_NULL_ERROR(value);
  }
  if (Api::GetNativeReceiver(arguments, value)) {
    return Api::Success();
  }
  return Api::NewError(
      "%s expects receiver argument to be non-null and of"
      " type Instance.",
      CURRENT_FUNC);
}

DART_EXPORT Dart_Handle Dart_GetNativeStringArgument(Dart_NativeArguments args,
                                                     int arg_index,
                                                     void** peer) {
  NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
  Dart_Handle result = Api::Null();
  if (!GetNativeStringArgument(arguments, arg_index, &result, peer)) {
    return Api::NewError(
        "%s expects argument at %d to be of"
        " type String.",
        CURRENT_FUNC, arg_index);
  }
  return result;
}

DART_EXPORT Dart_Handle Dart_GetNativeIntegerArgument(Dart_NativeArguments args,
                                                      int index,
                                                      int64_t* value) {
  NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
  if ((index < 0) || (index >= arguments->NativeArgCount())) {
    return Api::NewError(
        "%s: argument 'index' out of range. Expected 0..%d but saw %d.",
        CURRENT_FUNC, arguments->NativeArgCount() - 1, index);
  }
  if (!GetNativeIntegerArgument(arguments, index, value)) {
    return Api::NewError(
        "%s: expects argument at %d to be of"
        " type Integer.",
        CURRENT_FUNC, index);
  }
  return Api::Success();
}

DART_EXPORT Dart_Handle Dart_GetNativeBooleanArgument(Dart_NativeArguments args,
                                                      int index,
                                                      bool* value) {
  NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
  if ((index < 0) || (index >= arguments->NativeArgCount())) {
    return Api::NewError(
        "%s: argument 'index' out of range. Expected 0..%d but saw %d.",
        CURRENT_FUNC, arguments->NativeArgCount() - 1, index);
  }
  if (!Api::GetNativeBooleanArgument(arguments, index, value)) {
    return Api::NewError("%s: expects argument at %d to be of type Boolean.",
                         CURRENT_FUNC, index);
  }
  return Api::Success();
}

DART_EXPORT Dart_Handle Dart_GetNativeDoubleArgument(Dart_NativeArguments args,
                                                     int index,
                                                     double* value) {
  NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
  if ((index < 0) || (index >= arguments->NativeArgCount())) {
    return Api::NewError(
        "%s: argument 'index' out of range. Expected 0..%d but saw %d.",
        CURRENT_FUNC, arguments->NativeArgCount() - 1, index);
  }
  if (!GetNativeDoubleArgument(arguments, index, value)) {
    return Api::NewError(
        "%s: expects argument at %d to be of"
        " type Double.",
        CURRENT_FUNC, index);
  }
  return Api::Success();
}

DART_EXPORT void Dart_SetReturnValue(Dart_NativeArguments args,
                                     Dart_Handle retval) {
  NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
  ASSERT(arguments->thread()->isolate() == Isolate::Current());
  if ((retval != Api::Null()) && !Api::IsInstance(retval) &&
      !Api::IsError(retval)) {
    // Print the current stack trace to make the problematic caller
    // easier to find.
    const StackTrace& stacktrace = GetCurrentStackTrace(0);
    OS::PrintErr("=== Current Trace:\n%s===\n", stacktrace.ToCString());

    const Object& ret_obj = Object::Handle(Api::UnwrapHandle(retval));
    FATAL1(
        "Return value check failed: saw '%s' expected a dart Instance or "
        "an Error.",
        ret_obj.ToCString());
  }
  ASSERT(retval != 0);
  Api::SetReturnValue(arguments, retval);
}

DART_EXPORT void Dart_SetWeakHandleReturnValue(Dart_NativeArguments args,
                                               Dart_WeakPersistentHandle rval) {
  NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
#if defined(DEBUG)
  Isolate* isolate = arguments->thread()->isolate();
  ASSERT(isolate == Isolate::Current());
  ASSERT(isolate->api_state() != NULL &&
         (isolate->api_state()->IsValidWeakPersistentHandle(rval)));
#endif
  Api::SetWeakHandleReturnValue(arguments, rval);
}

// --- Environment ---
RawString* Api::GetEnvironmentValue(Thread* thread, const String& name) {
  String& result = String::Handle(CallEnvironmentCallback(thread, name));
  if (result.IsNull()) {
    // Every 'dart:X' library introduces an environment variable
    // 'dart.library.X' that is set to 'true'.
    // We just need to make sure to hide private libraries (starting with
    // "_", and the mirrors library, if it is not supported.

    if (!FLAG_enable_mirrors && name.Equals(Symbols::DartLibraryMirrors())) {
      return Symbols::False().raw();
    }

    if (name.Equals(Symbols::DartVMProduct())) {
#ifdef PRODUCT
      return Symbols::True().raw();
#else
      return Symbols::False().raw();
#endif
    }

    const String& prefix = Symbols::DartLibrary();
    if (name.StartsWith(prefix)) {
      const String& library_name =
          String::Handle(String::SubString(name, prefix.Length()));

      // Private libraries (starting with "_") are not exposed to the user.
      if (!library_name.IsNull() && library_name.CharAt(0) != '_') {
        const String& dart_library_name =
            String::Handle(String::Concat(Symbols::DartScheme(), library_name));
        const Library& library =
            Library::Handle(Library::LookupLibrary(thread, dart_library_name));
        if (!library.IsNull()) {
          return Symbols::True().raw();
        }
      }
    }
    // Check for default VM provided values. If it was not overridden on the
    // command line.
    if (Symbols::DartIsVM().Equals(name)) {
      return Symbols::True().raw();
    }
    if (FLAG_causal_async_stacks) {
      if (Symbols::DartDeveloperCausalAsyncStacks().Equals(name)) {
        return Symbols::True().raw();
      }
    }
  }
  return result.raw();
}

RawString* Api::CallEnvironmentCallback(Thread* thread, const String& name) {
  Isolate* isolate = thread->isolate();
  Dart_EnvironmentCallback callback = isolate->environment_callback();
  String& result = String::Handle(thread->zone());
  if (callback != NULL) {
    TransitionVMToNative transition(thread);
    Scope api_scope(thread);
    Dart_Handle response = callback(Api::NewHandle(thread, name.raw()));
    if (::Dart_IsString(response)) {
      result ^= Api::UnwrapHandle(response);
    } else if (::Dart_IsError(response)) {
      const Object& error =
          Object::Handle(thread->zone(), Api::UnwrapHandle(response));
      Exceptions::ThrowArgumentError(
          String::Handle(String::New(Error::Cast(error).ToErrorCString())));
    } else if (!::Dart_IsNull(response)) {
      // At this point everything except null are invalid environment values.
      Exceptions::ThrowArgumentError(
          String::Handle(String::New("Illegal environment value")));
    }
  }
  return result.raw();
}

DART_EXPORT Dart_Handle
Dart_SetEnvironmentCallback(Dart_EnvironmentCallback callback) {
  Isolate* isolate = Isolate::Current();
  CHECK_ISOLATE(isolate);
  isolate->set_environment_callback(callback);
  return Api::Success();
}

// --- Scripts and Libraries ---
DART_EXPORT void Dart_SetBooleanReturnValue(Dart_NativeArguments args,
                                            bool retval) {
  NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
  arguments->SetReturn(Bool::Get(retval));
}

DART_EXPORT void Dart_SetIntegerReturnValue(Dart_NativeArguments args,
                                            int64_t retval) {
  NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
  ASSERT(arguments->thread()->isolate() == Isolate::Current());
  if (Smi::IsValid(retval)) {
    Api::SetSmiReturnValue(arguments, static_cast<intptr_t>(retval));
  } else {
    // Slow path for Mints.
    ASSERT_CALLBACK_STATE(arguments->thread());
    TransitionNativeToVM transition(arguments->thread());
    Api::SetIntegerReturnValue(arguments, retval);
  }
}

DART_EXPORT void Dart_SetDoubleReturnValue(Dart_NativeArguments args,
                                           double retval) {
  NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
  ASSERT_CALLBACK_STATE(arguments->thread());
  TransitionNativeToVM transition(arguments->thread());
  Api::SetDoubleReturnValue(arguments, retval);
}

// --- Scripts and Libraries ---

DART_EXPORT Dart_Handle
Dart_SetLibraryTagHandler(Dart_LibraryTagHandler handler) {
  Isolate* isolate = Isolate::Current();
  CHECK_ISOLATE(isolate);
  isolate->set_library_tag_handler(handler);
  return Api::Success();
}

DART_EXPORT Dart_Handle Dart_DefaultCanonicalizeUrl(Dart_Handle base_url,
                                                    Dart_Handle url) {
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  CHECK_CALLBACK_STATE(T);

  const String& base_uri = Api::UnwrapStringHandle(Z, base_url);
  if (base_uri.IsNull()) {
    RETURN_TYPE_ERROR(Z, base_url, String);
  }
  const String& uri = Api::UnwrapStringHandle(Z, url);
  if (uri.IsNull()) {
    RETURN_TYPE_ERROR(Z, url, String);
  }

  const char* resolved_uri;
  if (!ResolveUri(uri.ToCString(), base_uri.ToCString(), &resolved_uri)) {
    return Api::NewError("%s: Unable to canonicalize uri '%s'.", CURRENT_FUNC,
                         uri.ToCString());
  }
  return Api::NewHandle(T, String::New(resolved_uri));
}

#if !defined(DART_PRECOMPILED_RUNTIME)
// NOTE: Need to pass 'result' as a parameter here in order to avoid
// warning: variable 'result' might be clobbered by 'longjmp' or 'vfork'
// which shows up because of the use of setjmp.
static void CompileSource(Thread* thread,
                          const Library& lib,
                          const Script& script,
                          Dart_Handle* result) {
  bool update_lib_status = (script.kind() == RawScript::kScriptTag ||
                            script.kind() == RawScript::kLibraryTag);
  if (update_lib_status) {
    lib.SetLoadInProgress();
  }
  ASSERT(thread != NULL);
  const Error& error =
      Error::Handle(thread->zone(), Compiler::Compile(lib, script));
  if (error.IsNull()) {
    *result = Api::NewHandle(thread, lib.raw());
  } else {
    *result = Api::NewHandle(thread, error.raw());
    // Compilation errors are not Dart instances, so just mark the library
    // as having failed to load without providing an error instance.
    lib.SetLoadError(Object::null_instance());
  }
}
#endif  // !defined(DART_PRECOMPILED_RUNTIME)

DART_EXPORT Dart_Handle Dart_LoadScript(Dart_Handle url,
                                        Dart_Handle resolved_url,
                                        Dart_Handle source,
                                        intptr_t line_offset,
                                        intptr_t column_offset) {
#if defined(DART_PRECOMPILED_RUNTIME)
  return Api::NewError("%s: Cannot compile on an AOT runtime.", CURRENT_FUNC);
#else
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  Isolate* I = T->isolate();
  const String& url_str = Api::UnwrapStringHandle(Z, url);
  if (url_str.IsNull()) {
    RETURN_TYPE_ERROR(Z, url, String);
  }
  if (::Dart_IsNull(resolved_url)) {
    resolved_url = url;
  }
  const String& resolved_url_str = Api::UnwrapStringHandle(Z, resolved_url);
  if (resolved_url_str.IsNull()) {
    RETURN_TYPE_ERROR(Z, resolved_url, String);
  }
  Library& library = Library::Handle(Z, I->object_store()->root_library());
  if (!library.IsNull()) {
    const String& library_url = String::Handle(Z, library.url());
    return Api::NewError("%s: A script has already been loaded from '%s'.",
                         CURRENT_FUNC, library_url.ToCString());
  }
  if (line_offset < 0) {
    return Api::NewError("%s: argument 'line_offset' must be positive number",
                         CURRENT_FUNC);
  }
  if (column_offset < 0) {
    return Api::NewError("%s: argument 'column_offset' must be positive number",
                         CURRENT_FUNC);
  }
  CHECK_CALLBACK_STATE(T);
  CHECK_COMPILATION_ALLOWED(I);

  Dart_Handle result;
  if (I->use_dart_frontend()) {
    return Api::NewError("%s: Should not be called with using Dart frontend",
                         CURRENT_FUNC);
  }

  const String& source_str = Api::UnwrapStringHandle(Z, source);
  if (source_str.IsNull()) {
    RETURN_TYPE_ERROR(Z, source, String);
  }

  NoHeapGrowthControlScope no_growth_control;

  library = Library::New(url_str);
  library.set_debuggable(true);
  library.Register(T);
  I->object_store()->set_root_library(library);

  const Script& script =
      Script::Handle(Z, Script::New(url_str, resolved_url_str, source_str,
                                    RawScript::kScriptTag));
  script.SetLocationOffset(line_offset, column_offset);
  CompileSource(T, library, script, &result);
  return result;
#endif  // defined(DART_PRECOMPILED_RUNTIME)
}

DART_EXPORT Dart_Handle Dart_LoadScriptFromSnapshot(const uint8_t* buffer,
                                                    intptr_t buffer_len) {
#if defined(DART_PRECOMPILED_RUNTIME)
  return Api::NewError("%s: Cannot compile on an AOT runtime.", CURRENT_FUNC);
#else
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  Isolate* I = T->isolate();
  StackZone zone(T);
  if (buffer == NULL) {
    RETURN_NULL_ERROR(buffer);
  }
  if (I->strong()) {
    return Api::NewError("Script snapshots are not supported in Dart 2");
  }
  NoHeapGrowthControlScope no_growth_control;

  const Snapshot* snapshot = Snapshot::SetupFromBuffer(buffer);
  if (snapshot == NULL) {
    return Api::NewError(
        "%s expects parameter 'buffer' to be a script type"
        " snapshot with a valid length.",
        CURRENT_FUNC);
  }
  if (snapshot->kind() != Snapshot::kScript) {
    return Api::NewError(
        "%s expects parameter 'buffer' to be a script type"
        " snapshot.",
        CURRENT_FUNC);
  }
  if (snapshot->length() != buffer_len) {
    return Api::NewError("%s: 'buffer_len' of %" Pd " is not equal to %" Pd
                         " which is the expected length in the snapshot.",
                         CURRENT_FUNC, buffer_len, snapshot->length());
  }
  Library& library = Library::Handle(Z, I->object_store()->root_library());
  if (!library.IsNull()) {
    const String& library_url = String::Handle(Z, library.url());
    return Api::NewError("%s: A script has already been loaded from '%s'.",
                         CURRENT_FUNC, library_url.ToCString());
  }
  CHECK_CALLBACK_STATE(T);
  CHECK_COMPILATION_ALLOWED(I);

  ASSERT(snapshot->kind() == Snapshot::kScript);
  NOT_IN_PRODUCT(TimelineDurationScope tds2(T, Timeline::GetIsolateStream(),
                                            "ScriptSnapshotReader"));

  ScriptSnapshotReader reader(snapshot->content(), snapshot->length(), T);
  const Object& tmp = Object::Handle(Z, reader.ReadScriptSnapshot());
  if (tmp.IsError()) {
    return Api::NewHandle(T, tmp.raw());
  }
#if !defined(PRODUCT)
  if (tds2.enabled()) {
    tds2.SetNumArguments(2);
    tds2.FormatArgument(0, "snapshotSize", "%" Pd, snapshot->length());
    tds2.FormatArgument(1, "heapSize", "%" Pd64,
                        I->heap()->UsedInWords(Heap::kOld) * kWordSize);
  }
#endif  // !defined(PRODUCT)
  library ^= tmp.raw();
  library.set_debuggable(true);
  I->object_store()->set_root_library(library);
  return Api::NewHandle(T, library.raw());
#endif  // defined(DART_PRECOMPILED_RUNTIME)
}

DART_EXPORT Dart_Handle Dart_LoadScriptFromKernel(const uint8_t* buffer,
                                                  intptr_t buffer_size) {
#if defined(DART_PRECOMPILED_RUNTIME)
  return Api::NewError("%s: Cannot compile on an AOT runtime.", CURRENT_FUNC);
#else
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  StackZone zone(T);
  Isolate* I = T->isolate();

  Library& library = Library::Handle(Z, I->object_store()->root_library());
  if (!library.IsNull()) {
    const String& library_url = String::Handle(Z, library.url());
    return Api::NewError("%s: A script has already been loaded from '%s'.",
                         CURRENT_FUNC, library_url.ToCString());
  }
  CHECK_CALLBACK_STATE(T);
  CHECK_COMPILATION_ALLOWED(I);

  kernel::Program* program = kernel::Program::ReadFromBuffer(
      buffer, buffer_size, false /* take_buffer_ownership */);
  const Object& tmp = kernel::KernelLoader::LoadEntireProgram(program);
  delete program;

  if (tmp.IsError()) {
    return Api::NewHandle(T, tmp.raw());
  }
  // TODO(32618): Setting root library based on whether it has 'main' or not
  // is not correct because main can be in the exported namespace of a library
  // or it could be a getter.
  if (tmp.IsNull()) {
    return Api::NewError("%s: The binary program does not contain 'main'.",
                         CURRENT_FUNC);
  }
  library ^= tmp.raw();
  I->object_store()->set_root_library(library);
  return Api::NewHandle(T, library.raw());
#endif  // defined(DART_PRECOMPILED_RUNTIME)
}

DART_EXPORT Dart_Handle Dart_RootLibrary() {
  Thread* thread = Thread::Current();
  Isolate* isolate = thread->isolate();
  CHECK_ISOLATE(isolate);
  return Api::NewHandle(thread, isolate->object_store()->root_library());
}

DART_EXPORT Dart_Handle Dart_SetRootLibrary(Dart_Handle library) {
  DARTSCOPE(Thread::Current());
  const Object& obj = Object::Handle(Z, Api::UnwrapHandle(library));
  if (obj.IsNull() || obj.IsLibrary()) {
    Library& lib = Library::Handle(Z);
    lib ^= obj.raw();
    T->isolate()->object_store()->set_root_library(lib);
    return library;
  }
  RETURN_TYPE_ERROR(Z, library, Library);
}

DART_EXPORT Dart_Handle Dart_GetClass(Dart_Handle library,
                                      Dart_Handle class_name) {
  DARTSCOPE(Thread::Current());
  const Library& lib = Api::UnwrapLibraryHandle(Z, library);
  if (lib.IsNull()) {
    RETURN_TYPE_ERROR(Z, library, Library);
  }
  const String& cls_name = Api::UnwrapStringHandle(Z, class_name);
  if (cls_name.IsNull()) {
    RETURN_TYPE_ERROR(Z, class_name, String);
  }
  const Class& cls = Class::Handle(Z, lib.LookupClassAllowPrivate(cls_name));
  if (cls.IsNull()) {
    // TODO(turnidge): Return null or error in this case?
    const String& lib_name = String::Handle(Z, lib.name());
    return Api::NewError("Class '%s' not found in library '%s'.",
                         cls_name.ToCString(), lib_name.ToCString());
  }
  return Api::NewHandle(T, cls.RareType());
}

DART_EXPORT Dart_Handle Dart_GetType(Dart_Handle library,
                                     Dart_Handle class_name,
                                     intptr_t number_of_type_arguments,
                                     Dart_Handle* type_arguments) {
  DARTSCOPE(Thread::Current());

  // Validate the input arguments.
  const Library& lib = Api::UnwrapLibraryHandle(Z, library);
  if (lib.IsNull()) {
    RETURN_TYPE_ERROR(Z, library, Library);
  }
  if (!lib.Loaded()) {
    return Api::NewError("%s expects library argument 'library' to be loaded.",
                         CURRENT_FUNC);
  }
  const String& name_str = Api::UnwrapStringHandle(Z, class_name);
  if (name_str.IsNull()) {
    RETURN_TYPE_ERROR(Z, class_name, String);
  }
  const Class& cls = Class::Handle(Z, lib.LookupClassAllowPrivate(name_str));
  if (cls.IsNull()) {
    const String& lib_name = String::Handle(Z, lib.name());
    return Api::NewError("Type '%s' not found in library '%s'.",
                         name_str.ToCString(), lib_name.ToCString());
  }
  if (cls.NumTypeArguments() == 0) {
    if (number_of_type_arguments != 0) {
      return Api::NewError(
          "Invalid number of type arguments specified, "
          "got %" Pd " expected 0",
          number_of_type_arguments);
    }
    return Api::NewHandle(T, Type::NewNonParameterizedType(cls));
  }
  intptr_t num_expected_type_arguments = cls.NumTypeParameters();
  TypeArguments& type_args_obj = TypeArguments::Handle();
  if (number_of_type_arguments > 0) {
    if (type_arguments == NULL) {
      RETURN_NULL_ERROR(type_arguments);
    }
    if (num_expected_type_arguments != number_of_type_arguments) {
      return Api::NewError(
          "Invalid number of type arguments specified, "
          "got %" Pd " expected %" Pd,
          number_of_type_arguments, num_expected_type_arguments);
    }
    const Array& array = Api::UnwrapArrayHandle(Z, *type_arguments);
    if (array.IsNull()) {
      RETURN_TYPE_ERROR(Z, *type_arguments, Array);
    }
    if (array.Length() != num_expected_type_arguments) {
      return Api::NewError(
          "Invalid type arguments specified, expected an "
          "array of len %" Pd " but got an array of len %" Pd,
          number_of_type_arguments, array.Length());
    }
    // Set up the type arguments array.
    type_args_obj ^= TypeArguments::New(num_expected_type_arguments);
    AbstractType& type_arg = AbstractType::Handle();
    for (intptr_t i = 0; i < number_of_type_arguments; i++) {
      type_arg ^= array.At(i);
      type_args_obj.SetTypeAt(i, type_arg);
    }
  }

  // Construct the type object, canonicalize it and return.
  Type& instantiated_type =
      Type::Handle(Type::New(cls, type_args_obj, TokenPosition::kNoSource));
  instantiated_type ^= ClassFinalizer::FinalizeType(cls, instantiated_type);
  return Api::NewHandle(T, instantiated_type.raw());
}

DART_EXPORT Dart_Handle Dart_LibraryUrl(Dart_Handle library) {
  DARTSCOPE(Thread::Current());
  const Library& lib = Api::UnwrapLibraryHandle(Z, library);
  if (lib.IsNull()) {
    RETURN_TYPE_ERROR(Z, library, Library);
  }
  const String& url = String::Handle(Z, lib.url());
  ASSERT(!url.IsNull());
  return Api::NewHandle(T, url.raw());
}

DART_EXPORT Dart_Handle Dart_GetLoadedLibraries() {
  DARTSCOPE(Thread::Current());
  Isolate* I = T->isolate();

  const GrowableObjectArray& libs =
      GrowableObjectArray::Handle(Z, I->object_store()->libraries());
  int num_libs = libs.Length();

  // Create new list and populate with the loaded libraries.
  Library& lib = Library::Handle();
  const Array& library_list = Array::Handle(Z, Array::New(num_libs));
  for (int i = 0; i < num_libs; i++) {
    lib ^= libs.At(i);
    ASSERT(!lib.IsNull());
    library_list.SetAt(i, lib);
  }
  return Api::NewHandle(T, library_list.raw());
}

DART_EXPORT Dart_Handle Dart_LookupLibrary(Dart_Handle url) {
  DARTSCOPE(Thread::Current());
  const String& url_str = Api::UnwrapStringHandle(Z, url);
  if (url_str.IsNull()) {
    RETURN_TYPE_ERROR(Z, url, String);
  }
  const Library& library =
      Library::Handle(Z, Library::LookupLibrary(T, url_str));
  if (library.IsNull()) {
    return Api::NewError("%s: library '%s' not found.", CURRENT_FUNC,
                         url_str.ToCString());
  } else {
    return Api::NewHandle(T, library.raw());
  }
}

DART_EXPORT Dart_Handle Dart_LibraryHandleError(Dart_Handle library_in,
                                                Dart_Handle error_in) {
  DARTSCOPE(Thread::Current());
  Isolate* I = T->isolate();

  const Library& lib = Api::UnwrapLibraryHandle(Z, library_in);
  if (lib.IsNull()) {
    RETURN_TYPE_ERROR(Z, library_in, Library);
  }
  const Instance& err = Api::UnwrapInstanceHandle(Z, error_in);
  if (err.IsNull()) {
    RETURN_TYPE_ERROR(Z, error_in, Instance);
  }
  CHECK_CALLBACK_STATE(T);

  const GrowableObjectArray& pending_deferred_loads =
      GrowableObjectArray::Handle(Z,
                                  I->object_store()->pending_deferred_loads());
  for (intptr_t i = 0; i < pending_deferred_loads.Length(); i++) {
    if (pending_deferred_loads.At(i) == lib.raw()) {
      lib.SetLoadError(err);
      return Api::Null();
    }
  }
  return error_in;
}

DART_EXPORT Dart_Handle Dart_LoadLibrary(Dart_Handle url,
                                         Dart_Handle resolved_url,
                                         Dart_Handle source,
                                         intptr_t line_offset,
                                         intptr_t column_offset) {
#if defined(DART_PRECOMPILED_RUNTIME)
  return Api::NewError("%s: Cannot compile on an AOT runtime.", CURRENT_FUNC);
#else
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  Isolate* I = T->isolate();

  const String& url_str = Api::UnwrapStringHandle(Z, url);
  if (url_str.IsNull()) {
    RETURN_TYPE_ERROR(Z, url, String);
  }
  Dart_Handle result;
  if (I->use_dart_frontend()) {
    return Api::NewError("%s: Should not be called with using Dart frontend",
                         CURRENT_FUNC);
  }
  if (::Dart_IsNull(resolved_url)) {
    resolved_url = url;
  }
  const String& resolved_url_str = Api::UnwrapStringHandle(Z, resolved_url);
  if (resolved_url_str.IsNull()) {
    RETURN_TYPE_ERROR(Z, resolved_url, String);
  }
  const String& source_str = Api::UnwrapStringHandle(Z, source);
  if (source_str.IsNull()) {
    RETURN_TYPE_ERROR(Z, source, String);
  }
  if (line_offset < 0) {
    return Api::NewError("%s: argument 'line_offset' must be positive number",
                         CURRENT_FUNC);
  }
  if (column_offset < 0) {
    return Api::NewError("%s: argument 'column_offset' must be positive number",
                         CURRENT_FUNC);
  }
  CHECK_CALLBACK_STATE(T);
  CHECK_COMPILATION_ALLOWED(I);

  NoHeapGrowthControlScope no_growth_control;

  Library& library = Library::Handle(Z, Library::LookupLibrary(T, url_str));
  if (library.IsNull()) {
    library = Library::New(url_str);
    library.Register(T);
  } else if (library.LoadInProgress() || library.Loaded() ||
             library.LoadFailed()) {
    // The source for this library has either been loaded or is in the
    // process of loading.  Return an error.
    return Api::NewError("%s: library '%s' has already been loaded.",
                         CURRENT_FUNC, url_str.ToCString());
  }
  const Script& script =
      Script::Handle(Z, Script::New(url_str, resolved_url_str, source_str,
                                    RawScript::kLibraryTag));
  script.SetLocationOffset(line_offset, column_offset);
  CompileSource(T, library, script, &result);
  // Propagate the error out right now.
  if (::Dart_IsError(result)) {
    return result;
  }

  // If this is the dart:_builtin library, register it with the VM.
  if (url_str.Equals("dart:_builtin")) {
    I->object_store()->set_builtin_library(library);
    Dart_Handle state = Api::CheckAndFinalizePendingClasses(T);
    if (::Dart_IsError(state)) {
      return state;
    }
  }
  return result;
#endif  // defined(DART_PRECOMPILED_RUNTIME)
}

DART_EXPORT Dart_Handle Dart_LoadLibraryFromKernel(const uint8_t* buffer,
                                                   intptr_t buffer_size) {
#if defined(DART_PRECOMPILED_RUNTIME)
  return Api::NewError("%s: Cannot compile on an AOT runtime.", CURRENT_FUNC);
#else
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  StackZone zone(T);
  Isolate* I = T->isolate();

  CHECK_CALLBACK_STATE(T);
  CHECK_COMPILATION_ALLOWED(I);

  kernel::Program* program = kernel::Program::ReadFromBuffer(
      buffer, buffer_size, false /* take_buffer_ownership */);
  const Object& result =
      kernel::KernelLoader::LoadEntireProgram(program, false);
  delete program;

  return Api::NewHandle(T, result.raw());
#endif  // defined(DART_PRECOMPILED_RUNTIME)
}

DART_EXPORT Dart_Handle Dart_LibraryImportLibrary(Dart_Handle library,
                                                  Dart_Handle import,
                                                  Dart_Handle prefix) {
#if defined(DART_PRECOMPILED_RUNTIME)
  return Api::NewError("%s: Cannot compile on an AOT runtime.", CURRENT_FUNC);
#else
  DARTSCOPE(Thread::Current());
  Isolate* I = T->isolate();
  const Library& library_vm = Api::UnwrapLibraryHandle(Z, library);
  if (library_vm.IsNull()) {
    RETURN_TYPE_ERROR(Z, library, Library);
  }
  const Library& import_vm = Api::UnwrapLibraryHandle(Z, import);
  if (import_vm.IsNull()) {
    RETURN_TYPE_ERROR(Z, import, Library);
  }
  const Object& prefix_object = Object::Handle(Z, Api::UnwrapHandle(prefix));
  const String& prefix_vm =
      prefix_object.IsNull() ? Symbols::Empty() : String::Cast(prefix_object);
  if (prefix_vm.IsNull()) {
    RETURN_TYPE_ERROR(Z, prefix, String);
  }
  CHECK_CALLBACK_STATE(T);
  CHECK_COMPILATION_ALLOWED(I);

  const String& prefix_symbol = String::Handle(Z, Symbols::New(T, prefix_vm));
  const Namespace& import_ns = Namespace::Handle(
      Z, Namespace::New(import_vm, Object::null_array(), Object::null_array()));
  if (prefix_vm.Length() == 0) {
    library_vm.AddImport(import_ns);
  } else {
    LibraryPrefix& library_prefix = LibraryPrefix::Handle();
    library_prefix = library_vm.LookupLocalLibraryPrefix(prefix_symbol);
    if (!library_prefix.IsNull()) {
      library_prefix.AddImport(import_ns);
    } else {
      library_prefix =
          LibraryPrefix::New(prefix_symbol, import_ns, false, library_vm);
      library_vm.AddObject(library_prefix, prefix_symbol);
    }
  }
  return Api::Success();
#endif  // defined(DART_PRECOMPILED_RUNTIME)
}

DART_EXPORT Dart_Handle Dart_GetImportsOfScheme(Dart_Handle scheme) {
  DARTSCOPE(Thread::Current());
  Isolate* I = T->isolate();
  const String& scheme_vm = Api::UnwrapStringHandle(Z, scheme);
  if (scheme_vm.IsNull()) {
    RETURN_TYPE_ERROR(Z, scheme, String);
  }

  const GrowableObjectArray& libraries =
      GrowableObjectArray::Handle(Z, I->object_store()->libraries());
  const GrowableObjectArray& result =
      GrowableObjectArray::Handle(Z, GrowableObjectArray::New());
  Library& importer = Library::Handle(Z);
  Array& imports = Array::Handle(Z);
  Namespace& ns = Namespace::Handle(Z);
  Library& importee = Library::Handle(Z);
  String& importee_uri = String::Handle(Z);
  for (intptr_t i = 0; i < libraries.Length(); i++) {
    importer ^= libraries.At(i);
    imports = importer.imports();
    for (intptr_t j = 0; j < imports.Length(); j++) {
      ns ^= imports.At(j);
      if (ns.IsNull()) continue;
      importee = ns.library();
      importee_uri = importee.url();
      if (importee_uri.StartsWith(scheme_vm)) {
        result.Add(importer);
        result.Add(importee);
      }
    }
  }

  return Api::NewHandle(T, Array::MakeFixedLength(result));
}

DART_EXPORT Dart_Handle Dart_LoadSource(Dart_Handle library,
                                        Dart_Handle url,
                                        Dart_Handle resolved_url,
                                        Dart_Handle source,
                                        intptr_t line_offset,
                                        intptr_t column_offset) {
#if defined(DART_PRECOMPILED_RUNTIME)
  return Api::NewError("%s: Cannot compile on an AOT runtime.", CURRENT_FUNC);
#else
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  Isolate* I = T->isolate();
  const Library& lib = Api::UnwrapLibraryHandle(Z, library);
  if (lib.IsNull()) {
    RETURN_TYPE_ERROR(Z, library, Library);
  }
  const String& url_str = Api::UnwrapStringHandle(Z, url);
  if (url_str.IsNull()) {
    RETURN_TYPE_ERROR(Z, url, String);
  }
  if (::Dart_IsNull(resolved_url)) {
    resolved_url = url;
  }
  const String& resolved_url_str = Api::UnwrapStringHandle(Z, resolved_url);
  if (resolved_url_str.IsNull()) {
    RETURN_TYPE_ERROR(Z, resolved_url, String);
  }
  const String& source_str = Api::UnwrapStringHandle(Z, source);
  if (source_str.IsNull()) {
    RETURN_TYPE_ERROR(Z, source, String);
  }
  if (line_offset < 0) {
    return Api::NewError("%s: argument 'line_offset' must be positive number",
                         CURRENT_FUNC);
  }
  if (column_offset < 0) {
    return Api::NewError("%s: argument 'column_offset' must be positive number",
                         CURRENT_FUNC);
  }
  CHECK_CALLBACK_STATE(T);
  CHECK_COMPILATION_ALLOWED(I);

  NoHeapGrowthControlScope no_growth_control;

  const Script& script =
      Script::Handle(Z, Script::New(url_str, resolved_url_str, source_str,
                                    RawScript::kSourceTag));
  script.SetLocationOffset(line_offset, column_offset);
  Dart_Handle result;
  CompileSource(T, lib, script, &result);
  return result;
#endif  // defined(DART_PRECOMPILED_RUNTIME)
}

DART_EXPORT Dart_Handle Dart_LibraryLoadPatch(Dart_Handle library,
                                              Dart_Handle url,
                                              Dart_Handle patch_source) {
#if defined(DART_PRECOMPILED_RUNTIME)
  return Api::NewError("%s: Cannot compile on an AOT runtime.", CURRENT_FUNC);
#else
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  Isolate* I = T->isolate();
  const Library& lib = Api::UnwrapLibraryHandle(Z, library);
  if (lib.IsNull()) {
    RETURN_TYPE_ERROR(Z, library, Library);
  }
  const String& url_str = Api::UnwrapStringHandle(Z, url);
  if (url_str.IsNull()) {
    RETURN_TYPE_ERROR(Z, url, String);
  }
  const String& source_str = Api::UnwrapStringHandle(Z, patch_source);
  if (source_str.IsNull()) {
    RETURN_TYPE_ERROR(Z, patch_source, String);
  }
  CHECK_CALLBACK_STATE(T);
  CHECK_COMPILATION_ALLOWED(I);

  NoHeapGrowthControlScope no_growth_control;

  const Script& script = Script::Handle(
      Z, Script::New(url_str, url_str, source_str, RawScript::kPatchTag));
  Dart_Handle result;
  CompileSource(T, lib, script, &result);
  return result;
#endif  // defined(DART_PRECOMPILED_RUNTIME)
}

// Finalizes classes and invokes Dart core library function that completes
// futures of loadLibrary calls (deferred library loading).
DART_EXPORT Dart_Handle Dart_FinalizeLoading(bool complete_futures) {
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  Isolate* I = T->isolate();
  CHECK_CALLBACK_STATE(T);

  I->DoneLoading();

  // TODO(hausner): move the remaining code below (finalization and
  // invoking of _completeDeferredLoads) into Isolate::DoneLoading().

  // Finalize all classes if needed.
  Dart_Handle state = Api::CheckAndFinalizePendingClasses(T);
  if (::Dart_IsError(state)) {
    return state;
  }

  I->DoneFinalizing();

#if !defined(PRODUCT)
  // Now that the newly loaded classes are finalized, notify the debugger
  // that new code has been loaded. If there are latent breakpoints in
  // the new code, the debugger convert them to unresolved source breakpoints.
  // The code that completes the futures (invoked below) may call into the
  // newly loaded code and trigger one of these breakpoints.
  I->debugger()->NotifyDoneLoading();
#endif

#if !defined(DART_PRECOMPILED_RUNTIME)
  if (FLAG_enable_mirrors) {
    // Notify mirrors that MirrorSystem.libraries needs to be recomputed.
    const Library& libmirrors = Library::Handle(Z, Library::MirrorsLibrary());
    const Field& dirty_bit = Field::Handle(
        Z, libmirrors.LookupLocalField(String::Handle(String::New("_dirty"))));
    ASSERT(!dirty_bit.IsNull() && dirty_bit.is_static());
    dirty_bit.SetStaticValue(Bool::True());
  }
#endif

  if (complete_futures) {
    const Library& corelib = Library::Handle(Z, Library::CoreLibrary());
    const String& function_name =
        String::Handle(Z, String::New("_completeDeferredLoads"));
    const Function& function =
        Function::Handle(Z, corelib.LookupFunctionAllowPrivate(function_name));
    ASSERT(!function.IsNull());
    const Array& args = Array::empty_array();

    const Object& res =
        Object::Handle(Z, DartEntry::InvokeFunction(function, args));
    I->object_store()->clear_pending_deferred_loads();
    if (res.IsError() || res.IsUnhandledException()) {
      return Api::NewHandle(T, res.raw());
    }
  }
  return Api::Success();
}

DART_EXPORT Dart_Handle
Dart_SetNativeResolver(Dart_Handle library,
                       Dart_NativeEntryResolver resolver,
                       Dart_NativeEntrySymbol symbol) {
  DARTSCOPE(Thread::Current());
  const Library& lib = Api::UnwrapLibraryHandle(Z, library);
  if (lib.IsNull()) {
    RETURN_TYPE_ERROR(Z, library, Library);
  }
  lib.set_native_entry_resolver(resolver);
  lib.set_native_entry_symbol_resolver(symbol);
  return Api::Success();
}

DART_EXPORT Dart_Handle
Dart_GetNativeResolver(Dart_Handle library,
                       Dart_NativeEntryResolver* resolver) {
  if (resolver == NULL) {
    RETURN_NULL_ERROR(resolver);
  }
  *resolver = NULL;
  DARTSCOPE(Thread::Current());
  const Library& lib = Api::UnwrapLibraryHandle(Z, library);
  if (lib.IsNull()) {
    RETURN_TYPE_ERROR(Z, library, Library);
  }
  *resolver = lib.native_entry_resolver();
  return Api::Success();
}

DART_EXPORT Dart_Handle Dart_GetNativeSymbol(Dart_Handle library,
                                             Dart_NativeEntrySymbol* resolver) {
  if (resolver == NULL) {
    RETURN_NULL_ERROR(resolver);
  }
  *resolver = NULL;
  DARTSCOPE(Thread::Current());
  const Library& lib = Api::UnwrapLibraryHandle(Z, library);
  if (lib.IsNull()) {
    RETURN_TYPE_ERROR(Z, library, Library);
  }
  *resolver = lib.native_entry_symbol_resolver();
  return Api::Success();
}

// --- Peer support ---

DART_EXPORT Dart_Handle Dart_GetPeer(Dart_Handle object, void** peer) {
  if (peer == NULL) {
    RETURN_NULL_ERROR(peer);
  }
  Thread* thread = Thread::Current();
  CHECK_ISOLATE(thread->isolate());
  REUSABLE_OBJECT_HANDLESCOPE(thread);
  Object& obj = thread->ObjectHandle();
  obj = Api::UnwrapHandle(object);
  if (obj.IsNull() || obj.IsNumber() || obj.IsBool()) {
    const char* msg =
        "%s: argument 'object' cannot be a subtype of Null, num, or bool";
    return Api::NewError(msg, CURRENT_FUNC);
  }
  {
    NoSafepointScope no_safepoint;
    RawObject* raw_obj = obj.raw();
    *peer = thread->isolate()->heap()->GetPeer(raw_obj);
  }
  return Api::Success();
}

DART_EXPORT Dart_Handle Dart_SetPeer(Dart_Handle object, void* peer) {
  Thread* thread = Thread::Current();
  CHECK_ISOLATE(thread->isolate());
  REUSABLE_OBJECT_HANDLESCOPE(thread);
  Object& obj = thread->ObjectHandle();
  obj = Api::UnwrapHandle(object);
  if (obj.IsNull() || obj.IsNumber() || obj.IsBool()) {
    const char* msg =
        "%s: argument 'object' cannot be a subtype of Null, num, or bool";
    return Api::NewError(msg, CURRENT_FUNC);
  }
  {
    NoSafepointScope no_safepoint;
    RawObject* raw_obj = obj.raw();
    thread->isolate()->heap()->SetPeer(raw_obj, peer);
  }
  return Api::Success();
}

// --- Dart Front-End (Kernel) support ---

DART_EXPORT bool Dart_IsKernelIsolate(Dart_Isolate isolate) {
#if defined(DART_PRECOMPILED_RUNTIME)
  return false;
#else
  Isolate* iso = reinterpret_cast<Isolate*>(isolate);
  return KernelIsolate::IsKernelIsolate(iso);
#endif
}

DART_EXPORT bool Dart_KernelIsolateIsRunning() {
#if defined(DART_PRECOMPILED_RUNTIME)
  return false;
#else
  return KernelIsolate::IsRunning();
#endif
}

DART_EXPORT Dart_Port Dart_KernelPort() {
#if defined(DART_PRECOMPILED_RUNTIME)
  return false;
#else
  return KernelIsolate::KernelPort();
#endif
}

DART_EXPORT Dart_KernelCompilationResult
Dart_CompileToKernel(const char* script_uri,
                     const uint8_t* platform_kernel,
                     intptr_t platform_kernel_size,
                     bool incremental_compile,
                     const char* package_config) {
  Dart_KernelCompilationResult result;
#if defined(DART_PRECOMPILED_RUNTIME)
  result.status = Dart_KernelCompilationStatus_Unknown;
  result.error = strdup("Dart_CompileToKernel is unsupported.");
  return result;
#else
  result = KernelIsolate::CompileToKernel(script_uri, platform_kernel,
                                          platform_kernel_size, 0, NULL,
                                          incremental_compile, package_config);
  if (result.status == Dart_KernelCompilationStatus_Ok) {
    if (KernelIsolate::AcceptCompilation().status !=
        Dart_KernelCompilationStatus_Ok) {
      FATAL(
          "An error occurred in the CFE while accepting the most recent"
          " compilation results.");
    }
  }
  return result;
#endif
}

DART_EXPORT Dart_KernelCompilationResult
Dart_CompileSourcesToKernel(const char* script_uri,
                            const uint8_t* platform_kernel,
                            intptr_t platform_kernel_size,
                            int source_files_count,
                            Dart_SourceFile sources[],
                            bool incremental_compile,
                            const char* package_config) {
  Dart_KernelCompilationResult result;
#if defined(DART_PRECOMPILED_RUNTIME)
  result.status = Dart_KernelCompilationStatus_Unknown;
  result.error = strdup("Dart_CompileSourcesToKernel is unsupported.");
  return result;
#else
  result = KernelIsolate::CompileToKernel(
      script_uri, platform_kernel, platform_kernel_size, source_files_count,
      sources, incremental_compile, package_config);
  if (result.status == Dart_KernelCompilationStatus_Ok) {
    if (KernelIsolate::AcceptCompilation().status !=
        Dart_KernelCompilationStatus_Ok) {
      FATAL(
          "An error occurred in the CFE while accepting the most recent"
          " compilation results.");
    }
  }
  return result;

#endif
}

// --- Service support ---

DART_EXPORT bool Dart_IsServiceIsolate(Dart_Isolate isolate) {
  Isolate* iso = reinterpret_cast<Isolate*>(isolate);
  return ServiceIsolate::IsServiceIsolate(iso);
}

DART_EXPORT Dart_Port Dart_ServiceWaitForLoadPort() {
  return ServiceIsolate::WaitForLoadPort();
}

DART_EXPORT int64_t Dart_TimelineGetMicros() {
  return OS::GetCurrentMonotonicMicros();
}

#if defined(PRODUCT)
DART_EXPORT void Dart_RegisterIsolateServiceRequestCallback(
    const char* name,
    Dart_ServiceRequestCallback callback,
    void* user_data) {
  return;
}

DART_EXPORT void Dart_RegisterRootServiceRequestCallback(
    const char* name,
    Dart_ServiceRequestCallback callback,
    void* user_data) {
  return;
}

DART_EXPORT void Dart_SetEmbedderInformationCallback(
    Dart_EmbedderInformationCallback callback) {
  return;
}

DART_EXPORT Dart_Handle Dart_SetServiceStreamCallbacks(
    Dart_ServiceStreamListenCallback listen_callback,
    Dart_ServiceStreamCancelCallback cancel_callback) {
  return Api::Success();
}

DART_EXPORT Dart_Handle Dart_ServiceSendDataEvent(const char* stream_id,
                                                  const char* event_kind,
                                                  const uint8_t* bytes,
                                                  intptr_t bytes_length) {
  return Api::Success();
}

DART_EXPORT Dart_Handle
Dart_SetFileModifiedCallback(Dart_FileModifiedCallback file_mod_callback) {
  return Api::Success();
}

DART_EXPORT bool Dart_IsReloading() {
  return false;
}

DART_EXPORT void Dart_GlobalTimelineSetRecordedStreams(int64_t stream_mask) {
  return;
}

DART_EXPORT void Dart_SetEmbedderTimelineCallbacks(
    Dart_EmbedderTimelineStartRecording start_recording,
    Dart_EmbedderTimelineStopRecording stop_recording) {
  return;
}

DART_EXPORT bool Dart_GlobalTimelineGetTrace(Dart_StreamConsumer consumer,
                                             void* user_data) {
  return false;
}

DART_EXPORT void Dart_TimelineEvent(const char* label,
                                    int64_t timestamp0,
                                    int64_t timestamp1_or_async_id,
                                    Dart_Timeline_Event_Type type,
                                    intptr_t argument_count,
                                    const char** argument_names,
                                    const char** argument_values) {
  return;
}
#else  // defined(PRODUCT)
DART_EXPORT void Dart_RegisterIsolateServiceRequestCallback(
    const char* name,
    Dart_ServiceRequestCallback callback,
    void* user_data) {
  if (FLAG_support_service) {
    Service::RegisterIsolateEmbedderCallback(name, callback, user_data);
  }
}

DART_EXPORT void Dart_RegisterRootServiceRequestCallback(
    const char* name,
    Dart_ServiceRequestCallback callback,
    void* user_data) {
  if (FLAG_support_service) {
    Service::RegisterRootEmbedderCallback(name, callback, user_data);
  }
}

DART_EXPORT void Dart_SetEmbedderInformationCallback(
    Dart_EmbedderInformationCallback callback) {
  if (FLAG_support_service) {
    Service::SetEmbedderInformationCallback(callback);
  }
}

DART_EXPORT Dart_Handle Dart_SetServiceStreamCallbacks(
    Dart_ServiceStreamListenCallback listen_callback,
    Dart_ServiceStreamCancelCallback cancel_callback) {
  if (!FLAG_support_service) {
    return Api::Success();
  }
  if (listen_callback != NULL) {
    if (Service::stream_listen_callback() != NULL) {
      return Api::NewError(
          "%s permits only one listen callback to be registered, please "
          "remove the existing callback and then add this callback",
          CURRENT_FUNC);
    }
  } else {
    if (Service::stream_listen_callback() == NULL) {
      return Api::NewError(
          "%s expects 'listen_callback' to be present in the callback set.",
          CURRENT_FUNC);
    }
  }
  if (cancel_callback != NULL) {
    if (Service::stream_cancel_callback() != NULL) {
      return Api::NewError(
          "%s permits only one cancel callback to be registered, please "
          "remove the existing callback and then add this callback",
          CURRENT_FUNC);
    }
  } else {
    if (Service::stream_cancel_callback() == NULL) {
      return Api::NewError(
          "%s expects 'cancel_callback' to be present in the callback set.",
          CURRENT_FUNC);
    }
  }
  Service::SetEmbedderStreamCallbacks(listen_callback, cancel_callback);
  return Api::Success();
}

DART_EXPORT Dart_Handle Dart_ServiceSendDataEvent(const char* stream_id,
                                                  const char* event_kind,
                                                  const uint8_t* bytes,
                                                  intptr_t bytes_length) {
  DARTSCOPE(Thread::Current());
  Isolate* I = T->isolate();
  if (stream_id == NULL) {
    RETURN_NULL_ERROR(stream_id);
  }
  if (event_kind == NULL) {
    RETURN_NULL_ERROR(event_kind);
  }
  if (bytes == NULL) {
    RETURN_NULL_ERROR(bytes);
  }
  if (bytes_length < 0) {
    return Api::NewError("%s expects argument 'bytes_length' to be >= 0.",
                         CURRENT_FUNC);
  }
  Service::SendEmbedderEvent(I, stream_id, event_kind, bytes, bytes_length);
  return Api::Success();
}

DART_EXPORT Dart_Handle
Dart_SetFileModifiedCallback(Dart_FileModifiedCallback file_modified_callback) {
  if (!FLAG_support_service) {
    return Api::Success();
  }
#if !defined(DART_PRECOMPILED_RUNTIME)
  if (file_modified_callback != NULL) {
    if (IsolateReloadContext::file_modified_callback() != NULL) {
      return Api::NewError(
          "%s permits only one callback to be registered, please "
          "remove the existing callback and then add this callback",
          CURRENT_FUNC);
    }
  } else {
    if (IsolateReloadContext::file_modified_callback() == NULL) {
      return Api::NewError(
          "%s expects 'file_modified_callback' to be set before it is cleared.",
          CURRENT_FUNC);
    }
  }
  IsolateReloadContext::SetFileModifiedCallback(file_modified_callback);
#endif  // !defined(DART_PRECOMPILED_RUNTIME)
  return Api::Success();
}

DART_EXPORT bool Dart_IsReloading() {
  Thread* thread = Thread::Current();
  Isolate* isolate = thread->isolate();
  CHECK_ISOLATE(isolate);
  return isolate->IsReloading();
}

DART_EXPORT void Dart_GlobalTimelineSetRecordedStreams(int64_t stream_mask) {
  if (!FLAG_support_timeline) {
    return;
  }
  const bool api_enabled = (stream_mask & DART_TIMELINE_STREAM_API) != 0;
  const bool compiler_enabled =
      (stream_mask & DART_TIMELINE_STREAM_COMPILER) != 0;
  const bool dart_enabled = (stream_mask & DART_TIMELINE_STREAM_DART) != 0;
  const bool debugger_enabled =
      (stream_mask & DART_TIMELINE_STREAM_DEBUGGER) != 0;
  const bool embedder_enabled =
      (stream_mask & DART_TIMELINE_STREAM_EMBEDDER) != 0;
  const bool gc_enabled = (stream_mask & DART_TIMELINE_STREAM_GC) != 0;
  const bool isolate_enabled =
      (stream_mask & DART_TIMELINE_STREAM_ISOLATE) != 0;
  const bool vm_enabled = (stream_mask & DART_TIMELINE_STREAM_VM) != 0;
  Timeline::SetStreamAPIEnabled(api_enabled);
  Timeline::SetStreamCompilerEnabled(compiler_enabled);
  Timeline::SetStreamDartEnabled(dart_enabled);
  Timeline::SetStreamDebuggerEnabled(debugger_enabled);
  Timeline::SetStreamEmbedderEnabled(embedder_enabled);
  Timeline::SetStreamGCEnabled(gc_enabled);
  Timeline::SetStreamIsolateEnabled(isolate_enabled);
  Timeline::SetStreamVMEnabled(vm_enabled);
}

static void StartStreamToConsumer(Dart_StreamConsumer consumer,
                                  void* user_data,
                                  const char* stream_name) {
  // Start stream.
  consumer(Dart_StreamConsumer_kStart, stream_name, NULL, 0, user_data);
}

static void FinishStreamToConsumer(Dart_StreamConsumer consumer,
                                   void* user_data,
                                   const char* stream_name) {
  // Finish stream.
  consumer(Dart_StreamConsumer_kFinish, stream_name, NULL, 0, user_data);
}

static void DataStreamToConsumer(Dart_StreamConsumer consumer,
                                 void* user_data,
                                 const char* output,
                                 intptr_t output_length,
                                 const char* stream_name) {
  if (output == NULL) {
    return;
  }
  const intptr_t kDataSize = 64 * KB;
  intptr_t cursor = 0;
  intptr_t remaining = output_length;
  while (remaining >= kDataSize) {
    consumer(Dart_StreamConsumer_kData, stream_name,
             reinterpret_cast<const uint8_t*>(&output[cursor]), kDataSize,
             user_data);
    cursor += kDataSize;
    remaining -= kDataSize;
  }
  if (remaining > 0) {
    ASSERT(remaining < kDataSize);
    consumer(Dart_StreamConsumer_kData, stream_name,
             reinterpret_cast<const uint8_t*>(&output[cursor]), remaining,
             user_data);
    cursor += remaining;
    remaining -= remaining;
  }
  ASSERT(cursor == output_length);
  ASSERT(remaining == 0);
}

static bool StreamTraceEvents(Dart_StreamConsumer consumer,
                              void* user_data,
                              JSONStream* js) {
  ASSERT(js != NULL);
  // Steal output from JSONStream.
  char* output = NULL;
  intptr_t output_length = 0;
  js->Steal(&output, &output_length);
  if (output_length < 3) {
    // Empty JSON array.
    free(output);
    return false;
  }
  // We want to send the JSON array without the leading '[' or trailing ']'
  // characters.
  ASSERT(output[0] == '[');
  ASSERT(output[output_length - 1] == ']');
  // Replace the ']' with the null character.
  output[output_length - 1] = '\0';
  char* start = &output[1];
  // We are skipping the '['.
  output_length -= 1;

  DataStreamToConsumer(consumer, user_data, start, output_length, "timeline");

  // We stole the JSONStream's output buffer, free it.
  free(output);

  return true;
}

DART_EXPORT void Dart_SetEmbedderTimelineCallbacks(
    Dart_EmbedderTimelineStartRecording start_recording,
    Dart_EmbedderTimelineStopRecording stop_recording) {
  if (!FLAG_support_timeline) {
    return;
  }
  Timeline::set_start_recording_cb(start_recording);
  Timeline::set_stop_recording_cb(stop_recording);
}

DART_EXPORT bool Dart_GlobalTimelineGetTrace(Dart_StreamConsumer consumer,
                                             void* user_data) {
  if (!FLAG_support_timeline) {
    return false;
  }
  // To support various embedders, it must be possible to call this function
  // from a thread for which we have not entered an Isolate and set up a Thread
  // TLS object. Therefore, a Zone may not be available, a StackZone cannot be
  // created, and no ZoneAllocated objects can be allocated.
  if (consumer == NULL) {
    return false;
  }
  TimelineEventRecorder* timeline_recorder = Timeline::recorder();
  if (timeline_recorder == NULL) {
    // Nothing has been recorded.
    return false;
  }
  Timeline::ReclaimCachedBlocksFromThreads();
  bool success = false;
  JSONStream js;
  TimelineEventFilter filter;
  timeline_recorder->PrintTraceEvent(&js, &filter);
  StartStreamToConsumer(consumer, user_data, "timeline");
  if (StreamTraceEvents(consumer, user_data, &js)) {
    success = true;
  }
  FinishStreamToConsumer(consumer, user_data, "timeline");
  return success;
}

DART_EXPORT void Dart_TimelineEvent(const char* label,
                                    int64_t timestamp0,
                                    int64_t timestamp1_or_async_id,
                                    Dart_Timeline_Event_Type type,
                                    intptr_t argument_count,
                                    const char** argument_names,
                                    const char** argument_values) {
  if (!FLAG_support_timeline) {
    return;
  }
  if (type < Dart_Timeline_Event_Begin) {
    return;
  }
  if (type > Dart_Timeline_Event_Flow_End) {
    return;
  }
  TimelineStream* stream = Timeline::GetEmbedderStream();
  ASSERT(stream != NULL);
  TimelineEvent* event = stream->StartEvent();
  if (event == NULL) {
    return;
  }
  label = strdup(label);
  switch (type) {
    case Dart_Timeline_Event_Begin:
      event->Begin(label, timestamp0);
      break;
    case Dart_Timeline_Event_End:
      event->End(label, timestamp0);
      break;
    case Dart_Timeline_Event_Instant:
      event->Instant(label, timestamp0);
      break;
    case Dart_Timeline_Event_Duration:
      event->Duration(label, timestamp0, timestamp1_or_async_id);
      break;
    case Dart_Timeline_Event_Async_Begin:
      event->AsyncBegin(label, timestamp1_or_async_id, timestamp0);
      break;
    case Dart_Timeline_Event_Async_End:
      event->AsyncEnd(label, timestamp1_or_async_id, timestamp0);
      break;
    case Dart_Timeline_Event_Async_Instant:
      event->AsyncInstant(label, timestamp1_or_async_id, timestamp0);
      break;
    case Dart_Timeline_Event_Counter:
      event->Counter(label, timestamp0);
      break;
    case Dart_Timeline_Event_Flow_Begin:
      event->FlowBegin(label, timestamp1_or_async_id, timestamp0);
      break;
    case Dart_Timeline_Event_Flow_Step:
      event->FlowStep(label, timestamp1_or_async_id, timestamp0);
      break;
    case Dart_Timeline_Event_Flow_End:
      event->FlowEnd(label, timestamp1_or_async_id, timestamp0);
      break;
    default:
      FATAL("Unknown Dart_Timeline_Event_Type");
  }
  event->set_owns_label(true);
  event->SetNumArguments(argument_count);
  for (intptr_t i = 0; i < argument_count; i++) {
    event->CopyArgument(i, argument_names[i], argument_values[i]);
  }
  event->Complete();
}
#endif  // defined(PRODUCT)

DART_EXPORT void Dart_SetThreadName(const char* name) {
  OSThread* thread = OSThread::Current();
  if (thread == NULL) {
    // VM is shutting down.
    return;
  }
  thread->SetName(name);
}

DART_EXPORT
Dart_Handle Dart_SaveCompilationTrace(uint8_t** buffer,
                                      intptr_t* buffer_length) {
#if defined(DART_PRECOMPILED_RUNTIME)
  return Api::NewError("%s: Cannot compile on an AOT runtime.", CURRENT_FUNC);
#else
  Thread* thread = Thread::Current();
  API_TIMELINE_DURATION(thread);
  DARTSCOPE(thread);
  CHECK_NULL(buffer);
  CHECK_NULL(buffer_length);
  CompilationTraceSaver saver(thread->zone());
  ProgramVisitor::VisitFunctions(&saver);
  saver.StealBuffer(buffer, buffer_length);
  return Api::Success();
#endif  // defined(DART_PRECOMPILED_RUNTIME)
}

DART_EXPORT
Dart_Handle Dart_LoadCompilationTrace(uint8_t* buffer, intptr_t buffer_length) {
#if defined(DART_PRECOMPILED_RUNTIME)
  return Api::NewError("%s: Cannot compile on an AOT runtime.", CURRENT_FUNC);
#else
  Thread* thread = Thread::Current();
  API_TIMELINE_DURATION(thread);
  DARTSCOPE(thread);
  CHECK_NULL(buffer);
  CompilationTraceLoader loader(thread);
  const Object& error =
      Object::Handle(loader.CompileTrace(buffer, buffer_length));
  if (error.IsError()) {
    return Api::NewHandle(T, Error::Cast(error).raw());
  }
  return Api::Success();
#endif  // defined(DART_PRECOMPILED_RUNTIME)
}

DART_EXPORT Dart_Handle Dart_SortClasses() {
#if defined(DART_PRECOMPILED_RUNTIME)
  return Api::NewError("%s: Cannot compile on an AOT runtime.", CURRENT_FUNC);
#else
  DARTSCOPE(Thread::Current());
  // We don't have mechanisms to change class-ids that are embedded in code and
  // ICData.
  ClassFinalizer::ClearAllCode();
  // Make sure that ICData etc. that have been cleared are also removed from
  // the heap so that they are not found by the heap verifier.
  Isolate::Current()->heap()->CollectAllGarbage();
  ClassFinalizer::SortClasses();
  return Api::Success();
#endif  // defined(DART_PRECOMPILED_RUNTIME)
}

DART_EXPORT Dart_Handle
Dart_Precompile(Dart_QualifiedFunctionName entry_points[]) {
#if defined(TARGET_ARCH_IA32)
  return Api::NewError("AOT compilation is not supported on IA32.");
#elif defined(TARGET_ARCH_DBC)
  return Api::NewError("AOT compilation is not supported on DBC.");
#elif !defined(DART_PRECOMPILER)
  return Api::NewError(
      "This VM was built without support for AOT compilation.");
#else
  DARTSCOPE(Thread::Current());
  API_TIMELINE_BEGIN_END(T);
  if (!FLAG_precompiled_mode) {
    return Api::NewError("Flag --precompilation was not specified.");
  }
  Dart_Handle result = Api::CheckAndFinalizePendingClasses(T);
  if (::Dart_IsError(result)) {
    return result;
  }
  CHECK_CALLBACK_STATE(T);
  const Error& error = Error::Handle(Precompiler::CompileAll(entry_points));
  if (!error.IsNull()) {
    return Api::NewHandle(T, error.raw());
  }
  return Api::Success();
#endif
}

DART_EXPORT Dart_Handle
Dart_CreateAppAOTSnapshotAsAssembly(Dart_StreamingWriteCallback callback,
                                    void* callback_data) {
#if defined(TARGET_ARCH_IA32)
  return Api::NewError("AOT compilation is not supported on IA32.");
#elif defined(TARGET_ARCH_DBC)
  return Api::NewError("AOT compilation is not supported on DBC.");
#elif defined(TARGET_OS_WINDOWS)
  return Api::NewError("Assembly generation is not implemented for Windows.");
#elif !defined(DART_PRECOMPILER)
  return Api::NewError(
      "This VM was built without support for AOT compilation.");
#else
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  Isolate* I = T->isolate();
  if (I->compilation_allowed()) {
    return Api::NewError(
        "Isolate is not precompiled. "
        "Did you forget to call Dart_Precompile?");
  }
  ASSERT(FLAG_load_deferred_eagerly);
  CHECK_NULL(callback);

  NOT_IN_PRODUCT(TimelineDurationScope tds2(T, Timeline::GetIsolateStream(),
                                            "WriteAppAOTSnapshot"));
  AssemblyImageWriter image_writer(callback, callback_data, NULL, NULL);
  uint8_t* vm_snapshot_data_buffer = NULL;
  uint8_t* isolate_snapshot_data_buffer = NULL;
  FullSnapshotWriter writer(Snapshot::kFullAOT, &vm_snapshot_data_buffer,
                            &isolate_snapshot_data_buffer, ApiReallocate,
                            &image_writer, &image_writer);

  writer.WriteFullSnapshot();
  image_writer.Finalize();

  return Api::Success();
#endif
}

DART_EXPORT Dart_Handle
Dart_CreateVMAOTSnapshotAsAssembly(Dart_StreamingWriteCallback callback,
                                   void* callback_data) {
#if defined(TARGET_ARCH_IA32)
  return Api::NewError("AOT compilation is not supported on IA32.");
#elif defined(TARGET_ARCH_DBC)
  return Api::NewError("AOT compilation is not supported on DBC.");
#elif defined(TARGET_OS_WINDOWS)
  return Api::NewError("Assembly generation is not implemented for Windows.");
#elif !defined(DART_PRECOMPILER)
  return Api::NewError(
      "This VM was built without support for AOT compilation.");
#else
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  CHECK_NULL(callback);

  NOT_IN_PRODUCT(TimelineDurationScope tds2(T, Timeline::GetIsolateStream(),
                                            "WriteVMAOTSnapshot"));
  AssemblyImageWriter image_writer(callback, callback_data, NULL, NULL);
  uint8_t* vm_snapshot_data_buffer = NULL;
  FullSnapshotWriter writer(Snapshot::kFullAOT, &vm_snapshot_data_buffer, NULL,
                            ApiReallocate, &image_writer, NULL);

  writer.WriteFullSnapshot();

  return Api::Success();
#endif
}

DART_EXPORT Dart_Handle
Dart_CreateAppAOTSnapshotAsBlobs(uint8_t** vm_snapshot_data_buffer,
                                 intptr_t* vm_snapshot_data_size,
                                 uint8_t** vm_snapshot_instructions_buffer,
                                 intptr_t* vm_snapshot_instructions_size,
                                 uint8_t** isolate_snapshot_data_buffer,
                                 intptr_t* isolate_snapshot_data_size,
                                 uint8_t** isolate_snapshot_instructions_buffer,
                                 intptr_t* isolate_snapshot_instructions_size,
                                 const uint8_t* shared_data,
                                 const uint8_t* shared_instructions) {
#if defined(TARGET_ARCH_IA32)
  return Api::NewError("AOT compilation is not supported on IA32.");
#elif defined(TARGET_ARCH_DBC)
  return Api::NewError("AOT compilation is not supported on DBC.");
#elif !defined(DART_PRECOMPILER)
  return Api::NewError(
      "This VM was built without support for AOT compilation.");
#else
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  Isolate* I = T->isolate();
  if (I->compilation_allowed()) {
    return Api::NewError(
        "Isolate is not precompiled. "
        "Did you forget to call Dart_Precompile?");
  }
  ASSERT(FLAG_load_deferred_eagerly);
  CHECK_NULL(vm_snapshot_data_buffer);
  CHECK_NULL(vm_snapshot_data_size);
  CHECK_NULL(vm_snapshot_instructions_buffer);
  CHECK_NULL(vm_snapshot_instructions_size);
  CHECK_NULL(isolate_snapshot_data_buffer);
  CHECK_NULL(isolate_snapshot_data_size);
  CHECK_NULL(isolate_snapshot_instructions_buffer);
  CHECK_NULL(isolate_snapshot_instructions_size);

  const void* shared_data_image = NULL;
  if (shared_data != NULL) {
    shared_data_image = Snapshot::SetupFromBuffer(shared_data)->DataImage();
  }
  const void* shared_instructions_image = shared_instructions;

  NOT_IN_PRODUCT(TimelineDurationScope tds2(T, Timeline::GetIsolateStream(),
                                            "WriteAppAOTSnapshot"));
  BlobImageWriter vm_image_writer(vm_snapshot_instructions_buffer,
                                  ApiReallocate, 2 * MB /* initial_size */,
                                  NULL, NULL);
  BlobImageWriter isolate_image_writer(
      isolate_snapshot_instructions_buffer, ApiReallocate,
      2 * MB /* initial_size */, shared_data_image, shared_instructions_image);
  FullSnapshotWriter writer(Snapshot::kFullAOT, vm_snapshot_data_buffer,
                            isolate_snapshot_data_buffer, ApiReallocate,
                            &vm_image_writer, &isolate_image_writer);

  writer.WriteFullSnapshot();
  *vm_snapshot_data_size = writer.VmIsolateSnapshotSize();
  *vm_snapshot_instructions_size = vm_image_writer.InstructionsBlobSize();
  *isolate_snapshot_data_size = writer.IsolateSnapshotSize();
  *isolate_snapshot_instructions_size =
      isolate_image_writer.InstructionsBlobSize();

  return Api::Success();
#endif
}

DART_EXPORT Dart_Handle Dart_CreateCoreJITSnapshotAsBlobs(
    uint8_t** vm_snapshot_data_buffer,
    intptr_t* vm_snapshot_data_size,
    uint8_t** vm_snapshot_instructions_buffer,
    intptr_t* vm_snapshot_instructions_size,
    uint8_t** isolate_snapshot_data_buffer,
    intptr_t* isolate_snapshot_data_size,
    uint8_t** isolate_snapshot_instructions_buffer,
    intptr_t* isolate_snapshot_instructions_size) {
#if defined(TARGET_ARCH_IA32)
  return Api::NewError("Snapshots with code are not supported on IA32.");
#elif defined(DART_PRECOMPILED_RUNTIME)
  return Api::NewError("JIT app snapshots cannot be taken from an AOT runtime");
#else
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  Isolate* I = T->isolate();
  if (!FLAG_load_deferred_eagerly) {
    return Api::NewError(
        "Creating full snapshots requires --load_deferred_eagerly");
  }
  CHECK_NULL(vm_snapshot_data_buffer);
  CHECK_NULL(vm_snapshot_data_size);
  CHECK_NULL(vm_snapshot_instructions_buffer);
  CHECK_NULL(vm_snapshot_instructions_size);
  CHECK_NULL(isolate_snapshot_data_buffer);
  CHECK_NULL(isolate_snapshot_data_size);
  CHECK_NULL(isolate_snapshot_instructions_buffer);
  CHECK_NULL(isolate_snapshot_instructions_size);
  // Finalize all classes if needed.
  Dart_Handle state = Api::CheckAndFinalizePendingClasses(T);
  if (::Dart_IsError(state)) {
    return state;
  }
  BackgroundCompiler::Stop(I);

  ProgramVisitor::Dedup();
  Symbols::Compact(I);

  NOT_IN_PRODUCT(TimelineDurationScope tds2(T, Timeline::GetIsolateStream(),
                                            "WriteCoreJITSnapshot"));
  BlobImageWriter vm_image_writer(vm_snapshot_instructions_buffer,
                                  ApiReallocate, 2 * MB /* initial_size */,
                                  NULL, NULL);
  BlobImageWriter isolate_image_writer(isolate_snapshot_instructions_buffer,
                                       ApiReallocate, 2 * MB /* initial_size */,
                                       NULL, NULL);
  FullSnapshotWriter writer(Snapshot::kFullJIT, vm_snapshot_data_buffer,
                            isolate_snapshot_data_buffer, ApiReallocate,
                            &vm_image_writer, &isolate_image_writer);
  writer.WriteFullSnapshot();

  *vm_snapshot_data_size = writer.VmIsolateSnapshotSize();
  *vm_snapshot_instructions_size = vm_image_writer.InstructionsBlobSize();
  *isolate_snapshot_data_size = writer.IsolateSnapshotSize();
  *isolate_snapshot_instructions_size =
      isolate_image_writer.InstructionsBlobSize();

  return Api::Success();
#endif
}

DART_EXPORT Dart_Handle
Dart_CreateAppJITSnapshotAsBlobs(uint8_t** isolate_snapshot_data_buffer,
                                 intptr_t* isolate_snapshot_data_size,
                                 uint8_t** isolate_snapshot_instructions_buffer,
                                 intptr_t* isolate_snapshot_instructions_size) {
#if defined(TARGET_ARCH_IA32)
  return Api::NewError("Snapshots with code are not supported on IA32.");
#elif defined(DART_PRECOMPILED_RUNTIME)
  return Api::NewError("JIT app snapshots cannot be taken from an AOT runtime");
#else
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  Isolate* I = T->isolate();
  if (!FLAG_load_deferred_eagerly) {
    return Api::NewError(
        "Creating full snapshots requires --load_deferred_eagerly");
  }
  CHECK_NULL(isolate_snapshot_data_buffer);
  CHECK_NULL(isolate_snapshot_data_size);
  CHECK_NULL(isolate_snapshot_instructions_buffer);
  CHECK_NULL(isolate_snapshot_instructions_size);
  // Finalize all classes if needed.
  Dart_Handle state = Api::CheckAndFinalizePendingClasses(T);
  if (::Dart_IsError(state)) {
    return state;
  }
  BackgroundCompiler::Stop(I);

  ProgramVisitor::Dedup();
  Symbols::Compact(I);

  NOT_IN_PRODUCT(TimelineDurationScope tds2(T, Timeline::GetIsolateStream(),
                                            "WriteAppJITSnapshot"));
  BlobImageWriter isolate_image_writer(isolate_snapshot_instructions_buffer,
                                       ApiReallocate, 2 * MB /* initial_size */,
                                       NULL, NULL);
  FullSnapshotWriter writer(Snapshot::kFullJIT, NULL,
                            isolate_snapshot_data_buffer, ApiReallocate, NULL,
                            &isolate_image_writer);
  writer.WriteFullSnapshot();

  *isolate_snapshot_data_size = writer.IsolateSnapshotSize();
  *isolate_snapshot_instructions_size =
      isolate_image_writer.InstructionsBlobSize();

  return Api::Success();
#endif
}

DART_EXPORT Dart_Handle Dart_GetObfuscationMap(uint8_t** buffer,
                                               intptr_t* buffer_length) {
#if defined(DART_PRECOMPILED_RUNTIME)
  return Api::NewError("No obfuscation map to save on an AOT runtime.");
#elif !defined(DART_PRECOMPILER)
  return Api::NewError("Obfuscation is only supported for AOT compiler.");
#else
  Thread* thread = Thread::Current();
  DARTSCOPE(thread);
  Isolate* isolate = thread->isolate();

  if (buffer == NULL) {
    RETURN_NULL_ERROR(buffer);
  }
  if (buffer_length == NULL) {
    RETURN_NULL_ERROR(buffer_length);
  }

  // Note: can't use JSONStream in PRODUCT builds.
  const intptr_t kInitialBufferSize = 1 * MB;
  TextBuffer text_buffer(kInitialBufferSize);

  text_buffer.AddChar('[');
  if (isolate->obfuscation_map() != NULL) {
    for (intptr_t i = 0; isolate->obfuscation_map()[i] != NULL; i++) {
      if (i > 0) {
        text_buffer.AddChar(',');
      }
      text_buffer.AddChar('"');
      text_buffer.AddEscapedString(isolate->obfuscation_map()[i]);
      text_buffer.AddChar('"');
    }
  }
  text_buffer.AddChar(']');

  *buffer_length = text_buffer.length();
  *reinterpret_cast<char**>(buffer) = text_buffer.Steal();
  return Api::Success();
#endif
}

DART_EXPORT bool Dart_IsPrecompiledRuntime() {
#if defined(DART_PRECOMPILED_RUNTIME)
  return true;
#else
  return false;
#endif
}

DART_EXPORT void Dart_DumpNativeStackTrace(void* context) {
#ifndef PRODUCT
  Profiler::DumpStackTrace(context);
#endif
}

}  // namespace dart
