// 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 <cstring>
#include <memory>
#include <utility>

#include "lib/stacktrace.h"
#include "platform/address_sanitizer.h"
#include "platform/assert.h"
#include "platform/memory_sanitizer.h"
#include "platform/thread_sanitizer.h"
#include "platform/unicode.h"
#include "vm/app_snapshot.h"
#include "vm/bytecode_reader.h"
#include "vm/class_finalizer.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"
#include "vm/dwarf.h"
#include "vm/elf.h"
#include "vm/exceptions.h"
#include "vm/flags.h"
#include "vm/growable_array.h"
#include "vm/heap/verifier.h"
#include "vm/image_snapshot.h"
#include "vm/isolate_reload.h"
#include "vm/kernel_isolate.h"
#include "vm/lockers.h"
#include "vm/mach_o.h"
#include "vm/message.h"
#include "vm/message_handler.h"
#include "vm/message_snapshot.h"
#include "vm/module_snapshot.h"
#include "vm/native_entry.h"
#include "vm/native_symbol.h"
#include "vm/object.h"
#include "vm/object_graph.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/profiler_service.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/version.h"
#include "vm/zone_text_buffer.h"

#if !defined(DART_PRECOMPILED_RUNTIME)
#include "vm/compiler/aot/precompiler.h"
#include "vm/kernel_loader.h"
#endif  // !defined(DART_PRECOMPILED_RUNTIME)

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);
#if defined(DEBUG) && !defined(DART_PRECOMPILED_RUNTIME)
DEFINE_FLAG(bool,
            check_function_fingerprints,
            true,
            "Check function fingerprints");
#endif  // defined(DEBUG) && !defined(DART_PRECOMPILED_RUNTIME).
DEFINE_FLAG(bool,
            verify_acquired_data,
            false,
            "Verify correct API acquire/release of typed data.");
DEFINE_FLAG(bool,
            dump_tables,
            false,
            "Dump common hash tables before snapshotting.");
DEFINE_FLAG(bool,
            enable_deprecated_wait_for,
            false,
            "Enable deprecated dart:cli waitFor. "
            "This feature will be fully removed in Dart 3.4 release. "
            "See https://dartbug.com/52121.");

#define CHECK_ERROR_HANDLE(error)                                              \
  {                                                                            \
    ErrorPtr err = (error);                                                    \
    if (err != Error::null()) {                                                \
      return Api::NewHandle(T, err);                                           \
    }                                                                          \
  }

ThreadLocalKey Api::api_native_key_ = kUnsetThreadLocalKey;
Dart_Handle Api::true_handle_ = nullptr;
Dart_Handle Api::false_handle_ = nullptr;
Dart_Handle Api::null_handle_ = nullptr;
Dart_Handle Api::empty_string_handle_ = nullptr;
Dart_Handle Api::no_callbacks_error_handle_ = nullptr;
Dart_Handle Api::unwind_in_progress_error_handle_ = nullptr;

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(ObjectPtr obj) override {
    if (obj->IsFunction()) {
      funcHandle_ ^= obj;
      classHandle_ ^= funcHandle_.Owner();
      // Verify that the result type of a function is canonical or a
      // TypeParameter.
      typeHandle_ ^= funcHandle_.result_type();
      ASSERT(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_.IsTypeParameter() || typeHandle_.IsCanonical());
      }
    }
  }

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

static InstancePtr GetListInstance(Zone* zone, const Object& obj) {
  if (obj.IsInstance()) {
    ObjectStore* object_store = IsolateGroup::Current()->object_store();
    const Type& list_rare_type =
        Type::Handle(zone, object_store->non_nullable_list_rare_type());
    ASSERT(!list_rare_type.IsNull());
    const Instance& instance = Instance::Cast(obj);
    const Class& obj_class = Class::Handle(zone, obj.clazz());
    if (Class::IsSubtypeOf(obj_class, Object::null_type_arguments(),
                           Nullability::kNonNullable, list_rare_type,
                           Heap::kNew)) {
      return instance.ptr();
    }
  }
  return Instance::null();
}

static InstancePtr GetMapInstance(Zone* zone, const Object& obj) {
  if (obj.IsInstance()) {
    ObjectStore* object_store = IsolateGroup::Current()->object_store();
    const Type& map_rare_type =
        Type::Handle(zone, object_store->non_nullable_map_rare_type());
    ASSERT(!map_rare_type.IsNull());
    const Instance& instance = Instance::Cast(obj);
    const Class& obj_class = Class::Handle(zone, obj.clazz());
    if (Class::IsSubtypeOf(obj_class, Object::null_type_arguments(),
                           Nullability::kNonNullable, map_rare_type,
                           Heap::kNew)) {
      return instance.ptr();
    }
  }
  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
  auto isolate_group = Thread::Current()->isolate_group();
  const Class& error_class = Class::Handle(
      zone, isolate_group->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 != nullptr);
  if (Api::StringGetPeerHelper(arguments, arg_index, peer)) {
    *str = nullptr;
    return true;
  }
  Thread* thread = arguments->thread();
  ASSERT(thread == Thread::Current());
  *peer = nullptr;
  REUSABLE_OBJECT_HANDLESCOPE(thread);
  Object& obj = thread->ObjectHandle();
  obj = arguments->NativeArgAt(arg_index);
  if (IsStringClassId(obj.GetClassId())) {
    ASSERT(thread->api_top_scope() != nullptr);
    *str = Api::NewHandle(thread, obj.ptr());
    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 != nullptr);
  return Api::GetNativeIntegerArgument(arguments, arg_index, value);
}

static bool GetNativeUnsignedIntegerArgument(NativeArguments* arguments,
                                             int arg_index,
                                             uint64_t* value) {
  ASSERT(value != nullptr);
  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 != nullptr);
  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 != nullptr);
  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);
}

static FunctionPtr FindCoreLibPrivateFunction(Zone* zone, const String& name) {
  const Library& core_lib = Library::Handle(zone, Library::CoreLibrary());
  ASSERT(!core_lib.IsNull());
  const Function& function =
      Function::Handle(zone, core_lib.LookupFunctionAllowPrivate(name));
  ASSERT(!function.IsNull());
  return function.ptr();
}

static ObjectPtr CallStatic1Arg(Zone* zone,
                                const String& name,
                                const Instance& arg0) {
  const intptr_t kNumArgs = 1;
  const Function& function =
      Function::Handle(zone, FindCoreLibPrivateFunction(zone, name));
  const Array& args = Array::Handle(zone, Array::New(kNumArgs));
  args.SetAt(0, arg0);
  return DartEntry::InvokeFunction(function, args);
}

static ObjectPtr CallStatic2Args(Zone* zone,
                                 const String& name,
                                 const Instance& arg0,
                                 const Instance& arg1) {
  const intptr_t kNumArgs = 2;
  const Function& function =
      Function::Handle(zone, FindCoreLibPrivateFunction(zone, name));
  const Array& args = Array::Handle(zone, Array::New(kNumArgs));
  args.SetAt(0, arg0);
  args.SetAt(1, arg1);
  return DartEntry::InvokeFunction(function, args);
}

static ObjectPtr CallStatic3Args(Zone* zone,
                                 const String& name,
                                 const Instance& arg0,
                                 const Instance& arg1,
                                 const Instance& arg2) {
  const intptr_t kNumArgs = 3;
  const Function& function =
      Function::Handle(zone, FindCoreLibPrivateFunction(zone, name));
  const Array& args = Array::Handle(Array::New(kNumArgs));
  args.SetAt(0, arg0);
  args.SetAt(1, arg1);
  args.SetAt(2, arg2);
  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() != nullptr);
    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, ObjectPtr raw) {
  LocalHandles* local_handles = Api::TopScope(thread)->local_handles();
  ASSERT(local_handles != nullptr);
  LocalHandle* ref = local_handles->AllocateHandle();
  ref->set_ptr(raw);
  return ref->apiHandle();
}

Dart_Handle Api::NewHandle(Thread* thread, ObjectPtr raw) {
  if (raw == Object::null()) {
    return Null();
  }
  if (raw == Bool::True().ptr()) {
    return True();
  }
  if (raw == Bool::False().ptr()) {
    return False();
  }
  ASSERT(thread->execution_state() == Thread::kThreadInVM);
  return InitNewHandle(thread, raw);
}

ObjectPtr Api::UnwrapHandle(Dart_Handle object) {
#if defined(DEBUG)
  Thread* thread = Thread::Current();
  ASSERT(thread->execution_state() == Thread::kThreadInVM);
  ASSERT(thread->IsDartMutatorThread());
  ASSERT(FinalizablePersistentHandle::ptr_offset() == 0 &&
         PersistentHandle::ptr_offset() == 0 && LocalHandle::ptr_offset() == 0);
#endif
  return (reinterpret_cast<LocalHandle*>(object))->ptr();
}

#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_IsolateGroup Api::CastIsolateGroup(IsolateGroup* isolate_group) {
  return reinterpret_cast<Dart_IsolateGroup>(isolate_group);
}

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

  va_list args;
  va_start(args, format);
  char* buffer = OS::VSCreate(Z, format, args);
  va_end(args);

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

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

  va_list args;
  va_start(args, format);
  char* buffer = OS::VSCreate(Z, format, args);
  va_end(args);

  const String& message = String::Handle(Z, String::New(buffer));
  const Array& arguments = Array::Handle(Z, Array::New(1));
  arguments.SetAt(0, message);
  Object& error = Object::Handle(
      Z, DartLibraryCalls::InstanceCreate(
             Library::Handle(Z, Library::CoreLibrary()),
             Symbols::ArgumentError(), Symbols::Dot(), arguments));
  if (!error.IsError()) {
    error = UnhandledException::New(Instance::Cast(error), Instance::Handle());
  }
  return Api::NewHandle(T, error.ptr());
}

bool Api::IsValid(Dart_Handle handle) {
  Thread* thread = Thread::Current();
  ASSERT(thread->IsDartMutatorThread());
  IsolateGroup* isolate_group = thread->isolate_group();
  CHECK_ISOLATE_GROUP(isolate_group);

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

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

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

static Dart_Handle InitNewReadOnlyApiHandle(ObjectPtr raw) {
  ASSERT(raw->untag()->InVMIsolateHeap());
  LocalHandle* ref = Dart::AllocateReadOnlyApiHandle();
  ref->set_ptr(raw);
  return ref->apiHandle();
}

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

  ASSERT(true_handle_ == nullptr);
  true_handle_ = InitNewReadOnlyApiHandle(Bool::True().ptr());

  ASSERT(false_handle_ == nullptr);
  false_handle_ = InitNewReadOnlyApiHandle(Bool::False().ptr());

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

  ASSERT(empty_string_handle_ == nullptr);
  empty_string_handle_ = InitNewReadOnlyApiHandle(Symbols::Empty().ptr());

  ASSERT(no_callbacks_error_handle_ == nullptr);
  no_callbacks_error_handle_ =
      InitNewReadOnlyApiHandle(Object::no_callbacks_error().ptr());

  ASSERT(unwind_in_progress_error_handle_ == nullptr);
  unwind_in_progress_error_handle_ =
      InitNewReadOnlyApiHandle(Object::unwind_in_progress_error().ptr());
}

void Api::Cleanup() {
  true_handle_ = nullptr;
  false_handle_ = nullptr;
  null_handle_ = nullptr;
  empty_string_handle_ = nullptr;
  no_callbacks_error_handle_ = nullptr;
  unwind_in_progress_error_handle_ = nullptr;
}

bool Api::StringGetPeerHelper(NativeArguments* arguments,
                              int arg_index,
                              void** peer) {
  NoSafepointScope no_safepoint_scope;
  ObjectPtr raw_obj = arguments->NativeArgAt(arg_index);
  intptr_t cid = raw_obj->GetClassId();
  if (cid == kOneByteStringCid || cid == kTwoByteStringCid) {
    auto isolate_group = arguments->thread()->isolate_group();
    *peer = isolate_group->heap()->GetPeer(raw_obj);
    return (*peer != nullptr);
  }
  return false;
}

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

bool Api::GetNativeBooleanArgument(NativeArguments* arguments,
                                   int arg_index,
                                   bool* value) {
  NoSafepointScope no_safepoint_scope;
  ObjectPtr raw_obj = arguments->NativeArgAt(arg_index);
  intptr_t cid = raw_obj->GetClassId();
  if (cid == kBoolCid) {
    *value = (raw_obj == Object::bool_true().ptr());
    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;
  ObjectPtr raw_obj = arguments->NativeArgAt(arg_index);
  intptr_t cid = raw_obj->GetClassId();
  if (cid == kSmiCid) {
    *value = Smi::Value(static_cast<SmiPtr>(raw_obj));
    return true;
  }
  if (cid == kMintCid) {
    *value = static_cast<MintPtr>(raw_obj)->untag()->value_;
    return true;
  }
  return false;
}

bool Api::GetNativeDoubleArgument(NativeArguments* arguments,
                                  int arg_index,
                                  double* value) {
  NoSafepointScope no_safepoint_scope;
  ObjectPtr raw_obj = arguments->NativeArgAt(arg_index);
  intptr_t cid = raw_obj->GetClassId();
  if (cid == kDoubleCid) {
    *value = static_cast<DoublePtr>(raw_obj)->untag()->value_;
    return true;
  }
  if (cid == kSmiCid) {
    *value = static_cast<double>(Smi::Value(static_cast<SmiPtr>(raw_obj)));
    return true;
  }
  if (cid == kMintCid) {
    *value =
        static_cast<double>(static_cast<MintPtr>(raw_obj)->untag()->value_);
    return true;
  }
  return false;
}

bool Api::GetNativeFieldsOfArgument(NativeArguments* arguments,
                                    int arg_index,
                                    int num_fields,
                                    intptr_t* field_values) {
  NoSafepointScope no_safepoint_scope;
  ObjectPtr raw_obj = arguments->NativeArgAt(arg_index);
  intptr_t cid = raw_obj->GetClassId();
  int class_num_fields = arguments->thread()
                             ->isolate_group()
                             ->class_table()
                             ->At(cid)
                             ->untag()
                             ->num_native_fields_;
  if (num_fields != class_num_fields) {
    // No native fields or mismatched native field count.
    return false;
  }
  TypedDataPtr native_fields =
      reinterpret_cast<CompressedTypedDataPtr*>(
          UntaggedObject::ToAddr(raw_obj) + sizeof(UntaggedObject))
          ->Decompress(raw_obj->heap_base());
  if (native_fields == TypedData::null()) {
    // Native fields not initialized.
    memset(field_values, 0, (num_fields * sizeof(field_values[0])));
    return true;
  }
  ASSERT(class_num_fields == Smi::Value(native_fields->untag()->length()));
  intptr_t* native_values =
      reinterpret_cast<intptr_t*>(native_fields->untag()->data());
  memmove(field_values, native_values, (num_fields * sizeof(field_values[0])));
  return true;
}

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

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

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

void FinalizablePersistentHandle::Finalize(
    IsolateGroup* isolate_group,
    FinalizablePersistentHandle* handle) {
  if (!handle->ptr()->IsHeapObject()) {
    return;  // Free handle.
  }
  Dart_HandleFinalizer callback = handle->callback();
  ASSERT(callback != nullptr);
  void* peer = handle->peer();
  ApiState* state = isolate_group->api_state();
  ASSERT(state != nullptr);

  if (!handle->auto_delete()) {
    // Clear handle before running finalizer, finalizer can free the handle.
    state->ClearWeakPersistentHandle(handle);
  }

  (*callback)(isolate_group->embedder_data(), peer);

  if (handle->auto_delete()) {
    state->FreeWeakPersistentHandle(handle);
  }
}

// --- Handles ---

DART_EXPORT bool Dart_IsError(Dart_Handle handle) {
  Thread* thread = Thread::Current();
  TransitionNativeToVM transition(thread);
  return Api::IsError(handle);
}

DART_EXPORT void Dart_KillIsolate(Dart_Isolate handle) {
  Isolate* isolate = reinterpret_cast<Isolate*>(handle);
  CHECK_ISOLATE(isolate);
  TransitionNativeToVM transition(Thread::Current());
  Isolate::KillIfExists(isolate, Isolate::kKillMsg);
}

DART_EXPORT bool Dart_IsApiError(Dart_Handle object) {
  Thread* thread = Thread::Current();
  TransitionNativeToVM transition(thread);
  return Api::ClassId(object) == kApiErrorCid;
}

DART_EXPORT bool Dart_IsUnhandledExceptionError(Dart_Handle object) {
  Thread* thread = Thread::Current();
  TransitionNativeToVM transition(thread);
  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);
  }

  Thread* thread = Thread::Current();
  TransitionNativeToVM transition(thread);
  return Api::ClassId(object) == kLanguageErrorCid;
}

DART_EXPORT bool Dart_IsFatalError(Dart_Handle object) {
  Thread* thread = Thread::Current();
  TransitionNativeToVM transition(thread);
  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).ptr();
    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 void Dart_PropagateError(Dart_Handle handle) {
  Thread* thread = Thread::Current();
  CHECK_ISOLATE_GROUP(thread->isolate_group());
  TransitionNativeToVM transition(thread);
  const Object& obj = Object::Handle(thread->zone(), Api::UnwrapHandle(handle));
  if (!obj.IsError()) {
    FATAL(
        "%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.
    FATAL("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;
    ErrorPtr raw_error = Api::UnwrapErrorHandle(thread->zone(), handle).ptr();
    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();
}

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.ptr());
  } 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();
  IsolateGroup* isolate_group = thread->isolate_group();
  CHECK_ISOLATE_GROUP(isolate_group);
  ApiState* state = isolate_group->api_state();
  ASSERT(state != nullptr);
  TransitionNativeToVM transition(thread);
  NoSafepointScope no_safepoint_scope;
  PersistentHandle* ref = PersistentHandle::Cast(object);
  return Api::NewHandle(thread, ref->ptr());
}

DART_EXPORT Dart_Handle
Dart_HandleFromWeakPersistent(Dart_WeakPersistentHandle object) {
  Thread* thread = Thread::Current();
  IsolateGroup* isolate_group = thread->isolate_group();
  CHECK_ISOLATE_GROUP(isolate_group);
  ApiState* state = isolate_group->api_state();
  ASSERT(state != nullptr);
  TransitionNativeToVM transition(thread);
  NoSafepointScope no_safepoint_scope;
  FinalizablePersistentHandle* weak_ref =
      FinalizablePersistentHandle::Cast(object);
  if (weak_ref->IsFinalizedNotFreed()) {
    return Dart_Null();
  }
  return Api::NewHandle(thread, weak_ref->ptr());
}

static Dart_Handle HandleFromFinalizable(Dart_FinalizableHandle object) {
  Thread* thread = Thread::Current();
  IsolateGroup* isolate_group = thread->isolate_group();
  CHECK_ISOLATE_GROUP(isolate_group);
  ApiState* state = isolate_group->api_state();
  ASSERT(state != nullptr);
  TransitionNativeToVM transition(thread);
  NoSafepointScope no_safepoint_scope;
  FinalizablePersistentHandle* weak_ref =
      FinalizablePersistentHandle::Cast(object);
  return Api::NewHandle(thread, weak_ref->ptr());
}

DART_EXPORT Dart_PersistentHandle Dart_NewPersistentHandle(Dart_Handle object) {
  DARTSCOPE(Thread::Current());
  Thread* thread = Thread::Current();
  IsolateGroup* isolate_group = thread->isolate_group();
  CHECK_ISOLATE_GROUP(isolate_group);
  ApiState* state = isolate_group->api_state();
  ASSERT(state != nullptr);
  const Object& old_ref = Object::Handle(Z, Api::UnwrapHandle(object));
  PersistentHandle* new_ref = state->AllocatePersistentHandle();
  new_ref->set_ptr(old_ref);
  return new_ref->apiHandle();
}

DART_EXPORT void Dart_SetPersistentHandle(Dart_PersistentHandle obj1,
                                          Dart_Handle obj2) {
  DARTSCOPE(Thread::Current());
  Thread* thread = Thread::Current();
  IsolateGroup* isolate_group = thread->isolate_group();
  CHECK_ISOLATE_GROUP(isolate_group);
  ApiState* state = isolate_group->api_state();
  ASSERT(state != nullptr);
  ASSERT(state->IsValidPersistentHandle(obj1));
  const Object& obj2_ref = Object::Handle(Z, Api::UnwrapHandle(obj2));
  PersistentHandle* obj1_ref = PersistentHandle::Cast(obj1);
  obj1_ref->set_ptr(obj2_ref);
}

