// Copyright (c) 2025, 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 <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <memory>
#include <utility>

#include "bin/builtin.h"
#include "bin/console.h"
#include "bin/crashpad.h"
#include "bin/dartdev_options.h"
#include "bin/dartutils.h"
#include "bin/error_exit.h"
#include "bin/eventhandler.h"
#include "bin/exe_utils.h"
#include "bin/file.h"
#include "bin/gzip.h"
#include "bin/isolate_data.h"
#include "bin/loader.h"
#include "bin/lockers.h"
#include "bin/platform.h"
#include "bin/process.h"
#include "bin/snapshot_utils.h"
#include "bin/thread.h"
#include "bin/utils.h"
#if defined(DART_HOST_OS_WINDOWS)
#include "bin/utils_win.h"
#endif
#include "bin/vmservice_impl.h"
#include "include/bin/dart_io_api.h"
#include "include/dart_api.h"
#include "include/dart_embedder_api.h"
#include "include/dart_native_api.h"
#include "include/dart_tools_api.h"
#include "platform/assert.h"
#include "platform/globals.h"
#include "platform/growable_array.h"
#include "platform/hashmap.h"
#include "platform/syslog.h"
#include "platform/text_buffer.h"
#include "platform/utils.h"

namespace dart {
namespace bin {

#if defined(DART_PRECOMPILED_RUNTIME)
/**
 * Global state used to control and store generation of application snapshots.
 */
static const uint8_t* ignore_vm_snapshot_data = nullptr;
static const uint8_t* ignore_vm_snapshot_instructions = nullptr;
static const uint8_t* app_isolate_snapshot_data = nullptr;
static const uint8_t* app_isolate_snapshot_instructions = nullptr;

#define SAVE_ERROR_AND_RETURN(result)                                          \
  if (Dart_IsError(result)) {                                                  \
    *error = Utils::StrDup(Dart_GetError(result));                             \
    return false;                                                              \
  }

#define SAVE_ERROR_AND_EXIT(result)                                            \
  *error = Utils::StrDup(Dart_GetError(result));                               \
  if (Dart_IsCompilationError(result)) {                                       \
    *exit_code = kCompilationErrorExitCode;                                    \
  } else if (Dart_IsApiError(result)) {                                        \
    *exit_code = kApiErrorExitCode;                                            \
  } else {                                                                     \
    *exit_code = kErrorExitCode;                                               \
  }                                                                            \
  Dart_ExitScope();                                                            \
  Dart_ShutdownIsolate();                                                      \
  return nullptr;

#define CHECK_RESULT(result)                                                   \
  if (Dart_IsError(result)) {                                                  \
    SAVE_ERROR_AND_EXIT(result);                                               \
  }

#define CHECK_RESULT_CLEANUP(result, cleanup)                                  \
  if (Dart_IsError(result)) {                                                  \
    delete (cleanup);                                                          \
    SAVE_ERROR_AND_EXIT(result);                                               \
  }

#define DART_DEV_ISOLATE_NAME "dartdev"

// Helper class to ensure we enter a new Dart Scope and exit it.
class DartScope {
 public:
  DartScope() { Dart_EnterScope(); }
  ~DartScope() { Dart_ExitScope(); }
};

static Dart_Handle SetupCoreLibraries(Dart_Isolate isolate,
                                      IsolateData* isolate_data,
                                      bool is_isolate_group_start,
                                      const char** resolved_packages_config) {
  auto isolate_group_data = isolate_data->isolate_group_data();
  const auto packages_file = isolate_data->packages_file();
  const auto script_uri = isolate_group_data->script_url;

  Dart_Handle result;

  // Prepare builtin and other core libraries for use to resolve URIs.
  // Set up various closures, e.g: printing, timers etc.
  // Set up package configuration for URI resolution.
  result = DartUtils::PrepareForScriptLoading(false, false, false);
  if (Dart_IsError(result)) return result;

  // Setup packages config if specified.
  result = DartUtils::SetupPackageConfig(packages_file);
  if (Dart_IsError(result)) return result;
  if (!Dart_IsNull(result) && resolved_packages_config != nullptr) {
    result = Dart_StringToCString(result, resolved_packages_config);
    if (Dart_IsError(result)) return result;
    ASSERT(*resolved_packages_config != nullptr);
  }

  result = Dart_SetEnvironmentCallback(DartUtils::EnvironmentCallback);
  if (Dart_IsError(result)) return result;

  // Setup the native resolver as the snapshot does not carry it.
  Builtin::SetNativeResolver(Builtin::kBuiltinLibrary);
  Builtin::SetNativeResolver(Builtin::kIOLibrary);
  Builtin::SetNativeResolver(Builtin::kCLILibrary);
  VmService::SetNativeResolver();

  const char* namespc = Options::namespc();
  result =
      DartUtils::SetupIOLibrary(namespc, script_uri, Options::exit_disabled());
  if (Dart_IsError(result)) return result;

  return Dart_Null();
}

static bool OnIsolateInitialize(void** child_callback_data, char** error) {
  Dart_Isolate isolate = Dart_CurrentIsolate();
  ASSERT(isolate != nullptr);

  auto isolate_group_data =
      reinterpret_cast<IsolateGroupData*>(Dart_CurrentIsolateGroupData());

  auto isolate_data = new IsolateData(isolate_group_data);
  *child_callback_data = isolate_data;

  DartScope scope;  // Enter a new scope.
  const auto script_uri = isolate_group_data->script_url;
  const bool isolate_run_app_snapshot =
      isolate_group_data->RunFromAppSnapshot();
  Dart_Handle result = SetupCoreLibraries(isolate, isolate_data,
                                          /*group_start=*/false,
                                          /*resolved_packages_config=*/nullptr);
  SAVE_ERROR_AND_RETURN(result);
  if (isolate_run_app_snapshot) {
    result = Loader::InitForSnapshot(script_uri, isolate_data);
    SAVE_ERROR_AND_RETURN(result);
  } else {
    result = DartUtils::ResolveScript(Dart_NewStringFromCString(script_uri));
    SAVE_ERROR_AND_RETURN(result);

    if (isolate_group_data->kernel_buffer() != nullptr) {
      // Various core-library parts will send requests to the Loader to resolve
      // relative URIs and perform other related tasks. We need Loader to be
      // initialized for this to work because loading from Kernel binary
      // bypasses normal source code loading paths that initialize it.
      const char* resolved_script_uri = nullptr;
      result = Dart_StringToCString(result, &resolved_script_uri);
      SAVE_ERROR_AND_RETURN(result);
      result = Loader::InitForSnapshot(resolved_script_uri, isolate_data);
      SAVE_ERROR_AND_RETURN(result);
    }
  }

  return true;
}

static Dart_Isolate IsolateSetupHelper(Dart_Isolate isolate,
                                       bool is_dartdev_isolate,
                                       const char* script_uri,
                                       const char* packages_config,
                                       bool isolate_run_app_snapshot,
                                       Dart_IsolateFlags* flags,
                                       char** error,
                                       int* exit_code) {
  Dart_EnterScope();

  // Set up the library tag handler for the isolate group shared by all
  // isolates in the group.
  Dart_Handle result = Dart_SetLibraryTagHandler(Loader::LibraryTagHandler);
  CHECK_RESULT(result);
  result = Dart_SetDeferredLoadHandler(Loader::DeferredLoadHandler);
  CHECK_RESULT(result);

  auto isolate_data = reinterpret_cast<IsolateData*>(Dart_IsolateData(isolate));

  const char* resolved_packages_config = nullptr;
  result = SetupCoreLibraries(isolate, isolate_data,
                              /*is_isolate_group_start=*/true,
                              &resolved_packages_config);
  CHECK_RESULT(result);

  if (isolate_run_app_snapshot) {
    Dart_Handle result = Loader::InitForSnapshot(script_uri, isolate_data);
    CHECK_RESULT(result);
  } else {
    UNREACHABLE();
  }

  // Make the isolate runnable so that it is ready to handle messages.
  Dart_ExitScope();
  Dart_ExitIsolate();
  *error = Dart_IsolateMakeRunnable(isolate);
  if (*error != nullptr) {
    Dart_EnterIsolate(isolate);
    Dart_ShutdownIsolate();
    return nullptr;
  }

  return isolate;
}

// Returns newly created Isolate on success, nullptr on failure.
static Dart_Isolate CreateIsolateGroupAndSetupHelper(
    bool is_dartdev_isolate,
    const char* script_uri,
    const char* name,
    const char* packages_config,
    Dart_IsolateFlags* flags,
    void* callback_data,
    char** error,
    int* exit_code) {
  int64_t start = Dart_TimelineGetMicros();
  ASSERT(script_uri != nullptr);
  uint8_t* kernel_buffer = nullptr;
  intptr_t kernel_buffer_size = 0;
  AppSnapshot* app_snapshot = nullptr;

  const uint8_t* isolate_snapshot_data = nullptr;
  const uint8_t* isolate_snapshot_instructions = nullptr;
  if (is_dartdev_isolate) {
    isolate_snapshot_data = app_isolate_snapshot_data;
    isolate_snapshot_instructions = app_isolate_snapshot_instructions;
  } else {
    // AOT: All isolates need to be run from AOT compiled snapshots.
    app_snapshot = Snapshot::TryReadAppSnapshot(
        script_uri, /*force_load_from_memory*/ false, /*decode_uri*/ true);
    if (app_snapshot == nullptr || !app_snapshot->IsAOT()) {
      *error = Utils::SCreate(
          "The uri(%s) provided to `Isolate.spawnUri()` does not "
          "contain a valid AOT snapshot.",
          script_uri);
      return nullptr;
    }

    app_snapshot->SetBuffers(
        &ignore_vm_snapshot_data, &ignore_vm_snapshot_instructions,
        &isolate_snapshot_data, &isolate_snapshot_instructions);
  }

  bool isolate_run_app_snapshot = true;

  auto isolate_group_data = new IsolateGroupData(
      script_uri, /*asset_resolution_base=*/nullptr, packages_config,
      app_snapshot, isolate_run_app_snapshot);
  if (kernel_buffer != nullptr) {
    isolate_group_data->SetKernelBufferNewlyOwned(kernel_buffer,
                                                  kernel_buffer_size);
  }

  Dart_Isolate isolate = nullptr;

  IsolateData* isolate_data = nullptr;
  isolate_data = new IsolateData(isolate_group_data);
  isolate = Dart_CreateIsolateGroup(script_uri, name, isolate_snapshot_data,
                                    isolate_snapshot_instructions, flags,
                                    isolate_group_data, isolate_data, error);
  Dart_Isolate created_isolate = nullptr;
  if (isolate == nullptr) {
    delete isolate_data;
    delete isolate_group_data;
  } else {
    created_isolate = IsolateSetupHelper(
        isolate, is_dartdev_isolate, script_uri, packages_config,
        isolate_run_app_snapshot, flags, error, exit_code);
  }
  int64_t end = Dart_TimelineGetMicros();
  Dart_RecordTimelineEvent("CreateIsolateGroupAndSetupHelper", start, end,
                           /*flow_id_count=*/0, nullptr,
                           Dart_Timeline_Event_Duration,
                           /*argument_count=*/0, nullptr, nullptr);
  return created_isolate;
}

#undef CHECK_RESULT

static Dart_Isolate CreateIsolateGroupAndSetup(const char* script_uri,
                                               const char* main,
                                               const char* package_root,
                                               const char* package_config,
                                               Dart_IsolateFlags* flags,
                                               void* callback_data,
                                               char** error) {
  // The VM should never call the isolate helper with a nullptr flags.
  ASSERT(flags != nullptr);
  ASSERT(flags->version == DART_FLAGS_CURRENT_VERSION);
  ASSERT(package_root == nullptr);

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

#if defined(DART_HOST_OS_LINUX)
  // This would also be true in Linux, except that Google3 overrides the default
  // ELF interpreter to one that apparently doesn't create proper mappings.
  flags->snapshot_is_dontneed_safe = false;
#else
  flags->snapshot_is_dontneed_safe = true;
#endif

  int exit_code = 0;

  if (strcmp(script_uri, DART_VM_SERVICE_ISOLATE_NAME) == 0) {
    // We do not start the service isolate in the Dart CLI mode of execution.
    // If profiling or debugging of the individual tools is desired it is
    // possible to do that using the 'dartaotruntime' or 'dartvm' executables.
    return nullptr;
  }

  bool is_dartdev_isolate = false;
  return CreateIsolateGroupAndSetupHelper(is_dartdev_isolate, script_uri, main,
                                          package_config, flags, callback_data,
                                          error, &exit_code);
}

static void OnIsolateShutdown(void* isolate_group_data, void* isolate_data) {
  Dart_EnterScope();
  Dart_Handle sticky_error = Dart_GetStickyError();
  if (!Dart_IsNull(sticky_error) && !Dart_IsFatalError(sticky_error)) {
    Syslog::PrintErr("%s\n", Dart_GetError(sticky_error));
  }
  Dart_ExitScope();
}

static void DeleteIsolateData(void* isolate_group_data, void* callback_data) {
  auto isolate_data = reinterpret_cast<IsolateData*>(callback_data);
  delete isolate_data;
}

static void DeleteIsolateGroupData(void* callback_data) {
  auto isolate_group_data = reinterpret_cast<IsolateGroupData*>(callback_data);
  delete isolate_group_data;
}

static constexpr const char* kStdoutStreamId = "Stdout";
static constexpr const char* kStderrStreamId = "Stderr";

static bool ServiceStreamListenCallback(const char* stream_id) {
  if (strcmp(stream_id, kStdoutStreamId) == 0) {
    SetCaptureStdout(true);
    return true;
  } else if (strcmp(stream_id, kStderrStreamId) == 0) {
    SetCaptureStderr(true);
    return true;
  }
  return false;
}

static void ServiceStreamCancelCallback(const char* stream_id) {
  if (strcmp(stream_id, kStdoutStreamId) == 0) {
    SetCaptureStdout(false);
  } else if (strcmp(stream_id, kStderrStreamId) == 0) {
    SetCaptureStderr(false);
  } else {
    UNREACHABLE();
  }
}

static bool FileModifiedCallback(const char* url, int64_t since) {
  auto path = File::UriToPath(url);
  if (path == nullptr) {
    // If it isn't a file on local disk, we don't know if it has been
    // modified.
    return true;
  }
  int64_t data[File::kStatSize];
  File::Stat(nullptr, path.get(), data);
  if (data[File::kType] == File::kDoesNotExist) {
    return true;
  }
  return data[File::kModifiedTime] > since;
}

static void EmbedderInformationCallback(Dart_EmbedderInformation* info) {
  info->version = DART_EMBEDDER_INFORMATION_CURRENT_VERSION;
  info->name = "Dart VM";
  Process::GetRSSInformation(&(info->max_rss), &(info->current_rss));
}

#define CHECK_RESULT(result)                                                   \
  if (Dart_IsError(result)) {                                                  \
    const int exit_code = Dart_IsCompilationError(result)                      \
                              ? kCompilationErrorExitCode                      \
                              : kErrorExitCode;                                \
    ErrorExit(exit_code, "%s\n", Dart_GetError(result));                       \
  }

static bool CheckForInvalidPath(const char* path) {
  // TODO(zichangguo): "\\?\" is a prefix for paths on Windows.
  // Arguments passed are parsed as an URI. "\\?\" causes problems as a part
  // of URIs. This is a temporary workaround to prevent VM from crashing.
  // Issue: https://github.com/dart-lang/sdk/issues/42779
  if (strncmp(path, R"(\\?\)", 4) == 0) {
    Syslog::PrintErr(R"(\\?\ prefix is not supported)");
    return false;
  }
  return true;
}

class DartDev {
 public:
  // Return codes from dartdev.
  // Note: keep in sync with pkg/dartdev/lib/vm_interop_handler.dart
  typedef enum {
    DartDev_Result_Unknown = -1,
    DartDev_Result_Run = 1,
    DartDev_Result_RunExec = 2,
    DartDev_Result_Exit = 3,
  } DartDev_Result;

