// Copyright 2017 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "flutter/runtime/dart_isolate.h"

#include <cstdlib>
#include <tuple>

#include "flutter/fml/trace_event.h"
#include "flutter/lib/io/dart_io.h"
#include "flutter/lib/ui/dart_runtime_hooks.h"
#include "flutter/lib/ui/dart_ui.h"
#include "flutter/runtime/dart_service_isolate.h"
#include "flutter/runtime/dart_vm.h"
#include "lib/fxl/files/path.h"
#include "lib/tonic/converter/dart_converter.h"
#include "lib/tonic/dart_class_library.h"
#include "lib/tonic/dart_class_provider.h"
#include "lib/tonic/dart_message_handler.h"
#include "lib/tonic/dart_state.h"
#include "lib/tonic/dart_sticky_error.h"
#include "lib/tonic/file_loader/file_loader.h"
#include "lib/tonic/scopes/dart_api_scope.h"
#include "lib/tonic/scopes/dart_isolate_scope.h"
#include "third_party/dart/runtime/include/dart_api.h"
#include "third_party/dart/runtime/include/dart_tools_api.h"

#ifdef ERROR
#undef ERROR
#endif

namespace blink {

fml::WeakPtr<DartIsolate> DartIsolate::CreateRootIsolate(
    const DartVM* vm,
    fxl::RefPtr<DartSnapshot> isolate_snapshot,
    fxl::RefPtr<DartSnapshot> shared_snapshot,
    TaskRunners task_runners,
    std::unique_ptr<Window> window,
    fml::WeakPtr<GrContext> resource_context,
    fxl::RefPtr<flow::SkiaUnrefQueue> unref_queue,
    std::string advisory_script_uri,
    std::string advisory_script_entrypoint,
    Dart_IsolateFlags* flags) {
  TRACE_EVENT0("flutter", "DartIsolate::CreateRootIsolate");
  Dart_Isolate vm_isolate = nullptr;
  fml::WeakPtr<DartIsolate> embedder_isolate;

  char* error = nullptr;

  // Since this is the root isolate, we fake a parent embedder data object. We
  // cannot use unique_ptr here because the destructor is private (since the
  // isolate lifecycle is entirely managed by the VM).
  auto root_embedder_data = std::make_unique<DartIsolate>(
      vm,                           // VM
      std::move(isolate_snapshot),  // isolate snapshot
      std::move(shared_snapshot),   // shared snapshot
      task_runners,                 // task runners
      std::move(resource_context),  // resource context
      std::move(unref_queue),       // skia unref queue
      advisory_script_uri,          // advisory URI
      advisory_script_entrypoint,   // advisory entrypoint
      nullptr  // child isolate preparer will be set when this isolate is
               // prepared to run
  );

  std::tie(vm_isolate, embedder_isolate) = CreateDartVMAndEmbedderObjectPair(
      advisory_script_uri.c_str(),         // advisory script URI
      advisory_script_entrypoint.c_str(),  // advisory script entrypoint
      nullptr,                             // package root
      nullptr,                             // package config
      flags,                               // flags
      root_embedder_data.get(),            // parent embedder data
      true,                                // is root isolate
      &error                               // error (out)
  );

  if (error != nullptr) {
    free(error);
  }

  if (vm_isolate == nullptr) {
    return {};
  }

  if (embedder_isolate) {
    // Only root isolates can interact with windows.
    embedder_isolate->SetWindow(std::move(window));
  }

  root_embedder_data.release();

  return embedder_isolate;
}

DartIsolate::DartIsolate(const DartVM* vm,
                         fxl::RefPtr<DartSnapshot> isolate_snapshot,
                         fxl::RefPtr<DartSnapshot> shared_snapshot,
                         TaskRunners task_runners,
                         fml::WeakPtr<GrContext> resource_context,
                         fxl::RefPtr<flow::SkiaUnrefQueue> unref_queue,
                         std::string advisory_script_uri,
                         std::string advisory_script_entrypoint,
                         ChildIsolatePreparer child_isolate_preparer)
    : UIDartState(std::move(task_runners),
                  vm->GetSettings().task_observer_add,
                  vm->GetSettings().task_observer_remove,
                  std::move(resource_context),
                  std::move(unref_queue),
                  advisory_script_uri,
                  advisory_script_entrypoint,
                  vm->GetSettings().log_tag),
      vm_(vm),
      isolate_snapshot_(std::move(isolate_snapshot)),
      shared_snapshot_(std::move(shared_snapshot)),
      child_isolate_preparer_(std::move(child_isolate_preparer)),
      weak_factory_(std::make_unique<fml::WeakPtrFactory<DartIsolate>>(this)) {
  FXL_DCHECK(isolate_snapshot_) << "Must contain a valid isolate snapshot.";

  if (vm_ == nullptr) {
    return;
  }

  phase_ = Phase::Uninitialized;
}

DartIsolate::~DartIsolate() = default;

DartIsolate::Phase DartIsolate::GetPhase() const {
  return phase_;
}

const DartVM* DartIsolate::GetDartVM() const {
  return vm_;
}

bool DartIsolate::Initialize(Dart_Isolate dart_isolate, bool is_root_isolate) {
  TRACE_EVENT0("flutter", "DartIsolate::Initialize");
  if (phase_ != Phase::Uninitialized) {
    return false;
  }

  if (dart_isolate == nullptr) {
    return false;
  }

  if (Dart_CurrentIsolate() != dart_isolate) {
    return false;
  }

  if (Dart_IsolateData(dart_isolate) != this) {
    return false;
  }

  // After this point, isolate scopes can be safely used.
  SetIsolate(dart_isolate);

  // We are entering a new scope (for the first time since initialization) and
  // we want to restore the current scope to null when we exit out of this
  // method. This balances the implicit Dart_EnterIsolate call made by
  // Dart_CreateIsolate (which calls the Initialize).
  Dart_ExitIsolate();

  tonic::DartIsolateScope scope(isolate());

  if (is_root_isolate) {
    if (auto task_runner = GetTaskRunners().GetUITaskRunner()) {
      // Isolates may not have any particular thread affinity. Only initialize
      // the message handler if a task runner is explicitly specified.
      message_handler().Initialize(task_runner);
    }
  }

  if (tonic::LogIfError(
          Dart_SetLibraryTagHandler(tonic::DartState::HandleLibraryTag))) {
    return false;
  }

  if (!UpdateThreadPoolNames()) {
    return false;
  }

  phase_ = Phase::Initialized;
  return true;
}

// Updating thread names here does not change the underlying OS thread names.
// Instead, this is just additional metadata for the Observatory to show the
// thread name of the isolate.
bool DartIsolate::UpdateThreadPoolNames() const {
  // TODO(chinmaygarde): This implementation does not account for multiple
  // shells sharing the same (or subset of) threads.
  const auto& task_runners = GetTaskRunners();

  if (auto task_runner = task_runners.GetGPUTaskRunner()) {
    task_runner->PostTask(
        [label = task_runners.GetLabel() + std::string{".gpu"}]() {
          Dart_SetThreadName(label.c_str());
        });
  }

  if (auto task_runner = task_runners.GetUITaskRunner()) {
    task_runner->PostTask(
        [label = task_runners.GetLabel() + std::string{".ui"}]() {
          Dart_SetThreadName(label.c_str());
        });
  }

  if (auto task_runner = task_runners.GetIOTaskRunner()) {
    task_runner->PostTask(
        [label = task_runners.GetLabel() + std::string{".io"}]() {
          Dart_SetThreadName(label.c_str());
        });
  }

  if (auto task_runner = task_runners.GetPlatformTaskRunner()) {
    task_runner->PostTask(
        [label = task_runners.GetLabel() + std::string{".platform"}]() {
          Dart_SetThreadName(label.c_str());
        });
  }

  return true;
}

bool DartIsolate::LoadLibraries(bool is_root_isolate) {
  TRACE_EVENT0("flutter", "DartIsolate::LoadLibraries");
  if (phase_ != Phase::Initialized) {
    return false;
  }

  tonic::DartState::Scope scope(this);

  DartIO::InitForIsolate();

  DartUI::InitForIsolate();

  const bool is_service_isolate = Dart_IsServiceIsolate(isolate());

  DartRuntimeHooks::Install(is_root_isolate && !is_service_isolate,
                            GetAdvisoryScriptURI());

  if (!is_service_isolate) {
    class_library().add_provider(
        "ui", std::make_unique<tonic::DartClassProvider>(this, "dart:ui"));
  }

  phase_ = Phase::LibrariesSetup;
  return true;
}

bool DartIsolate::PrepareForRunningFromPrecompiledCode() {
  TRACE_EVENT0("flutter", "DartIsolate::PrepareForRunningFromPrecompiledCode");
  if (phase_ != Phase::LibrariesSetup) {
    return false;
  }

  if (!DartVM::IsRunningPrecompiledCode()) {
    return false;
  }

  tonic::DartState::Scope scope(this);

  if (Dart_IsNull(Dart_RootLibrary())) {
    return false;
  }

  if (!MarkIsolateRunnable()) {
    return false;
  }

  child_isolate_preparer_ = [](DartIsolate* isolate) {
    return isolate->PrepareForRunningFromPrecompiledCode();
  };
  phase_ = Phase::Ready;
  return true;
}

static bool LoadScriptSnapshot(std::shared_ptr<const fml::Mapping> mapping,
                               bool last_piece) {
  FXL_CHECK(last_piece) << "Script snapshots cannot be divided";
  if (tonic::LogIfError(Dart_LoadScriptFromSnapshot(mapping->GetMapping(),
                                                    mapping->GetSize()))) {
    return false;
  }
  return true;
}

static bool LoadKernelSnapshot(std::shared_ptr<const fml::Mapping> mapping,
                               bool last_piece) {
  Dart_Handle library =
      Dart_LoadLibraryFromKernel(mapping->GetMapping(), mapping->GetSize());
  if (tonic::LogIfError(library)) {
    return false;
  }

  if (!last_piece) {
    // More to come.
    return true;
  }

  Dart_SetRootLibrary(library);
  if (tonic::LogIfError(Dart_FinalizeLoading(false))) {
    return false;
  }
  return true;
}

static bool LoadSnapshot(std::shared_ptr<const fml::Mapping> mapping,
                         bool last_piece) {
  if (Dart_IsKernel(mapping->GetMapping(), mapping->GetSize())) {
    return LoadKernelSnapshot(std::move(mapping), last_piece);
  } else {
    return LoadScriptSnapshot(std::move(mapping), last_piece);
  }
  return false;
}

FXL_WARN_UNUSED_RESULT
bool DartIsolate::PrepareForRunningFromSnapshot(
    std::shared_ptr<const fml::Mapping> mapping,
    bool last_piece) {
  TRACE_EVENT0("flutter", "DartIsolate::PrepareForRunningFromSnapshot");
  if (phase_ != Phase::LibrariesSetup) {
    return false;
  }

  if (DartVM::IsRunningPrecompiledCode()) {
    return false;
  }

  if (!mapping || mapping->GetSize() == 0) {
    return false;
  }

  tonic::DartState::Scope scope(this);

  if (!Dart_IsNull(Dart_RootLibrary())) {
    return false;
  }

  if (!LoadSnapshot(mapping, last_piece)) {
    return false;
  }

  if (!last_piece) {
    // More to come.
    return true;
  }

  if (Dart_IsNull(Dart_RootLibrary())) {
    return false;
  }

  if (!MarkIsolateRunnable()) {
    return false;
  }

  child_isolate_preparer_ = [mapping](DartIsolate* isolate) {
    return isolate->PrepareForRunningFromSnapshot(mapping);
  };
  phase_ = Phase::Ready;
  return true;
}

bool DartIsolate::PrepareForRunningFromSource(
    const std::string& main_source_file,
    const std::string& packages) {
  TRACE_EVENT0("flutter", "DartIsolate::PrepareForRunningFromSource");
  if (phase_ != Phase::LibrariesSetup) {
    return false;
  }

  if (DartVM::IsRunningPrecompiledCode()) {
    return false;
  }

  if (main_source_file.empty()) {
    return false;
  }

  tonic::DartState::Scope scope(this);

  if (!Dart_IsNull(Dart_RootLibrary())) {
    return false;
  }

  auto& loader = file_loader();

  if (!packages.empty()) {
    auto packages_absolute_path = files::AbsolutePath(packages);
    FXL_DLOG(INFO) << "Loading from packages: " << packages_absolute_path;
    if (!loader.LoadPackagesMap(packages_absolute_path)) {
      return false;
    }
  }

  auto main_source_absolute_path = files::AbsolutePath(main_source_file);
  FXL_DLOG(INFO) << "Loading from source: " << main_source_absolute_path;

  if (tonic::LogIfError(loader.LoadScript(main_source_absolute_path))) {
    return false;
  }

  if (Dart_IsNull(Dart_RootLibrary())) {
    return false;
  }

  if (!MarkIsolateRunnable()) {
    return false;
  }

  child_isolate_preparer_ = [main_source_file, packages](DartIsolate* isolate) {
    return isolate->PrepareForRunningFromSource(main_source_file, packages);
  };
  phase_ = Phase::Ready;
  return true;
}

bool DartIsolate::MarkIsolateRunnable() {
  TRACE_EVENT0("flutter", "DartIsolate::MarkIsolateRunnable");
  if (phase_ != Phase::LibrariesSetup) {
    return false;
  }

  // This function may only be called from an active isolate scope.
  if (Dart_CurrentIsolate() != isolate()) {
    return false;
  }

  // There must be no current isolate to mark an isolate as being runnable.
  Dart_ExitIsolate();

  char* error = Dart_IsolateMakeRunnable(isolate());
  if (error) {
    FXL_DLOG(ERROR) << error;
    ::free(error);
    // Failed. Restore the isolate.
    Dart_EnterIsolate(isolate());
    return false;
  }
  // Success. Restore the isolate.
  Dart_EnterIsolate(isolate());
  return true;
}

FXL_WARN_UNUSED_RESULT
bool DartIsolate::Run(const std::string& entrypoint_name) {
  TRACE_EVENT0("flutter", "DartIsolate::Run");
  if (phase_ != Phase::Ready) {
    return false;
  }

  tonic::DartState::Scope scope(this);

  Dart_Handle entrypoint = Dart_GetClosure(
      Dart_RootLibrary(), tonic::ToDart(entrypoint_name.c_str()));
  if (tonic::LogIfError(entrypoint)) {
    return false;
  }

  Dart_Handle isolate_lib = Dart_LookupLibrary(tonic::ToDart("dart:isolate"));
  if (tonic::LogIfError(isolate_lib)) {
    return false;
  }

  Dart_Handle isolate_args[] = {
      entrypoint,
      Dart_Null(),
  };

  if (tonic::LogIfError(Dart_Invoke(
          isolate_lib, tonic::ToDart("_startMainIsolate"),
          sizeof(isolate_args) / sizeof(isolate_args[0]), isolate_args))) {
    return false;
  }

  phase_ = Phase::Running;
  FXL_DLOG(INFO) << "New isolate is in the running state.";
  return true;
}

bool DartIsolate::Shutdown() {
  TRACE_EVENT0("flutter", "DartIsolate::Shutdown");
  // This call may be re-entrant since Dart_ShutdownIsolate can invoke the
  // cleanup callback which deletes the embedder side object of the dart isolate
  // (a.k.a. this).
  if (phase_ == Phase::Shutdown) {
    return false;
  }
  phase_ = Phase::Shutdown;
  Dart_Isolate vm_isolate = isolate();
  // The isolate can be nullptr if this instance is the stub isolate data used
  // during root isolate creation.
  if (vm_isolate != nullptr) {
    // We need to enter the isolate because Dart_ShutdownIsolate does not take
    // the isolate to shutdown as a parameter.
    FXL_DCHECK(Dart_CurrentIsolate() == nullptr);
    Dart_EnterIsolate(vm_isolate);
    Dart_ShutdownIsolate();
    FXL_DCHECK(Dart_CurrentIsolate() == nullptr);
  }
  return true;
}

Dart_Isolate DartIsolate::DartCreateAndStartServiceIsolate(
    const char* advisory_script_uri,
    const char* advisory_script_entrypoint,
    const char* package_root,
    const char* package_config,
    Dart_IsolateFlags* flags,
    char** error) {
  auto vm = DartVM::ForProcessIfInitialized();

  if (!vm) {
    *error = strdup(
        "Could not resolve the VM when attempting to create the service "
        "isolate.");
    return nullptr;
  }

  const auto& settings = vm->GetSettings();

  if (!settings.enable_observatory) {
    FXL_DLOG(INFO) << "Observatory is disabled.";
    return nullptr;
  }

  blink::TaskRunners null_task_runners(
      "io.flutter." DART_VM_SERVICE_ISOLATE_NAME, nullptr, nullptr, nullptr,
      nullptr);

  flags->load_vmservice_library = true;

  fml::WeakPtr<DartIsolate> weak_service_isolate =
      DartIsolate::CreateRootIsolate(
          vm.get(),                  // vm
          vm->GetIsolateSnapshot(),  // isolate snapshot
          vm->GetSharedSnapshot(),   // shared snapshot
          null_task_runners,         // task runners
          nullptr,                   // window
          {},                        // resource context
          {},                        // unref queue
          advisory_script_uri == nullptr ? ""
                                         : advisory_script_uri,  // script uri
          advisory_script_entrypoint == nullptr
              ? ""
              : advisory_script_entrypoint,  // script entrypoint
          flags                              // flags
      );

  if (!weak_service_isolate) {
    *error = strdup("Could not create the service isolate.");
    FXL_DLOG(ERROR) << *error;
    return nullptr;
  }

  // The engine never holds a strong reference to the VM service isolate. Since
  // we are about to lose our last weak reference to it, start the VM service
  // while we have this reference.
  DartIsolate* service_isolate = weak_service_isolate.get();

  // The service isolate is created and destroyed on arbitrary Dart pool threads
  // and can not support a weak pointer factory that must be bound to a specific
  // thread.
  service_isolate->ResetWeakPtrFactory();

  const bool isolate_snapshot_is_dart_2 = Dart_IsDart2Snapshot(
      vm->GetIsolateSnapshot()->GetData()->GetSnapshotPointer());
  const bool is_preview_dart2 =
      (vm->GetPlatformKernel().GetSize() > 0) || isolate_snapshot_is_dart_2;
  const bool running_from_sources =
      !DartVM::IsRunningPrecompiledCode() && !is_preview_dart2;

  tonic::DartState::Scope scope(service_isolate);
  if (!DartServiceIsolate::Startup(
          settings.ipv6 ? "::1" : "127.0.0.1",  // server IP address
          settings.observatory_port,            // server observatory port
          tonic::DartState::HandleLibraryTag,   // embedder library tag handler
          running_from_sources,                 // running from source code
          false,  //  disable websocket origin check
          error   // error (out)
          )) {
    // Error is populated by call to startup.
    FXL_DLOG(ERROR) << *error;
    return nullptr;
  }

  vm->GetServiceProtocol().ToggleHooks(true);

  return service_isolate->isolate();
}

// |Dart_IsolateCreateCallback|
Dart_Isolate DartIsolate::DartIsolateCreateCallback(
    const char* advisory_script_uri,
    const char* advisory_script_entrypoint,
    const char* package_root,
    const char* package_config,
    Dart_IsolateFlags* flags,
    DartIsolate* parent_embedder_isolate,
    char** error) {
  if (parent_embedder_isolate == nullptr &&
      strcmp(advisory_script_uri, DART_VM_SERVICE_ISOLATE_NAME) == 0) {
    // The VM attempts to start the VM service for us on |Dart_Initialize|. In
    // such a case, the callback data will be null and the script URI will be
    // DART_VM_SERVICE_ISOLATE_NAME. In such cases, we just create the service
    // isolate like normal but dont hold a reference to it at all. We also start
    // this isolate since we will never again reference it from the engine.
    return DartCreateAndStartServiceIsolate(advisory_script_uri,         //
                                            advisory_script_entrypoint,  //
                                            package_root,                //
                                            package_config,              //
                                            flags,                       //
                                            error                        //
    );
  }

  return CreateDartVMAndEmbedderObjectPair(
             advisory_script_uri,         // URI
             advisory_script_entrypoint,  // entrypoint
             package_root,                // package root
             package_config,              // package config
             flags,                       // isolate flags
             parent_embedder_isolate,     // embedder data
             false,                       // is root isolate
             error                        // error
             )
      .first;
}

std::pair<Dart_Isolate, fml::WeakPtr<DartIsolate>>
DartIsolate::CreateDartVMAndEmbedderObjectPair(
    const char* advisory_script_uri,
    const char* advisory_script_entrypoint,
    const char* package_root,
    const char* package_config,
    Dart_IsolateFlags* flags,
    DartIsolate* p_parent_embedder_isolate,
    bool is_root_isolate,
    char** error) {
  TRACE_EVENT0("flutter", "DartIsolate::CreateDartVMAndEmbedderObjectPair");

  std::unique_ptr<DartIsolate> embedder_isolate{p_parent_embedder_isolate};

  if (embedder_isolate == nullptr || embedder_isolate->GetDartVM() == nullptr) {
    *error =
        strdup("Parent isolate did not have embedder specific callback data.");
    FXL_DLOG(ERROR) << *error;
    return {nullptr, {}};
  }

  const DartVM* vm = embedder_isolate->GetDartVM();

  if (!is_root_isolate) {
    auto raw_embedder_isolate = embedder_isolate.release();

    blink::TaskRunners null_task_runners(advisory_script_uri, nullptr, nullptr,
                                         nullptr, nullptr);

    embedder_isolate = std::make_unique<DartIsolate>(
        vm,                                          // vm
        raw_embedder_isolate->GetIsolateSnapshot(),  // isolate_snapshot
        raw_embedder_isolate->GetSharedSnapshot(),   // shared_snapshot
        null_task_runners,                           // task_runners
        fml::WeakPtr<GrContext>{},                   // resource_context
        nullptr,                                     // unref_queue
        advisory_script_uri,                         // advisory_script_uri
        advisory_script_entrypoint,  // advisory_script_entrypoint
        raw_embedder_isolate->child_isolate_preparer_  // child isolate preparer
    );
  }

  // Create the Dart VM isolate and give it the embedder object as the baton.
  Dart_Isolate isolate =
      (vm->GetPlatformKernel().GetSize() > 0)
          ? Dart_CreateIsolateFromKernel(
                advisory_script_uri,                   //
                advisory_script_entrypoint,            //
                vm->GetPlatformKernel().GetMapping(),  //
                vm->GetPlatformKernel().GetSize(),     //
                flags,                                 //
                embedder_isolate.get(),                //
                error                                  //
                )
          : Dart_CreateIsolate(
                advisory_script_uri,         //
                advisory_script_entrypoint,  //
                embedder_isolate->GetIsolateSnapshot()
                    ->GetData()
                    ->GetSnapshotPointer(),  //
                embedder_isolate->GetIsolateSnapshot()
                    ->GetInstructionsIfPresent(),                           //
                embedder_isolate->GetSharedSnapshot()->GetDataIfPresent(),  //
                embedder_isolate->GetSharedSnapshot()
                    ->GetInstructionsIfPresent(),  //
                flags,                             //
                embedder_isolate.get(),            //
                error                              //
            );

  if (isolate == nullptr) {
    FXL_DLOG(ERROR) << *error;
    return {nullptr, {}};
  }

  if (!embedder_isolate->Initialize(isolate, is_root_isolate)) {
    *error = strdup("Embedder could not initialize the Dart isolate.");
    FXL_DLOG(ERROR) << *error;
    return {nullptr, {}};
  }

  if (!embedder_isolate->LoadLibraries(is_root_isolate)) {
    *error =
        strdup("Embedder could not load libraries in the new Dart isolate.");
    FXL_DLOG(ERROR) << *error;
    return {nullptr, {}};
  }

  auto weak_embedder_isolate = embedder_isolate->GetWeakIsolatePtr();

  // Root isolates will be setup by the engine and the service isolate (which is
  // also a root isolate) by the utility routines in the VM. However, secondary
  // isolates will be run by the VM if they are marked as runnable.
  if (!is_root_isolate) {
    FXL_DCHECK(embedder_isolate->child_isolate_preparer_);
    if (!embedder_isolate->child_isolate_preparer_(embedder_isolate.get())) {
      *error = strdup("Could not prepare the child isolate to run.");
      FXL_DLOG(ERROR) << *error;
      return {nullptr, {}};
    }
    embedder_isolate->ResetWeakPtrFactory();
  }

  // The ownership of the embedder object is controlled by the Dart VM. So the
  // only reference returned to the caller is weak.
  embedder_isolate.release();
  return {isolate, weak_embedder_isolate};
}

// |Dart_IsolateShutdownCallback|
void DartIsolate::DartIsolateShutdownCallback(DartIsolate* embedder_isolate) {
  if (!tonic::DartStickyError::IsSet()) {
    return;
  }

  tonic::DartApiScope api_scope;
  FXL_LOG(ERROR) << "Isolate " << tonic::StdStringFromDart(Dart_DebugName())
                 << " exited with an error";
  Dart_Handle sticky_error = Dart_GetStickyError();
  FXL_CHECK(tonic::LogIfError(sticky_error));
}

// |Dart_IsolateCleanupCallback|
void DartIsolate::DartIsolateCleanupCallback(DartIsolate* embedder_isolate) {
  delete embedder_isolate;
}

fxl::RefPtr<DartSnapshot> DartIsolate::GetIsolateSnapshot() const {
  return isolate_snapshot_;
}

fxl::RefPtr<DartSnapshot> DartIsolate::GetSharedSnapshot() const {
  return shared_snapshot_;
}

fml::WeakPtr<DartIsolate> DartIsolate::GetWeakIsolatePtr() const {
  return weak_factory_ ? weak_factory_->GetWeakPtr()
                       : fml::WeakPtr<DartIsolate>();
}

void DartIsolate::ResetWeakPtrFactory() {
  FXL_CHECK(weak_factory_);
  weak_factory_.reset();
}

void DartIsolate::AddIsolateShutdownCallback(fxl::Closure closure) {
  shutdown_callbacks_.emplace_back(
      std::make_unique<AutoFireClosure>(std::move(closure)));
}

}  // namespace blink