static bool IsFfiCompound(Thread* T, const Object& obj) {
  if (obj.IsNull()) {
    return false;
  }

  // CFE guarantees we can only have direct subclasses of `Struct` and `Union`
  // (no implementations or indirect subclasses are allowed).
  const auto& klass = Class::Handle(Z, obj.clazz());
  const auto& super_klass = Class::Handle(Z, klass.SuperClass());
  if (super_klass.IsNull()) {
    // This means klass is Object.
    return false;
  }
  if (super_klass.Name() != Symbols::Struct().ptr() &&
      super_klass.Name() != Symbols::Union().ptr()) {
    return false;
  }
  const auto& library = Library::Handle(Z, super_klass.library());
  return library.url() == Symbols::DartFfi().ptr();
}

static Dart_WeakPersistentHandle AllocateWeakPersistentHandle(
    Thread* thread,
    const Object& ref,
    void* peer,
    intptr_t external_allocation_size,
    Dart_HandleFinalizer callback) {
  if (!ref.ptr()->IsHeapObject()) {
    return nullptr;
  }
  if (ref.IsPointer()) {
    return nullptr;
  }
  if (IsFfiCompound(thread, ref)) {
    return nullptr;
  }

  FinalizablePersistentHandle* finalizable_ref =
      FinalizablePersistentHandle::New(thread->isolate_group(), ref, peer,
                                       callback, external_allocation_size,
                                       /*auto_delete=*/false);
  return finalizable_ref == nullptr
             ? nullptr
             : finalizable_ref->ApiWeakPersistentHandle();
}

static Dart_WeakPersistentHandle AllocateWeakPersistentHandle(
    Thread* T,
    Dart_Handle object,
    void* peer,
    intptr_t external_allocation_size,
    Dart_HandleFinalizer callback) {
  const auto& ref = Object::Handle(Z, Api::UnwrapHandle(object));
  return AllocateWeakPersistentHandle(T, ref, peer, external_allocation_size,
                                      callback);
}

static Dart_FinalizableHandle AllocateFinalizableHandle(
    Thread* thread,
    const Object& ref,
    void* peer,
    intptr_t external_allocation_size,
    Dart_HandleFinalizer callback) {
  if (!ref.ptr()->IsHeapObject()) {
    return nullptr;
  }
  if (ref.IsPointer()) {
    return nullptr;
  }
  if (IsFfiCompound(thread, ref)) {
    return nullptr;
  }

  FinalizablePersistentHandle* finalizable_ref =
      FinalizablePersistentHandle::New(thread->isolate_group(), ref, peer,
                                       callback, external_allocation_size,
                                       /*auto_delete=*/true);
  return finalizable_ref == nullptr ? nullptr
                                    : finalizable_ref->ApiFinalizableHandle();
}

static Dart_FinalizableHandle AllocateFinalizableHandle(
    Thread* T,
    Dart_Handle object,
    void* peer,
    intptr_t external_allocation_size,
    Dart_HandleFinalizer callback) {
  const auto& ref = Object::Handle(Z, Api::UnwrapHandle(object));
  return AllocateFinalizableHandle(T, ref, peer, external_allocation_size,
                                   callback);
}

DART_EXPORT Dart_WeakPersistentHandle
Dart_NewWeakPersistentHandle(Dart_Handle object,
                             void* peer,
                             intptr_t external_allocation_size,
                             Dart_HandleFinalizer callback) {
  DARTSCOPE(Thread::Current());
  if (callback == nullptr) {
    return nullptr;
  }

  return AllocateWeakPersistentHandle(T, object, peer, external_allocation_size,
                                      callback);
}

DART_EXPORT Dart_FinalizableHandle
Dart_NewFinalizableHandle(Dart_Handle object,
                          void* peer,
                          intptr_t external_allocation_size,
                          Dart_HandleFinalizer callback) {
  DARTSCOPE(Thread::Current());
  if (callback == nullptr) {
    return nullptr;
  }

  return AllocateFinalizableHandle(T, object, peer, external_allocation_size,
                                   callback);
}

DART_EXPORT void Dart_DeletePersistentHandle(Dart_PersistentHandle object) {
  Thread* T = Thread::Current();
  IsolateGroup* isolate_group = T->isolate_group();
  CHECK_ISOLATE_GROUP(isolate_group);
  TransitionToVM transition(T);
  ApiState* state = isolate_group->api_state();
  ASSERT(state != nullptr);
  ASSERT(state->IsActivePersistentHandle(object));
  ASSERT(!Api::IsProtectedHandle(object));
  if (!Api::IsProtectedHandle(object)) {
    PersistentHandle* ref = PersistentHandle::Cast(object);
    state->FreePersistentHandle(ref);
  }
}

DART_EXPORT void Dart_DeleteWeakPersistentHandle(
    Dart_WeakPersistentHandle object) {
  Thread* T = Thread::Current();
  IsolateGroup* isolate_group = T->isolate_group();
  CHECK_ISOLATE_GROUP(isolate_group);
  TransitionToVM transition(T);
  ApiState* state = isolate_group->api_state();
  ASSERT(state != nullptr);
  ASSERT(state->IsActiveWeakPersistentHandle(object));
  auto weak_ref = FinalizablePersistentHandle::Cast(object);
  weak_ref->EnsureFreedExternal(isolate_group);
  state->FreeWeakPersistentHandle(weak_ref);
}

DART_EXPORT void Dart_DeleteFinalizableHandle(
    Dart_FinalizableHandle object,
    Dart_Handle strong_ref_to_object) {
  if (!::Dart_IdentityEquals(strong_ref_to_object,
                             HandleFromFinalizable(object))) {
    FATAL(
        "%s expects arguments 'object' and 'strong_ref_to_object' to point to "
        "the same object.",
        CURRENT_FUNC);
  }

  auto wph_object = reinterpret_cast<Dart_WeakPersistentHandle>(object);

  ::Dart_DeleteWeakPersistentHandle(wph_object);
}

// --- Initialization and Globals ---

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

DART_EXPORT char* Dart_Initialize(Dart_InitializeParams* params) {
  if (params == nullptr) {
    return Utils::StrDup(
        "Dart_Initialize: "
        "Dart_InitializeParams is null.");
  }

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

  return Dart::Init(params);
}

DART_EXPORT char* Dart_Cleanup() {
  CHECK_NO_ISOLATE(Isolate::Current());
  return Dart::Cleanup();
}

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);
}

#define ISOLATE_GROUP_METRIC_API(type, variable, name, unit)                   \
  DART_EXPORT int64_t Dart_IsolateGroup##variable##Metric(                     \
      Dart_IsolateGroup isolate_group) {                                       \
    if (isolate_group == nullptr) {                                            \
      FATAL("%s expects argument 'isolate_group' to be non-null.",             \
            CURRENT_FUNC);                                                     \
    }                                                                          \
    IsolateGroup* group = reinterpret_cast<IsolateGroup*>(isolate_group);      \
    return group->Get##variable##Metric()->Value();                            \
  }
DART_API_ISOLATE_GROUP_METRIC_LIST(ISOLATE_GROUP_METRIC_API)
#undef ISOLATE_GROUP_METRIC_API

#if !defined(PRODUCT)
#define ISOLATE_METRIC_API(type, variable, name, unit)                         \
  DART_EXPORT int64_t Dart_Isolate##variable##Metric(Dart_Isolate isolate) {   \
    if (isolate == nullptr) {                                                  \
      FATAL("%s expects argument 'isolate' to be non-null.", CURRENT_FUNC);    \
    }                                                                          \
    Isolate* iso = reinterpret_cast<Isolate*>(isolate);                        \
    return iso->Get##variable##Metric()->Value();                              \
  }
ISOLATE_METRIC_LIST(ISOLATE_METRIC_API)
#undef ISOLATE_METRIC_API
#else  // !defined(PRODUCT)
#define ISOLATE_METRIC_API(type, variable, name, unit)                         \
  DART_EXPORT int64_t Dart_Isolate##variable##Metric(Dart_Isolate isolate) {   \
    return -1;                                                                 \
  }
ISOLATE_METRIC_LIST(ISOLATE_METRIC_API)
#undef ISOLATE_METRIC_API
#endif  // !defined(PRODUCT)

// --- Isolates ---

static Dart_Isolate CreateIsolate(IsolateGroup* group,
                                  bool is_new_group,
                                  const char* name,
                                  void* isolate_data,
                                  char** error) {
  CHECK_NO_ISOLATE(Isolate::Current());

  auto source = group->source();
  Isolate* I = Dart::CreateIsolate(name, source->flags, group);
  if (I == nullptr) {
    if (error != nullptr) {
      *error = Utils::StrDup("Isolate creation failed");
    }
    return static_cast<Dart_Isolate>(nullptr);
  }

  Thread* T = Thread::Current();
  bool success = false;
  {
    StackZone zone(T);
    HandleScope handle_scope(T);

#if defined(SUPPORT_TIMELINE)
    TimelineBeginEndScope tbes(T, Timeline::GetIsolateStream(),
                               "InitializeIsolate");
    tbes.SetNumArguments(1);
    tbes.CopyArgument(0, "isolateName", I->name());
#endif

    // 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.
    T->EnterApiScope();
    auto& error_obj = Error::Handle(Z);
    if (is_new_group) {
      error_obj = Dart::InitializeIsolateGroup(
          T, source->snapshot_data, source->snapshot_instructions,
          source->kernel_buffer, source->kernel_buffer_size);
    }
    if (error_obj.IsNull()) {
      error_obj = Dart::InitializeIsolate(T, is_new_group, isolate_data);
    }
    if (error_obj.IsNull()) {
#if defined(DEBUG) && !defined(DART_PRECOMPILED_RUNTIME)
      if (FLAG_check_function_fingerprints && !FLAG_precompiled_mode) {
        Library::CheckFunctionFingerprints();
      }
#endif  // defined(DEBUG) && !defined(DART_PRECOMPILED_RUNTIME).
      success = true;
    } else if (error != nullptr) {
      *error = Utils::StrDup(error_obj.ToErrorCString());
    }
    // We exit the API scope entered above.
    T->ExitApiScope();
  }

  if (success) {
    // 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 != nullptr) {
      *error = nullptr;
    }
    return Api::CastIsolate(I);
  }

  Dart::ShutdownIsolate(T);
  return static_cast<Dart_Isolate>(nullptr);
}

Isolate* CreateWithinExistingIsolateGroup(IsolateGroup* group,
                                          const char* name,
                                          char** error) {
  API_TIMELINE_DURATION(Thread::Current());
  CHECK_NO_ISOLATE(Isolate::Current());

  auto spawning_group = group;

  Isolate* isolate = reinterpret_cast<Isolate*>(
      CreateIsolate(spawning_group, /*is_new_group=*/false, name,
                    /*isolate_data=*/nullptr, error));
  if (isolate == nullptr) return nullptr;

  auto source = spawning_group->source();
  ASSERT(isolate->source() == source);

  return isolate;
}

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

DART_EXPORT Dart_Isolate
Dart_CreateIsolateGroup(const char* script_uri,
                        const char* name,
                        const uint8_t* snapshot_data,
                        const uint8_t* snapshot_instructions,
                        Dart_IsolateFlags* flags,
                        void* isolate_group_data,
                        void* isolate_data,
                        char** error) {
  API_TIMELINE_DURATION(Thread::Current());

  Dart_IsolateFlags api_flags;
  if (flags == nullptr) {
    Isolate::FlagsInitialize(&api_flags);
    flags = &api_flags;
  }

  const char* non_null_name = name == nullptr ? "isolate" : name;
  std::unique_ptr<IsolateGroupSource> source(
      new IsolateGroupSource(script_uri, non_null_name, snapshot_data,
                             snapshot_instructions, nullptr, -1, *flags));
  auto group = new IsolateGroup(std::move(source), isolate_group_data, *flags,
                                /*is_vm_isolate=*/false);
  group->CreateHeap(
      /*is_vm_isolate=*/false,
      flags->is_service_isolate || flags->is_kernel_isolate);
  IsolateGroup::RegisterIsolateGroup(group);
  Dart_Isolate isolate = CreateIsolate(group, /*is_new_group=*/true,
                                       non_null_name, isolate_data, error);
  if (isolate != nullptr) {
    group->set_initial_spawn_successful();
  }
  return isolate;
}

DART_EXPORT Dart_Isolate
Dart_CreateIsolateGroupFromKernel(const char* script_uri,
                                  const char* name,
                                  const uint8_t* kernel_buffer,
                                  intptr_t kernel_buffer_size,
                                  Dart_IsolateFlags* flags,
                                  void* isolate_group_data,
                                  void* isolate_data,
                                  char** error) {
  API_TIMELINE_DURATION(Thread::Current());

  Dart_IsolateFlags api_flags;
  if (flags == nullptr) {
    Isolate::FlagsInitialize(&api_flags);
    flags = &api_flags;
  }

  const char* non_null_name = name == nullptr ? "isolate" : name;
  std::shared_ptr<IsolateGroupSource> source(
      new IsolateGroupSource(script_uri, non_null_name, nullptr, nullptr,
                             kernel_buffer, kernel_buffer_size, *flags));
  auto group = new IsolateGroup(source, isolate_group_data, *flags,
                                /*is_vm_isolate=*/false);
  IsolateGroup::RegisterIsolateGroup(group);
  group->CreateHeap(
      /*is_vm_isolate=*/false,
      flags->is_service_isolate || flags->is_kernel_isolate);
  Dart_Isolate isolate = CreateIsolate(group, /*is_new_group=*/true,
                                       non_null_name, isolate_data, error);
  if (isolate != nullptr) {
    group->set_initial_spawn_successful();
  }
  return isolate;
}

DART_EXPORT Dart_Isolate
Dart_CreateIsolateInGroup(Dart_Isolate group_member,
                          const char* name,
                          Dart_IsolateShutdownCallback shutdown_callback,
                          Dart_IsolateCleanupCallback cleanup_callback,
                          void* child_isolate_data,
                          char** error) {
  CHECK_NO_ISOLATE(Isolate::Current());
  auto member = reinterpret_cast<Isolate*>(group_member);
  if (member->IsScheduled()) {
    FATAL("The given member isolate (%s) must not have been entered.",
          member->name());
  }

  *error = nullptr;

  Isolate* isolate;
  isolate = CreateWithinExistingIsolateGroup(member->group(), name, error);
  if (isolate != nullptr) {
    isolate->set_init_callback_data(child_isolate_data);
    isolate->set_on_shutdown_callback(shutdown_callback);
    isolate->set_on_cleanup_callback(cleanup_callback);
  }

  return Api::CastIsolate(isolate);
}

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

  // 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_CreateIsolateGroup.
  ASSERT(T->execution_state() == Thread::kThreadInNative);
  T->ExitSafepointFromNative();
  T->set_execution_state(Thread::kThreadInVM);

  I->WaitForOutstandingSpawns();

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

  {
    StackZone zone(T);
    HandleScope handle_scope(T);
    Dart::RunShutdownCallback();
  }
  Dart::ShutdownIsolate(T);
}

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 == nullptr) {
    FATAL("%s expects argument 'isolate' to be non-null.", CURRENT_FUNC);
  }
  // TODO(http://dartbug.com/16615): Validate isolate parameter.
  return reinterpret_cast<Isolate*>(isolate)->init_callback_data();
}

DART_EXPORT Dart_IsolateGroup Dart_CurrentIsolateGroup() {
  return Api::CastIsolateGroup(IsolateGroup::Current());
}

DART_EXPORT void* Dart_CurrentIsolateGroupData() {
  IsolateGroup* isolate_group = IsolateGroup::Current();
  CHECK_ISOLATE_GROUP(isolate_group);
  NoSafepointScope no_safepoint_scope;
  return isolate_group->embedder_data();
}

DART_EXPORT Dart_IsolateGroupId Dart_CurrentIsolateGroupId() {
  IsolateGroup* isolate_group = IsolateGroup::Current();
  CHECK_ISOLATE_GROUP(isolate_group);
  return isolate_group->id();
}