  static CStringUniquePtr ResolvedDartVmPath() {
#if defined(DART_HOST_OS_WINDOWS)
    const char* filename = "dartvm.exe";
#else
    const char* filename = "dartvm";
#endif  // defined(DART_HOST_OS_WINDOWS)
    auto try_resolve_path = [&](CStringUniquePtr dir_prefix) {
      // |dir_prefix| includes the last path separator.
      // Assume 'dartvm' and 'dart' executables are in the same directory.
      char* dartvm_path = Utils::SCreate("%s%s", dir_prefix.get(), filename);
      if (File::Exists(nullptr, dartvm_path)) {
        return CStringUniquePtr(dartvm_path);
      }
      free(dartvm_path);
      return CStringUniquePtr(nullptr);
    };

    auto result =
        try_resolve_path(EXEUtils::GetDirectoryPrefixFromResolvedExeName());
    if (result == nullptr) {
      result =
          try_resolve_path(EXEUtils::GetDirectoryPrefixFromUnresolvedExeName());
    }
    return result;
  }

  static CStringUniquePtr ResolvedSnapshotPath() {
    const char* filename = "dartdev_aot.dart.snapshot";

    auto try_resolve_path = [&](CStringUniquePtr dir_prefix) {
      // |dir_prefix| includes the last path separator.
      // First assume we're in dart-sdk/bin.
      char* snapshot_path =
          Utils::SCreate("%ssnapshots/%s", dir_prefix.get(), filename);
      if (File::Exists(nullptr, snapshot_path)) {
        return CStringUniquePtr(snapshot_path);
      }
      free(snapshot_path);

      // If we're not in dart-sdk/bin, we might be in one of the $SDK/out*/
      // directories, Try to use a snapshot from that directory.
      snapshot_path = Utils::SCreate("%s%s", dir_prefix.get(), filename);
      if (File::Exists(nullptr, snapshot_path)) {
        return CStringUniquePtr(snapshot_path);
      }
      free(snapshot_path);
      return CStringUniquePtr(nullptr);
    };

    auto result =
        try_resolve_path(EXEUtils::GetDirectoryPrefixFromResolvedExeName());
    if (result == nullptr) {
      result =
          try_resolve_path(EXEUtils::GetDirectoryPrefixFromUnresolvedExeName());
    }
    return result;
  }

