// 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.

// Generate a snapshot file after loading all the scripts specified on the
// command line.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <cstdarg>
#include <memory>

#include "bin/builtin.h"
#include "bin/console.h"
#include "bin/dartutils.h"
#include "bin/eventhandler.h"
#include "bin/file.h"
#include "bin/loader.h"
#include "bin/options.h"
#include "bin/platform.h"
#include "bin/snapshot_utils.h"
#include "bin/thread.h"
#include "bin/utils.h"
#include "bin/vmservice_impl.h"

#include "include/dart_api.h"
#include "include/dart_tools_api.h"

#include "platform/globals.h"
#include "platform/growable_array.h"
#include "platform/hashmap.h"
#include "platform/syslog.h"
#include "platform/text_buffer.h"

namespace dart {
namespace bin {

// Exit code indicating an API error.
static const int kApiErrorExitCode = 253;
// Exit code indicating a compilation error.
static const int kCompilationErrorExitCode = 254;
// Exit code indicating an unhandled error that is not a compilation error.
static const int kErrorExitCode = 255;

#define CHECK_RESULT(result)                                                   \
  if (Dart_IsError(result)) {                                                  \
    intptr_t exit_code = 0;                                                    \
    Syslog::PrintErr("Error: %s\n", 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();                                                    \
    exit(exit_code);                                                           \
  }

// The environment provided through the command line using -D options.
static dart::SimpleHashMap* environment = NULL;

static bool ProcessEnvironmentOption(const char* arg,
                                     CommandLineOptions* vm_options) {
  return OptionProcessor::ProcessEnvironmentOption(arg, vm_options,
                                                   &environment);
}

// The core snapshot to use when creating isolates. Normally NULL, but loaded
// from a file when creating AppJIT snapshots.
const uint8_t* isolate_snapshot_data = NULL;
const uint8_t* isolate_snapshot_instructions = NULL;

// Global state that indicates whether a snapshot is to be created and
// if so which file to write the snapshot into. The ordering of this list must
// match kSnapshotKindNames below.
enum SnapshotKind {
  kCore,
  kCoreJIT,
  kApp,
  kAppJIT,
  kAppAOTAssembly,
  kAppAOTElf,
  kVMAOTAssembly,
};
static SnapshotKind snapshot_kind = kCore;

// The ordering of this list must match the SnapshotKind enum above.
static const char* kSnapshotKindNames[] = {
    // clang-format off
    "core",
    "core-jit",
    "app",
    "app-jit",
    "app-aot-assembly",
    "app-aot-elf",
    "vm-aot-assembly",
    NULL,
    // clang-format on
};

#define STRING_OPTIONS_LIST(V)                                                 \
  V(load_vm_snapshot_data, load_vm_snapshot_data_filename)                     \
  V(load_vm_snapshot_instructions, load_vm_snapshot_instructions_filename)     \
  V(load_isolate_snapshot_data, load_isolate_snapshot_data_filename)           \
  V(load_isolate_snapshot_instructions,                                        \
    load_isolate_snapshot_instructions_filename)                               \
  V(vm_snapshot_data, vm_snapshot_data_filename)                               \
  V(vm_snapshot_instructions, vm_snapshot_instructions_filename)               \
  V(isolate_snapshot_data, isolate_snapshot_data_filename)                     \
  V(isolate_snapshot_instructions, isolate_snapshot_instructions_filename)     \
  V(blobs_container_filename, blobs_container_filename)                        \
  V(assembly, assembly_filename)                                               \
  V(elf, elf_filename)                                                         \
  V(loading_unit_manifest, loading_unit_manifest_filename)                     \
  V(load_compilation_trace, load_compilation_trace_filename)                   \
  V(load_type_feedback, load_type_feedback_filename)                           \
  V(save_debugging_info, debugging_info_filename)                              \
  V(save_obfuscation_map, obfuscation_map_filename)

#define BOOL_OPTIONS_LIST(V)                                                   \
  V(compile_all, compile_all)                                                  \
  V(help, help)                                                                \
  V(obfuscate, obfuscate)                                                      \
  V(read_all_bytecode, read_all_bytecode)                                      \
  V(strip, strip)                                                              \
  V(verbose, verbose)                                                          \
  V(version, version)

#define STRING_OPTION_DEFINITION(flag, variable)                               \
  static const char* variable = NULL;                                          \
  DEFINE_STRING_OPTION(flag, variable)
STRING_OPTIONS_LIST(STRING_OPTION_DEFINITION)
#undef STRING_OPTION_DEFINITION

#define BOOL_OPTION_DEFINITION(flag, variable)                                 \
  static bool variable = false;                                                \
  DEFINE_BOOL_OPTION(flag, variable)
BOOL_OPTIONS_LIST(BOOL_OPTION_DEFINITION)
#undef BOOL_OPTION_DEFINITION

DEFINE_ENUM_OPTION(snapshot_kind, SnapshotKind, snapshot_kind);
DEFINE_CB_OPTION(ProcessEnvironmentOption);

static bool IsSnapshottingForPrecompilation() {
  return (snapshot_kind == kAppAOTAssembly) || (snapshot_kind == kAppAOTElf) ||
         (snapshot_kind == kVMAOTAssembly);
}

// clang-format off
static void PrintUsage() {
  Syslog::PrintErr(
"Usage: gen_snapshot [<vm-flags>] [<options>] <dart-kernel-file>             \n"
"                                                                            \n"
"Common options:                                                             \n"
"--help                                                                      \n"
"  Display this message (add --verbose for information about all VM options).\n"
"--version                                                                   \n"
"  Print the SDK version.                                                    \n"
"                                                                            \n"
"To create a core snapshot:                                                  \n"
"--snapshot_kind=core                                                        \n"
"--vm_snapshot_data=<output-file>                                            \n"
"--isolate_snapshot_data=<output-file>                                       \n"
"<dart-kernel-file>                                                          \n"
"                                                                            \n"
"To create an AOT application snapshot as assembly suitable for compilation  \n"
"as a static or dynamic library:                                             \n"
"--snapshot_kind=app-aot-assembly                                            \n"
"--assembly=<output-file>                                                    \n"
"[--strip]                                                                   \n"
"[--obfuscate]                                                               \n"
"[--save-debugging-info=<debug-filename>]                                    \n"
"[--save-obfuscation-map=<map-filename>]                                     \n"
"<dart-kernel-file>                                                          \n"
"                                                                            \n"
"To create an AOT application snapshot as an ELF shared library:             \n"
"--snapshot_kind=app-aot-elf                                                 \n"
"--elf=<output-file>                                                         \n"
"[--strip]                                                                   \n"
"[--obfuscate]                                                               \n"
"[--save-debugging-info=<debug-filename>]                                    \n"
"[--save-obfuscation-map=<map-filename>]                                     \n"
"<dart-kernel-file>                                                          \n"
"                                                                            \n"
"AOT snapshots can be obfuscated: that is all identifiers will be renamed    \n"
"during compilation. This mode is enabled with --obfuscate flag. Mapping     \n"
"between original and obfuscated names can be serialized as a JSON array     \n"
"using --save-obfuscation-map=<filename> option. See dartbug.com/30524       \n"
"for implementation details and limitations of the obfuscation pass.         \n"
"                                                                            \n"
"\n");
  if (verbose) {
    Syslog::PrintErr(
"The following options are only used for VM development and may\n"
"be changed in any future version:\n");
    const char* print_flags = "--print_flags";
    char* error = Dart_SetVMFlags(1, &print_flags);
    ASSERT(error == NULL);
  }
}
// clang-format on

// Parse out the command line arguments. Returns -1 if the arguments
// are incorrect, 0 otherwise.
static int ParseArguments(int argc,
                          char** argv,
                          CommandLineOptions* vm_options,
                          CommandLineOptions* inputs) {
  const char* kPrefix = "-";
  const intptr_t kPrefixLen = strlen(kPrefix);

  // Skip the binary name.
  int i = 1;

  // Parse out the vm options.
  while ((i < argc) &&
         OptionProcessor::IsValidFlag(argv[i], kPrefix, kPrefixLen)) {
    if (OptionProcessor::TryProcess(argv[i], vm_options)) {
      i += 1;
      continue;
    }
    vm_options->AddArgument(argv[i]);
    i += 1;
  }

  // Parse out the kernel inputs.
  while (i < argc) {
    inputs->AddArgument(argv[i]);
    i++;
  }

  if (help) {
    PrintUsage();
    Platform::Exit(0);
  } else if (version) {
    Syslog::PrintErr("Dart SDK version: %s\n", Dart_VersionString());
    Platform::Exit(0);
  }

  // Verify consistency of arguments.
  if (inputs->count() < 1) {
    Syslog::PrintErr("At least one input is required\n");
    return -1;
  }

  switch (snapshot_kind) {
    case kCore: {
      if ((vm_snapshot_data_filename == NULL) ||
          (isolate_snapshot_data_filename == NULL)) {
        Syslog::PrintErr(
            "Building a core snapshot requires specifying output files for "
            "--vm_snapshot_data and --isolate_snapshot_data.\n\n");
        return -1;
      }
      break;
    }
    case kCoreJIT: {
      if ((vm_snapshot_data_filename == NULL) ||
          (vm_snapshot_instructions_filename == NULL) ||
          (isolate_snapshot_data_filename == NULL) ||
          (isolate_snapshot_instructions_filename == NULL)) {
        Syslog::PrintErr(
            "Building a core JIT snapshot requires specifying output "
            "files for --vm_snapshot_data, --vm_snapshot_instructions, "
            "--isolate_snapshot_data and --isolate_snapshot_instructions.\n\n");
        return -1;
      }
      break;
    }
    case kApp:
    case kAppJIT: {
      if ((load_vm_snapshot_data_filename == NULL) ||
          (isolate_snapshot_data_filename == NULL) ||
          (isolate_snapshot_instructions_filename == NULL)) {
        Syslog::PrintErr(
            "Building an app JIT snapshot requires specifying input files for "
            "--load_vm_snapshot_data and --load_vm_snapshot_instructions, an "
            " output file for --isolate_snapshot_data, and an output "
            "file for --isolate_snapshot_instructions.\n\n");
        return -1;
      }
      break;
    }
    case kAppAOTElf: {
      if (elf_filename == NULL) {
        Syslog::PrintErr(
            "Building an AOT snapshot as ELF requires specifying "
            "an output file for --elf.\n\n");
        return -1;
      }
      break;
    }
    case kAppAOTAssembly:
    case kVMAOTAssembly: {
      if (assembly_filename == NULL) {
        Syslog::PrintErr(
            "Building an AOT snapshot as assembly requires specifying "
            "an output file for --assembly.\n\n");
        return -1;
      }
      break;
    }
  }

  if (!obfuscate && obfuscation_map_filename != NULL) {
    Syslog::PrintErr(
        "--save-obfuscation_map=<...> should only be specified when "
        "obfuscation is enabled by the --obfuscate flag.\n\n");
    return -1;
  }

  if (!IsSnapshottingForPrecompilation()) {
    if (obfuscate) {
      Syslog::PrintErr(
          "Obfuscation can only be enabled when building an AOT snapshot.\n\n");
      return -1;
    }

    if (debugging_info_filename != nullptr) {
      Syslog::PrintErr(
          "--save-debugging-info=<...> can only be enabled when building an "
          "AOT snapshot.\n\n");
      return -1;
    }

    if (strip) {
      Syslog::PrintErr(
          "Stripping can only be enabled when building an AOT snapshot.\n\n");
      return -1;
    }
  }

  return 0;
}

PRINTF_ATTRIBUTE(1, 2) static void PrintErrAndExit(const char* format, ...) {
  va_list args;
  va_start(args, format);
  Syslog::VPrintErr(format, args);
  va_end(args);

  Dart_ExitScope();
  Dart_ShutdownIsolate();
  exit(kErrorExitCode);
}

static File* OpenFile(const char* filename) {
  File* file = File::Open(NULL, filename, File::kWriteTruncate);
  if (file == NULL) {
    PrintErrAndExit("Error: Unable to write file: %s\n\n", filename);
  }
  return file;
}

static void WriteFile(const char* filename,
                      const uint8_t* buffer,
                      const intptr_t size) {
  File* file = OpenFile(filename);
  RefCntReleaseScope<File> rs(file);
  if (!file->WriteFully(buffer, size)) {
    PrintErrAndExit("Error: Unable to write file: %s\n\n", filename);
  }
}

static void ReadFile(const char* filename, uint8_t** buffer, intptr_t* size) {
  File* file = File::Open(NULL, filename, File::kRead);
  if (file == NULL) {
    PrintErrAndExit("Error: Unable to read file: %s\n", filename);
  }
  RefCntReleaseScope<File> rs(file);
  *size = file->Length();
  *buffer = reinterpret_cast<uint8_t*>(malloc(*size));
  if (!file->ReadFully(*buffer, *size)) {
    PrintErrAndExit("Error: Unable to read file: %s\n", filename);
  }
}

static void MaybeLoadExtraInputs(const CommandLineOptions& inputs) {
  for (intptr_t i = 1; i < inputs.count(); i++) {
    uint8_t* buffer = NULL;
    intptr_t size = 0;
    ReadFile(inputs.GetArgument(i), &buffer, &size);
    Dart_Handle result = Dart_LoadLibraryFromKernel(buffer, size);
    CHECK_RESULT(result);
  }
}

static void MaybeLoadCode() {
  if (read_all_bytecode &&
      ((snapshot_kind == kCore) || (snapshot_kind == kCoreJIT) ||
       (snapshot_kind == kApp) || (snapshot_kind == kAppJIT))) {
    Dart_Handle result = Dart_ReadAllBytecode();
    CHECK_RESULT(result);
  }

  if (compile_all &&
      ((snapshot_kind == kCoreJIT) || (snapshot_kind == kAppJIT))) {
    Dart_Handle result = Dart_CompileAll();
    CHECK_RESULT(result);
  }

  if ((load_compilation_trace_filename != NULL) &&
      ((snapshot_kind == kCoreJIT) || (snapshot_kind == kAppJIT))) {
    // Finalize all classes. This ensures that there are no non-finalized
    // classes in the gaps between cid ranges. Such classes prevent merging of
    // cid ranges.
    Dart_Handle result = Dart_FinalizeAllClasses();
    CHECK_RESULT(result);
    // Sort classes to have better cid ranges.
    result = Dart_SortClasses();
    CHECK_RESULT(result);
    uint8_t* buffer = NULL;
    intptr_t size = 0;
    ReadFile(load_compilation_trace_filename, &buffer, &size);
    result = Dart_LoadCompilationTrace(buffer, size);
    free(buffer);
    CHECK_RESULT(result);
  }

  if ((load_type_feedback_filename != NULL) &&
      ((snapshot_kind == kCoreJIT) || (snapshot_kind == kAppJIT))) {
    uint8_t* buffer = NULL;
    intptr_t size = 0;
    ReadFile(load_type_feedback_filename, &buffer, &size);
    Dart_Handle result = Dart_LoadTypeFeedback(buffer, size);
    free(buffer);
    CHECK_RESULT(result);
  }
}

static void CreateAndWriteCoreSnapshot() {
  ASSERT(snapshot_kind == kCore);
  ASSERT(vm_snapshot_data_filename != NULL);
  ASSERT(isolate_snapshot_data_filename != NULL);

  Dart_Handle result;
  uint8_t* vm_snapshot_data_buffer = NULL;
  intptr_t vm_snapshot_data_size = 0;
  uint8_t* isolate_snapshot_data_buffer = NULL;
  intptr_t isolate_snapshot_data_size = 0;

  // First create a snapshot.
  result = Dart_CreateSnapshot(&vm_snapshot_data_buffer, &vm_snapshot_data_size,
                               &isolate_snapshot_data_buffer,
                               &isolate_snapshot_data_size,
                               /*is_core=*/true);
  CHECK_RESULT(result);

  // Now write the vm isolate and isolate snapshots out to the
  // specified file and exit.
  WriteFile(vm_snapshot_data_filename, vm_snapshot_data_buffer,
            vm_snapshot_data_size);
  if (vm_snapshot_instructions_filename != NULL) {
    // Create empty file for the convenience of build systems. Makes things
    // polymorphic with generating core-jit snapshots.
    WriteFile(vm_snapshot_instructions_filename, NULL, 0);
  }
  WriteFile(isolate_snapshot_data_filename, isolate_snapshot_data_buffer,
            isolate_snapshot_data_size);
  if (isolate_snapshot_instructions_filename != NULL) {
    // Create empty file for the convenience of build systems. Makes things
    // polymorphic with generating core-jit snapshots.
    WriteFile(isolate_snapshot_instructions_filename, NULL, 0);
  }
}

static std::unique_ptr<MappedMemory> MapFile(const char* filename,
                                             File::MapType type,
                                             const uint8_t** buffer) {
  File* file = File::Open(NULL, filename, File::kRead);
  if (file == NULL) {
    Syslog::PrintErr("Failed to open: %s\n", filename);
    exit(kErrorExitCode);
  }
  RefCntReleaseScope<File> rs(file);
  intptr_t length = file->Length();
  if (length == 0) {
    // Can't map an empty file.
    *buffer = NULL;
    return NULL;
  }
  MappedMemory* mapping = file->Map(type, 0, length);
  if (mapping == NULL) {
    Syslog::PrintErr("Failed to read: %s\n", filename);
    exit(kErrorExitCode);
  }
  *buffer = reinterpret_cast<const uint8_t*>(mapping->address());
  return std::unique_ptr<MappedMemory>(mapping);
}

static void CreateAndWriteCoreJITSnapshot() {
  ASSERT(snapshot_kind == kCoreJIT);
  ASSERT(vm_snapshot_data_filename != NULL);
  ASSERT(vm_snapshot_instructions_filename != NULL);
  ASSERT(isolate_snapshot_data_filename != NULL);
  ASSERT(isolate_snapshot_instructions_filename != NULL);

  Dart_Handle result;
  uint8_t* vm_snapshot_data_buffer = NULL;
  intptr_t vm_snapshot_data_size = 0;
  uint8_t* vm_snapshot_instructions_buffer = NULL;
  intptr_t vm_snapshot_instructions_size = 0;
  uint8_t* isolate_snapshot_data_buffer = NULL;
  intptr_t isolate_snapshot_data_size = 0;
  uint8_t* isolate_snapshot_instructions_buffer = NULL;
  intptr_t isolate_snapshot_instructions_size = 0;

  // First create a snapshot.
  result = Dart_CreateCoreJITSnapshotAsBlobs(
      &vm_snapshot_data_buffer, &vm_snapshot_data_size,
      &vm_snapshot_instructions_buffer, &vm_snapshot_instructions_size,
      &isolate_snapshot_data_buffer, &isolate_snapshot_data_size,
      &isolate_snapshot_instructions_buffer,
      &isolate_snapshot_instructions_size);
  CHECK_RESULT(result);

  // Now write the vm isolate and isolate snapshots out to the
  // specified file and exit.
  WriteFile(vm_snapshot_data_filename, vm_snapshot_data_buffer,
            vm_snapshot_data_size);
  WriteFile(vm_snapshot_instructions_filename, vm_snapshot_instructions_buffer,
            vm_snapshot_instructions_size);
  WriteFile(isolate_snapshot_data_filename, isolate_snapshot_data_buffer,
            isolate_snapshot_data_size);
  WriteFile(isolate_snapshot_instructions_filename,
            isolate_snapshot_instructions_buffer,
            isolate_snapshot_instructions_size);
}

static void CreateAndWriteAppSnapshot() {
  ASSERT(snapshot_kind == kApp);
  ASSERT(isolate_snapshot_data_filename != NULL);

  Dart_Handle result;
  uint8_t* isolate_snapshot_data_buffer = NULL;
  intptr_t isolate_snapshot_data_size = 0;

  result = Dart_CreateSnapshot(NULL, NULL, &isolate_snapshot_data_buffer,
                               &isolate_snapshot_data_size, /*is_core=*/false);
  CHECK_RESULT(result);

  WriteFile(isolate_snapshot_data_filename, isolate_snapshot_data_buffer,
            isolate_snapshot_data_size);
  if (isolate_snapshot_instructions_filename != NULL) {
    // Create empty file for the convenience of build systems. Makes things
    // polymorphic with generating core-jit snapshots.
    WriteFile(isolate_snapshot_instructions_filename, NULL, 0);
  }
}

static void CreateAndWriteAppJITSnapshot() {
  ASSERT(snapshot_kind == kAppJIT);
  ASSERT(isolate_snapshot_data_filename != NULL);
  ASSERT(isolate_snapshot_instructions_filename != NULL);

  Dart_Handle result;
  uint8_t* isolate_snapshot_data_buffer = NULL;
  intptr_t isolate_snapshot_data_size = 0;
  uint8_t* isolate_snapshot_instructions_buffer = NULL;
  intptr_t isolate_snapshot_instructions_size = 0;

  result = Dart_CreateAppJITSnapshotAsBlobs(
      &isolate_snapshot_data_buffer, &isolate_snapshot_data_size,
      &isolate_snapshot_instructions_buffer,
      &isolate_snapshot_instructions_size);
  CHECK_RESULT(result);

  WriteFile(isolate_snapshot_data_filename, isolate_snapshot_data_buffer,
            isolate_snapshot_data_size);
  WriteFile(isolate_snapshot_instructions_filename,
            isolate_snapshot_instructions_buffer,
            isolate_snapshot_instructions_size);
}

static void StreamingWriteCallback(void* callback_data,
                                   const uint8_t* buffer,
                                   intptr_t size) {
  File* file = reinterpret_cast<File*>(callback_data);
  if ((file != nullptr) && !file->WriteFully(buffer, size)) {
    PrintErrAndExit("Error: Unable to write snapshot file\n\n");
  }
}

static void StreamingCloseCallback(void* callback_data) {
  File* file = reinterpret_cast<File*>(callback_data);
  file->Release();
}

static File* OpenLoadingUnitManifest() {
  File* manifest_file = OpenFile(loading_unit_manifest_filename);
  if (!manifest_file->Print("{ \"loadingUnits\": [\n")) {
    PrintErrAndExit("Error: Unable to write file: %s\n\n",
                    loading_unit_manifest_filename);
  }
  return manifest_file;
}

static void WriteLoadingUnitManifest(File* manifest_file,
                                     intptr_t id,
                                     const char* path) {
  TextBuffer line(128);
  if (id != 1) {
    line.AddString(",\n");
  }
  line.Printf("{ \"id\": %" Pd ", \"path\": \"", id);
  line.AddEscapedString(path);
  line.AddString("\", \"libraries\": [\n");
  Dart_Handle uris = Dart_LoadingUnitLibraryUris(id);
  CHECK_RESULT(uris);
  intptr_t length;
  CHECK_RESULT(Dart_ListLength(uris, &length));
  for (intptr_t i = 0; i < length; i++) {
    const char* uri;
    CHECK_RESULT(Dart_StringToCString(Dart_ListGetAt(uris, i), &uri));
    if (i != 0) {
      line.AddString(",\n");
    }
    line.AddString("\"");
    line.AddEscapedString(uri);
    line.AddString("\"");
  }
  line.AddString("]}");
  if (!manifest_file->Print("%s\n", line.buffer())) {
    PrintErrAndExit("Error: Unable to write file: %s\n\n",
                    loading_unit_manifest_filename);
  }
}

static void CloseLoadingUnitManifest(File* manifest_file) {
  if (!manifest_file->Print("] }\n")) {
    PrintErrAndExit("Error: Unable to write file: %s\n\n",
                    loading_unit_manifest_filename);
  }
  manifest_file->Release();
}

static void NextLoadingUnit(void* callback_data,
                            intptr_t loading_unit_id,
                            void** write_callback_data,
                            void** write_debug_callback_data,
                            const char* main_filename,
                            const char* suffix) {
  char* filename = loading_unit_id == 1
                       ? strdup(main_filename)
                       : Utils::SCreate("%s-%" Pd ".part.%s", main_filename,
                                        loading_unit_id, suffix);
  File* file = OpenFile(filename);
  *write_callback_data = file;

  if (debugging_info_filename != nullptr) {
    char* debug_filename =
        loading_unit_id == 1
            ? strdup(debugging_info_filename)
            : Utils::SCreate("%s-%" Pd ".part.so", debugging_info_filename,
                             loading_unit_id);
    File* debug_file = OpenFile(debug_filename);
    *write_debug_callback_data = debug_file;
    free(debug_filename);
  }

  WriteLoadingUnitManifest(reinterpret_cast<File*>(callback_data),
                           loading_unit_id, filename);

  free(filename);
}

static void NextAsmCallback(void* callback_data,
                            intptr_t loading_unit_id,
                            void** write_callback_data,
                            void** write_debug_callback_data) {
  NextLoadingUnit(callback_data, loading_unit_id, write_callback_data,
                  write_debug_callback_data, assembly_filename, "S");
}

static void NextElfCallback(void* callback_data,
                            intptr_t loading_unit_id,
                            void** write_callback_data,
                            void** write_debug_callback_data) {
  NextLoadingUnit(callback_data, loading_unit_id, write_callback_data,
                  write_debug_callback_data, elf_filename, "so");
}

static void CreateAndWritePrecompiledSnapshot() {
  ASSERT(IsSnapshottingForPrecompilation());
  Dart_Handle result;

  // Precompile with specified embedder entry points
  result = Dart_Precompile();
  CHECK_RESULT(result);

  // Create a precompiled snapshot.
  if (snapshot_kind == kAppAOTAssembly) {
    if (strip && (debugging_info_filename == nullptr)) {
      Syslog::PrintErr(
          "Warning: Generating assembly code without DWARF debugging"
          " information.\n");
    }
    if (loading_unit_manifest_filename == nullptr) {
      File* file = OpenFile(assembly_filename);
      RefCntReleaseScope<File> rs(file);
      File* debug_file = nullptr;
      if (debugging_info_filename != nullptr) {
        debug_file = OpenFile(debugging_info_filename);
      }
      result = Dart_CreateAppAOTSnapshotAsAssembly(StreamingWriteCallback, file,
                                                   strip, debug_file);
      if (debug_file != nullptr) debug_file->Release();
      CHECK_RESULT(result);
    } else {
      File* manifest_file = OpenLoadingUnitManifest();
      result = Dart_CreateAppAOTSnapshotAsAssemblies(
          NextAsmCallback, manifest_file, strip, StreamingWriteCallback,
          StreamingCloseCallback);
      CHECK_RESULT(result);
      CloseLoadingUnitManifest(manifest_file);
    }
    if (obfuscate && !strip) {
      Syslog::PrintErr(
          "Warning: The generated assembly code contains unobfuscated DWARF "
          "debugging information.\n"
          "         To avoid this, use --strip to remove it.\n");
    }
  } else if (snapshot_kind == kAppAOTElf) {
    if (strip && (debugging_info_filename == nullptr)) {
      Syslog::PrintErr(
          "Warning: Generating ELF library without DWARF debugging"
          " information.\n");
    }
    if (loading_unit_manifest_filename == nullptr) {
      File* file = OpenFile(elf_filename);
      RefCntReleaseScope<File> rs(file);
      File* debug_file = nullptr;
      if (debugging_info_filename != nullptr) {
        debug_file = OpenFile(debugging_info_filename);
      }
      result = Dart_CreateAppAOTSnapshotAsElf(StreamingWriteCallback, file,
                                              strip, debug_file);
      if (debug_file != nullptr) debug_file->Release();
      CHECK_RESULT(result);
    } else {
      File* manifest_file = OpenLoadingUnitManifest();
      result = Dart_CreateAppAOTSnapshotAsElfs(NextElfCallback, manifest_file,
                                               strip, StreamingWriteCallback,
                                               StreamingCloseCallback);
      CHECK_RESULT(result);
      CloseLoadingUnitManifest(manifest_file);
    }
    if (obfuscate && !strip) {
      Syslog::PrintErr(
          "Warning: The generated ELF library contains unobfuscated DWARF "
          "debugging information.\n"
          "         To avoid this, use --strip to remove it and "
          "--save-debugging-info=<...> to save it to a separate file.\n");
    }
  } else {
    UNREACHABLE();
  }

  // Serialize obfuscation map if requested.
  if (obfuscation_map_filename != NULL) {
    ASSERT(obfuscate);
    uint8_t* buffer = NULL;
    intptr_t size = 0;
    result = Dart_GetObfuscationMap(&buffer, &size);
    CHECK_RESULT(result);
    WriteFile(obfuscation_map_filename, buffer, size);
  }
}

static Dart_QualifiedFunctionName no_entry_points[] = {
    {NULL, NULL, NULL}  // Must be terminated with NULL entries.
};

static int CreateIsolateAndSnapshot(const CommandLineOptions& inputs) {
  uint8_t* kernel_buffer = NULL;
  intptr_t kernel_buffer_size = 0;
  ReadFile(inputs.GetArgument(0), &kernel_buffer, &kernel_buffer_size);

  Dart_IsolateFlags isolate_flags;
  Dart_IsolateFlagsInitialize(&isolate_flags);
  isolate_flags.null_safety =
      Dart_DetectNullSafety(nullptr, nullptr, nullptr, nullptr, nullptr,
                            kernel_buffer, kernel_buffer_size);
  if (IsSnapshottingForPrecompilation()) {
    isolate_flags.obfuscate = obfuscate;
    isolate_flags.entry_points = no_entry_points;
  }

  auto isolate_group_data = std::unique_ptr<IsolateGroupData>(
      new IsolateGroupData(nullptr, nullptr, nullptr, false));
  Dart_Isolate isolate;
  char* error = NULL;

  bool loading_kernel_failed = false;
  if (isolate_snapshot_data == NULL) {
    // We need to capture the vmservice library in the core snapshot, so load it
    // in the main isolate as well.
    isolate_flags.load_vmservice_library = true;
    isolate = Dart_CreateIsolateGroupFromKernel(
        NULL, NULL, kernel_buffer, kernel_buffer_size, &isolate_flags,
        isolate_group_data.get(), /*isolate_data=*/nullptr, &error);
    loading_kernel_failed = (isolate == nullptr);
  } else {
    isolate = Dart_CreateIsolateGroup(NULL, NULL, isolate_snapshot_data,
                                      isolate_snapshot_instructions,
                                      &isolate_flags, isolate_group_data.get(),
                                      /*isolate_data=*/nullptr, &error);
  }
  if (isolate == NULL) {
    Syslog::PrintErr("%s\n", error);
    free(error);
    free(kernel_buffer);
    // The only real reason when `gen_snapshot` fails to create an isolate from
    // a valid kernel file is if loading the kernel results in a "compile-time"
    // error.
    //
    // There are other possible reasons, like memory allocation failures, but
    // those are very uncommon.
    //
    // The Dart API doesn't allow us to distinguish the different error cases,
    // so we'll use [kCompilationErrorExitCode] for failed kernel loading, since
    // a compile-time error is the most probable cause.
    return loading_kernel_failed ? kCompilationErrorExitCode : kErrorExitCode;
  }

  Dart_EnterScope();
  Dart_Handle result =
      Dart_SetEnvironmentCallback(DartUtils::EnvironmentCallback);
  CHECK_RESULT(result);

  // The root library has to be set to generate AOT snapshots, and sometimes we
  // set one for the core snapshot too.
  // If the input dill file has a root library, then Dart_LoadScript will
  // ignore this dummy uri and set the root library to the one reported in
  // the dill file. Since dill files are not dart script files,
  // trying to resolve the root library URI based on the dill file name
  // would not help.
  //
  // If the input dill file does not have a root library, then
  // Dart_LoadScript will error.
  //
  // TODO(kernel): Dart_CreateIsolateGroupFromKernel should respect the root
  // library in the kernel file, though this requires auditing the other
  // loading paths in the embedders that had to work around this.
  result = Dart_SetRootLibrary(
      Dart_LoadLibraryFromKernel(kernel_buffer, kernel_buffer_size));
  CHECK_RESULT(result);

  MaybeLoadExtraInputs(inputs);

  MaybeLoadCode();

  switch (snapshot_kind) {
    case kCore:
      CreateAndWriteCoreSnapshot();
      break;
    case kCoreJIT:
      CreateAndWriteCoreJITSnapshot();
      break;
    case kApp:
      CreateAndWriteAppSnapshot();
      break;
    case kAppJIT:
      CreateAndWriteAppJITSnapshot();
      break;
    case kAppAOTAssembly:
    case kAppAOTElf:
      CreateAndWritePrecompiledSnapshot();
      break;
    case kVMAOTAssembly: {
      File* file = OpenFile(assembly_filename);
      RefCntReleaseScope<File> rs(file);
      result = Dart_CreateVMAOTSnapshotAsAssembly(StreamingWriteCallback, file);
      CHECK_RESULT(result);
      break;
    }
    default:
      UNREACHABLE();
  }

  Dart_ExitScope();
  Dart_ShutdownIsolate();

  free(kernel_buffer);
  return 0;
}

int main(int argc, char** argv) {
  const int EXTRA_VM_ARGUMENTS = 7;
  CommandLineOptions vm_options(argc + EXTRA_VM_ARGUMENTS);
  CommandLineOptions inputs(argc);

  // 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");
  vm_options.AddArgument("--deterministic");

  // Parse command line arguments.
  if (ParseArguments(argc, argv, &vm_options, &inputs) < 0) {
    PrintUsage();
    return kErrorExitCode;
  }
  DartUtils::SetEnvironment(environment);

  if (!Platform::Initialize()) {
    Syslog::PrintErr("Initialization failed\n");
    return kErrorExitCode;
  }
  Console::SaveConfig();
  Loader::InitOnce();
  DartUtils::SetOriginalWorkingDirectory();
  // Start event handler.
  TimerUtils::InitOnce();
  EventHandler::Start();

  if (IsSnapshottingForPrecompilation()) {
    vm_options.AddArgument("--precompilation");
  } else if ((snapshot_kind == kCoreJIT) || (snapshot_kind == kAppJIT)) {
    vm_options.AddArgument("--fields_may_be_reset");
#if !defined(TARGET_ARCH_IA32)
    vm_options.AddArgument("--link_natives_lazily");
#endif
  }

  char* error = Dart_SetVMFlags(vm_options.count(), vm_options.arguments());
  if (error != NULL) {
    Syslog::PrintErr("Setting VM flags failed: %s\n", error);
    free(error);
    return kErrorExitCode;
  }

  Dart_InitializeParams init_params;
  memset(&init_params, 0, sizeof(init_params));
  init_params.version = DART_INITIALIZE_PARAMS_CURRENT_VERSION;
  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;

  std::unique_ptr<MappedMemory> mapped_vm_snapshot_data;
  std::unique_ptr<MappedMemory> mapped_vm_snapshot_instructions;
  std::unique_ptr<MappedMemory> mapped_isolate_snapshot_data;
  std::unique_ptr<MappedMemory> mapped_isolate_snapshot_instructions;
  if (load_vm_snapshot_data_filename != NULL) {
    mapped_vm_snapshot_data =
        MapFile(load_vm_snapshot_data_filename, File::kReadOnly,
                &init_params.vm_snapshot_data);
  }
  if (load_vm_snapshot_instructions_filename != NULL) {
    mapped_vm_snapshot_instructions =
        MapFile(load_vm_snapshot_instructions_filename, File::kReadExecute,
                &init_params.vm_snapshot_instructions);
  }
  if (load_isolate_snapshot_data_filename != nullptr) {
    mapped_isolate_snapshot_data =
        MapFile(load_isolate_snapshot_data_filename, File::kReadOnly,
                &isolate_snapshot_data);
  }
  if (load_isolate_snapshot_instructions_filename != NULL) {
    mapped_isolate_snapshot_instructions =
        MapFile(load_isolate_snapshot_instructions_filename, File::kReadExecute,
                &isolate_snapshot_instructions);
  }

  error = Dart_Initialize(&init_params);
  if (error != NULL) {
    Syslog::PrintErr("VM initialization failed: %s\n", error);
    free(error);
    return kErrorExitCode;
  }

  int result = CreateIsolateAndSnapshot(inputs);
  if (result != 0) {
    return result;
  }

  error = Dart_Cleanup();
  if (error != NULL) {
    Syslog::PrintErr("VM cleanup failed: %s\n", error);
    free(error);
  }
  EventHandler::Stop();
  return 0;
}

}  // namespace bin
}  // namespace dart

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