DART_EXPORT void* Dart_IsolateGroupData(Dart_Isolate isolate) {
  if (isolate == nullptr) {
    FATAL("%s expects argument 'isolate' to be non-null.", CURRENT_FUNC);
  }
  // TODO(http://dartbug.com/16615): Validate isolate parameter.
  return reinterpret_cast<Isolate*>(isolate)->group()->embedder_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 const char* Dart_DebugNameToCString() {
  Thread* thread = Thread::Current();
  if (thread == nullptr) {
    return nullptr;
  }
  Isolate* I = thread->isolate();
  if (I == nullptr) {
    return nullptr;
  }
  int64_t main_port = static_cast<int64_t>(I->main_port());
  const char* fmt = "%s (%" Pd64 ")";
  int length = snprintf(nullptr, 0, fmt, I->name(), main_port) + 1;
  char* res = Api::TopScope(thread)->zone()->Alloc<char>(length);
  snprintf(res, length, fmt, I->name(), main_port);
  return res;
}

DART_EXPORT const char* Dart_IsolateServiceId(Dart_Isolate isolate) {
  if (isolate == nullptr) {
    FATAL("%s expects argument 'isolate' to be non-null.", CURRENT_FUNC);
  }
  // TODO(http://dartbug.com/16615): Validate isolate parameter.
  Isolate* I = reinterpret_cast<Isolate*>(isolate);
  int64_t main_port = static_cast<int64_t>(I->main_port());
  return OS::SCreate(nullptr, "isolates/%" Pd64, main_port);
}

DART_EXPORT void Dart_EnterIsolate(Dart_Isolate isolate) {
  CHECK_NO_ISOLATE(Isolate::Current());
  // TODO(http://dartbug.com/16615): Validate isolate parameter.
  Isolate* iso = reinterpret_cast<Isolate*>(isolate);
  ThreadId os_thread = OSThread::GetCurrentThreadId();
  if (iso->IsScheduled()) {
    FATAL(
        "Isolate %s is already scheduled on mutator thread %p, "
        "failed to schedule from os thread 0x%" Px "\n",
        iso->name(), iso->scheduled_mutator_thread(),
        OSThread::ThreadIdToIntPtr(os_thread));
  }
  Thread::EnterIsolate(iso);
  ThreadId owner_thread = iso->GetOwnerThread(nullptr);
  if (owner_thread != OSThread::kInvalidThreadId && owner_thread != os_thread) {
    FATAL("Isolate %s is owned by os thread 0x%" Px
          ", "
          "failed to schedule from os thread 0x%" Px "\n",
          iso->name(), OSThread::ThreadIdToIntPtr(owner_thread),
          OSThread::ThreadIdToIntPtr(os_thread));
  }
  // 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->EnterSafepointToNative();
}

DART_EXPORT void Dart_StartProfiling() {
#if !defined(PRODUCT)
  if (!FLAG_profiler) {
    FLAG_profiler = true;
    Profiler::Init();
  }
#endif  // !defined(PRODUCT)
}

DART_EXPORT void Dart_StopProfiling() {
#if !defined(PRODUCT)
  if (FLAG_profiler) {
    Profiler::Cleanup();
    FLAG_profiler = false;
  }
#endif  // !defined(PRODUCT)
}

DART_EXPORT void Dart_ThreadDisableProfiling() {
#if defined(DART_INCLUDE_PROFILER)
  OSThread* os_thread = OSThread::Current();
  if (os_thread == nullptr) {
    return;
  }
  os_thread->DisableThreadInterrupts();
#endif  // defined(DART_INCLUDE_PROFILER)
}

DART_EXPORT void Dart_ThreadEnableProfiling() {
#if defined(DART_INCLUDE_PROFILER)
  OSThread* os_thread = OSThread::Current();
  if (os_thread == nullptr) {
    return;
  }
  os_thread->EnableThreadInterrupts();
#endif  // defined(DART_INCLUDE_PROFILER)
}

DART_EXPORT void Dart_AddSymbols(const char* dso_name,
                                 void* buffer,
                                 intptr_t buffer_size) {
  NativeSymbolResolver::AddSymbols(dso_name, buffer, buffer_size);
}

DART_EXPORT bool Dart_WriteProfileToTimeline(Dart_Port main_port,
                                             char** error) {
#if defined(PRODUCT)
  return false;
#else
  if (!FLAG_profiler) {
    if (error != nullptr) {
      *error = Utils::StrDup("The profiler is not running.");
    }
    return false;
  }

  const intptr_t kBufferLength = 512;
  char method[kBufferLength];

  // clang-format off
  intptr_t method_length = snprintf(method, kBufferLength, "{"
      "\"jsonrpc\": \"2.0\","
      "\"method\": \"_writeCpuProfileTimeline\","
      "\"id\": \"\","
      "\"params\": {"
      "  \"isolateId\": \"isolates/%" Pd64 "\","
      "  \"tags\": \"None\""
      "}"
  "}", main_port);
  // clang-format on
  ASSERT(method_length <= kBufferLength);

  char* response = nullptr;
  intptr_t response_length;
  bool success = Dart_InvokeVMServiceMethod(
      reinterpret_cast<uint8_t*>(method), method_length,
      reinterpret_cast<uint8_t**>(&response), &response_length, error);
  free(response);
  return success;
#endif
}

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) {
    FATAL("%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()) {
    FATAL("%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) {
    FATAL("%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) {
    FATAL("%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) {
    FATAL("%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;
  const Error& error_handle = Api::UnwrapErrorHandle(Z, error);
  if ((isolate->sticky_error() != Error::null()) &&
      (error_handle.ptr() != Object::null())) {
    FATAL("%s expects there to be no sticky error.", CURRENT_FUNC);
  }
  if (!error_handle.IsUnhandledException() &&
      (error_handle.ptr() != Object::null())) {
    FATAL("%s expects the error to be an unhandled exception error or null.",
          CURRENT_FUNC);
  }
  isolate->SetStickyError(error_handle.ptr());
}

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()) {
      return Api::Null();
    }
  }
  TransitionNativeToVM transition(T);
  return Api::NewHandle(T, I->sticky_error());
}

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()->group()->idle_time_handler()->NotifyIdle(deadline);
}

DART_EXPORT void Dart_NotifyDestroyed() {
  Thread* T = Thread::Current();
  CHECK_ISOLATE(T->isolate());
  API_TIMELINE_BEGIN_END(T);
  TransitionNativeToVM transition(T);
  T->heap()->NotifyDestroyed();
}

DART_EXPORT void Dart_EnableHeapSampling() {
#if !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)
  HeapProfileSampler::Enable(true);
#endif
}

DART_EXPORT void Dart_DisableHeapSampling() {
#if !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)
  HeapProfileSampler::Enable(false);
#endif
}

DART_EXPORT void Dart_RegisterHeapSamplingCallback(
    Dart_HeapSamplingCreateCallback create_callback,
    Dart_HeapSamplingDeleteCallback delete_callback) {
#if !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)
  HeapProfileSampler::SetSamplingCallback(create_callback, delete_callback);
#endif
}

DART_EXPORT void Dart_ReportSurvivingAllocations(
    Dart_HeapSamplingReportCallback callback,
    void* context,
    bool force_gc) {
#if !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)
  CHECK_NO_ISOLATE(Thread::Current());
  IsolateGroup::ForEach([&](IsolateGroup* group) {
    Thread::EnterIsolateGroupAsHelper(group, Thread::kUnknownTask,
                                      /*bypass_safepoint=*/false);
    if (force_gc) {
      group->heap()->CollectAllGarbage(GCReason::kDebugging);
    }
    group->heap()->ReportSurvivingAllocations(callback, context);
    Thread::ExitIsolateGroupAsHelper(/*bypass_safepoint=*/false);
  });
#endif
}

DART_EXPORT void Dart_SetHeapSamplingPeriod(intptr_t bytes) {
#if !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)
  HeapProfileSampler::SetSamplingInterval(bytes);
#endif
}

DART_EXPORT void Dart_NotifyLowMemory() {
  API_TIMELINE_BEGIN_END(Thread::Current());
  Page::ClearCache();
  Zone::ClearCache();

  // For each isolate's global variables, we might also clear:
  //  - RegExp backtracking stack (both bytecode and compiled versions)
  //  - String -> RegExp cache
  //  - BigInt division/remainder cache
  //  - double.toString cache
  // But cache invalidation code might be larger than the expected size of some
  // caches.
}

DART_EXPORT Dart_PerformanceMode
Dart_SetPerformanceMode(Dart_PerformanceMode mode) {
  Thread* T = Thread::Current();
  CHECK_ISOLATE(T->isolate());
  TransitionNativeToVM transition(T);
  return T->heap()->SetMode(mode);
}

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_CreateIsolateGroup.
  ASSERT(T->execution_state() == Thread::kThreadInNative);
  T->ExitSafepointFromNative();
  T->set_execution_state(Thread::kThreadInVM);
  Thread::ExitIsolate();
}

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,
                    bool is_core) {
#if defined(DART_PRECOMPILED_RUNTIME)
  return Api::NewError("Cannot create snapshots on an AOT runtime.");
#else
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  if (vm_snapshot_data_buffer != nullptr) {
    CHECK_NULL(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 (Api::IsError(state)) {
    return state;
  }
  NoBackgroundCompilerScope no_bg_compiler(T);

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

  ZoneWriteStream vm_snapshot_data(Api::TopScope(T)->zone(),
                                   FullSnapshotWriter::kInitialSize);
  ZoneWriteStream isolate_snapshot_data(Api::TopScope(T)->zone(),
                                        FullSnapshotWriter::kInitialSize);
  const Snapshot::Kind snapshot_kind =
      is_core ? Snapshot::kFullCore : Snapshot::kFull;
  FullSnapshotWriter writer(
      snapshot_kind, &vm_snapshot_data, &isolate_snapshot_data,
      nullptr /* vm_image_writer */, nullptr /* isolate_image_writer */);
  writer.WriteFullSnapshot();
  if (vm_snapshot_data_buffer != nullptr) {
    *vm_snapshot_data_buffer = vm_snapshot_data.buffer();
    *vm_snapshot_data_size = writer.VmIsolateSnapshotSize();
  }
  *isolate_snapshot_data_buffer = isolate_snapshot_data.buffer();
  *isolate_snapshot_data_size = writer.IsolateSnapshotSize();
  return Api::Success();
#endif
}

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_IsBytecode(const uint8_t* buffer, intptr_t buffer_size) {
  if (buffer_size < 4) {
    return false;
  }
  return (buffer[0] == 0x33) && (buffer[1] == 0x43) && (buffer[2] == 0x42) &&
         (buffer[3] == 0x44);
}

DART_EXPORT char* Dart_IsolateMakeRunnable(Dart_Isolate isolate) {
  CHECK_NO_ISOLATE(Isolate::Current());
  API_TIMELINE_DURATION(Thread::Current());
  if (isolate == nullptr) {
    FATAL("%s expects argument 'isolate' to be non-null.", CURRENT_FUNC);
  }
  // TODO(16615): Validate isolate parameter.
  const char* error = reinterpret_cast<Isolate*>(isolate)->MakeRunnable();
  if (error != nullptr) {
    return Utils::StrDup(error);
  }
  return nullptr;
}

// --- 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);
  }

  if (message_notify_callback != nullptr && isolate->HasPendingMessages()) {
    ::Dart_ExitIsolate();

    // If a new handler gets installed and there are pending messages in the
    // queue (e.g. OOB messages for doing vm service work) we need to notify
    // the newly registered callback, otherwise the embedder might never get
    // notified about the pending messages.
    message_notify_callback(Api::CastIsolate(isolate));

    ::Dart_EnterIsolate(Api::CastIsolate(isolate));
  }
}

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 != nullptr);
  MonitorLocker ml(data->monitor);
  data->done = true;
  ml.Notify();
}

DART_EXPORT Dart_Handle Dart_RunLoop() {
  Isolate* I;
  bool result;
  {
    Thread* T = Thread::Current();
    CHECK_API_SCOPE(T);
    I = T->isolate();
    CHECK_ISOLATE(I);
    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;
    result =
        I->message_handler()->Run(I->group()->thread_pool(), nullptr,
                                  RunLoopDone, reinterpret_cast<uword>(&data));
    if (result) {
      while (!data.done) {
        ml.Wait();
      }
    }
  }
  ::Dart_EnterIsolate(Api::CastIsolate(I));
  if (!result) {
    Thread* T = Thread::Current();
    TransitionNativeToVM transition(T);
    return Api::NewError("Run method in isolate message handler failed");
  } else if (I->sticky_error() != Object::null()) {
    Thread* T = Thread::Current();
    TransitionNativeToVM transition(T);
    return Api::NewHandle(T, I->StealStickyError());
  }
  if (FLAG_print_class_table) {
    HANDLESCOPE(Thread::Current());
    I->group()->class_table()->Print();
  }
  return Api::Success();
}

DART_EXPORT bool Dart_RunLoopAsync(bool errors_are_fatal,
                                   Dart_Port on_error_port,
                                   Dart_Port on_exit_port,
                                   char** error) {
  auto thread = Thread::Current();
  auto isolate = thread->isolate();
  CHECK_ISOLATE(isolate);
  *error = nullptr;

  if (thread->api_top_scope() != nullptr) {
    *error = Utils::StrDup("There must not be an active api scope.");
    return false;
  }

  if (!isolate->is_runnable()) {
    const char* error_msg = isolate->MakeRunnable();
    if (error_msg != nullptr) {
      *error = Utils::StrDup(error_msg);
      return false;
    }
  }

  isolate->SetErrorsFatal(errors_are_fatal);

  if (on_error_port != ILLEGAL_PORT || on_exit_port != ILLEGAL_PORT) {
    auto thread = Thread::Current();
    TransitionNativeToVM transition(thread);
    StackZone zone(thread);

    if (on_error_port != ILLEGAL_PORT) {
      const auto& port =
          SendPort::Handle(thread->zone(), SendPort::New(on_error_port));
      isolate->AddErrorListener(port);
    }
    if (on_exit_port != ILLEGAL_PORT) {
      const auto& port =
          SendPort::Handle(thread->zone(), SendPort::New(on_exit_port));
      isolate->AddExitListener(port, Instance::null_instance());
    }
  }

  Dart_ExitIsolate();
  isolate->Run();
  return true;
}

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

DART_EXPORT bool Dart_HandleServiceMessages() {
#if defined(PRODUCT)
  return true;
#else
  Thread* T = Thread::Current();
  CHECK_API_SCOPE(T);
  Isolate* I = T->isolate();
  CHECK_ISOLATE(I);
  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->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;
  }

  const Object& object = Object::Handle(Z, Api::UnwrapHandle(handle));
  return PortMap::PostMessage(WriteMessage(/* same_group */ false, 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);
  }
  int64_t origin_id = PortMap::GetOriginId(port_id);
  return Api::NewHandle(T, SendPort::New(port_id, origin_id));
}

DART_EXPORT Dart_Handle Dart_NewSendPortEx(Dart_PortEx portex_id) {
  DARTSCOPE(Thread::Current());
  CHECK_CALLBACK_STATE(T);
  if (portex_id.port_id == ILLEGAL_PORT) {
    return Api::NewError("%s: illegal port_id %" Pd64 ".", CURRENT_FUNC,
                         portex_id.port_id);
  }
  return Api::NewHandle(T,
                        SendPort::New(portex_id.port_id, portex_id.origin_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 == nullptr) {
    RETURN_NULL_ERROR(port_id);
  }
  *port_id = send_port.Id();
  return Api::Success();
}

DART_EXPORT Dart_Handle Dart_SendPortGetIdEx(Dart_Handle port,
                                             Dart_PortEx* portex_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 (portex_id == nullptr) {
    RETURN_NULL_ERROR(port_id);
  }
  portex_id->port_id = send_port.Id();
  portex_id->origin_id = send_port.origin_id();
  return Api::Success();
}

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

DART_EXPORT void Dart_SetCurrentThreadOwnsIsolate() {
  Isolate* isolate = Isolate::Current();
  CHECK_ISOLATE(isolate);
  if (!isolate->SetOwnerThread(OSThread::kInvalidThreadId,
                               OSThread::GetCurrentThreadId())) {
    FATAL("Tried to claim ownership of isolate %s, but it is already owned\n",
          isolate->name());
  }
}

DART_EXPORT bool Dart_GetCurrentThreadOwnsIsolate(Dart_Port port) {
  return PortMap::IsOwnedByCurrentThread(port);
}

// --- Scopes ----

DART_EXPORT void Dart_EnterScope() {
  Thread* thread = Thread::Current();
  Isolate* isolate = thread->isolate();
  CHECK_ISOLATE(isolate);
  TransitionNativeToVM transition(thread);
  thread->EnterApiScope();
}

DART_EXPORT void Dart_ExitScope() {
  Thread* thread = Thread::Current();
  CHECK_API_SCOPE(thread);
  TransitionNativeToVM transition(thread);
  thread->ExitApiScope();
}

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

// --- Objects ----

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

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

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

DART_EXPORT Dart_Handle Dart_TypeDynamic() {
  DARTSCOPE(Thread::Current());
  CHECK_CALLBACK_STATE(T);
  API_TIMELINE_DURATION(T);
  return Api::NewHandle(T, Type::DynamicType());
}

DART_EXPORT Dart_Handle Dart_TypeVoid() {
  DARTSCOPE(Thread::Current());
  CHECK_CALLBACK_STATE(T);
  API_TIMELINE_DURATION(T);
  return Api::NewHandle(T, Type::VoidType());
}

DART_EXPORT Dart_Handle Dart_TypeNever() {
  DARTSCOPE(Thread::Current());
  CHECK_CALLBACK_STATE(T);
  API_TIMELINE_DURATION(T);
  return Api::NewHandle(T, Type::NeverType());
}

DART_EXPORT Dart_Handle Dart_TypeString() {
  DARTSCOPE(Thread::Current());
  CHECK_CALLBACK_STATE(T);
  API_TIMELINE_DURATION(T);
  return Api::NewHandle(T, T->isolate_group()->object_store()->string_type());
}

DART_EXPORT Dart_Handle Dart_TypeDouble() {
  DARTSCOPE(Thread::Current());
  CHECK_CALLBACK_STATE(T);
  API_TIMELINE_DURATION(T);
  return Api::NewHandle(T, T->isolate_group()->object_store()->double_type());
}

DART_EXPORT Dart_Handle Dart_TypeInt() {
  DARTSCOPE(Thread::Current());
  CHECK_CALLBACK_STATE(T);
  API_TIMELINE_DURATION(T);
  return Api::NewHandle(T, T->isolate_group()->object_store()->int_type());
}

DART_EXPORT Dart_Handle Dart_TypeBoolean() {
  DARTSCOPE(Thread::Current());
  CHECK_CALLBACK_STATE(T);
  API_TIMELINE_DURATION(T);
  return Api::NewHandle(T, T->isolate_group()->object_store()->bool_type());
}

DART_EXPORT Dart_Handle Dart_TypeObject() {
  DARTSCOPE(Thread::Current());
  CHECK_CALLBACK_STATE(T);
  API_TIMELINE_DURATION(T);
  return Api::NewHandle(T, T->isolate_group()->object_store()->object_type());
}

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.ptr());
  } else {
    return Api::NewError("Expected boolean result from ==");
  }
}

// Assumes type is non-null.
static bool InstanceIsType(const Thread* thread,
                           const Instance& instance,
                           const Type& type) {
  ASSERT(!type.IsNull());
  CHECK_CALLBACK_STATE(thread);
  return instance.IsInstanceOf(type, Object::null_type_arguments(),
                               Object::null_type_arguments());
}

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);
  }
  *value = InstanceIsType(T, instance, type_obj);
  return Api::Success();
}

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

DART_EXPORT bool Dart_IsNumber(Dart_Handle object) {
  Thread* thread = Thread::Current();
  CHECK_ISOLATE_GROUP(thread->isolate_group());
  TransitionNativeToVM transition(thread);
  return IsNumberClassId(Api::ClassId(object));
}

DART_EXPORT bool Dart_IsInteger(Dart_Handle object) {
  Thread* thread = Thread::Current();
  CHECK_ISOLATE_GROUP(thread->isolate_group());
  TransitionNativeToVM transition(thread);
  return IsIntegerClassId(Api::ClassId(object));
}

DART_EXPORT bool Dart_IsDouble(Dart_Handle object) {
  Thread* thread = Thread::Current();
  CHECK_ISOLATE_GROUP(thread->isolate_group());
  TransitionNativeToVM transition(thread);
  return Api::ClassId(object) == kDoubleCid;
}

DART_EXPORT bool Dart_IsBoolean(Dart_Handle object) {
  Thread* thread = Thread::Current();
  CHECK_ISOLATE_GROUP(thread->isolate_group());
  TransitionNativeToVM transition(thread);
  return Api::ClassId(object) == kBoolCid;
}

DART_EXPORT bool Dart_IsString(Dart_Handle object) {
  Thread* thread = Thread::Current();
  CHECK_ISOLATE_GROUP(thread->isolate_group());
  TransitionNativeToVM transition(thread);
  return IsStringClassId(Api::ClassId(object));
}

DART_EXPORT bool Dart_IsStringLatin1(Dart_Handle object) {
  Thread* thread = Thread::Current();
  CHECK_ISOLATE_GROUP(thread->isolate_group());
  TransitionNativeToVM transition(thread);
  return IsOneByteStringClassId(Api::ClassId(object));
}

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

  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) {
  Thread* thread = Thread::Current();
  CHECK_ISOLATE_GROUP(thread->isolate_group());
  TransitionNativeToVM transition(thread);
  return Api::ClassId(object) == kLibraryCid;
}

DART_EXPORT bool Dart_IsType(Dart_Handle handle) {
  Thread* thread = Thread::Current();
  CHECK_ISOLATE_GROUP(thread->isolate_group());
  TransitionNativeToVM transition(thread);
  return IsTypeClassId(Api::ClassId(handle));
}

DART_EXPORT bool Dart_IsFunction(Dart_Handle handle) {
  Thread* thread = Thread::Current();
  CHECK_ISOLATE_GROUP(thread->isolate_group());
  TransitionNativeToVM transition(thread);
  return Api::ClassId(handle) == kFunctionCid;
}

DART_EXPORT bool Dart_IsVariable(Dart_Handle handle) {
  Thread* thread = Thread::Current();
  CHECK_ISOLATE_GROUP(thread->isolate_group());
  TransitionNativeToVM transition(thread);
  return Api::ClassId(handle) == kFieldCid;
}

DART_EXPORT bool Dart_IsTypeVariable(Dart_Handle handle) {
  Thread* thread = Thread::Current();
  CHECK_ISOLATE_GROUP(thread->isolate_group());
  TransitionNativeToVM transition(thread);
  return Api::ClassId(handle) == kTypeParameterCid;
}

DART_EXPORT bool Dart_IsClosure(Dart_Handle object) {
  Thread* thread = Thread::Current();
  CHECK_ISOLATE_GROUP(thread->isolate_group());
  TransitionNativeToVM transition(thread);
  return Api::ClassId(object) == kClosureCid;
}

DART_EXPORT bool Dart_IsTearOff(Dart_Handle object) {
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  const Object& obj = Object::Handle(Z, Api::UnwrapHandle(object));
  if (obj.IsClosure()) {
    const Closure& closure = Closure::Cast(obj);
    const Function& func = Function::Handle(Z, closure.function());
    return func.IsImplicitClosureFunction();
  }
  return false;
}

DART_EXPORT bool Dart_IsTypedData(Dart_Handle handle) {
  Thread* thread = Thread::Current();
  CHECK_ISOLATE_GROUP(thread->isolate_group());
  TransitionNativeToVM transition(thread);
  intptr_t cid = Api::ClassId(handle);
  return IsTypedDataClassId(cid) || IsExternalTypedDataClassId(cid) ||
         IsTypedDataViewClassId(cid) || IsUnmodifiableTypedDataViewClassId(cid);
}

DART_EXPORT bool Dart_IsByteBuffer(Dart_Handle handle) {
  Thread* thread = Thread::Current();
  CHECK_ISOLATE_GROUP(thread->isolate_group());
  TransitionNativeToVM transition(thread);
  return Api::ClassId(handle) == kByteBufferCid;
}

DART_EXPORT bool Dart_IsFuture(Dart_Handle handle) {
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  const Object& obj = Object::Handle(Z, Api::UnwrapHandle(handle));
  if (obj.IsInstance()) {
    const Class& obj_class = Class::Handle(Z, obj.clazz());
    return obj_class.is_future_subtype();
  }
  return false;
}

// --- Instances ----