  // Invoke the Dart VM directly bypassing dartdev.
  static void InvokeDartVM(int argc, char** argv, bool argv_converted) {
    auto dartvm_path = DartDev::ResolvedDartVmPath();
    if (dartvm_path.get() == nullptr ||
        !CheckForInvalidPath(dartvm_path.get())) {
      // Free environment if any.
      Syslog::PrintErr("Unable to locate the Dart VM executable");
      Options::Cleanup();
      Platform::Exit(kErrorExitCode);
    }
    int idx = 0;
    char err_msg[256];
    err_msg[0] = '\0';
    intptr_t num_args = argc + 3;
    char** exec_argv = new char*[num_args];
#if defined(DART_HOST_OS_WINDOWS)
    char* exec_name = StringUtilsWin::ArgumentEscape(dartvm_path.get());
#else
    char* exec_name = Utils::StrDup(dartvm_path.get());
#endif
    exec_argv[idx] = exec_name;
    const size_t kPathBufSize = PATH_MAX + 1;
    char dart_path[kPathBufSize];
    Platform::ResolveExecutablePathInto(dart_path, kPathBufSize);
    idx += 1;
#if defined(DART_HOST_OS_WINDOWS)
    char* dart_name =
        Utils::SCreate("--resolved_executable_name=%s", dart_path);
    exec_argv[idx] = StringUtilsWin::ArgumentEscape(dart_name);
    free(dart_name);
    idx += 1;
    dart_name =
        Utils::SCreate("--executable_name=%s", Platform::GetExecutableName());
    exec_argv[idx] = StringUtilsWin::ArgumentEscape(dart_name);
    free(dart_name);
#else
    exec_argv[idx] = Utils::SCreate("--resolved_executable_name=%s", dart_path);
    idx += 1;
    exec_argv[idx] =
        Utils::SCreate("--executable_name=%s", Platform::GetExecutableName());
#endif
    for (intptr_t i = 1; i < argc; ++i) {
#if defined(DART_HOST_OS_WINDOWS)
      exec_argv[i + idx] = StringUtilsWin::ArgumentEscape(argv[i]);
#else
      exec_argv[i + idx] = Utils::StrDup(argv[i]);
#endif  // defined(DART_HOST_OS_WINDOWS)
    }
    // Null terminate the exec_argv array.
    exec_argv[num_args - 1] = nullptr;

    // Exec the script to be run and pass the arguments.
    int ret =
        Process::Exec(nullptr, exec_name, const_cast<const char**>(exec_argv),
                      (num_args - 1), nullptr, err_msg, sizeof(err_msg));
    // Exec process done.
    if (ret != 0) {
      Syslog::PrintErr("%s\n", err_msg);
    }
    // Free copied argument strings if converted.
    if (argv_converted) {
      for (int i = 0; i < argc; i++) {
        free(argv[i]);
      }
    }
    for (int i = 0; i < argc; i++) {
      free(exec_argv[i]);
    }
    delete[] exec_argv;

    // Free environment if any.
    Options::Cleanup();
    Platform::Exit(ret);
  }