DART_EXPORT Dart_Handle Dart_InstanceGetType(Dart_Handle instance) {
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  auto isolate_group = T->isolate_group();
  const Object& obj = Object::Handle(Z, Api::UnwrapHandle(instance));
  if (obj.IsNull()) {
    return Api::NewHandle(T, isolate_group->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(T));
}

DART_EXPORT Dart_Handle Dart_FunctionName(Dart_Handle function) {
  DARTSCOPE(Thread::Current());
  const Function& func = Api::UnwrapFunctionHandle(Z, function);
  if (func.IsNull()) {
    RETURN_TYPE_ERROR(Z, function, Function);
  }
  return Api::NewHandle(T, func.UserVisibleName());
}

DART_EXPORT Dart_Handle Dart_ClassName(Dart_Handle cls_type) {
  DARTSCOPE(Thread::Current());
  const Type& type_obj = Api::UnwrapTypeHandle(Z, cls_type);
  if (type_obj.IsNull()) {
    RETURN_TYPE_ERROR(Z, cls_type, Type);
  }
  const Class& klass = Class::Handle(Z, type_obj.type_class());
  if (klass.IsNull()) {
    return Api::NewError(
        "cls_type must be a Type object which represents a Class.");
  }
  return Api::NewHandle(T, klass.UserVisibleName());
}

DART_EXPORT Dart_Handle Dart_FunctionOwner(Dart_Handle function) {
  DARTSCOPE(Thread::Current());
  const Function& func = Api::UnwrapFunctionHandle(Z, function);
  if (func.IsNull()) {
    RETURN_TYPE_ERROR(Z, function, Function);
  }
  if (func.IsNonImplicitClosureFunction()) {
    FunctionPtr parent_function = func.parent_function();
    return Api::NewHandle(T, parent_function);
  }
  const Class& owner = Class::Handle(Z, func.Owner());
  ASSERT(!owner.IsNull());
  if (owner.IsTopLevel()) {
// Top-level functions are implemented as members of a hidden class. We hide
// that class here and instead answer the library.
#if defined(DEBUG)
    const Library& lib = Library::Handle(Z, owner.library());
    if (lib.IsNull()) {
      ASSERT(owner.IsDynamicClass() || owner.IsVoidClass() ||
             owner.IsNeverClass());
    }
#endif
    return Api::NewHandle(T, owner.library());
  } else {
    return Api::NewHandle(T, owner.RareType());
  }
}

DART_EXPORT Dart_Handle Dart_FunctionIsStatic(Dart_Handle function,
                                              bool* is_static) {
  DARTSCOPE(Thread::Current());
  if (is_static == nullptr) {
    RETURN_NULL_ERROR(is_static);
  }
  const Function& func = Api::UnwrapFunctionHandle(Z, function);
  if (func.IsNull()) {
    RETURN_TYPE_ERROR(Z, function, Function);
  }
  *is_static = func.is_static();
  return Api::Success();
}

DART_EXPORT Dart_Handle Dart_ClosureFunction(Dart_Handle closure) {
  DARTSCOPE(Thread::Current());
  const Instance& closure_obj = Api::UnwrapInstanceHandle(Z, closure);
  if (closure_obj.IsNull() || !closure_obj.IsClosure()) {
    RETURN_TYPE_ERROR(Z, closure, Instance);
  }

  ASSERT(ClassFinalizer::AllClassesFinalized());

  FunctionPtr rf = Closure::Cast(closure_obj).function();
  return Api::NewHandle(T, rf);
}

DART_EXPORT Dart_Handle Dart_ClassLibrary(Dart_Handle cls_type) {
  DARTSCOPE(Thread::Current());
  const Type& type_obj = Api::UnwrapTypeHandle(Z, cls_type);
  const Class& klass = Class::Handle(Z, type_obj.type_class());
  if (klass.IsNull()) {
    return Api::NewError(
        "cls_type must be a Type object which represents a Class.");
  }
  const Library& library = Library::Handle(klass.library());
  if (library.IsNull()) {
    return Dart_Null();
  }
  return Api::NewHandle(Thread::Current(), library.ptr());
}

// --- 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);
  CHECK_ISOLATE_GROUP(thread->isolate_group());
  if (Api::IsSmi(integer)) {
    *fits = true;
    return Api::Success();
  }
  // Slow path for mints and type error.
  DARTSCOPE(thread);
  if (Api::ClassId(integer) == kMintCid) {
    *fits = true;
    return Api::Success();
  }
  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();
  CHECK_ISOLATE_GROUP(thread->isolate_group());
  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.Value() >= 0);
  return Api::Success();
}

DART_EXPORT Dart_Handle Dart_NewInteger(int64_t value) {
  // Fast path for Smis.
  Thread* thread = Thread::Current();
  CHECK_ISOLATE_GROUP(thread->isolate_group());
  API_TIMELINE_DURATION(thread);
  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));
  IntegerPtr 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();
  CHECK_ISOLATE_GROUP(thread->isolate_group());
  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.Value();
  return Api::Success();
}

DART_EXPORT Dart_Handle Dart_IntegerToUint64(Dart_Handle integer,
                                             uint64_t* value) {
  // Fast path for Smis.
  Thread* thread = Thread::Current();
  CHECK_ISOLATE_GROUP(thread->isolate_group());
  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.Value() < 0);
  } else {
    ASSERT(int_obj.IsMint());
    const int64_t v = int_obj.Value();
    if (v >= 0) {
      *value = v;
      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_GetStaticMethodClosure(Dart_Handle library,
                                                    Dart_Handle cls_type,
                                                    Dart_Handle function_name) {
  DARTSCOPE(Thread::Current());
  const Library& lib = Api::UnwrapLibraryHandle(Z, library);
  if (lib.IsNull()) {
    RETURN_TYPE_ERROR(Z, library, Library);
  }

  const Type& type_obj = Api::UnwrapTypeHandle(Z, cls_type);
  if (type_obj.IsNull()) {
    RETURN_TYPE_ERROR(Z, cls_type, Type);
  }

  const Class& klass = Class::Handle(Z, type_obj.type_class());
  if (klass.IsNull()) {
    return Api::NewError(
        "cls_type must be a Type object which represents a Class");
  }

  const auto& error = klass.EnsureIsFinalized(Thread::Current());
  if (error != Error::null()) {
    return Api::NewHandle(T, error);
  }

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

  Function& func =
      Function::Handle(Z, klass.LookupStaticFunctionAllowPrivate(func_name));
  if (func.IsNull()) {
    return Dart_Null();
  }

  if (!func.is_static()) {
    return Api::NewError("function_name must refer to a static method.");
  }

  if (func.kind() != UntaggedFunction::kRegularFunction) {
    return Api::NewError(
        "function_name must be the name of a regular function.");
  }

  if (FLAG_verify_entry_points) {
    CHECK_ERROR_HANDLE(func.VerifyEntryPoint(EntryPointPragma::kGetterOnly));
  }

  func = func.ImplicitClosureFunction();
  if (func.IsNull()) {
    return Dart_Null();
  }

  return Api::NewHandle(T, func.ImplicitStaticClosure());
}

// --- Booleans ----

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

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

DART_EXPORT Dart_Handle Dart_NewBoolean(bool value) {
  CHECK_ISOLATE_GROUP(IsolateGroup::Current());
  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();
  DARTSCOPE(thread);
  {
    ReusableObjectHandleScope reused_obj_handle(thread);
    const String& str_obj = Api::UnwrapStringHandle(reused_obj_handle, str);
    if (!str_obj.IsNull()) {
      *len = str_obj.Length();
      return Api::Success();
    }
  }
  RETURN_TYPE_ERROR(thread->zone(), str, String);
}

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

DART_EXPORT Dart_Handle Dart_NewStringFromCString(const char* str) {
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  if (str == nullptr) {
    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 == nullptr && 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 == nullptr && 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 == nullptr && 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_StringToCString(Dart_Handle object,
                                             const char** cstr) {
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  if (cstr == nullptr) {
    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 == nullptr) {
    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 == nullptr) {
    RETURN_NULL_ERROR(utf8_array);
  }
  if (length == nullptr) {
    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 == nullptr) {
    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_CopyUTF8EncodingOfString(Dart_Handle str,
                                                      uint8_t* utf8_array,
                                                      intptr_t length) {
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  if (utf8_array == nullptr) {
    RETURN_NULL_ERROR(utf8_array);
  }
  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);
  if (length < str_len) {
    return Api::NewError(
        "Provided buffer is not large enough to hold "
        "the UTF-8 representation of the string");
  }
  str_obj.ToUTF8(utf8_array, 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 == nullptr) {
    RETURN_NULL_ERROR(latin1_array);
  }
  if (length == nullptr) {
    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_GROUP(thread->isolate_group());
  TransitionNativeToVM transition(thread);
  if (size == nullptr) {
    RETURN_NULL_ERROR(size);
  }
  {
    ReusableObjectHandleScope reused_obj_handle(thread);
    const String& str_obj = Api::UnwrapStringHandle(reused_obj_handle, str);
    if (!str_obj.IsNull()) {
      *size = (str_obj.Length() * str_obj.CharSize());
      return Api::Success();
    }
  }
  RETURN_TYPE_ERROR(thread->zone(), str, String);
}

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_GROUP(thread->isolate_group());
  TransitionNativeToVM transition(thread);
  {
    ReusableObjectHandleScope reused_obj_handle(thread);
    const String& str = Api::UnwrapStringHandle(reused_obj_handle, object);
    if (!str.IsNull()) {
      NoSafepointScope no_safepoint_scope;
      *peer = thread->heap()->GetPeer(str.ptr());
      *char_size = str.CharSize();
      *str_len = str.Length();
      return Api::Success();
    }
  }
  RETURN_TYPE_ERROR(thread->zone(), object, String);
}

// --- Lists ---

DART_EXPORT Dart_Handle Dart_NewList(intptr_t length) {
  DARTSCOPE(Thread::Current());
  CHECK_LENGTH(length, Array::kMaxElements);
  CHECK_CALLBACK_STATE(T);
  const Array& arr = Array::Handle(Z, Array::New(length));
  return Api::NewHandle(T, arr.ptr());
}

static bool CanTypeContainNull(const Type& type) {
  return (type.nullability() == Nullability::kNullable);
}

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);
  }
  if ((length > 0) && !CanTypeContainNull(type)) {
    return Api::NewError("%s expects argument 'type' to be a nullable type.",
                         CURRENT_FUNC);
  }
  return Api::NewHandle(T, Array::New(length, type));
}

DART_EXPORT Dart_Handle Dart_NewMap(Dart_Handle keys_type,
                                    Dart_Handle keys_handle,
                                    Dart_Handle values_type,
                                    Dart_Handle values_handle) {
  {  // Validate that keys and values are lists.
    if (!Dart_IsList(keys_handle)) {
      return Api::NewError("%s expects argument 'keys_handle' to be a list.",
                           CURRENT_FUNC);
    }
    if (!Dart_IsList(values_handle)) {
      return Api::NewError("%s expects argument 'values_handle' to be a list.",
                           CURRENT_FUNC);
    }
  }
  {  // Validate length of keys and values
    intptr_t keys_len = 0;
    intptr_t values_len = 0;
    Dart_Handle api_result = Dart_ListLength(keys_handle, &keys_len);
    if (Dart_IsError(api_result)) {
      return api_result;
    }
    api_result = Dart_ListLength(values_handle, &values_len);
    if (Dart_IsError(api_result)) {
      return api_result;
    }
    if (keys_len != values_len) {
      return Api::NewError(
          "%s expects length of 'keys_handle' list to be equal to length of "
          "'values_handle' list.",
          CURRENT_FUNC);
    }
  }

  DARTSCOPE(Thread::Current());
  CHECK_CALLBACK_STATE(T);

  const Type& keys_type_obj = Api::UnwrapTypeHandle(Z, keys_type);
  if (keys_type_obj.IsNull()) {
    RETURN_TYPE_ERROR(Z, keys_type, Type);
  }
  const Type& values_type_obj = Api::UnwrapTypeHandle(Z, values_type);
  if (values_type_obj.IsNull()) {
    RETURN_TYPE_ERROR(Z, values_type, Type);
  }
  const Object& keys_obj = Object::Handle(Z, Api::UnwrapHandle(keys_handle));
  const Object& values_obj =
      Object::Handle(Z, Api::UnwrapHandle(values_handle));

  // Init type arguments
  auto& type_arguments =
      TypeArguments::Handle(Z, TypeArguments::New(2, Heap::kOld));
  type_arguments.SetTypeAt(0, keys_type_obj);
  type_arguments.SetTypeAt(1, values_type_obj);
  type_arguments ^= type_arguments.Canonicalize(T);

  const Class& map_class =
      Class::Handle(Z, T->isolate_group()->object_store()->map_class());
  map_class.EnsureIsFinalized(T);

  // Invoke Map._fromKeysValue class factory:
  Function& factory_method = Function::ZoneHandle(Z);
  factory_method = map_class.LookupFactoryAllowPrivate(
      Library::PrivateCoreLibName(Symbols::MapKeyValuesFactory()));
  const Array& args = Array::Handle(Z, Array::New(3));
  args.SetAt(0, type_arguments);
  args.SetAt(1, keys_obj);
  args.SetAt(2, values_obj);
  return Api::NewHandle(T, DartEntry::InvokeFunction(factory_method, args));
}

DART_EXPORT Dart_Handle Dart_NewListOfTypeFilled(Dart_Handle element_type,
                                                 Dart_Handle fill_object,
                                                 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);
  }
  const Instance& instance = Api::UnwrapInstanceHandle(Z, fill_object);
  if (!instance.IsNull() && !InstanceIsType(T, instance, type)) {
    return Api::NewError(
        "%s expects argument 'fill_object' to have the same type as "
        "'element_type'.",
        CURRENT_FUNC);
  }
  if ((length > 0) && instance.IsNull() && !CanTypeContainNull(type)) {
    return Api::NewError(
        "%s expects argument 'fill_object' to be non-null for a non-nullable "
        "'element_type'.",
        CURRENT_FUNC);
  }
  Array& arr = Array::Handle(Z, Array::New(length, type));
  for (intptr_t i = 0; i < arr.Length(); ++i) {
    arr.SetAt(i, instance);
  }
  return Api::NewHandle(T, arr.ptr());
}

#define GET_LIST_LENGTH(zone, type, obj, len)                                  \
  type& array = type::Handle(zone);                                            \
  array ^= obj.ptr();                                                          \
  *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.IsTypedDataBase()) {
    GET_LIST_LENGTH(Z, TypedDataBase, obj, len);
  }
  if (obj.IsArray()) {
    GET_LIST_LENGTH(Z, Array, obj, len);
  }
  if (obj.IsGrowableObjectArray()) {
    GET_LIST_LENGTH(Z, GrowableObjectArray, 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::NewArgumentError(
        "Object does not implement the List interface");
  }
  const Object& retval =
      Object::Handle(Z, CallStatic1Arg(Z, Symbols::_listLength(), instance));
  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.ptr());
  } 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 into 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, CallStatic2Args(Z, Symbols::_listGetAt(), instance,
                             Instance::Handle(Z, Integer::New(index))));
    }
    return Api::NewArgumentError(
        "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 into 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 == nullptr) {
    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 kNumArgs = 2;
      const Function& function = Function::Handle(
          Z, FindCoreLibPrivateFunction(Z, Symbols::_listGetAt()));
      const Array& args = Array::Handle(Z, 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 (Api::IsError(value)) return value;
        result[i] = value;
      }
      return Api::Success();
    }
    return Api::NewArgumentError(
        "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 into 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 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);
      }
      return Api::NewHandle(
          T, CallStatic3Args(Z, Symbols::_listSetAt(), instance, index_obj,
                             Instance::Cast(value_obj)));
    }
    return Api::NewArgumentError(
        "Object does not implement the 'List' interface");
  }
}

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

static ObjectPtr 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.ptr();
  ASSERT(result.IsFunction());
  Function& constructor = Function::Handle(zone);
  constructor ^= result.ptr();
  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.ptr();
  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;
    InstancePtr raw_exception = exception.ptr();
    thread->UnwindScopes(thread->top_exit_frame_info());
    saved_exception = &Instance::Handle(raw_exception);
  }
  Exceptions::Throw(thread, *saved_exception);
  UNREACHABLE();
}

// 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.Value() & 0xff);          \
      ASSERT(integer.Value() <= 0xff);                                         \
    }                                                                          \
    return Api::Success();                                                     \
  }                                                                            \
  return Api::NewError("Invalid length passed into access array elements");

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.IsTypedDataBase()) {
    const TypedDataBase& array = TypedDataBase::Cast(obj);
    if (array.ElementSizeInBytes() == 1) {
      if (Utils::RangeCheck(offset, length, array.Length())) {
        NoSafepointScope no_safepoint;
        memmove(native_array,
                reinterpret_cast<uint8_t*>(array.DataAddr(offset)), length);
        return Api::Success();
      }
      return Api::NewError("Invalid length passed into access list elements");
    }
  }
  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 kNumArgs = 2;
    const Function& function = Function::Handle(
        Z, FindCoreLibPrivateFunction(Z, Symbols::_listGetAt()));
    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.ptr());
      }
      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.Value() <= 0xff);
      // TODO(hpayer): value should always be smaller then 0xff. Add error
      // handling.
      native_array[i] = static_cast<uint8_t>(integer_result.Value() & 0xff);
    }
    return Api::Success();
  }
  return Api::NewArgumentError(
      "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 into 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.IsTypedDataBase()) {
    const TypedDataBase& array = TypedDataBase::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 into 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 kNumArgs = 3;
    const Function& function = Function::Handle(
        Z, FindCoreLibPrivateFunction(Z, Symbols::_listSetAt()));
    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.ptr());
      }
    }
    return Api::Success();
  }
  return Api::NewArgumentError(
      "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, CallStatic2Args(Z, Symbols::_mapGet(), instance,
                                             Instance::Cast(key_obj)));
  }
  return Api::NewArgumentError("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, CallStatic2Args(Z, Symbols::_mapContainsKey(), instance,
                           Instance::Cast(key_obj)));
  }
  return Api::NewArgumentError("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()) {
    return Api::NewHandle(T, CallStatic1Arg(Z, Symbols::_mapKeys(), instance));
  }
  return Api::NewArgumentError("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:
    case kUnmodifiableByteDataViewCid:
      type = Dart_TypedData_kByteData;
      break;
    case kTypedDataInt8ArrayCid:
    case kTypedDataInt8ArrayViewCid:
    case kUnmodifiableTypedDataInt8ArrayViewCid:
    case kExternalTypedDataInt8ArrayCid:
      type = Dart_TypedData_kInt8;
      break;
    case kTypedDataUint8ArrayCid:
    case kTypedDataUint8ArrayViewCid:
    case kUnmodifiableTypedDataUint8ArrayViewCid:
    case kExternalTypedDataUint8ArrayCid:
      type = Dart_TypedData_kUint8;
      break;
    case kTypedDataUint8ClampedArrayCid:
    case kTypedDataUint8ClampedArrayViewCid:
    case kUnmodifiableTypedDataUint8ClampedArrayViewCid:
    case kExternalTypedDataUint8ClampedArrayCid:
      type = Dart_TypedData_kUint8Clamped;
      break;
    case kTypedDataInt16ArrayCid:
    case kTypedDataInt16ArrayViewCid:
    case kUnmodifiableTypedDataInt16ArrayViewCid:
    case kExternalTypedDataInt16ArrayCid:
      type = Dart_TypedData_kInt16;
      break;
    case kTypedDataUint16ArrayCid:
    case kTypedDataUint16ArrayViewCid:
    case kUnmodifiableTypedDataUint16ArrayViewCid:
    case kExternalTypedDataUint16ArrayCid:
      type = Dart_TypedData_kUint16;
      break;
    case kTypedDataInt32ArrayCid:
    case kTypedDataInt32ArrayViewCid:
    case kUnmodifiableTypedDataInt32ArrayViewCid:
    case kExternalTypedDataInt32ArrayCid:
      type = Dart_TypedData_kInt32;
      break;
    case kTypedDataUint32ArrayCid:
    case kTypedDataUint32ArrayViewCid:
    case kUnmodifiableTypedDataUint32ArrayViewCid:
    case kExternalTypedDataUint32ArrayCid:
      type = Dart_TypedData_kUint32;
      break;
    case kTypedDataInt64ArrayCid:
    case kTypedDataInt64ArrayViewCid:
    case kUnmodifiableTypedDataInt64ArrayViewCid:
    case kExternalTypedDataInt64ArrayCid:
      type = Dart_TypedData_kInt64;
      break;
    case kTypedDataUint64ArrayCid:
    case kTypedDataUint64ArrayViewCid:
    case kUnmodifiableTypedDataUint64ArrayViewCid:
    case kExternalTypedDataUint64ArrayCid:
      type = Dart_TypedData_kUint64;
      break;
    case kTypedDataFloat32ArrayCid:
    case kTypedDataFloat32ArrayViewCid:
    case kUnmodifiableTypedDataFloat32ArrayViewCid:
    case kExternalTypedDataFloat32ArrayCid:
      type = Dart_TypedData_kFloat32;
      break;
    case kTypedDataFloat64ArrayCid:
    case kTypedDataFloat64ArrayViewCid:
    case kUnmodifiableTypedDataFloat64ArrayViewCid:
    case kExternalTypedDataFloat64ArrayCid:
      type = Dart_TypedData_kFloat64;
      break;
    case kTypedDataInt32x4ArrayCid:
    case kTypedDataInt32x4ArrayViewCid:
    case kUnmodifiableTypedDataInt32x4ArrayViewCid:
    case kExternalTypedDataInt32x4ArrayCid:
      type = Dart_TypedData_kInt32x4;
      break;
    case kTypedDataFloat32x4ArrayCid:
    case kTypedDataFloat32x4ArrayViewCid:
    case kUnmodifiableTypedDataFloat32x4ArrayViewCid:
    case kExternalTypedDataFloat32x4ArrayCid:
      type = Dart_TypedData_kFloat32x4;
      break;
    case kTypedDataFloat64x2ArrayCid:
    case kTypedDataFloat64x2ArrayViewCid:
    case kUnmodifiableTypedDataFloat64x2ArrayViewCid:
    case kExternalTypedDataFloat64x2ArrayCid:
      type = Dart_TypedData_kFloat64x2;
      break;
    default:
      type = Dart_TypedData_kInvalid;
      break;
  }
  return type;
}

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

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