  // Process the DartDev_Result_Run result message produced by
  // VmInteropHandler in pkg/dartdev/lib/src/vm_interop_handler.dart
  static void RunResultCallback(Dart_CObject* message) {
    result_ = DartDev_Result_Run;
    ASSERT(GetArrayItem(message, 1)->type == Dart_CObject_kString);
    auto item2 = GetArrayItem(message, 2);

    ASSERT(item2->type == Dart_CObject_kString ||
           item2->type == Dart_CObject_kNull);

    auto item3 = GetArrayItem(message, 3);

    // ignoring mark_main_isolate_as_system_isolate
    ASSERT(item3->type == Dart_CObject_kBool);

    script_name_ = Utils::StrDup(GetArrayItem(message, 1)->value.as_string);

    ASSERT(GetArrayItem(message, 4)->type == Dart_CObject_kArray);
    Dart_CObject* args = GetArrayItem(message, 4);
    argc_ = args->value.as_array.length;
    Dart_CObject** dart_args = args->value.as_array.values;

    auto deleter = [](char** args) {
      for (intptr_t i = 0; i < argc_; ++i) {
        free(args[i]);
      }
      delete[] args;
    };
    argv_ =
        std::unique_ptr<char*[], void (*)(char**)>(new char*[argc_], deleter);
    for (intptr_t i = 0; i < argc_; ++i) {
      argv_[i] = Utils::StrDup(dart_args[i]->value.as_string);
    }
  }