static Dart_Handle NewByteData(Thread* thread, intptr_t length) {
  CHECK_LENGTH(length, TypedData::MaxElements(kTypedDataUint8ArrayCid));
  const TypedData& array =
      TypedData::Handle(TypedData::New(kTypedDataUint8ArrayCid, length));
  return Api::NewHandle(thread,
                        TypedDataView::New(kByteDataViewCid, array, 0, length));
}

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_HandleFinalizer callback,
                                        bool unmodifiable) {
  CHECK_LENGTH(length, ExternalTypedData::MaxElements(cid));
  Zone* zone = thread->zone();
  intptr_t bytes = length * ExternalTypedData::ElementSizeInBytes(cid);
  Object& result = Object::Handle(
      zone,
      ExternalTypedData::New(cid, reinterpret_cast<uint8_t*>(data), length,
                             thread->heap()->SpaceForExternal(bytes)));
  if (callback != nullptr) {
    AllocateFinalizableHandle(thread, result, peer, external_allocation_size,
                              callback);
  }
  if (unmodifiable) {
    result.SetImmutable();  // Can pass by reference.
    const intptr_t view_cid = cid - kTypedDataCidRemainderExternal +
                              kTypedDataCidRemainderUnmodifiable;
    result = TypedDataView::New(view_cid, ExternalTypedData::Cast(result), 0,
                                length);
  }
  return Api::NewHandle(thread, result.ptr());
}

static Dart_Handle NewExternalByteData(Thread* thread,
                                       void* data,
                                       intptr_t length,
                                       void* peer,
                                       intptr_t external_allocation_size,
                                       Dart_HandleFinalizer callback,
                                       bool unmodifiable) {
  Zone* zone = thread->zone();
  Dart_Handle ext_data = NewExternalTypedData(
      thread, kExternalTypedDataUint8ArrayCid, data, length, peer,
      external_allocation_size, callback, false);
  if (Api::IsError(ext_data)) {
    return ext_data;
  }
  const ExternalTypedData& array =
      Api::UnwrapExternalTypedDataHandle(zone, ext_data);
  if (unmodifiable) {
    array.SetImmutable();  // Can pass by reference.
  }
  return Api::NewHandle(
      thread, TypedDataView::New(unmodifiable ? kUnmodifiableByteDataViewCid
                                              : kByteDataViewCid,
                                 array, 0, length));
}

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_kInt32x4:
      return NewTypedData(T, kTypedDataInt32x4ArrayCid, length);
    case Dart_TypedData_kFloat32x4:
      return NewTypedData(T, kTypedDataFloat32x4ArrayCid, length);
    case Dart_TypedData_kFloat64x2:
      return NewTypedData(T, kTypedDataFloat64x2ArrayCid, length);
    default:
      return Api::NewError("%s expects argument 'type' to be of 'TypedData'",
                           CURRENT_FUNC);
  }
  UNREACHABLE();
  return Api::Null();
}

static Dart_Handle NewExternalTypedDataWithFinalizer(
    Dart_TypedData_Type type,
    void* data,
    intptr_t length,
    void* peer,
    intptr_t external_allocation_size,
    Dart_HandleFinalizer callback,
    bool unmodifiable) {
  DARTSCOPE(Thread::Current());
  if (data == nullptr && 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,
                                 unmodifiable);
    case Dart_TypedData_kInt8:
      return NewExternalTypedData(T, kExternalTypedDataInt8ArrayCid, data,
                                  length, peer, external_allocation_size,
                                  callback, unmodifiable);
    case Dart_TypedData_kUint8:
      return NewExternalTypedData(T, kExternalTypedDataUint8ArrayCid, data,
                                  length, peer, external_allocation_size,
                                  callback, unmodifiable);
    case Dart_TypedData_kUint8Clamped:
      return NewExternalTypedData(T, kExternalTypedDataUint8ClampedArrayCid,
                                  data, length, peer, external_allocation_size,
                                  callback, unmodifiable);
    case Dart_TypedData_kInt16:
      return NewExternalTypedData(T, kExternalTypedDataInt16ArrayCid, data,
                                  length, peer, external_allocation_size,
                                  callback, unmodifiable);
    case Dart_TypedData_kUint16:
      return NewExternalTypedData(T, kExternalTypedDataUint16ArrayCid, data,
                                  length, peer, external_allocation_size,
                                  callback, unmodifiable);
    case Dart_TypedData_kInt32:
      return NewExternalTypedData(T, kExternalTypedDataInt32ArrayCid, data,
                                  length, peer, external_allocation_size,
                                  callback, unmodifiable);
    case Dart_TypedData_kUint32:
      return NewExternalTypedData(T, kExternalTypedDataUint32ArrayCid, data,
                                  length, peer, external_allocation_size,
                                  callback, unmodifiable);
    case Dart_TypedData_kInt64:
      return NewExternalTypedData(T, kExternalTypedDataInt64ArrayCid, data,
                                  length, peer, external_allocation_size,
                                  callback, unmodifiable);
    case Dart_TypedData_kUint64:
      return NewExternalTypedData(T, kExternalTypedDataUint64ArrayCid, data,
                                  length, peer, external_allocation_size,
                                  callback, unmodifiable);
    case Dart_TypedData_kFloat32:
      return NewExternalTypedData(T, kExternalTypedDataFloat32ArrayCid, data,
                                  length, peer, external_allocation_size,
                                  callback, unmodifiable);
    case Dart_TypedData_kFloat64:
      return NewExternalTypedData(T, kExternalTypedDataFloat64ArrayCid, data,
                                  length, peer, external_allocation_size,
                                  callback, unmodifiable);
    case Dart_TypedData_kInt32x4:
      return NewExternalTypedData(T, kExternalTypedDataInt32x4ArrayCid, data,
                                  length, peer, external_allocation_size,
                                  callback, unmodifiable);
    case Dart_TypedData_kFloat32x4:
      return NewExternalTypedData(T, kExternalTypedDataFloat32x4ArrayCid, data,
                                  length, peer, external_allocation_size,
                                  callback, unmodifiable);
    case Dart_TypedData_kFloat64x2:
      return NewExternalTypedData(T, kExternalTypedDataFloat64x2ArrayCid, data,
                                  length, peer, external_allocation_size,
                                  callback, unmodifiable);
    default:
      return Api::NewError(
          "%s expects argument 'type' to be of"
          " 'external TypedData'",
          CURRENT_FUNC);
  }
  UNREACHABLE();
  return Api::Null();
}

DART_EXPORT Dart_Handle Dart_NewExternalTypedData(Dart_TypedData_Type type,
                                                  void* data,
                                                  intptr_t length) {
  return NewExternalTypedDataWithFinalizer(type, data, length, nullptr, 0,
                                           nullptr, false);
}

DART_EXPORT Dart_Handle
Dart_NewExternalTypedDataWithFinalizer(Dart_TypedData_Type type,
                                       void* data,
                                       intptr_t length,
                                       void* peer,
                                       intptr_t external_allocation_size,
                                       Dart_HandleFinalizer callback) {
  return NewExternalTypedDataWithFinalizer(
      type, data, length, peer, external_allocation_size, callback, false);
}

DART_EXPORT Dart_Handle Dart_NewUnmodifiableExternalTypedDataWithFinalizer(
    Dart_TypedData_Type type,
    const void* data,
    intptr_t length,
    void* peer,
    intptr_t external_allocation_size,
    Dart_HandleFinalizer callback) {
  return NewExternalTypedDataWithFinalizer(
      type, const_cast<void*>(data), length, peer, external_allocation_size,
      callback, true);
}

static ObjectPtr GetByteBufferConstructor(Thread* thread,
                                          const String& class_name,
                                          const String& constructor_name,
                                          intptr_t num_args) {
  const Library& lib = Library::Handle(
      thread->isolate_group()->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 (!IsExternalTypedDataClassId(class_id) &&
      !IsTypedDataViewClassId(class_id) && !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.ptr());
}

// 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_(nullptr) {
    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_ != nullptr ? data_copy_ : data_; }

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

 private:
  static constexpr 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 (!IsExternalTypedDataClassId(class_id) &&
      !IsTypedDataViewClassId(class_id) && !IsTypedDataClassId(class_id) &&
      !IsUnmodifiableTypedDataViewClassId(class_id)) {
    RETURN_TYPE_ERROR(Z, object, 'TypedData');
  }
  if (type == nullptr) {
    RETURN_NULL_ERROR(type);
  }
  if (data == nullptr) {
    RETURN_NULL_ERROR(data);
  }
  if (len == nullptr) {
    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 = nullptr;
  bool external = false;
  T->IncrementNoSafepointScopeDepth();
  START_NO_CALLBACK_SCOPE(T);
  if (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 (IsTypedDataClassId(class_id)) {
    const TypedData& obj = Api::UnwrapTypedDataHandle(Z, object);
    ASSERT(!obj.IsNull());
    length = obj.Length();
    size_in_bytes = length * TypedData::ElementSizeInBytes(class_id);
    data_tmp = obj.DataAddr(0);
  } else {
    ASSERT(IsTypedDataViewClassId(class_id) ||
           IsUnmodifiableTypedDataViewClassId(class_id));
    const auto& view_obj = Api::UnwrapTypedDataViewHandle(Z, object);
    ASSERT(!view_obj.IsNull());
    Smi& val = Smi::Handle();
    val = view_obj.length();
    length = val.Value();
    size_in_bytes = length * TypedDataView::ElementSizeInBytes(class_id);
    val = view_obj.offset_in_bytes();
    intptr_t offset_in_bytes = val.Value();
    const auto& obj = Instance::Handle(view_obj.typed_data());
    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) {
    {
      NoSafepointScope no_safepoint(T);
      bool sweep_in_progress;
      {
        PageSpace* old_space = T->heap()->old_space();
        MonitorLocker ml(old_space->tasks_lock());
        sweep_in_progress = (old_space->phase() == PageSpace::kSweepingLarge) ||
                            (old_space->phase() == PageSpace::kSweepingRegular);
      }
      if (!sweep_in_progress) {
        if (external) {
          ASSERT(!T->heap()->Contains(reinterpret_cast<uword>(data_tmp)));
        } else {
          ASSERT(T->heap()->Contains(reinterpret_cast<uword>(data_tmp)));
        }
      }
    }
    const Object& obj = Object::Handle(Z, Api::UnwrapHandle(object));
    WeakTable* table = I->group()->api_state()->acquired_table();
    intptr_t current = table->GetValue(obj.ptr());
    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.ptr(), 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 (!IsExternalTypedDataClassId(class_id) &&
      !IsTypedDataViewClassId(class_id) && !IsTypedDataClassId(class_id) &&
      !IsUnmodifiableTypedDataViewClassId(class_id)) {
    RETURN_TYPE_ERROR(Z, object, 'TypedData');
  }
  if (FLAG_verify_acquired_data) {
    const Object& obj = Object::Handle(Z, Api::UnwrapHandle(object));
    WeakTable* table = I->group()->api_state()->acquired_table();
    intptr_t current = table->GetValue(obj.ptr());
    if (current == 0) {
      return Api::NewError("Data was not acquired for this object.");
    }
    AcquiredData* ad = reinterpret_cast<AcquiredData*>(current);
    table->SetValue(obj.ptr(), 0);  // Delete entry from table.
    delete ad;
  }
  T->DecrementNoSafepointScopeDepth();
  END_NO_CALLBACK_SCOPE(T);
  return Api::Success();
}

DART_EXPORT Dart_Handle Dart_GetDataFromByteBuffer(Dart_Handle object) {
  Thread* thread = Thread::Current();
  Zone* zone = thread->zone();
  CHECK_ISOLATE_GROUP(thread->isolate_group());
  TransitionNativeToVM transition(thread);
  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 ObjectPtr 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.
  Function& constructor = Function::Handle();
  if (cls.EnsureIsFinalized(Thread::Current()) == Error::null()) {
    constructor = 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);
  }
  if (FLAG_verify_entry_points) {
    ErrorPtr error = constructor.VerifyEntryPoint(EntryPointPragma::kCallOnly);
    if (error != Error::null()) return error;
  }
  return constructor.ptr();
}

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.ptr();
  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());
  CHECK_ERROR_HANDLE(cls.EnsureIsAllocateFinalized(T));

  TypeArguments& type_arguments =
      TypeArguments::Handle(Z, type_obj.GetInstanceTypeArguments(T));

  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().ptr();
  } 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.ptr());
  }
  ASSERT(result.IsFunction());
  Function& constructor = Function::Handle(Z);
  constructor ^= result.ptr();

  Instance& new_object = Instance::Handle(Z);
  if (constructor.IsGenerativeConstructor()) {
    if (FLAG_verify_entry_points) {
      CHECK_ERROR_HANDLE(cls.VerifyEntryPoint());
    }
#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.ptr());
      } else {
        return Api::NewError(
            "%s expects arguments[%d] to be an Instance handle.", CURRENT_FUNC,
            i);
      }
    }
    args.SetAt(arg_index++, argument);
  }

  const int kTypeArgsLen = 0;
  Array& args_descriptor_array = Array::Handle(
      Z, ArgumentsDescriptor::NewBoxed(kTypeArgsLen, args.Length()));

  ArgumentsDescriptor args_descriptor(args_descriptor_array);
  ObjectPtr type_error = constructor.DoArgumentTypesMatch(
      args, args_descriptor, type_arguments, Object::empty_type_arguments());
  if (type_error != Error::null()) {
    return Api::NewHandle(T, type_error);
  }

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

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

static InstancePtr 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.ptr());
    Field& field = Field::Handle(zone);
    Array& fields = Array::Handle(zone);
    SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
    if (!cls.is_fields_marked_nullable()) {
      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);
  }

  if (!type_obj.IsFinalized()) {
    return Api::NewError(
        "%s expects argument 'type' to be a fully resolved type.",
        CURRENT_FUNC);
  }

  const Class& cls = Class::Handle(Z, type_obj.type_class());
  const TypeArguments& type_arguments =
      TypeArguments::Handle(Z, type_obj.GetInstanceTypeArguments(T));

  if (FLAG_verify_entry_points) {
    CHECK_ERROR_HANDLE(cls.VerifyEntryPoint());
  }
#if defined(DEBUG)
  if (!cls.is_allocated() && (Dart::vm_snapshot_kind() == Snapshot::kFullAOT)) {
    return Api::NewError("Precompilation dropped '%s'", cls.ToCString());
  }
#endif
  CHECK_ERROR_HANDLE(cls.EnsureIsAllocateFinalized(T));
  const Instance& new_obj = Instance::Handle(Z, AllocateObject(T, cls));
  if (!type_arguments.IsNull()) {
    new_obj.SetTypeArguments(type_arguments);
  }
  return Api::NewHandle(T, new_obj.ptr());
}

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 == nullptr) {
    RETURN_NULL_ERROR(native_fields);
  }
  const Class& cls = Class::Handle(Z, type_obj.type_class());
  if (FLAG_verify_entry_points) {
    CHECK_ERROR_HANDLE(cls.VerifyEntryPoint());
  }
#if defined(DEBUG)
  if (!cls.is_allocated() && (Dart::vm_snapshot_kind() == Snapshot::kFullAOT)) {
    return Api::NewError("Precompilation dropped '%s'", cls.ToCString());
  }
#endif
  CHECK_ERROR_HANDLE(cls.EnsureIsAllocateFinalized(T));
  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.ptr());
}

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.ptr());
      } 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);
  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));
  TypeArguments& type_arguments = TypeArguments::Handle(Z);
  if (type_obj.IsType()) {
    type_arguments = Type::Cast(type_obj).GetInstanceTypeArguments(T);
  }
  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, nullptr)) {
    if (FLAG_verify_entry_points) {
      CHECK_ERROR_HANDLE(
          constructor.VerifyEntryPoint(EntryPointPragma::kCallOnly));
    }
    // Create the argument list.
    Dart_Handle result;
    Array& args = Array::Handle(Z);
    result =
        SetupArguments(T, number_of_arguments, arguments, extra_args, &args);
    if (!Api::IsError(result)) {
      args.SetAt(0, instance);

      const int kTypeArgsLen = 0;
      const Array& args_descriptor_array = Array::Handle(
          Z, ArgumentsDescriptor::NewBoxed(kTypeArgsLen, args.Length()));
      ArgumentsDescriptor args_descriptor(args_descriptor_array);
      ObjectPtr type_error = constructor.DoArgumentTypesMatch(
          args, args_descriptor, type_arguments);
      if (type_error != Error::null()) {
        return Api::NewHandle(T, type_error);
      }

      const Object& retval =
          Object::Handle(Z, DartEntry::InvokeFunction(constructor, args));
      if (retval.IsError()) {
        result = Api::NewHandle(T, retval.ptr());
      } else {
        result = Api::NewHandle(T, instance.ptr());
      }
    }
    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);

  String& function_name =
      String::Handle(Z, Api::UnwrapStringHandle(Z, name).ptr());
  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);
  // This API does not provide a way to pass named parameters.
  const Array& arg_names = Object::empty_array();
  const bool respect_reflectable = false;
  const bool check_is_entrypoint = FLAG_verify_entry_points;
  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());
    if (Library::IsPrivate(function_name)) {
      const Library& lib = Library::Handle(Z, cls.library());
      function_name = lib.PrivateName(function_name);
    }

    // Setup args and check for malformed arguments in the arguments list.
    result = SetupArguments(T, number_of_arguments, arguments, 0, &args);
    if (Api::IsError(result)) {
      return result;
    }
    return Api::NewHandle(
        T, cls.Invoke(function_name, args, arg_names, check_is_entrypoint,
                      respect_reflectable));
  } 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.ptr();

    // Setup args and check for malformed arguments in the arguments list.
    result = SetupArguments(T, number_of_arguments, arguments, 1, &args);
    if (Api::IsError(result)) {
      return result;
    }
    args.SetAt(0, instance);
    return Api::NewHandle(
        T, instance.Invoke(function_name, args, arg_names, check_is_entrypoint,
                           respect_reflectable));
  } 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);
    }

    if (Library::IsPrivate(function_name)) {
      function_name = lib.PrivateName(function_name);
    }

    // Setup args and check for malformed arguments in the arguments list.
    result = SetupArguments(T, number_of_arguments, arguments, 0, &args);
    if (Api::IsError(result)) {
      return result;
    }

    return Api::NewHandle(
        T, lib.Invoke(function_name, args, arg_names, check_is_entrypoint,
                      respect_reflectable));
  } 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(nullptr)) {
    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(T, args));
}

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

  String& field_name =
      String::Handle(Z, Api::UnwrapStringHandle(Z, name).ptr());
  if (field_name.IsNull()) {
    RETURN_TYPE_ERROR(Z, name, String);
  }
  const Object& obj = Object::Handle(Z, Api::UnwrapHandle(container));
  const bool respect_reflectable = false;
  const bool check_is_entrypoint = FLAG_verify_entry_points;

  if (obj.IsType()) {
    if (!Type::Cast(obj).IsFinalized()) {
      return Api::NewError(
          "%s expects argument 'container' to be a fully resolved type.",
          CURRENT_FUNC);
    }
    Class& cls = Class::Handle(Z, Type::Cast(obj).type_class());
    if (Library::IsPrivate(field_name)) {
      const Library& lib = Library::Handle(Z, cls.library());
      field_name = lib.PrivateName(field_name);
    }
    return Api::NewHandle(T, cls.InvokeGetter(field_name, check_is_entrypoint,
                                              respect_reflectable));
  } else if (obj.IsNull() || obj.IsInstance()) {
    Instance& instance = Instance::Handle(Z);
    instance ^= obj.ptr();
    if (Library::IsPrivate(field_name)) {
      const Class& cls = Class::Handle(Z, instance.clazz());
      const Library& lib = Library::Handle(Z, cls.library());
      field_name = lib.PrivateName(field_name);
    }
    return Api::NewHandle(T,
                          instance.InvokeGetter(field_name, check_is_entrypoint,
                                                respect_reflectable));
  } else if (obj.IsLibrary()) {
    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);
    }
    if (Library::IsPrivate(field_name)) {
      field_name = lib.PrivateName(field_name);
    }
    return Api::NewHandle(T, lib.InvokeGetter(field_name, check_is_entrypoint,
                                              respect_reflectable));
  } 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);

  String& field_name =
      String::Handle(Z, Api::UnwrapStringHandle(Z, name).ptr());
  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.ptr();

  const Object& obj = Object::Handle(Z, Api::UnwrapHandle(container));
  const bool respect_reflectable = false;
  const bool check_is_entrypoint = FLAG_verify_entry_points;

  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());
    if (Library::IsPrivate(field_name)) {
      const Library& lib = Library::Handle(Z, cls.library());
      field_name = lib.PrivateName(field_name);
    }
    return Api::NewHandle(
        T, cls.InvokeSetter(field_name, value_instance, check_is_entrypoint,
                            respect_reflectable));
  } else if (obj.IsNull() || obj.IsInstance()) {
    Instance& instance = Instance::Handle(Z);
    instance ^= obj.ptr();
    if (Library::IsPrivate(field_name)) {
      const Class& cls = Class::Handle(Z, instance.clazz());
      const Library& lib = Library::Handle(Z, cls.library());
      field_name = lib.PrivateName(field_name);
    }
    return Api::NewHandle(
        T, instance.InvokeSetter(field_name, value_instance,
                                 check_is_entrypoint, respect_reflectable));
  } 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);
    }

    if (Library::IsPrivate(field_name)) {
      field_name = lib.PrivateName(field_name);
    }
    return Api::NewHandle(
        T, lib.InvokeSetter(field_name, value_instance, check_is_entrypoint,
                            respect_reflectable));
  } 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();
  CHECK_ISOLATE_GROUP(thread->isolate_group());
  CHECK_CALLBACK_STATE(thread);
  if (::Dart_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;
    InstancePtr raw_exception =
        Api::UnwrapInstanceHandle(zone, exception).ptr();
    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();
  CHECK_ISOLATE_GROUP(thread->isolate_group());
  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;
    InstancePtr raw_exception =
        Api::UnwrapInstanceHandle(zone, exception).ptr();
    StackTracePtr raw_stacktrace =
        Api::UnwrapStackTraceHandle(zone, stacktrace).ptr();
    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_GetNativeInstanceFieldCount(Dart_Handle obj,
                                                         int* count) {
  Thread* thread = Thread::Current();
  CHECK_ISOLATE_GROUP(thread->isolate_group());
  TransitionNativeToVM transition(thread);
  {
    ReusableObjectHandleScope reused_obj_handle(thread);
    const Instance& instance =
        Api::UnwrapInstanceHandle(reused_obj_handle, obj);
    if (!instance.IsNull()) {
      *count = instance.NumNativeFields();
      return Api::Success();
    }
  }
  RETURN_TYPE_ERROR(thread->zone(), obj, Instance);
}

DART_EXPORT Dart_Handle Dart_GetNativeInstanceField(Dart_Handle obj,
                                                    int index,
                                                    intptr_t* value) {
  Thread* thread = Thread::Current();
  CHECK_ISOLATE_GROUP(thread->isolate_group());
  TransitionNativeToVM transition(thread);
  bool is_null = false;
  {
    ReusableObjectHandleScope reused_obj_handle(thread);
    const Instance& instance =
        Api::UnwrapInstanceHandle(reused_obj_handle, obj);
    if (!instance.IsNull()) {
      if (instance.IsValidNativeIndex(index)) {
        *value = instance.GetNativeField(index);
        return Api::Success();
      }
    } else {
      is_null = true;
    }
  }
  if (is_null) {
    RETURN_TYPE_ERROR(thread->zone(), obj, Instance);
  }
  return Api::NewError(
      "%s: invalid index %d passed into access native instance field",
      CURRENT_FUNC, index);
}

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 into set native instance field",
        CURRENT_FUNC, index);
  }
  instance.SetNativeField(index, value);
  return Api::Success();
}

DART_EXPORT void* Dart_GetNativeIsolateGroupData(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);
  TransitionNativeToVM transition(arguments->thread());
  ASSERT(arguments->thread()->isolate() == Isolate::Current());
  if (arg_values == nullptr) {
    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::NewArgumentError(
              "%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::NewArgumentError(
              "%s: expects argument at index %d to be of"
              " type Integer.",
              CURRENT_FUNC, i);
        }
        if (value < INT32_MIN || value > INT32_MAX) {
          return Api::NewArgumentError(
              "%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::NewArgumentError(
              "%s: expects argument at index %d to be of"
              " type Integer.",
              CURRENT_FUNC, i);
        }
        if (value < 0 || value > UINT32_MAX) {
          return Api::NewArgumentError(
              "%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::NewArgumentError(
              "%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::NewArgumentError(
              "%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::NewArgumentError(
              "%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::NewArgumentError(
              "%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() != nullptr);
        native_value->as_instance = Api::NewHandle(
            arguments->thread(), arguments->NativeArgAt(arg_index));
        break;
      }

      default:
        return Api::NewArgumentError("%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);
  }
  TransitionNativeToVM transition(arguments->thread());
  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 == nullptr) {
    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);
  TransitionNativeToVM transition(arguments->thread());
  ASSERT(arguments->thread()->isolate() == Isolate::Current());
  if (value == nullptr) {
    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);
  TransitionNativeToVM transition(arguments->thread());
  Dart_Handle result = Api::Null();
  if (!GetNativeStringArgument(arguments, arg_index, &result, peer)) {
    return Api::NewArgumentError(
        "%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::NewArgumentError(
        "%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::NewArgumentError(
        "%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::NewArgumentError(
        "%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());
  ASSERT_CALLBACK_STATE(arguments->thread());
  TransitionNativeToVM transition(arguments->thread());
  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));
    FATAL(
        "Return value check failed: saw '%s' expected a dart Instance or "
        "an Error.",
        ret_obj.ToCString());
  }
  ASSERT(retval != nullptr);
  Api::SetReturnValue(arguments, retval);
}

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

// --- Environment ---
StringPtr 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().ptr();
    }

    if (!Api::IsFfiEnabled() && name.Equals(Symbols::DartLibraryFfi())) {
      return Symbols::False().ptr();
    }

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

    if (name.Equals(Symbols::DartVMASAN())) {
#ifdef USING_ADDRESS_SANITIZER
      return Symbols::True().ptr();
#else
      return Symbols::False().ptr();
#endif
    }

    if (name.Equals(Symbols::DartVMMSAN())) {
#ifdef USING_MEMORY_SANITIZER
      return Symbols::True().ptr();
#else
      return Symbols::False().ptr();
#endif
    }

    if (name.Equals(Symbols::DartVMTSAN())) {
#ifdef USING_THREAD_SANITIZER
      return Symbols::True().ptr();
#else
      return Symbols::False().ptr();
#endif
    }

    if (name.Equals(Symbols::DartDeveloperTimeline())) {
#ifdef SUPPORT_TIMELINE
      return Symbols::True().ptr();
#else
      return Symbols::False().ptr();
#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().ptr();
        }
      }
    }
    // Check for default VM provided values. If it was not overridden on the
    // command line.
    if (Symbols::DartIsVM().Equals(name)) {
      return Symbols::True().ptr();
    }
  }
  return result.ptr();
}

StringPtr Api::CallEnvironmentCallback(Thread* thread, const String& name) {
  Isolate* isolate = thread->isolate();
  if (isolate == nullptr) {
    ThrowCantRunWithoutIsolateError();
    UNREACHABLE();
  }
  Dart_EnvironmentCallback callback = isolate->environment_callback();
  if (callback != nullptr) {
    Scope api_scope(thread);
    Dart_Handle api_name = Api::NewHandle(thread, name.ptr());
    Dart_Handle api_response;
    {
      TransitionVMToNative transition(thread);
      api_response = callback(api_name);
    }
    const Object& response =
        Object::Handle(thread->zone(), Api::UnwrapHandle(api_response));
    if (response.IsString()) {
      return String::Cast(response).ptr();
    } else if (response.IsError()) {
      Exceptions::ThrowArgumentError(
          String::Handle(String::New(Error::Cast(response).ToErrorCString())));
    } else if (!response.IsNull()) {
      // At this point everything except null are invalid environment values.
      Exceptions::ThrowArgumentError(
          String::Handle(String::New("Illegal environment value")));
    }
  }
  return String::null();
}

DART_EXPORT Dart_Handle
Dart_SetEnvironmentCallback(Dart_EnvironmentCallback callback) {
  Isolate* isolate = Isolate::Current();
  if (isolate == nullptr) {
    ThrowCantRunWithoutIsolateError();
    UNREACHABLE();
  }
  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);
  TransitionNativeToVM transition(arguments->thread());
  ASSERT(arguments->thread()->isolate() == Isolate::Current());
  ASSERT_CALLBACK_STATE(arguments->thread());
  arguments->SetReturn(Bool::Get(retval));
}

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

DART_EXPORT void Dart_SetDoubleReturnValue(Dart_NativeArguments args,
                                           double retval) {
  NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
  ASSERT(arguments->thread()->isolate() == Isolate::Current());
  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) {
  IsolateGroup* isolate_group = IsolateGroup::Current();
  CHECK_ISOLATE_GROUP(isolate_group);
  isolate_group->set_library_tag_handler(handler);
  return Api::Success();
}

DART_EXPORT Dart_Handle
Dart_SetDeferredLoadHandler(Dart_DeferredLoadHandler handler) {
  IsolateGroup* isolate_group = IsolateGroup::Current();
  CHECK_ISOLATE_GROUP(isolate_group);
  isolate_group->set_deferred_load_handler(handler);
  return Api::Success();
}

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);
  IsolateGroup* IG = T->isolate_group();

  Library& library = Library::Handle(Z, IG->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);

  // NOTE: We do not attach a finalizer for this object, because the embedder
  // will free it once the isolate group has shutdown.
  const auto& td = ExternalTypedData::Handle(ExternalTypedData::New(
      kExternalTypedDataUint8ArrayCid, const_cast<uint8_t*>(buffer),
      buffer_size, Heap::kOld));

  const char* error = nullptr;
  std::unique_ptr<kernel::Program> program =
      kernel::Program::ReadFromTypedData(td, &error);
  if (program == nullptr) {
    return Api::NewError("Can't load Kernel binary: %s.", error);
  }
  const Object& tmp = kernel::KernelLoader::LoadEntireProgram(program.get());
  program.reset();

  if (tmp.IsError()) {
    return Api::NewHandle(T, tmp.ptr());
  }

  IG->source()->script_kernel_size = buffer_size;
  IG->source()->script_kernel_buffer = buffer;

  // 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(
        "Invoked Dart programs must have a 'main' function defined:\n"
        "https://dart.dev/to/main-function");
  }
  library ^= tmp.ptr();
  IG->object_store()->set_root_library(library);
  return Api::NewHandle(T, library.ptr());
#endif  // defined(DART_PRECOMPILED_RUNTIME)
}

DART_EXPORT Dart_Handle Dart_LoadScriptFromBytecode(const uint8_t* buffer,
                                                    intptr_t buffer_size) {
#if defined(DART_DYNAMIC_MODULES)
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  StackZone zone(T);
  IsolateGroup* IG = T->isolate_group();

  Library& library = Library::Handle(Z, IG->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);

  // NOTE: We do not attach a finalizer for this object, because the embedder
  // will free it once the isolate group has shutdown.
  const auto& typed_data = ExternalTypedData::Handle(ExternalTypedData::New(
      kExternalTypedDataUint8ArrayCid, const_cast<uint8_t*>(buffer),
      buffer_size, Heap::kOld));

  SafepointWriteRwLocker ml(T, IG->program_lock());
  bytecode::BytecodeLoader loader(T, typed_data);
  const Function& function = Function::Handle(loader.LoadBytecode());

  if (function.IsNull()) {
    return Api::NewError(
        "Invoked Dart programs must have a 'main' function defined:\n"
        "https://dart.dev/to/main-function");
  }
  library ^= Class::Handle(function.Owner()).library();
  IG->object_store()->set_root_library(library);
  return Api::NewHandle(T, library.ptr());
#else
  return Api::NewError(
      "%s: Cannot load bytecode as dynamic modules are disabled.",
      CURRENT_FUNC);
#endif  // defined(DART_DYNAMIC_MODULES)
}

DART_EXPORT DART_API_WARN_UNUSED_RESULT Dart_Handle
Dart_LoadModuleSnapshot(const uint8_t* snapshot_data,
                        const uint8_t* snapshot_instructions) {
#if defined(DART_PRECOMPILED_RUNTIME)
  return Api::NewError("%s: Cannot load module snapshots on an AOT runtime.",
                       CURRENT_FUNC);
#else
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  CHECK_CALLBACK_STATE(T);

#if defined(SUPPORT_TIMELINE)
  TimelineBeginEndScope tbes(T, Timeline::GetIsolateStream(),
                             "ReadModuleSnapshot");
#endif  // defined(SUPPORT_TIMELINE)
  const Snapshot* snapshot = Snapshot::SetupFromBuffer(snapshot_data);
  if (snapshot == nullptr) {
    return Api::NewError("Invalid snapshot");
  }
  if (snapshot->kind() != Snapshot::kModule) {
    return Api::NewError("Invalid snapshot kind");
  }

  const Error& error = Error::Handle(
      module_snapshot::ReadModuleSnapshot(T, snapshot, snapshot_instructions));
  if (!error.IsNull()) {
    return Api::NewHandle(T, error.ptr());
  }

  return Api::Success();
#endif  // defined(DART_PRECOMPILED_RUNTIME)
}

DART_EXPORT Dart_Handle Dart_RootLibrary() {
  Thread* thread = Thread::Current();
  IsolateGroup* isolate_group = thread->isolate_group();
  CHECK_ISOLATE_GROUP(isolate_group);
  TransitionNativeToVM transition(thread);
  return Api::NewHandle(thread, isolate_group->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.ptr();
    T->isolate_group()->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());
  }
  cls.EnsureDeclarationLoaded();
  if (FLAG_verify_entry_points) {
    CHECK_ERROR_HANDLE(cls.VerifyEntryPoint());
  }
  return Api::NewHandle(T, cls.RareType());
}

static Dart_Handle GetTypeCommon(Dart_Handle library,
                                 Dart_Handle class_name,
                                 intptr_t number_of_type_arguments,
                                 Dart_Handle* type_arguments,
                                 Nullability nullability) {
  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());
  }
  cls.EnsureDeclarationLoaded();
  if (FLAG_verify_entry_points) {
    CHECK_ERROR_HANDLE(cls.VerifyEntryPoint());
  }

  Type& type = Type::Handle();
  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);
    }
    type ^= Type::NewNonParameterizedType(cls);
    type ^= type.ToNullability(nullability, Heap::kOld);
  } else {
    intptr_t num_expected_type_arguments = cls.NumTypeParameters();
    TypeArguments& type_args_obj = TypeArguments::Handle();
    if (number_of_type_arguments > 0) {
      if (type_arguments == nullptr) {
        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 ^= Type::New(cls, type_args_obj, nullability);
  }
  type ^= ClassFinalizer::FinalizeType(type);
  return Api::NewHandle(T, type.ptr());
}

DART_EXPORT Dart_Handle Dart_GetType(Dart_Handle library,
                                     Dart_Handle class_name,
                                     intptr_t number_of_type_arguments,
                                     Dart_Handle* type_arguments) {
  return Api::NewError(
      "Cannot use legacy types with --sound-null-safety enabled. "
      "Use Dart_GetNullableType or Dart_GetNonNullableType instead.");
}

DART_EXPORT Dart_Handle Dart_GetNullableType(Dart_Handle library,
                                             Dart_Handle class_name,
                                             intptr_t number_of_type_arguments,
                                             Dart_Handle* type_arguments) {
  return GetTypeCommon(library, class_name, number_of_type_arguments,
                       type_arguments, Nullability::kNullable);
}

DART_EXPORT Dart_Handle
Dart_GetNonNullableType(Dart_Handle library,
                        Dart_Handle class_name,
                        intptr_t number_of_type_arguments,
                        Dart_Handle* type_arguments) {
  return GetTypeCommon(library, class_name, number_of_type_arguments,
                       type_arguments, Nullability::kNonNullable);
}

static Dart_Handle TypeToHelper(Dart_Handle type, Nullability nullability) {
  DARTSCOPE(Thread::Current());
  const Type& ty = Api::UnwrapTypeHandle(Z, type);
  if (ty.IsNull()) {
    RETURN_TYPE_ERROR(Z, type, Type);
  }
  if (ty.nullability() == nullability) {
    return type;
  }
  return Api::NewHandle(T, ty.ToNullability(nullability, Heap::kOld));
}

DART_EXPORT Dart_Handle Dart_TypeToNullableType(Dart_Handle type) {
  return TypeToHelper(type, Nullability::kNullable);
}

DART_EXPORT Dart_Handle Dart_TypeToNonNullableType(Dart_Handle type) {
  return TypeToHelper(type, Nullability::kNonNullable);
}

static Dart_Handle IsOfTypeNullabilityHelper(Dart_Handle type,
                                             Nullability nullability,
                                             bool* result) {
  DARTSCOPE(Thread::Current());
  const Type& ty = Api::UnwrapTypeHandle(Z, type);
  if (ty.IsNull()) {
    *result = false;
    RETURN_TYPE_ERROR(Z, type, Type);
  }
  *result = (ty.nullability() == nullability);
  return Api::Success();
}

DART_EXPORT Dart_Handle Dart_IsNullableType(Dart_Handle type, bool* result) {
  return IsOfTypeNullabilityHelper(type, Nullability::kNullable, result);
}

DART_EXPORT Dart_Handle Dart_IsNonNullableType(Dart_Handle type, bool* result) {
  return IsOfTypeNullabilityHelper(type, Nullability::kNonNullable, result);
}

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.ptr());
}

DART_EXPORT Dart_Handle Dart_LibraryResolvedUrl(Dart_Handle library) {
  DARTSCOPE(Thread::Current());
  const Library& lib = Api::UnwrapLibraryHandle(Z, library);
  if (lib.IsNull()) {
    RETURN_TYPE_ERROR(Z, library, Library);
  }
  const Class& toplevel = Class::Handle(lib.toplevel_class());
  ASSERT(!toplevel.IsNull());
  const Script& script = Script::Handle(toplevel.script());
  ASSERT(!script.IsNull());
  const String& url = String::Handle(script.resolved_url());
  ASSERT(!url.IsNull());
  return Api::NewHandle(T, url.ptr());
}

DART_EXPORT Dart_Handle Dart_GetLoadedLibraries() {
  DARTSCOPE(Thread::Current());
  auto IG = T->isolate_group();

  const GrowableObjectArray& libs =
      GrowableObjectArray::Handle(Z, IG->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.ptr());
}

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.ptr());
  }
}

DART_EXPORT Dart_Handle Dart_LibraryHandleError(Dart_Handle library_in,
                                                Dart_Handle error_in) {
  DARTSCOPE(Thread::Current());

  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);

  return error_in;
}

#if !defined(DART_PRECOMPILED_RUNTIME)
static Dart_Handle LoadLibrary(Thread* T, const ExternalTypedData& td) {
  const char* error = nullptr;
  std::unique_ptr<kernel::Program> program =
      kernel::Program::ReadFromTypedData(td, &error);
  if (program == nullptr) {
    return Api::NewError("Can't load Kernel binary: %s.", error);
  }
  const Object& result =
      kernel::KernelLoader::LoadEntireProgram(program.get(), false);
  program.reset();

  IsolateGroupSource* source = IsolateGroup::Current()->source();
  source->add_loaded_blob(Z, td);

  return Api::NewHandle(T, result.ptr());
}
#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);

  CHECK_CALLBACK_STATE(T);

  // NOTE: We do not attach a finalizer for this object, because the embedder
  // will/should free it once the isolate group has shutdown.
  const auto& td = ExternalTypedData::Handle(ExternalTypedData::New(
      kExternalTypedDataUint8ArrayCid, const_cast<uint8_t*>(buffer),
      buffer_size, Heap::kOld));
  return LoadLibrary(T, td);