  // Process the DartDev_Result_RunExec result message produced by
  // VmInteropHandler in pkg/dartdev/lib/src/vm_interop_handler.dart
  static void RunExecResultCallback(Dart_CObject* message) {
    result_ = DartDev_Result_RunExec;
    auto dartvm_path = DartDev::ResolvedDartVmPath();
    if (dartvm_path.get() == nullptr ||
        !CheckForInvalidPath(dartvm_path.get())) {
      Syslog::PrintErr("Unable to locate the Dart VM executable");
      Platform::Exit(kErrorExitCode);
    }
    ASSERT(GetArrayItem(message, 1)->type == Dart_CObject_kString);
    auto item2 = GetArrayItem(message, 2);

    ASSERT(item2->type == Dart_CObject_kString ||
           item2->type == Dart_CObject_kNull);

    package_config_override_ = nullptr;

    if (item2->type == Dart_CObject_kString) {
      package_config_override_ = Utils::StrDup(item2->value.as_string);
    }

    intptr_t num_vm_options = dart_vm_options_->count();
    const char** vm_options = dart_vm_options_->arguments();
    ASSERT(GetArrayItem(message, 4)->type == Dart_CObject_kArray);
    Dart_CObject* args = GetArrayItem(message, 4);
    intptr_t argc = args->value.as_array.length;
    Dart_CObject** dart_args = args->value.as_array.values;
    auto item3 = GetArrayItem(message, 3);
    ASSERT(item3->type == Dart_CObject_kBool);
    const bool mark_main_isolate_as_system_isolate = item3->value.as_bool;
    auto deleter = [](char** args) {
      for (intptr_t i = 0; i < argc_; ++i) {
        free(args[i]);
      }
      delete[] args;
    };
    // Total count of arguments to be passed to the script being execed.
    if (mark_main_isolate_as_system_isolate) {
      argc_ = argc + num_vm_options + 5;
    } else {
      argc_ = argc + num_vm_options + 4;
    }

    // Array of arguments to be passed to the script being execed.
    argv_ = std::unique_ptr<char*[], void (*)(char**)>(new char*[argc_ + 1],
                                                       deleter);

    intptr_t idx = 0;
    // Copy in name of the executable to run (should be the dart vm).
#if defined(DART_HOST_OS_WINDOWS)
    script_name_ = StringUtilsWin::ArgumentEscape(dartvm_path.get());
#else
    script_name_ = Utils::StrDup(dartvm_path.get());
#endif
    argv_[idx++] = script_name_;
    // Copy in VM options if any.
    // Copy in any vm options that need to be passed to the execed process.
    for (intptr_t i = 0; i < num_vm_options; ++i) {
#if defined(DART_HOST_OS_WINDOWS)
      argv_[i + idx] = StringUtilsWin::ArgumentEscape(vm_options[i]);
#else
      argv_[i + idx] = Utils::StrDup(vm_options[i]);
#endif
    }
    idx += num_vm_options;
    {
      const size_t kPathBufSize = PATH_MAX + 1;
      char dart_path[kPathBufSize];
      Platform::ResolveExecutablePathInto(dart_path, kPathBufSize);
#if defined(DART_HOST_OS_WINDOWS)
      char* dart_name =
          Utils::SCreate("--resolved_executable_name=%s", dart_path);
      argv_[idx++] = StringUtilsWin::ArgumentEscape(dart_name);
      free(dart_name);
      dart_name =
          Utils::SCreate("--executable_name=%s", Platform::GetExecutableName());
      argv_[idx++] = StringUtilsWin::ArgumentEscape(dart_name);
      free(dart_name);
#else
      argv_[idx++] = Utils::SCreate("--resolved_executable_name=%s", dart_path);
      argv_[idx++] =
          Utils::SCreate("--executable_name=%s", Platform::GetExecutableName());
#endif
    }
    if (mark_main_isolate_as_system_isolate) {
      argv_[idx++] = Utils::StrDup("--mark_main_isolate_as_system_isolate");
    }
    // Copy in name of the script to run.
    argv_[idx++] = Utils::StrDup(GetArrayItem(message, 1)->value.as_string);
    // Copy in the dart options that need to be passed to the script.
    for (intptr_t i = 0; i < argc; ++i) {
      argv_[i + idx] = Utils::StrDup(dart_args[i]->value.as_string);
    }
    // Null terminate the argv array.
    argv_[argc + idx] = nullptr;
  }

  // Process the DartDev_Result_Exit result message produced by
  // VmInteropHandler in pkg/dartdev/lib/src/vm_interop_handler.dart
  static void ExitResultCallback(Dart_CObject* message) {
    ASSERT(GetArrayItem(message, 1)->type == Dart_CObject_kInt32);
    int32_t dartdev_exit_code = GetArrayItem(message, 1)->value.as_int32;

    // If we're given a non-zero exit code, DartDev is signaling for us to
    // shutdown.
    Process::SetGlobalExitCode(dartdev_exit_code);

    // If DartDev hasn't signaled for us to do anything else, we can assume
    // there's nothing else for the VM to run and that we can exit.
    if (result_ == DartDev_Result_Unknown || dartdev_exit_code != 0) {
      result_ = DartDev_Result_Exit;
    }
    // Notify the dartdev runner that it can proceed with processing
    // the result from execution of dartdev.
    {
      MonitorLocker locker(monitor_);
      exited_ = true;
      locker.Notify();
    }
  }