#endif  // defined(DART_PRECOMPILED_RUNTIME)
}

DART_EXPORT Dart_Handle Dart_LoadLibrary(Dart_Handle kernel_buffer) {
#if defined(DART_PRECOMPILED_RUNTIME)
  return Api::NewError("%s: Cannot compile on an AOT runtime.", CURRENT_FUNC);
#else
  DARTSCOPE(Thread::Current());
  const ExternalTypedData& td =
      Api::UnwrapExternalTypedDataHandle(Z, kernel_buffer);
  if (td.IsNull()) {
    RETURN_TYPE_ERROR(Z, kernel_buffer, ExternalTypedData);
  }
  return LoadLibrary(T, td);
#endif  // defined(DART_PRECOMPILED_RUNTIME)
}

DART_EXPORT Dart_Handle
Dart_LoadLibraryFromBytecode(Dart_Handle bytecode_buffer) {
#if defined(DART_DYNAMIC_MODULES)
  DARTSCOPE(Thread::Current());
  const ExternalTypedData& td =
      Api::UnwrapExternalTypedDataHandle(Z, bytecode_buffer);
  if (td.IsNull()) {
    RETURN_TYPE_ERROR(Z, bytecode_buffer, ExternalTypedData);
  }
  SafepointWriteRwLocker ml(T, T->isolate_group()->program_lock());
  bytecode::BytecodeLoader loader(T, td);
  const Function& function = Function::Handle(loader.LoadBytecode());
  if (function.IsNull()) {
    return Api::Null();
  }
  return Api::NewHandle(T, Class::Handle(function.Owner()).library());
#else
  return Api::NewError(
      "%s: Cannot load bytecode as dynamic modules are disabled.",
      CURRENT_FUNC);
#endif  // defined(DART_DYNAMIC_MODULES)
}

// 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);

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

#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

  // After having loaded all the code, we can let the GC set reasonable limits
  // for the heap growth.
  // If this is an auxiliary isolate inside a larger isolate group, we will not
  // re-initialize the growth policy.
  if (I->group()->ContainsOnlyOneIsolate()) {
    // Helper tasks like the background compile might be running. Avoid data
    // races on the growth policy.
    GcSafepointOperationScope safepoint(T);
    I->group()->heap()->old_space()->EvaluateAfterLoading();
  }

#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.LookupFieldAllowPrivate(
                             String::Handle(String::New("_dirty"))));
    ASSERT(!dirty_bit.IsNull() && dirty_bit.is_static());
    dirty_bit.SetStaticValue(Bool::True());
  }
#endif

  return Api::Success();
}

static Dart_Handle DeferredLoadComplete(intptr_t loading_unit_id,
                                        bool error,
                                        const uint8_t* snapshot_data,
                                        const uint8_t* snapshot_instructions,
                                        const char* error_message,
                                        bool transient_error) {
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  auto IG = T->isolate_group();
  CHECK_CALLBACK_STATE(T);

  const Array& loading_units =
      Array::Handle(IG->object_store()->loading_units());
  if (loading_units.IsNull() || (loading_unit_id < LoadingUnit::kRootId) ||
      (loading_unit_id >= loading_units.Length())) {
    return Api::NewError("Invalid loading unit");
  }
  LoadingUnit& unit = LoadingUnit::Handle();
  unit ^= loading_units.At(loading_unit_id);
  if (unit.loaded()) {
    return Api::NewError("Unit already loaded");
  }

  if (error) {
    CHECK_NULL(error_message);
    return Api::NewHandle(
        T, unit.CompleteLoad(String::Handle(String::New(error_message)),
                             transient_error));
  } else {
#if defined(SUPPORT_TIMELINE)
    TimelineBeginEndScope tbes(T, Timeline::GetIsolateStream(),
                               "ReadUnitSnapshot");
#endif  // defined(SUPPORT_TIMELINE)
    const Snapshot* snapshot = Snapshot::SetupFromBuffer(snapshot_data);
    if (snapshot == nullptr) {
      return Api::NewError("Invalid snapshot");
    }
    if (!IsSnapshotCompatible(Dart::vm_snapshot_kind(), snapshot->kind())) {
      const String& message = String::Handle(String::NewFormatted(
          "Incompatible snapshot kinds: vm '%s', isolate '%s'",
          Snapshot::KindToCString(Dart::vm_snapshot_kind()),
          Snapshot::KindToCString(snapshot->kind())));
      return Api::NewHandle(T, ApiError::New(message));
    }

    FullSnapshotReader reader(snapshot, snapshot_instructions, T);
    const Error& error = Error::Handle(reader.ReadUnitSnapshot(unit));
    if (!error.IsNull()) {
      return Api::NewHandle(T, error.ptr());
    }

    return Api::NewHandle(T, unit.CompleteLoad(String::Handle(), false));
  }
}

DART_EXPORT Dart_Handle
Dart_DeferredLoadComplete(intptr_t loading_unit_id,
                          const uint8_t* snapshot_data,
                          const uint8_t* snapshot_instructions) {
  return DeferredLoadComplete(loading_unit_id, false, snapshot_data,
                              snapshot_instructions, nullptr, false);
}

DART_EXPORT Dart_Handle
Dart_DeferredLoadCompleteError(intptr_t loading_unit_id,
                               const char* error_message,
                               bool transient) {
  return DeferredLoadComplete(loading_unit_id, true, nullptr, nullptr,
                              error_message, transient);
}

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 == nullptr) {
    RETURN_NULL_ERROR(resolver);
  }
  *resolver = nullptr;
  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 == nullptr) {
    RETURN_NULL_ERROR(resolver);
  }
  *resolver = nullptr;
  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();
}

DART_EXPORT Dart_Handle
Dart_SetFfiNativeResolver(Dart_Handle library,
                          Dart_FfiNativeResolver resolver) {
  DARTSCOPE(Thread::Current());
  const Library& lib = Api::UnwrapLibraryHandle(Z, library);
  if (lib.IsNull()) {
    RETURN_TYPE_ERROR(Z, library, Library);
  }
  lib.set_ffi_native_resolver(resolver);
  return Api::Success();
}

DART_EXPORT
void Dart_InitializeNativeAssetsResolver(NativeAssetsApi* native_assets_api) {
  Thread* T = Thread::Current();
  IsolateGroup* isolate_group = T->isolate_group();
  CHECK_ISOLATE_GROUP(isolate_group);
  isolate_group->SetNativeAssetsCallbacks(native_assets_api);
}

// --- Peer support ---

DART_EXPORT Dart_Handle Dart_GetPeer(Dart_Handle object, void** peer) {
  if (peer == nullptr) {
    RETURN_NULL_ERROR(peer);
  }
  Thread* thread = Thread::Current();
  CHECK_ISOLATE_GROUP(thread->isolate_group());
  TransitionNativeToVM transition(thread);
  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;
    ObjectPtr raw_obj = obj.ptr();
    *peer = thread->heap()->GetPeer(raw_obj);
  }
  return Api::Success();
}

DART_EXPORT Dart_Handle Dart_SetPeer(Dart_Handle object, void* peer) {
  Thread* thread = Thread::Current();
  CHECK_ISOLATE_GROUP(thread->isolate_group());
  TransitionNativeToVM transition(thread);
  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;
    ObjectPtr raw_obj = obj.ptr();
    thread->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 iso->is_kernel_isolate();
#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,
                     bool for_snapshot,
                     bool embed_sources,
                     const char* package_config,
                     Dart_KernelCompilationVerbosityLevel verbosity) {
  API_TIMELINE_DURATION(Thread::Current());

  Dart_KernelCompilationResult result = {};
#if defined(DART_PRECOMPILED_RUNTIME)
  result.status = Dart_KernelCompilationStatus_Unknown;
  result.error = Utils::StrDup("Dart_CompileToKernel is unsupported.");
#else
  result = KernelIsolate::CompileToKernel(
      script_uri, platform_kernel, platform_kernel_size, 0, nullptr,
      incremental_compile, for_snapshot, embed_sources, package_config, nullptr,
      nullptr, verbosity);
  if (incremental_compile) {
    Dart_KernelCompilationResult ack_result =
        result.status == Dart_KernelCompilationStatus_Ok
            ? KernelIsolate::AcceptCompilation()
            : KernelIsolate::RejectCompilation();
    if (ack_result.status != Dart_KernelCompilationStatus_Ok) {
      FATAL(
          "An error occurred in the CFE while acking the most recent"
          " compilation results: %s",
          ack_result.error);
    }
  }
#endif
  return result;
}

DART_EXPORT Dart_KernelCompilationResult Dart_KernelListDependencies() {
  Dart_KernelCompilationResult result = {};
#if defined(DART_PRECOMPILED_RUNTIME)
  result.status = Dart_KernelCompilationStatus_Unknown;
  result.error = Utils::StrDup("Dart_KernelListDependencies is unsupported.");
#else
  result = KernelIsolate::ListDependencies();
#endif
  return result;
}

DART_EXPORT void Dart_SetDartLibrarySourcesKernel(
    const uint8_t* platform_kernel,
    const intptr_t platform_kernel_size) {
#if !defined(PRODUCT)
  Service::SetDartLibraryKernelForSources(platform_kernel,
                                          platform_kernel_size);
#endif
}

DART_EXPORT bool Dart_DetectNullSafety(const char* script_uri,
                                       const char* package_config,
                                       const char* original_working_directory,
                                       const uint8_t* snapshot_data,
                                       const uint8_t* snapshot_instructions,
                                       const uint8_t* kernel_buffer,
                                       intptr_t kernel_buffer_size) {
  return true;
}

// --- Service support ---

DART_EXPORT bool Dart_IsServiceIsolate(Dart_Isolate isolate) {
  Isolate* iso = reinterpret_cast<Isolate*>(isolate);
  return iso->is_service_isolate();
}

DART_EXPORT void Dart_RegisterIsolateServiceRequestCallback(
    const char* name,
    Dart_ServiceRequestCallback callback,
    void* user_data) {
#if !defined(PRODUCT)
  Service::RegisterIsolateEmbedderCallback(name, callback, user_data);
#endif
}

DART_EXPORT void Dart_RegisterRootServiceRequestCallback(
    const char* name,
    Dart_ServiceRequestCallback callback,
    void* user_data) {
#if !defined(PRODUCT)
  Service::RegisterRootEmbedderCallback(name, callback, user_data);
#endif
}

DART_EXPORT void Dart_SetEmbedderInformationCallback(
    Dart_EmbedderInformationCallback callback) {
#if !defined(PRODUCT)
  Service::SetEmbedderInformationCallback(callback);
#endif
}

DART_EXPORT char* Dart_SetServiceStreamCallbacks(
    Dart_ServiceStreamListenCallback listen_callback,
    Dart_ServiceStreamCancelCallback cancel_callback) {
#if defined(PRODUCT)
  return nullptr;
#else
  if (listen_callback != nullptr) {
    if (Service::stream_listen_callback() != nullptr) {
      return Utils::StrDup(
          "Dart_SetServiceStreamCallbacks "
          "permits only one listen callback to be registered, please "
          "remove the existing callback and then add this callback");
    }
  } else {
    if (Service::stream_listen_callback() == nullptr) {
      return Utils::StrDup(
          "Dart_SetServiceStreamCallbacks "
          "expects 'listen_callback' to be present in the callback set.");
    }
  }
  if (cancel_callback != nullptr) {
    if (Service::stream_cancel_callback() != nullptr) {
      return Utils::StrDup(
          "Dart_SetServiceStreamCallbacks "
          "permits only one cancel callback to be registered, please "
          "remove the existing callback and then add this callback");
    }
  } else {
    if (Service::stream_cancel_callback() == nullptr) {
      return Utils::StrDup(
          "Dart_SetServiceStreamCallbacks "
          "expects 'cancel_callback' to be present in the callback set.");
    }
  }
  Service::SetEmbedderStreamCallbacks(listen_callback, cancel_callback);
  return nullptr;
#endif
}

DART_EXPORT char* Dart_ServiceSendDataEvent(const char* stream_id,
                                            const char* event_kind,
                                            const uint8_t* bytes,
                                            intptr_t bytes_length) {
#if !defined(PRODUCT)
  if (stream_id == nullptr) {
    return Utils::StrDup(
        "Dart_ServiceSendDataEvent expects argument 'stream_id' to be "
        "non-null.");
  }
  if (event_kind == nullptr) {
    return Utils::StrDup(
        "Dart_ServiceSendDataEvent expects argument 'event_kind' to be "
        "non-null.");
  }
  if (bytes == nullptr) {
    return Utils::StrDup(
        "Dart_ServiceSendDataEvent expects argument 'bytes' to be non-null.");
  }
  if (bytes_length < 0) {
    return Utils::StrDup(
        "Dart_ServiceSendDataEvent expects argument 'bytes_length' to be >= "
        "0.");
  }
  Service::SendEmbedderEvent(Isolate::Current(),  // May be nullptr
                             stream_id, event_kind, bytes, bytes_length);
#endif
  return nullptr;
}

DART_EXPORT void Dart_SetDwarfStackTraceFootnoteCallback(
    Dart_DwarfStackTraceFootnoteCallback callback) {
  Dart::set_dwarf_stacktrace_footnote_callback(callback);
}

DART_EXPORT char* Dart_SetFileModifiedCallback(
    Dart_FileModifiedCallback file_modified_callback) {
#if !defined(PRODUCT)
#if !defined(DART_PRECOMPILED_RUNTIME)
  if (file_modified_callback != nullptr) {
    if (IsolateGroupReloadContext::file_modified_callback() != nullptr) {
      return Utils::StrDup(
          "Dart_SetFileModifiedCallback permits only one callback to be"
          " registered, please remove the existing callback and then add"
          " this callback");
    }
  } else {
    if (IsolateGroupReloadContext::file_modified_callback() == nullptr) {
      return Utils::StrDup(
          "Dart_SetFileModifiedCallback expects 'file_modified_callback' to"
          " be set before it is cleared.");
    }
  }
  IsolateGroupReloadContext::SetFileModifiedCallback(file_modified_callback);
#endif  // !defined(DART_PRECOMPILED_RUNTIME)
#endif  // !defined(PRODUCT)
  return nullptr;
}

DART_EXPORT bool Dart_IsReloading() {
#if defined(PRODUCT) || defined(DART_PRECOMPILED_RUNTIME)
  return false;
#else
  Thread* thread = Thread::Current();
  IsolateGroup* isolate_group = thread->isolate_group();
  CHECK_ISOLATE_GROUP(isolate_group);
  return isolate_group->IsReloading();
#endif
}

DART_EXPORT bool Dart_SetEnabledTimelineCategory(const char* categories) {
#if defined(SUPPORT_TIMELINE)
  bool result = false;
  if (categories != nullptr) {
    char* carray = Utils::SCreate("[%s]", categories);
    result = Service::EnableTimelineStreams(carray);
    free(carray);
  }
  return result;
#else
  return false;
#endif
}

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

DART_EXPORT int64_t Dart_TimelineGetTicks() {
  return OS::GetCurrentMonotonicTicks();
}

DART_EXPORT int64_t Dart_TimelineGetTicksFrequency() {
  return OS::GetCurrentMonotonicFrequency();
}

DART_EXPORT void Dart_RecordTimelineEvent(const char* label,
                                          int64_t timestamp0,
                                          int64_t timestamp1_or_id,
                                          intptr_t flow_id_count,
                                          const int64_t* flow_ids,
                                          Dart_Timeline_Event_Type type,
                                          intptr_t argument_count,
                                          const char** argument_names,
                                          const char** argument_values) {
#if defined(SUPPORT_TIMELINE)
  if (type < Dart_Timeline_Event_Begin) {
    return;
  }
  if (type > Dart_Timeline_Event_Flow_End) {
    return;
  }
  if (!Dart::SetActiveApiCall()) {
    return;
  }
  TimelineStream* stream = Timeline::GetEmbedderStream();
  ASSERT(stream != nullptr);
  TimelineEvent* event = stream->StartEvent();
  if (event != nullptr) {
    switch (type) {
      case Dart_Timeline_Event_Begin:
        event->Begin(label, timestamp1_or_id, timestamp0);
        break;
      case Dart_Timeline_Event_End:
        event->End(label, timestamp1_or_id, timestamp0);
        break;
      case Dart_Timeline_Event_Instant:
        event->Instant(label, timestamp0);
        break;
      case Dart_Timeline_Event_Duration:
        event->Duration(label, timestamp0, timestamp1_or_id);
        break;
      case Dart_Timeline_Event_Async_Begin:
        event->AsyncBegin(label, timestamp1_or_id, timestamp0);
        break;
      case Dart_Timeline_Event_Async_End:
        event->AsyncEnd(label, timestamp1_or_id, timestamp0);
        break;
      case Dart_Timeline_Event_Async_Instant:
        event->AsyncInstant(label, timestamp1_or_id, timestamp0);
        break;
      case Dart_Timeline_Event_Counter:
        event->Counter(label, timestamp0);
        break;
      case Dart_Timeline_Event_Flow_Begin:
        event->FlowBegin(label, timestamp1_or_id, timestamp0);
        break;
      case Dart_Timeline_Event_Flow_Step:
        event->FlowStep(label, timestamp1_or_id, timestamp0);
        break;
      case Dart_Timeline_Event_Flow_End:
        event->FlowEnd(label, timestamp1_or_id, timestamp0);
        break;
      default:
        FATAL("Unknown Dart_Timeline_Event_Type");
    }
    if (flow_id_count > 0 && flow_ids != nullptr) {
      std::unique_ptr<const int64_t[]> flow_ids_copy;
      int64_t* flow_ids_internal = new int64_t[flow_id_count];
      for (intptr_t i = 0; i < flow_id_count; ++i) {
        flow_ids_internal[i] = flow_ids[i];
      }
      flow_ids_copy = std::unique_ptr<const int64_t[]>(flow_ids_internal);
      event->SetFlowIds(flow_id_count, flow_ids_copy);
    }
    event->SetNumArguments(argument_count);
    for (intptr_t i = 0; i < argument_count; i++) {
      event->CopyArgument(i, argument_names[i], argument_values[i]);
    }
    event->Complete();
  }
  Dart::ResetActiveApiCall();
#endif
}

DART_EXPORT void Dart_SetTimelineRecorderCallback(
    Dart_TimelineRecorderCallback callback) {
#if defined(SUPPORT_TIMELINE)
  Timeline::set_callback(callback);
#endif
}

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

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());

  // Prevent background compiler from running while code is being cleared and
  // adding new code.
  NoBackgroundCompilerScope no_bg_compiler(T);

  // 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.
  IsolateGroup::Current()->heap()->CollectAllGarbage();
  ClassFinalizer::SortClasses();
  return Api::Success();
#endif  // defined(DART_PRECOMPILED_RUNTIME)
}

DART_EXPORT Dart_Handle Dart_Precompile() {
#if defined(TARGET_ARCH_IA32)
  return Api::NewError("AOT compilation is not supported on IA32.");
#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 (Api::IsError(result)) {
    return result;
  }
  CHECK_CALLBACK_STATE(T);
  CompilerState state(Thread::Current(), /*is_aot=*/true,
                      /*is_optimizing=*/true);
  CHECK_ERROR_HANDLE(Precompiler::CompileAll());
  return Api::Success();
#endif
}

// Used for StreamingWriteStream/BlobImageWriter sizes for ELF and blobs.
#if !defined(TARGET_ARCH_IA32) && defined(DART_PRECOMPILER)
static constexpr intptr_t kAssemblyInitialSize = 512 * KB;
static constexpr intptr_t kInitialSize = 2 * MB;
static constexpr intptr_t kInitialDebugSize = 1 * MB;