  // Callback that processes the result from execution of dartdev
  //
  static void ResultCallback(Dart_Port dest_port_id, Dart_CObject* message) {
    // These messages are produced in
    // pkg/dartdev/lib/src/vm_interop_handler.dart.
    ASSERT(message->type == Dart_CObject_kArray);
    int32_t type = GetArrayItem(message, 0)->value.as_int32;
    switch (type) {
      case DartDev_Result_Run: {
        RunResultCallback(message);
        break;
      }
      case DartDev_Result_RunExec: {
        RunExecResultCallback(message);
        break;
      }
      case DartDev_Result_Exit: {
        ExitResultCallback(message);
        break;
      }
      default:
        UNREACHABLE();
    }
  }

  static void RunDartDev(const char* script_name,
                         CommandLineOptions* dart_vm_options,
                         CommandLineOptions* dart_options) {
    ASSERT(script_name != nullptr);
    const char* base_name = strrchr(script_name, '/');
    if (base_name == nullptr) {
      base_name = script_name;
    } else {
      base_name++;  // Skip '/'.
    }
    const intptr_t kMaxNameLength = 64;
    char name[kMaxNameLength];
    Utils::SNPrint(name, kMaxNameLength, "dart:%s", base_name);
    Platform::SetProcessName(name);

    dart_vm_options_ = dart_vm_options;

    // Call CreateIsolateGroupAndSetup which creates an isolate and loads up
    // the specified application script.
    Dart_IsolateFlags flags;
    Dart_IsolateFlagsInitialize(&flags);
#if defined(DART_HOST_OS_LINUX)
    // This would also be true in Linux, except that Google3 overrides the
    // default ELF interpreter to one that apparently doesn't create proper
    // mappings.
    flags.snapshot_is_dontneed_safe = false;
#else
    flags.snapshot_is_dontneed_safe = true;
#endif
    flags.is_system_isolate = true;
    SpawnIsolate(script_name, "_startIsolate",
                 /*is_dartdev_isolate*/ true,
                 /*package_config_override*/ nullptr, &flags, dart_options);

    // Wait for the callbacks on the native port to be done before we
    // proceed.
    {
      MonitorLocker locker(monitor_);
      while (!exited_) {
        locker.Wait();
      }
    }

    /* Process the result returned by the dartdev isolate. */
    switch (result_) {
      case DartDev_Result_Run: {
        flags.is_system_isolate = false;
        SpawnIsolate(script_name_, "_startMainIsolate",
                     /*is_dartdev_isolate*/ false, package_config_override_,
                     &flags, dart_options);
        free(script_name_);
        free(package_config_override_);
        break;
      }
      case DartDev_Result_RunExec: {
        RunExec(script_name_);
        break;
      }
      case DartDev_Result_Exit: {
        // Nothing to do here, the process will terminate with the exit code
        // set earlier.
        break;
      }
      default:
        UNREACHABLE();
    }
  }

 private:
  static void SpawnIsolate(const char* script_name,
                           const char* entry_point,
                           bool is_dartdev_isolate,
                           const char* package_config_override,
                           Dart_IsolateFlags* flags,
                           CommandLineOptions* dart_options) {
    // Start a new Isolate with the specified AOT snapshot.
    int exit_code = 0;
    char* error = nullptr;

    Dart_Isolate isolate = CreateIsolateGroupAndSetupHelper(
        is_dartdev_isolate, script_name, "main",
        Options::packages_file() == nullptr ? package_config_override
                                            : Options::packages_file(),
        flags, nullptr /* callback_data */, &error, &exit_code);

    if (isolate == nullptr) {
      if (error != nullptr) {
        Syslog::PrintErr("Isolate spawning failed: %s\n", error);
        free(error);
      }
      error = nullptr;
      Process::TerminateExitCodeHandler();
      error = Dart_Cleanup();
      if (error != nullptr) {
        Syslog::PrintErr("Dart_Cleanup failed: %s\n", error);
        free(error);
      }
      dart::embedder::Cleanup();
      Platform::Exit((exit_code != 0) ? exit_code : kErrorExitCode);
    }

    Dart_EnterIsolate(isolate);
    ASSERT(isolate == Dart_CurrentIsolate());
    ASSERT(isolate != nullptr);
    Dart_Handle result;

    Dart_EnterScope();

    Dart_Handle send_port = Dart_Null();
    Dart_Port send_port_id = ILLEGAL_PORT;
    if (is_dartdev_isolate) {
      // Create a SendPort that DartDev can use to communicate its results over.
      send_port_id =
          Dart_NewNativePort(DART_DEV_ISOLATE_NAME, ResultCallback, false);
      ASSERT(send_port_id != ILLEGAL_PORT);
      send_port = Dart_NewSendPort(send_port_id);
      CHECK_RESULT(send_port);
    }

    // Lookup the library of the root script.
    Dart_Handle root_lib = Dart_RootLibrary();

    if (Dart_IsNull(root_lib)) {
      ErrorExit(kErrorExitCode, "Unable to find root library for '%s'\n",
                script_name);
    }

    // Create a closure for the main entry point which is in the exported
    // namespace of the root library or invoke a getter of the same name
    // in the exported namespace and return the resulting closure.
    Dart_Handle main_closure =
        Dart_GetField(root_lib, Dart_NewStringFromCString("main"));
    CHECK_RESULT(main_closure);
    if (!Dart_IsClosure(main_closure)) {
      ErrorExit(kErrorExitCode, "Unable to find 'main' in root library '%s'\n",
                script_name);
    }

    Dart_Handle isolate_lib =
        Dart_LookupLibrary(Dart_NewStringFromCString("dart:isolate"));
    if (is_dartdev_isolate) {
      const intptr_t kNumIsolateArgs = 4;
      Dart_Handle isolate_args[kNumIsolateArgs];
      isolate_args[0] = main_closure;                          // entryPoint
      isolate_args[1] = dart_options->CreateRuntimeOptions();  // args
      isolate_args[2] = send_port;
      isolate_args[3] = Dart_True();  // isSpawnUri
      result = Dart_Invoke(isolate_lib, Dart_NewStringFromCString(entry_point),
                           kNumIsolateArgs, isolate_args);
    } else {
      // Call _startIsolate in the isolate library to enable dispatching the
      // initial startup message.
      dart_options->Reset();
      dart_options->AddArguments(const_cast<const char**>(argv_.get()), argc_);
      const intptr_t kNumIsolateArgs = 2;
      Dart_Handle isolate_args[kNumIsolateArgs];
      isolate_args[0] = main_closure;                          // entryPoint
      isolate_args[1] = dart_options->CreateRuntimeOptions();  // args
      result = Dart_Invoke(isolate_lib, Dart_NewStringFromCString(entry_point),
                           kNumIsolateArgs, isolate_args);
    }
    CHECK_RESULT(result);

    // Keep handling messages until the last active receive port is closed.
    result = Dart_RunLoop();
    CHECK_RESULT(result);

    if (is_dartdev_isolate) {
      // DartDev is done processing the command. Close the native port, this
      // will ensure we exit from the event handler loop and exit dartdev
      // isolate.
      Dart_CloseNativePort(send_port_id);
    }
    Dart_ExitScope();

    // Shutdown the isolate.
    Dart_ShutdownIsolate();
  }

  static void RunExec(const char* script_name) {
    // Exec the JIT Dart VM with the specified script file.
    char err_msg[256];
    err_msg[0] = '\0';
    int ret = Process::Exec(nullptr, script_name,
                            const_cast<const char**>(argv_.get()), argc_,
                            nullptr, err_msg, sizeof(err_msg));
    if (ret != 0) {
      Syslog::PrintErr("%s.\n", err_msg);
      Process::SetGlobalExitCode(ret);
    } else {
      Process::SetGlobalExitCode(ret);
    }
  }

  static Dart_CObject* GetArrayItem(Dart_CObject* message, intptr_t index) {
    return message->value.as_array.values[index];
  }

  static Monitor* monitor_;
  static bool exited_;
  static DartDev_Result result_;
  static char* script_name_;
  static char* package_config_override_;
  static CommandLineOptions* dart_vm_options_;
  static std::unique_ptr<char*[], void (*)(char**)> argv_;
  static intptr_t argc_;
};

Monitor* DartDev::monitor_ = new Monitor();
bool DartDev::exited_ = false;
DartDev::DartDev_Result DartDev::result_ = DartDev::DartDev_Result_Unknown;
char* DartDev::script_name_ = nullptr;
char* DartDev::package_config_override_ = nullptr;
CommandLineOptions* DartDev::dart_vm_options_ = nullptr;
std::unique_ptr<char*[], void (*)(char**)> DartDev::argv_ =
    std::unique_ptr<char*[], void (*)(char**)>(nullptr, [](char**) {});
intptr_t DartDev::argc_ = 0;

#undef CHECK_RESULT

static void FreeConvertedArgs(int argc, char** argv, bool argv_converted) {
  // Free copied argument strings if converted.
  if (argv_converted) {
    for (int i = 0; i < argc; i++) {
      free(argv[i]);
    }
  }
}

void main(int argc, char** argv) {
#if !defined(DART_HOST_OS_WINDOWS)
  // Very early so any crashes during startup can also be symbolized.
  EXEUtils::LoadDartProfilerSymbols(argv[0]);
#endif

  const int EXTRA_VM_ARGUMENTS = 10;
  // An invocation line is as follows
  // dart <vm_opts> <cmd-name> <vm-opts-to-cmd> <script_name> <dart-options>

  // vm-opts : Set of VM options that need to be passed to the AOT runtime
  // running in this dartdev process.
  CommandLineOptions vm_options(argc + EXTRA_VM_ARGUMENTS);

  // vm-opts-to-cmd : Set of VM options that need to be passed to the runtime
  // that executes the dartdev command.
  CommandLineOptions dart_vm_options(argc + EXTRA_VM_ARGUMENTS);

  // dart-options : Set of options to be passed to the Dart program
  CommandLineOptions dart_options(argc + EXTRA_VM_ARGUMENTS);

  // Perform platform specific initialization.
  if (!Platform::Initialize()) {
    Syslog::PrintErr("Initialization failed\n");
    Platform::Exit(kErrorExitCode);
  }

  // Save the console state so we can restore it at shutdown.
  Console::SaveConfig();

  // On Windows, the argv strings are code page encoded and not
  // utf8. We need to convert them to utf8.
  bool argv_converted = ShellUtils::GetUtf8Argv(argc, argv);

  // When running from the command line we assume that we are optimizing for
  // throughput, and therefore use a larger new gen semi space size and a faster
  // new gen growth factor unless others have been specified.
  if (kWordSize <= 4) {
    vm_options.AddArgument("--new_gen_semi_max_size=16");
  } else {
    vm_options.AddArgument("--new_gen_semi_max_size=32");
  }
  vm_options.AddArgument("--new_gen_growth_factor=4");

  // Parse command line arguments.
  bool skip_dartdev;
  bool success = Options::ParseDartDevArguments(
      argc, argv, &vm_options, &dart_vm_options, &dart_options, &skip_dartdev);
  if (!success) {
    FreeConvertedArgs(argc, argv, argv_converted);
    if (Options::help_option()) {
      Options::PrintUsage();
      Platform::Exit(0);
    } else if (Options::version_option()) {
      Options::PrintVersion();
      Platform::Exit(0);
    } else {
      Options::PrintUsage();
      Platform::Exit(kErrorExitCode);
    }
  }
  if (skip_dartdev) {
    // We are skipping execution of dartdev as no Dart command line has
    // been specified, in this case we directly exec the Dart JIT VM to
    // run the specified script and pass in the original command line
    // arguments.
    DartDev::InvokeDartVM(argc, argv, argv_converted);
  }

  DartUtils::SetEnvironment(Options::environment());

  if (Options::suppress_core_dump()) {
    Platform::SetCoreDumpResourceLimit(0);
  }

  Loader::InitOnce();

  // Setup script_name to point to the dartdev AOT snapshot.
  auto dartdev_path = DartDev::ResolvedSnapshotPath();
  char* script_name = dartdev_path.get();
  if (script_name == nullptr || !CheckForInvalidPath(script_name)) {
    Syslog::PrintErr("Unable to find AOT snapshot for dartdev\n");
    FreeConvertedArgs(argc, argv, argv_converted);
    Platform::Exit(kErrorExitCode);
  }
  AppSnapshot* app_snapshot = Snapshot::TryReadAppSnapshot(
      script_name, /*force_load_from_memory*/ false, /*decode_uri*/ false);
  if (app_snapshot == nullptr || !app_snapshot->IsAOT()) {
    Syslog::PrintErr("%s is not an AOT snapshot\n", script_name);
    FreeConvertedArgs(argc, argv, argv_converted);
    if (app_snapshot != nullptr) {
      delete app_snapshot;
    }
    Platform::Exit(kErrorExitCode);
  }
  app_snapshot->SetBuffers(
      &ignore_vm_snapshot_data, &ignore_vm_snapshot_instructions,
      &app_isolate_snapshot_data, &app_isolate_snapshot_instructions);

  vm_options.AddArgument("--precompilation");

  char* error = nullptr;
  if (!dart::embedder::InitOnce(&error)) {
    Syslog::PrintErr("dartdev embedder initialization failed: %s\n", error);
    free(error);
    FreeConvertedArgs(argc, argv, argv_converted);
    delete app_snapshot;
    Platform::Exit(kErrorExitCode);
  }

  error = Dart_SetVMFlags(vm_options.count(), vm_options.arguments());
  if (error != nullptr) {
    for (int i = 0; i < argc; i++) {
      Syslog::PrintErr("argv[%d]: %s\n", i, argv[i]);
    }
    Syslog::PrintErr("Setting VM flags failed: %s\n", error);
    free(error);
    FreeConvertedArgs(argc, argv, argv_converted);
    delete app_snapshot;
    Platform::Exit(kErrorExitCode);
  }

  // Initialize the Dart VM.
  Dart_InitializeParams init_params;
  memset(&init_params, 0, sizeof(init_params));
  init_params.version = DART_INITIALIZE_PARAMS_CURRENT_VERSION;
  init_params.vm_snapshot_data = ignore_vm_snapshot_data;
  init_params.vm_snapshot_instructions = ignore_vm_snapshot_instructions;
  init_params.create_group = CreateIsolateGroupAndSetup;
  init_params.initialize_isolate = OnIsolateInitialize;
  init_params.shutdown_isolate = OnIsolateShutdown;
  init_params.cleanup_isolate = DeleteIsolateData;
  init_params.cleanup_group = DeleteIsolateGroupData;
  init_params.file_open = DartUtils::OpenFile;
  init_params.file_read = DartUtils::ReadFile;
  init_params.file_write = DartUtils::WriteFile;
  init_params.file_close = DartUtils::CloseFile;
  init_params.entropy_source = DartUtils::EntropySource;
  init_params.start_kernel_isolate = false;
#if defined(DART_HOST_OS_FUCHSIA)
  init_params.vmex_resource = ZX_HANDLE_INVALID;
#endif

  error = Dart_Initialize(&init_params);
  if (error != nullptr) {
    dart::embedder::Cleanup();
    Syslog::PrintErr("VM initialization failed: %s\n", error);
    free(error);
    FreeConvertedArgs(argc, argv, argv_converted);
    delete app_snapshot;
    Platform::Exit(kErrorExitCode);
  }

  Dart_SetServiceStreamCallbacks(&ServiceStreamListenCallback,
                                 &ServiceStreamCancelCallback);
  Dart_SetFileModifiedCallback(&FileModifiedCallback);
  Dart_SetEmbedderInformationCallback(&EmbedderInformationCallback);

  // Run dartdev as the main isolate.
  // The result from the running the dartdev isolate could result in one of
  // these options
  // - Exit the process due to some command parsing errors
  // - Run the Dart script in a JIT mode by execing the JIT runtime
  // - Run the Dart AOT snapshot by creating a new Isolate
  DartDev::RunDartDev(script_name, &dart_vm_options, &dart_options);

  // Terminate process exit-code handler.
  Process::TerminateExitCodeHandler();

  error = Dart_Cleanup();
  if (error != nullptr) {
    Syslog::PrintErr("VM cleanup failed: %s\n", error);
    free(error);
  }
  const intptr_t global_exit_code = Process::GlobalExitCode();
  dart::embedder::Cleanup();

  delete app_snapshot;

  // Free copied argument strings if converted.
  if (argv_converted) {
    for (int i = 0; i < argc; i++) {
      free(argv[i]);
    }
  }

  // Free environment if any.
  Options::Cleanup();

  Platform::Exit(global_exit_code);
}
#else
void main(int argc, char** argv) {
  Platform::Exit(kErrorExitCode);
}
#endif  // defined(DART_PRECOMPILED_RUNTIME)

}  // namespace bin
}  // namespace dart

int main(int argc, char** argv) {
  dart::bin::main(argc, argv);
  UNREACHABLE();
}