static void CreateAppAOTSnapshotHelper(
    Dart_StreamingWriteCallback callback,
    void* callback_data,
    bool strip,
    Dart_AotBinaryFormat format,
    void* debug_callback_data,
    GrowableArray<LoadingUnitSerializationData*>* units,
    LoadingUnitSerializationData* unit,
    uint32_t program_hash,
    const char* identifier,
    const char* path,
    void* object_callback_data) {
  Thread* T = Thread::Current();

  NOT_IN_PRODUCT(TimelineBeginEndScope tbes2(T, Timeline::GetIsolateStream(),
                                             "WriteAppAOTSnapshot"));

  ZoneWriteStream vm_snapshot_data(T->zone(), FullSnapshotWriter::kInitialSize);
  ZoneWriteStream vm_snapshot_instructions(T->zone(), kInitialSize);
  ZoneWriteStream isolate_snapshot_data(T->zone(),
                                        FullSnapshotWriter::kInitialSize);
  ZoneWriteStream isolate_snapshot_instructions(T->zone(), kInitialSize);

  bool generate_debug = debug_callback_data != nullptr;
#if defined(DART_TARGET_OS_WINDOWS)
  if (format == Dart_AotBinaryFormat_Assembly) {
    // TODO(https://github.com/dart-lang/sdk/issues/60812): Support PDB.
    generate_debug = false;  // PDB unimplemented, no DWARF in PE.
  }
#endif

  auto* const deobfuscation_trie =
      (strip && !generate_debug) ? nullptr
                                 : ImageWriter::CreateReverseObfuscationTrie(T);

  StreamingWriteStream debug_stream(generate_debug ? kInitialDebugSize : 0,
                                    callback, debug_callback_data);
  Dwarf* debug_dwarf = nullptr;
  SharedObjectWriter* debug_so = nullptr;
  if (generate_debug) {
    debug_dwarf = new (Z) Dwarf(Z, deobfuscation_trie, identifier);
    if (format == Dart_AotBinaryFormat_MachO_Dylib) {
      debug_so = new (Z)
          MachOWriter(Z, &debug_stream, SharedObjectWriter::Type::DebugInfo,
                      identifier, /*path=*/nullptr, debug_dwarf);
    } else {
      debug_so = new (Z) ElfWriter(
          Z, &debug_stream, SharedObjectWriter::Type::DebugInfo, debug_dwarf);
    }
  }

  StreamingWriteStream output_stream(format == Dart_AotBinaryFormat_Assembly
                                         ? kAssemblyInitialSize
                                         : kInitialSize,
                                     callback, callback_data);

  // Should not be directly used below as writing to it when
  // [object_callback_data] is null causes a crash. Instead, use
  // [object_stream], which is appropriately nullptr in this case.
  StreamingWriteStream object_stream_value(kInitialSize, callback,
                                           object_callback_data);
  StreamingWriteStream* object_stream =
      object_callback_data != nullptr ? &object_stream_value : nullptr;

  auto const use_output_writer = [&](ImageWriter* image_writer) {
    FullSnapshotWriter writer(Snapshot::kFullAOT, &vm_snapshot_data,
                              &isolate_snapshot_data, image_writer,
                              image_writer);

    if (unit == nullptr || unit->id() == LoadingUnit::kRootId) {
      writer.WriteFullSnapshot(units);
    } else {
      writer.WriteUnitSnapshot(units, unit, program_hash);
    }
    image_writer->Finalize();
  };

  Dwarf* const dwarf =
      (format == Dart_AotBinaryFormat_Assembly || strip) ? nullptr
      : generate_debug                                   ? debug_dwarf
                       : new (Z) Dwarf(Z, deobfuscation_trie, identifier);
  SharedObjectWriter* so = nullptr;
  if (format == Dart_AotBinaryFormat_Elf) {
    so = new (Z)
        ElfWriter(Z, &output_stream, SharedObjectWriter::Type::Snapshot, dwarf);
  } else if (format == Dart_AotBinaryFormat_MachO_Dylib) {
    MachOWriter* object_writer = nullptr;
    if (object_stream != nullptr) {
      object_writer = new (Z)
          MachOWriter(Z, object_stream, SharedObjectWriter::Type::Object,
                      identifier, path, dwarf);
    }
    so = new (Z)
        MachOWriter(Z, &output_stream, SharedObjectWriter::Type::Snapshot,
                    identifier, path, dwarf, object_writer);
  }

  if (format == Dart_AotBinaryFormat_Assembly) {
    ASSERT(so == nullptr);
    AssemblyImageWriter assembly_writer(T, &output_stream, deobfuscation_trie,
                                        strip, debug_so);
    use_output_writer(&assembly_writer);
  } else {
    BlobImageWriter blob_writer(
        T, &vm_snapshot_instructions, &isolate_snapshot_instructions,
        deobfuscation_trie, debug_so, so,
        /*needs_unique_names=*/object_callback_data != nullptr);
    use_output_writer(&blob_writer);
  }
}

static void CreateAppAOTProgramSnapshot(Dart_StreamingWriteCallback callback,
                                        void* callback_data,
                                        bool strip,
                                        Dart_AotBinaryFormat format,
                                        void* debug_callback_data,
                                        const char* identifier = nullptr,
                                        const char* path = nullptr,
                                        void* object_callback_data = nullptr) {
  CreateAppAOTSnapshotHelper(
      callback, callback_data, strip, format, debug_callback_data,
      /*units=*/nullptr,
      /*unit=*/nullptr,
      /*program_hash=*/0, identifier, path, object_callback_data);
}

static void CreateAppAOTUnitSnapshot(
    Dart_StreamingWriteCallback callback,
    void* callback_data,
    bool strip,
    Dart_AotBinaryFormat format,
    void* debug_callback_data,
    GrowableArray<LoadingUnitSerializationData*>* units,
    LoadingUnitSerializationData* unit,
    uint32_t program_hash) {
  CreateAppAOTSnapshotHelper(callback, callback_data, strip, format,
                             debug_callback_data, units, unit, program_hash,
                             /*identifier=*/nullptr, /*path=*/nullptr,
                             /*object_callback_data=*/nullptr);
}

static void Split(Dart_CreateLoadingUnitCallback next_callback,
                  void* next_callback_data,
                  bool strip,
                  Dart_AotBinaryFormat format,
                  Dart_StreamingWriteCallback write_callback,
                  Dart_StreamingCloseCallback close_callback) {
  Thread* T = Thread::Current();
  ProgramVisitor::AssignUnits(T);

  const Array& loading_units =
      Array::Handle(T->isolate_group()->object_store()->loading_units());
  const uint32_t program_hash = ProgramVisitor::Hash(T);
  loading_units.SetAt(0, Smi::Handle(Z, Smi::New(program_hash)));
  GrowableArray<LoadingUnitSerializationData*> data;
  data.SetLength(loading_units.Length());
  data[0] = nullptr;

  LoadingUnit& loading_unit = LoadingUnit::Handle();
  LoadingUnit& parent = LoadingUnit::Handle();
  for (intptr_t id = 1; id < loading_units.Length(); id++) {
    loading_unit ^= loading_units.At(id);
    parent = loading_unit.parent();
    LoadingUnitSerializationData* parent_data =
        parent.IsNull() ? nullptr : data[parent.id()];
    data[id] = new LoadingUnitSerializationData(id, parent_data);
  }

  for (intptr_t id = 1; id < loading_units.Length(); id++) {
    void* write_callback_data = nullptr;
    void* write_debug_callback_data = nullptr;
    {
      TransitionVMToNative transition(T);
      next_callback(next_callback_data, id, &write_callback_data,
                    &write_debug_callback_data);
    }
    CreateAppAOTUnitSnapshot(write_callback, write_callback_data, strip, format,
                             write_debug_callback_data, &data, data[id],
                             program_hash);
    {
      TransitionVMToNative transition(T);
      close_callback(write_callback_data);
      if (write_debug_callback_data != nullptr) {
        close_callback(write_debug_callback_data);
      }
    }
  }
}
#endif

DART_EXPORT Dart_Handle
Dart_CreateAppAOTSnapshotAsAssembly(Dart_StreamingWriteCallback callback,
                                    void* callback_data,
                                    bool strip,
                                    void* debug_callback_data) {
#if defined(TARGET_ARCH_IA32)
  return Api::NewError("AOT compilation is not supported on IA32.");
#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);

  // Mark as not split.
  T->isolate_group()->object_store()->set_loading_units(Object::null_array());

  CreateAppAOTProgramSnapshot(callback, callback_data, strip,
                              Dart_AotBinaryFormat_Assembly,
                              debug_callback_data);

  return Api::Success();
#endif
}

DART_EXPORT Dart_Handle Dart_CreateAppAOTSnapshotAsAssemblies(
    Dart_CreateLoadingUnitCallback next_callback,
    void* next_callback_data,
    bool strip,
    Dart_StreamingWriteCallback write_callback,
    Dart_StreamingCloseCallback close_callback) {
#if defined(TARGET_ARCH_IA32)
  return Api::NewError("AOT compilation is not supported on IA32.");
#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(next_callback);
  CHECK_NULL(write_callback);
  CHECK_NULL(close_callback);

  Split(next_callback, next_callback_data, strip, Dart_AotBinaryFormat_Assembly,
        write_callback, close_callback);

  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(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);

  TIMELINE_DURATION(T, Isolate, "WriteVMAOTSnapshot");
  StreamingWriteStream assembly_stream(kAssemblyInitialSize, callback,
                                       callback_data);
  AssemblyImageWriter image_writer(T, &assembly_stream);
  ZoneWriteStream vm_snapshot_data(T->zone(), FullSnapshotWriter::kInitialSize);
  FullSnapshotWriter writer(Snapshot::kFullAOT, &vm_snapshot_data, nullptr,
                            &image_writer, nullptr);

  writer.WriteFullSnapshot();

  return Api::Success();
#endif
}

DART_EXPORT Dart_Handle
Dart_CreateAppAOTSnapshotAsElf(Dart_StreamingWriteCallback callback,
                               void* callback_data,
                               bool strip,
                               void* debug_callback_data) {
#if defined(TARGET_ARCH_IA32)
  return Api::NewError("AOT compilation is not supported on IA32.");
#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);

  // Mark as not split.
  T->isolate_group()->object_store()->set_loading_units(Object::null_array());

  CreateAppAOTProgramSnapshot(callback, callback_data, strip,
                              Dart_AotBinaryFormat_Elf, debug_callback_data);

  return Api::Success();
#endif
}

DART_EXPORT Dart_Handle
Dart_CreateAppAOTSnapshotAsElfs(Dart_CreateLoadingUnitCallback next_callback,
                                void* next_callback_data,
                                bool strip,
                                Dart_StreamingWriteCallback write_callback,
                                Dart_StreamingCloseCallback close_callback) {
#if defined(TARGET_ARCH_IA32)
  return Api::NewError("AOT compilation is not supported on IA32.");
#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(next_callback);
  CHECK_NULL(write_callback);
  CHECK_NULL(close_callback);

  Split(next_callback, next_callback_data, strip, Dart_AotBinaryFormat_Elf,
        write_callback, close_callback);

  return Api::Success();
#endif
}

DART_EXPORT Dart_Handle
Dart_CreateAppAOTSnapshotAsBinary(Dart_AotBinaryFormat format,
                                  Dart_StreamingWriteCallback callback,
                                  void* callback_data,
                                  bool strip,
                                  void* debug_callback_data,
                                  const char* identifier,
                                  const char* path) {
#if defined(TARGET_ARCH_IA32)
  return Api::NewError("AOT compilation is not supported on IA32.");
#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);

  // Mark as not split.
  T->isolate_group()->object_store()->set_loading_units(Object::null_array());

  CreateAppAOTProgramSnapshot(callback, callback_data, strip, format,
                              debug_callback_data, identifier, path);

  return Api::Success();
#endif
}

DART_EXPORT Dart_Handle Dart_CreateAppAOTSnapshotAndRelocatableObject(
    Dart_AotBinaryFormat format,
    Dart_StreamingWriteCallback callback,
    void* snapshot_callback_data,
    void* object_callback_data,
    bool strip,
    void* debug_callback_data,
    const char* identifier,
    const char* path) {
#if defined(TARGET_ARCH_IA32)
  return Api::NewError("AOT compilation is not supported on IA32.");
#elif !defined(DART_PRECOMPILER)
  return Api::NewError(
      "This VM was built without support for AOT compilation.");
#else
  if (format != Dart_AotBinaryFormat_MachO_Dylib) {
    return Api::NewError(
        "Relocatable objects are currently only supported for Mach-O output.");
  }
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  CHECK_NULL(callback);

  // Mark as not split.
  T->isolate_group()->object_store()->set_loading_units(Object::null_array());

  CreateAppAOTProgramSnapshot(callback, snapshot_callback_data, strip, format,
                              debug_callback_data, identifier, path,
                              object_callback_data);

  return Api::Success();
#endif
}

DART_EXPORT Dart_Handle Dart_LoadingUnitLibraryUris(intptr_t loading_unit_id) {
#if defined(TARGET_ARCH_IA32)
  return Api::NewError("AOT compilation is not supported on IA32.");
#elif !defined(DART_PRECOMPILER)
  return Api::NewError(
      "This VM was built without support for AOT compilation.");
#else
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);

  const Array& loading_units =
      Array::Handle(Z, T->isolate_group()->object_store()->loading_unit_uris());
  if (loading_unit_id >= 0 && loading_unit_id < loading_units.Length()) {
    return Api::NewHandle(T, loading_units.At(loading_unit_id));
  }
  return Api::NewError("Invalid loading_unit_id");
#endif
}

#if (!defined(TARGET_ARCH_IA32) && !defined(DART_PRECOMPILED_RUNTIME))

// Any flag that affects how we compile code might cause a problem when the
// snapshot writer generates code with one value of the flag and the snapshot
// reader expects code to behave according to another value of the flag.
// Normally, we add these flags to Dart::FeaturesString and refuse to run the
// snapshot it they don't match, but since --interpret-irregexp affects only
// 2 functions we choose to remove the code instead. See issue #34422.
static void DropRegExpMatchCode(Zone* zone) {
  const String& execute_match_name =
      String::Handle(zone, String::New("_ExecuteMatch"));
  const String& execute_match_sticky_name =
      String::Handle(zone, String::New("_ExecuteMatchSticky"));

  const Library& core_lib = Library::Handle(zone, Library::CoreLibrary());
  const Class& reg_exp_class =
      Class::Handle(zone, core_lib.LookupClassAllowPrivate(Symbols::_RegExp()));
  ASSERT(!reg_exp_class.IsNull());

  auto thread = Thread::Current();
  Function& func = Function::Handle(
      zone, reg_exp_class.LookupFunctionAllowPrivate(execute_match_name));
  ASSERT(!func.IsNull());
  Code& code = Code::Handle(zone);
  SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
  if (func.HasCode()) {
    code = func.CurrentCode();
    ASSERT(!code.IsNull());
    code.DisableDartCode();
  }
  func.ClearCode();
  func.ClearICDataArray();
  ASSERT(!func.HasCode());

  func = reg_exp_class.LookupFunctionAllowPrivate(execute_match_sticky_name);
  ASSERT(!func.IsNull());
  if (func.HasCode()) {
    code = func.CurrentCode();
    ASSERT(!code.IsNull());
    code.DisableDartCode();
  }
  func.ClearCode();
  func.ClearICDataArray();
  ASSERT(!func.HasCode());
}

#endif  // (!defined(TARGET_ARCH_IA32) && !defined(DART_PRECOMPILED_RUNTIME))

#if !defined(TARGET_ARCH_IA32) && !defined(DART_PRECOMPILED_RUNTIME)
static void KillNonMainIsolatesSlow(Thread* thread, Isolate* main_isolate) {
  auto group = main_isolate->group();
  while (true) {
    bool non_main_isolates_alive = false;
    {
      DeoptSafepointOperationScope safepoint(thread);
      group->ForEachIsolate(
          [&](Isolate* isolate) {
            if (isolate != main_isolate) {
              Isolate::KillIfExists(isolate, Isolate::kKillMsg);
              non_main_isolates_alive = true;
            }
          },
          /*at_safepoint=*/true);
      if (!non_main_isolates_alive) {
        break;
      }
    }
    OS::SleepMicros(10 * 1000);
  }
}
#endif  // !defined(TARGET_ARCH_IA32) && !defined(DART_PRECOMPILED_RUNTIME)

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);
  auto I = T->isolate();
  auto IG = T->isolate_group();
  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 (Api::IsError(state)) {
    return state;
  }

  // Kill off any auxiliary isolates before starting with deduping.
  KillNonMainIsolatesSlow(T, I);

  NoBackgroundCompilerScope no_bg_compiler(T);
  DropRegExpMatchCode(Z);

  ProgramVisitor::Dedup(T);

  if (FLAG_dump_tables) {
    Symbols::DumpTable(IG);
    DumpTypeTable(I);
    DumpTypeParameterTable(I);
    DumpTypeArgumentsTable(I);
  }

  TIMELINE_DURATION(T, Isolate, "WriteAppJITSnapshot");
  ZoneWriteStream isolate_snapshot_data(Api::TopScope(T)->zone(),
                                        FullSnapshotWriter::kInitialSize);
  ZoneWriteStream isolate_snapshot_instructions(
      Api::TopScope(T)->zone(), FullSnapshotWriter::kInitialSize);
  BlobImageWriter image_writer(T, /*vm_instructions=*/nullptr,
                               &isolate_snapshot_instructions);
  FullSnapshotWriter writer(Snapshot::kFullJIT, nullptr, &isolate_snapshot_data,
                            nullptr, &image_writer);
  writer.WriteFullSnapshot();

  *isolate_snapshot_data_buffer = isolate_snapshot_data.buffer();
  *isolate_snapshot_data_size = isolate_snapshot_data.bytes_written();
  *isolate_snapshot_instructions_buffer =
      isolate_snapshot_instructions.buffer();
  *isolate_snapshot_instructions_size =
      isolate_snapshot_instructions.bytes_written();

  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);
  auto isolate_group = thread->isolate_group();

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

  // Note: can't use JSONStream in PRODUCT builds.
  const intptr_t kInitialBufferSize = 1 * MB;
  ZoneTextBuffer text_buffer(Api::TopScope(T)->zone(), kInitialBufferSize);

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

  *buffer_length = text_buffer.length();
  *reinterpret_cast<char**>(buffer) = text_buffer.buffer();
  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) {
#if defined(DART_INCLUDE_PROFILER)
  Profiler::DumpStackTrace(context);
#endif
}

DART_EXPORT void Dart_PrepareToAbort() {
  OS::PrepareToAbort();
}

DART_EXPORT Dart_Handle Dart_GetCurrentUserTag() {
  Thread* thread = Thread::Current();
  CHECK_ISOLATE_GROUP(thread->isolate_group());
  DARTSCOPE(thread);
  return Api::NewHandle(thread, thread->current_tag());
}

DART_EXPORT Dart_Handle Dart_GetDefaultUserTag() {
  Thread* thread = Thread::Current();
  CHECK_ISOLATE_GROUP(thread->isolate_group());
  DARTSCOPE(thread);
  return Api::NewHandle(thread, thread->default_tag());
}

DART_EXPORT Dart_Handle Dart_NewUserTag(const char* label) {
  Thread* thread = Thread::Current();
  CHECK_ISOLATE_GROUP(thread->isolate_group());
  DARTSCOPE(thread);
  if (label == nullptr) {
    return Api::NewError(
        "Dart_NewUserTag expects argument 'label' to be non-null");
  }
  const String& value = String::Handle(String::New(label));
  return Api::NewHandle(thread, UserTag::New(thread, value));
}

DART_EXPORT Dart_Handle Dart_SetCurrentUserTag(Dart_Handle user_tag) {
  Thread* thread = Thread::Current();
  CHECK_ISOLATE_GROUP(thread->isolate_group());
  DARTSCOPE(thread);
  const UserTag& tag = Api::UnwrapUserTagHandle(Z, user_tag);
  if (tag.IsNull()) {
    RETURN_TYPE_ERROR(Z, user_tag, UserTag);
  }
  return Api::NewHandle(thread, tag.MakeActive());
}

DART_EXPORT char* Dart_GetUserTagLabel(Dart_Handle user_tag) {
  DARTSCOPE(Thread::Current());
  const UserTag& tag = Api::UnwrapUserTagHandle(Z, user_tag);
  if (tag.IsNull()) {
    return nullptr;
  }
  const String& label = String::Handle(Z, tag.label());
  return Utils::StrDup(label.ToCString());
}

DART_EXPORT char* Dart_WriteHeapSnapshot(
    Dart_HeapSnapshotWriteChunkCallback write,
    void* context) {
#if defined(DART_ENABLE_HEAP_SNAPSHOT_WRITER)
  DARTSCOPE(Thread::Current());
  CallbackHeapSnapshotWriter callback_writer(T, write, context);
  HeapSnapshotWriter writer(T, &callback_writer);
  writer.Write();
  return nullptr;
#else
  return Utils::StrDup("VM is built without the heap snapshot writer.");
#endif
}

void ThrowCantRunWithoutIsolateError() {
  const auto& error =
      String::Handle(String::New("Only available when running in context of "
                                 "an isolate, rather than isolate group."));
  Exceptions::ThrowArgumentError(error);
}

}  // namespace dart
