
#include "node_snapshotable.h"
#include <iostream>
#include <sstream>
#include "base_object-inl.h"
#include "debug_utils-inl.h"
#include "env-inl.h"
#include "node_blob.h"
#include "node_builtins.h"
#include "node_contextify.h"
#include "node_errors.h"
#include "node_external_reference.h"
#include "node_file.h"
#include "node_internals.h"
#include "node_main_instance.h"
#include "node_metadata.h"
#include "node_process.h"
#include "node_snapshot_builder.h"
#include "node_util.h"
#include "node_v8.h"
#include "node_v8_platform-inl.h"

#if HAVE_INSPECTOR
#include "inspector/worker_inspector.h"  // ParentInspectorHandle
#endif

namespace node {

using v8::Context;
using v8::Function;
using v8::FunctionCallbackInfo;
using v8::HandleScope;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::ObjectTemplate;
using v8::ScriptCompiler;
using v8::ScriptOrigin;
using v8::SnapshotCreator;
using v8::StartupData;
using v8::String;
using v8::TryCatch;
using v8::Value;

const uint32_t SnapshotData::kMagic;

std::ostream& operator<<(std::ostream& output,
                         const builtins::CodeCacheInfo& info) {
  output << "<builtins::CodeCacheInfo id=" << info.id
         << ", size=" << info.data.size() << ">\n";
  return output;
}

std::ostream& operator<<(std::ostream& output,
                         const std::vector<builtins::CodeCacheInfo>& vec) {
  output << "{\n";
  for (const auto& info : vec) {
    output << info;
  }
  output << "}\n";
  return output;
}

std::ostream& operator<<(std::ostream& output,
                         const std::vector<uint8_t>& vec) {
  output << "{\n";
  for (const auto& i : vec) {
    output << i << ",";
  }
  output << "}";
  return output;
}

std::ostream& operator<<(std::ostream& output,
                         const std::vector<PropInfo>& vec) {
  output << "{\n";
  for (const auto& info : vec) {
    output << "  " << info << ",\n";
  }
  output << "}";
  return output;
}

std::ostream& operator<<(std::ostream& output, const PropInfo& info) {
  output << "{ \"" << info.name << "\", " << std::to_string(info.id) << ", "
         << std::to_string(info.index) << " }";
  return output;
}

std::ostream& operator<<(std::ostream& output,
                         const std::vector<std::string>& vec) {
  output << "{\n";
  for (const auto& info : vec) {
    output << "  \"" << info << "\",\n";
  }
  output << "}";
  return output;
}

std::ostream& operator<<(std::ostream& output, const RealmSerializeInfo& i) {
  output << "{\n"
         << "// -- persistent_values begins --\n"
         << i.persistent_values << ",\n"
         << "// -- persistent_values ends --\n"
         << "// -- native_objects begins --\n"
         << i.native_objects << ",\n"
         << "// -- native_objects ends --\n"
         << i.context << ",  // context\n"
         << "}";
  return output;
}

std::ostream& operator<<(std::ostream& output, const EnvSerializeInfo& i) {
  output << "{\n"
         << "// -- builtins begins --\n"
         << i.builtins << ",\n"
         << "// -- builtins ends --\n"
         << "// -- async_hooks begins --\n"
         << i.async_hooks << ",\n"
         << "// -- async_hooks ends --\n"
         << i.tick_info << ",  // tick_info\n"
         << i.immediate_info << ",  // immediate_info\n"
         << "// -- performance_state begins --\n"
         << i.performance_state << ",\n"
         << "// -- performance_state ends --\n"
         << i.exiting << ",  // exiting\n"
         << i.stream_base_state << ",  // stream_base_state\n"
         << i.should_abort_on_uncaught_toggle
         << ",  // should_abort_on_uncaught_toggle\n"
         << "// -- principal_realm begins --\n"
         << i.principal_realm << ",\n"
         << "// -- principal_realm ends --\n"
         << "}";
  return output;
}

class FileIO {
 public:
  explicit FileIO(FILE* file)
      : f(file),
        is_debug(per_process::enabled_debug_list.enabled(
            DebugCategory::MKSNAPSHOT)) {}

  template <typename... Args>
  void Debug(const char* format, Args&&... args) const {
    per_process::Debug(
        DebugCategory::MKSNAPSHOT, format, std::forward<Args>(args)...);
  }

  template <typename T>
  std::string ToStr(const T& arg) const {
    std::stringstream ss;
    ss << arg;
    return ss.str();
  }

  template <typename T>
  std::string GetName() const {
#define TYPE_LIST(V)                                                           \
  V(builtins::CodeCacheInfo)                                                   \
  V(PropInfo)                                                                  \
  V(std::string)

#define V(TypeName)                                                            \
  if (std::is_same_v<T, TypeName>) {                                           \
    return #TypeName;                                                          \
  }
    TYPE_LIST(V)
#undef V

    std::string name;
    if (std::is_arithmetic_v<T>) {
      if (!std::is_signed_v<T>) {
        name += "u";
      }
      name += std::is_integral_v<T> ? "int" : "float";
      name += std::to_string(sizeof(T) * 8);
      name += "_t";
    }
    return name;
  }

  FILE* f = nullptr;
  bool is_debug = false;
};

class FileReader : public FileIO {
 public:
  explicit FileReader(FILE* file) : FileIO(file) {}
  ~FileReader() {}

  // Helper for reading numeric types.
  template <typename T>
  T Read() {
    static_assert(std::is_arithmetic_v<T>, "Not an arithmetic type");
    T result;
    Read(&result, 1);
    return result;
  }

  // Layout of vectors:
  // [ 4/8 bytes ] count
  // [   ...     ] contents (count * size of individual elements)
  template <typename T>
  std::vector<T> ReadVector() {
    if (is_debug) {
      std::string name = GetName<T>();
      Debug("\nReadVector<%s>()(%d-byte)\n", name.c_str(), sizeof(T));
    }
    size_t count = static_cast<size_t>(Read<size_t>());
    if (count == 0) {
      return std::vector<T>();
    }
    if (is_debug) {
      Debug("Reading %d vector elements...\n", count);
    }
    std::vector<T> result = ReadVector<T>(count, std::is_arithmetic<T>{});
    if (is_debug) {
      std::string str = std::is_arithmetic_v<T> ? "" : ToStr(result);
      std::string name = GetName<T>();
      Debug("ReadVector<%s>() read %s\n", name.c_str(), str.c_str());
    }
    return result;
  }

  std::string ReadString() {
    size_t length = Read<size_t>();

    if (is_debug) {
      Debug("ReadString(), length=%d: ", length);
    }

    CHECK_GT(length, 0);  // There should be no empty strings.
    MallocedBuffer<char> buf(length + 1);
    size_t r = fread(buf.data, 1, length + 1, f);
    CHECK_EQ(r, length + 1);
    std::string result(buf.data, length);  // This creates a copy of buf.data.

    if (is_debug) {
      Debug("\"%s\", read %d bytes\n", result.c_str(), r);
    }

    read_total += r;
    return result;
  }

  size_t read_total = 0;

 private:
  // Helper for reading an array of numeric types.
  template <typename T>
  void Read(T* out, size_t count) {
    static_assert(std::is_arithmetic_v<T>, "Not an arithmetic type");
    DCHECK_GT(count, 0);  // Should not read contents for vectors of size 0.
    if (is_debug) {
      std::string name = GetName<T>();
      Debug("Read<%s>()(%d-byte), count=%d: ", name.c_str(), sizeof(T), count);
    }

    size_t r = fread(out, sizeof(T), count, f);
    CHECK_EQ(r, count);

    if (is_debug) {
      std::string str =
          "{ " + std::to_string(out[0]) + (count > 1 ? ", ... }" : " }");
      Debug("%s, read %d bytes\n", str.c_str(), r);
    }
    read_total += r;
  }

  // Helper for reading numeric vectors.
  template <typename Number>
  std::vector<Number> ReadVector(size_t count, std::true_type) {
    static_assert(std::is_arithmetic_v<Number>, "Not an arithmetic type");
    DCHECK_GT(count, 0);  // Should not read contents for vectors of size 0.
    std::vector<Number> result(count);
    Read(result.data(), count);
    return result;
  }

  // Helper for reading non-numeric vectors.
  template <typename T>
  std::vector<T> ReadVector(size_t count, std::false_type) {
    static_assert(!std::is_arithmetic_v<T>, "Arithmetic type");
    DCHECK_GT(count, 0);  // Should not read contents for vectors of size 0.
    std::vector<T> result;
    result.reserve(count);
    bool original_is_debug = is_debug;
    is_debug = original_is_debug && !std::is_same_v<T, std::string>;
    for (size_t i = 0; i < count; ++i) {
      if (is_debug) {
        Debug("\n[%d] ", i);
      }
      result.push_back(Read<T>());
    }
    is_debug = original_is_debug;

    return result;
  }
};

class FileWriter : public FileIO {
 public:
  explicit FileWriter(FILE* file) : FileIO(file) {}
  ~FileWriter() {}

  // Helper for writing numeric types.
  template <typename T>
  size_t Write(const T& data) {
    static_assert(std::is_arithmetic_v<T>, "Not an arithmetic type");
    return Write(&data, 1);
  }

  // Layout of vectors:
  // [ 4/8 bytes ] count
  // [   ...     ] contents (count * size of individual elements)
  template <typename T>
  size_t WriteVector(const std::vector<T>& data) {
    if (is_debug) {
      std::string str = std::is_arithmetic_v<T> ? "" : ToStr(data);
      std::string name = GetName<T>();
      Debug("\nWriteVector<%s>() (%d-byte), count=%d: %s\n",
            name.c_str(),
            sizeof(T),
            data.size(),
            str.c_str());
    }

    size_t written_total = Write<size_t>(data.size());
    if (data.size() == 0) {
      return written_total;
    }
    written_total += WriteVector<T>(data, std::is_arithmetic<T>{});

    if (is_debug) {
      std::string name = GetName<T>();
      Debug("WriteVector<%s>() wrote %d bytes\n", name.c_str(), written_total);
    }

    return written_total;
  }

  // The layout of a written string:
  // [  4/8 bytes     ] length
  // [ |length| bytes ] contents
  size_t WriteString(const std::string& data) {
    CHECK_GT(data.size(), 0);  // No empty strings should be written.
    size_t written_total = Write<size_t>(data.size());
    if (is_debug) {
      std::string str = ToStr(data);
      Debug("WriteString(), length=%d: \"%s\"\n", data.size(), data.c_str());
    }

    size_t r = fwrite(data.c_str(), 1, data.size() + 1, f);
    CHECK_EQ(r, data.size() + 1);
    written_total += r;

    if (is_debug) {
      Debug("WriteString() wrote %d bytes\n", written_total);
    }

    return written_total;
  }

 private:
  // Helper for writing an array of numeric types.
  template <typename T>
  size_t Write(const T* data, size_t count) {
    DCHECK_GT(count, 0);  // Should not write contents for vectors of size 0.
    if (is_debug) {
      std::string str =
          "{ " + std::to_string(data[0]) + (count > 1 ? ", ... }" : " }");
      std::string name = GetName<T>();
      Debug("Write<%s>() (%d-byte), count=%d: %s",
            name.c_str(),
            sizeof(T),
            count,
            str.c_str());
    }

    size_t r = fwrite(data, sizeof(T), count, f);
    CHECK_EQ(r, count);

    if (is_debug) {
      Debug(", wrote %d bytes\n", r);
    }
    return r;
  }

  // Helper for writing numeric vectors.
  template <typename Number>
  size_t WriteVector(const std::vector<Number>& data, std::true_type) {
    return Write(data.data(), data.size());
  }

  // Helper for writing non-numeric vectors.
  template <typename T>
  size_t WriteVector(const std::vector<T>& data, std::false_type) {
    DCHECK_GT(data.size(),
              0);  // Should not write contents for vectors of size 0.
    size_t written_total = 0;
    bool original_is_debug = is_debug;
    is_debug = original_is_debug && !std::is_same_v<T, std::string>;
    for (size_t i = 0; i < data.size(); ++i) {
      if (is_debug) {
        Debug("\n[%d] ", i);
      }
      written_total += Write<T>(data[i]);
    }
    is_debug = original_is_debug;

    return written_total;
  }
};

// Layout of serialized std::string:
// [  4/8 bytes     ] length
// [ |length| bytes ] contents
template <>
std::string FileReader::Read() {
  return ReadString();
}
template <>
size_t FileWriter::Write(const std::string& data) {
  return WriteString(data);
}

// Layout of v8::StartupData
// [  4/8 bytes       ] raw_size
// [ |raw_size| bytes ] contents
template <>
v8::StartupData FileReader::Read() {
  Debug("Read<v8::StartupData>()\n");

  int raw_size = Read<int>();
  Debug("size=%d\n", raw_size);

  CHECK_GT(raw_size, 0);  // There should be no startup data of size 0.
  // The data pointer of v8::StartupData would be deleted so it must be new'ed.
  std::unique_ptr<char> buf = std::unique_ptr<char>(new char[raw_size]);
  Read<char>(buf.get(), raw_size);

  return v8::StartupData{buf.release(), raw_size};
}

template <>
size_t FileWriter::Write(const v8::StartupData& data) {
  Debug("\nWrite<v8::StartupData>() size=%d\n", data.raw_size);

  CHECK_GT(data.raw_size, 0);  // There should be no startup data of size 0.
  size_t written_total = Write<int>(data.raw_size);
  written_total += Write<char>(data.data, static_cast<size_t>(data.raw_size));

  Debug("Write<v8::StartupData>() wrote %d bytes\n\n", written_total);
  return written_total;
}

// Layout of builtins::CodeCacheInfo
// [  4/8 bytes ]  length of the module id string
// [    ...     ]  |length| bytes of module id
// [  4/8 bytes ]  length of module code cache
// [    ...     ]  |length| bytes of module code cache
template <>
builtins::CodeCacheInfo FileReader::Read() {
  Debug("Read<builtins::CodeCacheInfo>()\n");

  builtins::CodeCacheInfo result{ReadString(), ReadVector<uint8_t>()};

  if (is_debug) {
    std::string str = ToStr(result);
    Debug("Read<builtins::CodeCacheInfo>() %s\n", str.c_str());
  }
  return result;
}

template <>
size_t FileWriter::Write(const builtins::CodeCacheInfo& data) {
  Debug("\nWrite<builtins::CodeCacheInfo>() id = %s"
        ", size=%d\n",
        data.id.c_str(),
        data.data.size());

  size_t written_total = WriteString(data.id);
  written_total += WriteVector<uint8_t>(data.data);

  Debug("Write<builtins::CodeCacheInfo>() wrote %d bytes\n", written_total);
  return written_total;
}

// Layout of PropInfo
// [ 4/8 bytes ]  length of the data name string
// [    ...    ]  |length| bytes of data name
// [  4 bytes  ]  index in the PropInfo vector
// [ 4/8 bytes ]  index in the snapshot blob, can be used with
//                GetDataFromSnapshotOnce().
template <>
PropInfo FileReader::Read() {
  Debug("Read<PropInfo>()\n");

  PropInfo result;
  result.name = ReadString();
  result.id = Read<uint32_t>();
  result.index = Read<SnapshotIndex>();

  if (is_debug) {
    std::string str = ToStr(result);
    Debug("Read<PropInfo>() %s\n", str.c_str());
  }

  return result;
}

template <>
size_t FileWriter::Write(const PropInfo& data) {
  if (is_debug) {
    std::string str = ToStr(data);
    Debug("Write<PropInfo>() %s\n", str.c_str());
  }

  size_t written_total = WriteString(data.name);
  written_total += Write<uint32_t>(data.id);
  written_total += Write<SnapshotIndex>(data.index);

  Debug("Write<PropInfo>() wrote %d bytes\n", written_total);
  return written_total;
}

// Layout of AsyncHooks::SerializeInfo
// [ 4/8 bytes ]  snapshot index of async_ids_stack
// [ 4/8 bytes ]  snapshot index of fields
// [ 4/8 bytes ]  snapshot index of async_id_fields
// [ 4/8 bytes ]  snapshot index of js_execution_async_resources
// [ 4/8 bytes ]  length of native_execution_async_resources
// [   ...     ]  snapshot indices of each element in
//                native_execution_async_resources
template <>
AsyncHooks::SerializeInfo FileReader::Read() {
  Debug("Read<AsyncHooks::SerializeInfo>()\n");

  AsyncHooks::SerializeInfo result;
  result.async_ids_stack = Read<AliasedBufferIndex>();
  result.fields = Read<AliasedBufferIndex>();
  result.async_id_fields = Read<AliasedBufferIndex>();
  result.js_execution_async_resources = Read<SnapshotIndex>();
  result.native_execution_async_resources = ReadVector<SnapshotIndex>();

  if (is_debug) {
    std::string str = ToStr(result);
    Debug("Read<AsyncHooks::SerializeInfo>() %s\n", str.c_str());
  }

  return result;
}
template <>
size_t FileWriter::Write(const AsyncHooks::SerializeInfo& data) {
  if (is_debug) {
    std::string str = ToStr(data);
    Debug("Write<AsyncHooks::SerializeInfo>() %s\n", str.c_str());
  }

  size_t written_total = Write<AliasedBufferIndex>(data.async_ids_stack);
  written_total += Write<AliasedBufferIndex>(data.fields);
  written_total += Write<AliasedBufferIndex>(data.async_id_fields);
  written_total += Write<SnapshotIndex>(data.js_execution_async_resources);
  written_total +=
      WriteVector<SnapshotIndex>(data.native_execution_async_resources);

  Debug("Write<AsyncHooks::SerializeInfo>() wrote %d bytes\n", written_total);
  return written_total;
}

// Layout of TickInfo::SerializeInfo
// [ 4/8 bytes ]  snapshot index of fields
template <>
TickInfo::SerializeInfo FileReader::Read() {
  Debug("Read<TickInfo::SerializeInfo>()\n");

  TickInfo::SerializeInfo result;
  result.fields = Read<AliasedBufferIndex>();

  if (is_debug) {
    std::string str = ToStr(result);
    Debug("Read<TickInfo::SerializeInfo>() %s\n", str.c_str());
  }

  return result;
}

template <>
size_t FileWriter::Write(const TickInfo::SerializeInfo& data) {
  if (is_debug) {
    std::string str = ToStr(data);
    Debug("Write<TickInfo::SerializeInfo>() %s\n", str.c_str());
  }

  size_t written_total = Write<AliasedBufferIndex>(data.fields);

  Debug("Write<TickInfo::SerializeInfo>() wrote %d bytes\n", written_total);
  return written_total;
}

// Layout of TickInfo::SerializeInfo
// [ 4/8 bytes ]  snapshot index of fields
template <>
ImmediateInfo::SerializeInfo FileReader::Read() {
  per_process::Debug(DebugCategory::MKSNAPSHOT,
                     "Read<ImmediateInfo::SerializeInfo>()\n");

  ImmediateInfo::SerializeInfo result;
  result.fields = Read<AliasedBufferIndex>();
  if (is_debug) {
    std::string str = ToStr(result);
    Debug("Read<ImmediateInfo::SerializeInfo>() %s\n", str.c_str());
  }
  return result;
}

template <>
size_t FileWriter::Write(const ImmediateInfo::SerializeInfo& data) {
  if (is_debug) {
    std::string str = ToStr(data);
    Debug("Write<ImmeidateInfo::SerializeInfo>() %s\n", str.c_str());
  }

  size_t written_total = Write<AliasedBufferIndex>(data.fields);

  Debug("Write<ImmeidateInfo::SerializeInfo>() wrote %d bytes\n",
        written_total);
  return written_total;
}

// Layout of PerformanceState::SerializeInfo
// [ 4/8 bytes ]  snapshot index of root
// [ 4/8 bytes ]  snapshot index of milestones
// [ 4/8 bytes ]  snapshot index of observers
template <>
performance::PerformanceState::SerializeInfo FileReader::Read() {
  per_process::Debug(DebugCategory::MKSNAPSHOT,
                     "Read<PerformanceState::SerializeInfo>()\n");

  performance::PerformanceState::SerializeInfo result;
  result.root = Read<AliasedBufferIndex>();
  result.milestones = Read<AliasedBufferIndex>();
  result.observers = Read<AliasedBufferIndex>();
  if (is_debug) {
    std::string str = ToStr(result);
    Debug("Read<PerformanceState::SerializeInfo>() %s\n", str.c_str());
  }
  return result;
}

template <>
size_t FileWriter::Write(
    const performance::PerformanceState::SerializeInfo& data) {
  if (is_debug) {
    std::string str = ToStr(data);
    Debug("Write<PerformanceState::SerializeInfo>() %s\n", str.c_str());
  }

  size_t written_total = Write<AliasedBufferIndex>(data.root);
  written_total += Write<AliasedBufferIndex>(data.milestones);
  written_total += Write<AliasedBufferIndex>(data.observers);

  Debug("Write<PerformanceState::SerializeInfo>() wrote %d bytes\n",
        written_total);
  return written_total;
}

// Layout of IsolateDataSerializeInfo
// [ 4/8 bytes ]  length of primitive_values vector
// [    ...    ]  |length| of primitive_values indices
// [ 4/8 bytes ]  length of template_values vector
// [    ...    ]  |length| of PropInfo data
template <>
IsolateDataSerializeInfo FileReader::Read() {
  per_process::Debug(DebugCategory::MKSNAPSHOT,
                     "Read<IsolateDataSerializeInfo>()\n");

  IsolateDataSerializeInfo result;
  result.primitive_values = ReadVector<SnapshotIndex>();
  result.template_values = ReadVector<PropInfo>();
  if (is_debug) {
    std::string str = ToStr(result);
    Debug("Read<IsolateDataSerializeInfo>() %s\n", str.c_str());
  }
  return result;
}

template <>
size_t FileWriter::Write(const IsolateDataSerializeInfo& data) {
  if (is_debug) {
    std::string str = ToStr(data);
    Debug("Write<IsolateDataSerializeInfo>() %s\n", str.c_str());
  }

  size_t written_total = WriteVector<SnapshotIndex>(data.primitive_values);
  written_total += WriteVector<PropInfo>(data.template_values);

  Debug("Write<IsolateDataSerializeInfo>() wrote %d bytes\n", written_total);
  return written_total;
}

template <>
RealmSerializeInfo FileReader::Read() {
  per_process::Debug(DebugCategory::MKSNAPSHOT, "Read<RealmSerializeInfo>()\n");
  RealmSerializeInfo result;
  result.persistent_values = ReadVector<PropInfo>();
  result.native_objects = ReadVector<PropInfo>();
  result.context = Read<SnapshotIndex>();
  return result;
}

template <>
size_t FileWriter::Write(const RealmSerializeInfo& data) {
  if (is_debug) {
    std::string str = ToStr(data);
    Debug("\nWrite<RealmSerializeInfo>() %s\n", str.c_str());
  }

  // Use += here to ensure order of evaluation.
  size_t written_total = WriteVector<PropInfo>(data.persistent_values);
  written_total += WriteVector<PropInfo>(data.native_objects);
  written_total += Write<SnapshotIndex>(data.context);

  Debug("Write<RealmSerializeInfo>() wrote %d bytes\n", written_total);
  return written_total;
}

template <>
EnvSerializeInfo FileReader::Read() {
  per_process::Debug(DebugCategory::MKSNAPSHOT, "Read<EnvSerializeInfo>()\n");
  EnvSerializeInfo result;
  result.builtins = ReadVector<std::string>();
  result.async_hooks = Read<AsyncHooks::SerializeInfo>();
  result.tick_info = Read<TickInfo::SerializeInfo>();
  result.immediate_info = Read<ImmediateInfo::SerializeInfo>();
  result.performance_state =
      Read<performance::PerformanceState::SerializeInfo>();
  result.exiting = Read<AliasedBufferIndex>();
  result.stream_base_state = Read<AliasedBufferIndex>();
  result.should_abort_on_uncaught_toggle = Read<AliasedBufferIndex>();
  result.principal_realm = Read<RealmSerializeInfo>();
  return result;
}

template <>
size_t FileWriter::Write(const EnvSerializeInfo& data) {
  if (is_debug) {
    std::string str = ToStr(data);
    Debug("\nWrite<EnvSerializeInfo>() %s\n", str.c_str());
  }

  // Use += here to ensure order of evaluation.
  size_t written_total = WriteVector<std::string>(data.builtins);
  written_total += Write<AsyncHooks::SerializeInfo>(data.async_hooks);
  written_total += Write<TickInfo::SerializeInfo>(data.tick_info);
  written_total += Write<ImmediateInfo::SerializeInfo>(data.immediate_info);
  written_total += Write<performance::PerformanceState::SerializeInfo>(
      data.performance_state);
  written_total += Write<AliasedBufferIndex>(data.exiting);
  written_total += Write<AliasedBufferIndex>(data.stream_base_state);
  written_total +=
      Write<AliasedBufferIndex>(data.should_abort_on_uncaught_toggle);
  written_total += Write<RealmSerializeInfo>(data.principal_realm);

  Debug("Write<EnvSerializeInfo>() wrote %d bytes\n", written_total);
  return written_total;
}

// Layout of SnapshotMetadata
// [  1 byte   ]  type of the snapshot
// [ 4/8 bytes ]  length of the node version string
// [    ...    ]  |length| bytes of node version
// [ 4/8 bytes ]  length of the node arch string
// [    ...    ]  |length| bytes of node arch
// [ 4/8 bytes ]  length of the node platform string
// [    ...    ]  |length| bytes of node platform
// [  4 bytes  ]  v8 cache version tag
template <>
SnapshotMetadata FileReader::Read() {
  per_process::Debug(DebugCategory::MKSNAPSHOT, "Read<SnapshotMetadata>()\n");

  SnapshotMetadata result;
  result.type = static_cast<SnapshotMetadata::Type>(Read<uint8_t>());
  result.node_version = ReadString();
  result.node_arch = ReadString();
  result.node_platform = ReadString();
  result.v8_cache_version_tag = Read<uint32_t>();

  if (is_debug) {
    std::string str = ToStr(result);
    Debug("Read<SnapshotMetadata>() %s\n", str.c_str());
  }
  return result;
}

template <>
size_t FileWriter::Write(const SnapshotMetadata& data) {
  if (is_debug) {
    std::string str = ToStr(data);
    Debug("\nWrite<SnapshotMetadata>() %s\n", str.c_str());
  }
  size_t written_total = 0;
  // We need the Node.js version, platform and arch to match because
  // Node.js may perform synchronizations that are platform-specific and they
  // can be changed in semver-patches.
  Debug("Write snapshot type %" PRIu8 "\n", static_cast<uint8_t>(data.type));
  written_total += Write<uint8_t>(static_cast<uint8_t>(data.type));
  Debug("Write Node.js version %s\n", data.node_version.c_str());
  written_total += WriteString(data.node_version);
  Debug("Write Node.js arch %s\n", data.node_arch);
  written_total += WriteString(data.node_arch);
  Debug("Write Node.js platform %s\n", data.node_platform);
  written_total += WriteString(data.node_platform);
  Debug("Write V8 cached data version tag %" PRIx32 "\n",
        data.v8_cache_version_tag);
  written_total += Write<uint32_t>(data.v8_cache_version_tag);
  return written_total;
}

// Layout of the snapshot blob
// [   4 bytes    ]  kMagic
// [   4/8 bytes  ]  length of Node.js version string
// [    ...       ]  contents of Node.js version string
// [   4/8 bytes  ]  length of Node.js arch string
// [    ...       ]  contents of Node.js arch string
// [    ...       ]  v8_snapshot_blob_data from SnapshotCreator::CreateBlob()
// [    ...       ]  isolate_data_info
// [    ...       ]  env_info
// [    ...       ]  code_cache

void SnapshotData::ToBlob(FILE* out) const {
  FileWriter w(out);
  w.Debug("SnapshotData::ToBlob()\n");

  size_t written_total = 0;

  // Metadata
  w.Debug("Write magic %" PRIx32 "\n", kMagic);
  written_total += w.Write<uint32_t>(kMagic);
  w.Debug("Write metadata\n");
  written_total += w.Write<SnapshotMetadata>(metadata);

  written_total += w.Write<v8::StartupData>(v8_snapshot_blob_data);
  w.Debug("Write isolate_data_indices\n");
  written_total += w.Write<IsolateDataSerializeInfo>(isolate_data_info);
  written_total += w.Write<EnvSerializeInfo>(env_info);
  w.Debug("Write code_cache\n");
  written_total += w.WriteVector<builtins::CodeCacheInfo>(code_cache);
  w.Debug("SnapshotData::ToBlob() Wrote %d bytes\n", written_total);
}

bool SnapshotData::FromBlob(SnapshotData* out, FILE* in) {
  FileReader r(in);
  r.Debug("SnapshotData::FromBlob()\n");

  DCHECK_EQ(out->data_ownership, SnapshotData::DataOwnership::kOwned);

  // Metadata
  uint32_t magic = r.Read<uint32_t>();
  r.Debug("Read magic %" PRIx32 "\n", magic);
  CHECK_EQ(magic, kMagic);
  out->metadata = r.Read<SnapshotMetadata>();
  r.Debug("Read metadata\n");
  if (!out->Check()) {
    return false;
  }

  out->v8_snapshot_blob_data = r.Read<v8::StartupData>();
  r.Debug("Read isolate_data_info\n");
  out->isolate_data_info = r.Read<IsolateDataSerializeInfo>();
  out->env_info = r.Read<EnvSerializeInfo>();
  r.Debug("Read code_cache\n");
  out->code_cache = r.ReadVector<builtins::CodeCacheInfo>();

  r.Debug("SnapshotData::FromBlob() read %d bytes\n", r.read_total);
  return true;
}

bool SnapshotData::Check() const {
  if (metadata.node_version != per_process::metadata.versions.node) {
    fprintf(stderr,
            "Failed to load the startup snapshot because it was built with"
            "Node.js version %s and the current Node.js version is %s.\n",
            metadata.node_version.c_str(),
            NODE_VERSION);
    return false;
  }

  if (metadata.node_arch != per_process::metadata.arch) {
    fprintf(stderr,
            "Failed to load the startup snapshot because it was built with"
            "architecture %s and the architecture is %s.\n",
            metadata.node_arch.c_str(),
            NODE_ARCH);
    return false;
  }

  if (metadata.node_platform != per_process::metadata.platform) {
    fprintf(stderr,
            "Failed to load the startup snapshot because it was built with"
            "platform %s and the current platform is %s.\n",
            metadata.node_platform.c_str(),
            NODE_PLATFORM);
    return false;
  }

  uint32_t current_cache_version = v8::ScriptCompiler::CachedDataVersionTag();
  if (metadata.v8_cache_version_tag != current_cache_version &&
      metadata.type == SnapshotMetadata::Type::kFullyCustomized) {
    // For now we only do this check for the customized snapshots - we know
    // that the flags we use in the default snapshot are limited and safe
    // enough so we can relax the constraints for it.
    fprintf(stderr,
            "Failed to load the startup snapshot because it was built with "
            "a different version of V8 or with different V8 configurations.\n"
            "Expected tag %" PRIx32 ", read %" PRIx32 "\n",
            current_cache_version,
            metadata.v8_cache_version_tag);
    return false;
  }

  // TODO(joyeecheung): check incompatible Node.js flags.
  return true;
}

SnapshotData::~SnapshotData() {
  if (data_ownership == DataOwnership::kOwned &&
      v8_snapshot_blob_data.data != nullptr) {
    delete[] v8_snapshot_blob_data.data;
  }
}

template <typename T>
void WriteVector(std::ostream* ss, const T* vec, size_t size) {
  for (size_t i = 0; i < size; i++) {
    *ss << std::to_string(vec[i]) << (i == size - 1 ? '\n' : ',');
  }
}

static std::string GetCodeCacheDefName(const std::string& id) {
  char buf[64] = {0};
  size_t size = id.size();
  CHECK_LT(size, sizeof(buf));
  for (size_t i = 0; i < size; ++i) {
    char ch = id[i];
    buf[i] = (ch == '-' || ch == '/') ? '_' : ch;
  }
  return std::string(buf) + std::string("_cache_data");
}

static std::string FormatSize(size_t size) {
  char buf[64] = {0};
  if (size < 1024) {
    snprintf(buf, sizeof(buf), "%.2fB", static_cast<double>(size));
  } else if (size < 1024 * 1024) {
    snprintf(buf, sizeof(buf), "%.2fKB", static_cast<double>(size / 1024));
  } else {
    snprintf(
        buf, sizeof(buf), "%.2fMB", static_cast<double>(size / 1024 / 1024));
  }
  return buf;
}

static void WriteStaticCodeCacheData(std::ostream* ss,
                                     const builtins::CodeCacheInfo& info) {
  *ss << "static const uint8_t " << GetCodeCacheDefName(info.id) << "[] = {\n";
  WriteVector(ss, info.data.data(), info.data.size());
  *ss << "};";
}

static void WriteCodeCacheInitializer(std::ostream* ss, const std::string& id) {
  std::string def_name = GetCodeCacheDefName(id);
  *ss << "    { \"" << id << "\",\n";
  *ss << "      {" << def_name << ",\n";
  *ss << "       " << def_name << " + arraysize(" << def_name << "),\n";
  *ss << "      }\n";
  *ss << "    },\n";
}

void FormatBlob(std::ostream& ss, SnapshotData* data) {
  ss << R"(#include <cstddef>
#include "env.h"
#include "node_snapshot_builder.h"
#include "v8.h"

// This file is generated by tools/snapshot. Do not edit.

namespace node {

static const char v8_snapshot_blob_data[] = {
)";
  WriteVector(&ss,
              data->v8_snapshot_blob_data.data,
              data->v8_snapshot_blob_data.raw_size);
  ss << R"(};

static const int v8_snapshot_blob_size = )"
     << data->v8_snapshot_blob_data.raw_size << ";";

  // Windows can't deal with too many large vector initializers.
  // Store the data into static arrays first.
  for (const auto& item : data->code_cache) {
    WriteStaticCodeCacheData(&ss, item);
  }

  ss << R"(SnapshotData snapshot_data {
  // -- data_ownership begins --
  SnapshotData::DataOwnership::kNotOwned,
  // -- data_ownership ends --
  // -- metadata begins --
)" << data->metadata
     << R"(,
  // -- metadata ends --
  // -- v8_snapshot_blob_data begins --
  { v8_snapshot_blob_data, v8_snapshot_blob_size },
  // -- v8_snapshot_blob_data ends --
  // -- isolate_data_indices begins --
)" << data->isolate_data_info
     << R"(
  // -- isolate_data_indices ends --
  ,
  // -- env_info begins --
)" << data->env_info
     << R"(
  // -- env_info ends --
  ,
  // -- code_cache begins --
  {)";
  for (const auto& item : data->code_cache) {
    WriteCodeCacheInitializer(&ss, item.id);
  }
  ss << R"(
  }
  // -- code_cache ends --
};

const SnapshotData* SnapshotBuilder::GetEmbeddedSnapshotData() {
  Mutex::ScopedLock lock(snapshot_data_mutex_);
  return &snapshot_data;
}
}  // namespace node
)";
}

// Reset context settings that need to be initialized again after
// deserialization.
static void ResetContextSettingsBeforeSnapshot(Local<Context> context) {
  // Reset the AllowCodeGenerationFromStrings flag to true (default value) so
  // that it can be re-initialized with v8 flag
  // --disallow-code-generation-from-strings and recognized in
  // node::InitializeContextRuntime.
  context->AllowCodeGenerationFromStrings(true);
}

Mutex SnapshotBuilder::snapshot_data_mutex_;

const std::vector<intptr_t>& SnapshotBuilder::CollectExternalReferences() {
  static auto registry = std::make_unique<ExternalReferenceRegistry>();
  return registry->external_references();
}

void SnapshotBuilder::InitializeIsolateParams(const SnapshotData* data,
                                              Isolate::CreateParams* params) {
  params->external_references = CollectExternalReferences().data();
  params->snapshot_blob =
      const_cast<v8::StartupData*>(&(data->v8_snapshot_blob_data));
}

ExitCode SnapshotBuilder::Generate(SnapshotData* out,
                                   const std::vector<std::string> args,
                                   const std::vector<std::string> exec_args) {
  const std::vector<intptr_t>& external_references =
      CollectExternalReferences();
  Isolate* isolate = Isolate::Allocate();
  // Must be done before the SnapshotCreator creation so  that the
  // memory reducer can be initialized.
  per_process::v8_platform.Platform()->RegisterIsolate(isolate,
                                                       uv_default_loop());

  SnapshotCreator creator(isolate, external_references.data());

  isolate->SetCaptureStackTraceForUncaughtExceptions(
      true, 10, v8::StackTrace::StackTraceOptions::kDetailed);

  Environment* env = nullptr;
  std::unique_ptr<NodeMainInstance> main_instance =
      NodeMainInstance::Create(isolate,
                               uv_default_loop(),
                               per_process::v8_platform.Platform(),
                               args,
                               exec_args);

  // The cleanups should be done in case of an early exit due to errors.
  auto cleanup = OnScopeLeave([&]() {
    // Must be done while the snapshot creator isolate is entered i.e. the
    // creator is still alive. The snapshot creator destructor will destroy
    // the isolate.
    if (env != nullptr) {
      FreeEnvironment(env);
    }
    main_instance->Dispose();
    per_process::v8_platform.Platform()->UnregisterIsolate(isolate);
  });

  // It's only possible to be kDefault in node_mksnapshot.
  SnapshotMetadata::Type snapshot_type =
      per_process::cli_options->build_snapshot
          ? SnapshotMetadata::Type::kFullyCustomized
          : SnapshotMetadata::Type::kDefault;

  {
    HandleScope scope(isolate);
    TryCatch bootstrapCatch(isolate);

    auto print_Exception = OnScopeLeave([&]() {
      if (bootstrapCatch.HasCaught()) {
        PrintCaughtException(
            isolate, isolate->GetCurrentContext(), bootstrapCatch);
      }
    });

    // The default context with only things created by V8.
    Local<Context> default_context = Context::New(isolate);

    // The context used by the vm module.
    Local<Context> vm_context;
    {
      Local<ObjectTemplate> global_template =
          main_instance->isolate_data()->contextify_global_template();
      CHECK(!global_template.IsEmpty());
      if (!contextify::ContextifyContext::CreateV8Context(
               isolate, global_template, nullptr, nullptr)
               .ToLocal(&vm_context)) {
        return ExitCode::kStartupSnapshotFailure;
      }
    }

    // The Node.js-specific context with primodials, can be used by workers
    // TODO(joyeecheung): investigate if this can be used by vm contexts
    // without breaking compatibility.
    Local<Context> base_context = NewContext(isolate);
    if (base_context.IsEmpty()) {
      return ExitCode::kBootstrapFailure;
    }
    ResetContextSettingsBeforeSnapshot(base_context);

    Local<Context> main_context = NewContext(isolate);
    if (main_context.IsEmpty()) {
      return ExitCode::kBootstrapFailure;
    }
    // Initialize the main instance context.
    {
      Context::Scope context_scope(main_context);

      // Create the environment.
      env = new Environment(main_instance->isolate_data(),
                            main_context,
                            args,
                            exec_args,
                            nullptr,
                            node::EnvironmentFlags::kDefaultFlags,
                            {});

      // Run scripts in lib/internal/bootstrap/
      if (env->principal_realm()->RunBootstrapping().IsEmpty()) {
        return ExitCode::kBootstrapFailure;
      }
      // If --build-snapshot is true, lib/internal/main/mksnapshot.js would be
      // loaded via LoadEnvironment() to execute process.argv[1] as the entry
      // point (we currently only support this kind of entry point, but we
      // could also explore snapshotting other kinds of execution modes
      // in the future).
      if (snapshot_type == SnapshotMetadata::Type::kFullyCustomized) {
#if HAVE_INSPECTOR
        env->InitializeInspector({});
#endif
        if (LoadEnvironment(env, StartExecutionCallback{}).IsEmpty()) {
          return ExitCode::kGenericUserError;
        }
        // FIXME(joyeecheung): right now running the loop in the snapshot
        // builder seems to introduces inconsistencies in JS land that need to
        // be synchronized again after snapshot restoration.
        ExitCode exit_code =
            SpinEventLoopInternal(env).FromMaybe(ExitCode::kGenericUserError);
        if (exit_code != ExitCode::kNoFailure) {
          return exit_code;
        }
      }

      if (per_process::enabled_debug_list.enabled(DebugCategory::MKSNAPSHOT)) {
        env->ForEachRealm([](Realm* realm) { realm->PrintInfoForSnapshot(); });
        printf("Environment = %p\n", env);
      }

      // Serialize the native states
      out->isolate_data_info =
          main_instance->isolate_data()->Serialize(&creator);
      out->env_info = env->Serialize(&creator);

#ifdef NODE_USE_NODE_CODE_CACHE
      // Regenerate all the code cache.
      if (!builtins::BuiltinLoader::CompileAllBuiltins(main_context)) {
        return ExitCode::kGenericUserError;
      }
      builtins::BuiltinLoader::CopyCodeCache(&(out->code_cache));
      for (const auto& item : out->code_cache) {
        std::string size_str = FormatSize(item.data.size());
        per_process::Debug(DebugCategory::MKSNAPSHOT,
                           "Generated code cache for %d: %s\n",
                           item.id.c_str(),
                           size_str.c_str());
      }
#endif

      ResetContextSettingsBeforeSnapshot(main_context);
    }

    // Global handles to the contexts can't be disposed before the
    // blob is created. So initialize all the contexts before adding them.
    // TODO(joyeecheung): figure out how to remove this restriction.
    creator.SetDefaultContext(default_context);
    size_t index = creator.AddContext(vm_context);
    CHECK_EQ(index, SnapshotData::kNodeVMContextIndex);
    index = creator.AddContext(base_context);
    CHECK_EQ(index, SnapshotData::kNodeBaseContextIndex);
    index = creator.AddContext(main_context,
                               {SerializeNodeContextInternalFields, env});
    CHECK_EQ(index, SnapshotData::kNodeMainContextIndex);
  }

  // Must be out of HandleScope
  out->v8_snapshot_blob_data =
      creator.CreateBlob(SnapshotCreator::FunctionCodeHandling::kKeep);

  // We must be able to rehash the blob when we restore it or otherwise
  // the hash seed would be fixed by V8, introducing a vulnerability.
  if (!out->v8_snapshot_blob_data.CanBeRehashed()) {
    return ExitCode::kStartupSnapshotFailure;
  }

  out->metadata = SnapshotMetadata{snapshot_type,
                                   per_process::metadata.versions.node,
                                   per_process::metadata.arch,
                                   per_process::metadata.platform,
                                   v8::ScriptCompiler::CachedDataVersionTag()};

  // We cannot resurrect the handles from the snapshot, so make sure that
  // no handles are left open in the environment after the blob is created
  // (which should trigger a GC and close all handles that can be closed).
  bool queues_are_empty =
      env->req_wrap_queue()->IsEmpty() && env->handle_wrap_queue()->IsEmpty();
  if (!queues_are_empty ||
      per_process::enabled_debug_list.enabled(DebugCategory::MKSNAPSHOT)) {
    PrintLibuvHandleInformation(env->event_loop(), stderr);
  }
  if (!queues_are_empty) {
    return ExitCode::kStartupSnapshotFailure;
  }
  return ExitCode::kNoFailure;
}

ExitCode SnapshotBuilder::Generate(std::ostream& out,
                                   const std::vector<std::string> args,
                                   const std::vector<std::string> exec_args) {
  SnapshotData data;
  ExitCode exit_code = Generate(&data, args, exec_args);
  if (exit_code != ExitCode::kNoFailure) {
    return exit_code;
  }
  FormatBlob(out, &data);
  return exit_code;
}

SnapshotableObject::SnapshotableObject(Environment* env,
                                       Local<Object> wrap,
                                       EmbedderObjectType type)
    : BaseObject(env, wrap), type_(type) {
}

const char* SnapshotableObject::GetTypeNameChars() const {
  switch (type_) {
#define V(PropertyName, NativeTypeName)                                        \
  case EmbedderObjectType::k_##PropertyName: {                                 \
    return NativeTypeName::type_name.c_str();                                  \
  }
    SERIALIZABLE_OBJECT_TYPES(V)
#undef V
    default: { UNREACHABLE(); }
  }
}

void DeserializeNodeInternalFields(Local<Object> holder,
                                   int index,
                                   StartupData payload,
                                   void* env) {
  if (payload.raw_size == 0) {
    holder->SetAlignedPointerInInternalField(index, nullptr);
    return;
  }
  per_process::Debug(DebugCategory::MKSNAPSHOT,
                     "Deserialize internal field %d of %p, size=%d\n",
                     static_cast<int>(index),
                     (*holder),
                     static_cast<int>(payload.raw_size));

  if (payload.raw_size == 0) {
    holder->SetAlignedPointerInInternalField(index, nullptr);
    return;
  }

  DCHECK_EQ(index, BaseObject::kEmbedderType);

  Environment* env_ptr = static_cast<Environment*>(env);
  const InternalFieldInfoBase* info =
      reinterpret_cast<const InternalFieldInfoBase*>(payload.data);
  // TODO(joyeecheung): we can add a constant kNodeEmbedderId to the
  // beginning of every InternalFieldInfoBase to ensure that we don't
  // step on payloads that were not serialized by Node.js.
  switch (info->type) {
#define V(PropertyName, NativeTypeName)                                        \
  case EmbedderObjectType::k_##PropertyName: {                                 \
    per_process::Debug(DebugCategory::MKSNAPSHOT,                              \
                       "Object %p is %s\n",                                    \
                       (*holder),                                              \
                       NativeTypeName::type_name.c_str());                     \
    env_ptr->EnqueueDeserializeRequest(                                        \
        NativeTypeName::Deserialize,                                           \
        holder,                                                                \
        index,                                                                 \
        info->Copy<NativeTypeName::InternalFieldInfo>());                      \
    break;                                                                     \
  }
    SERIALIZABLE_OBJECT_TYPES(V)
#undef V
    default: {
      // This should only be reachable during development when trying to
      // deserialize a snapshot blob built by a version of Node.js that
      // has more recognizable EmbedderObjectTypes than the deserializing
      // Node.js binary.
      fprintf(stderr,
              "Unknown embedder object type %" PRIu8 ", possibly caused by "
              "mismatched Node.js versions\n",
              static_cast<uint8_t>(info->type));
      ABORT();
    }
  }
}

StartupData SerializeNodeContextInternalFields(Local<Object> holder,
                                               int index,
                                               void* env) {
  // We only do one serialization for the kEmbedderType slot, the result
  // contains everything necessary for deserializing the entire object,
  // including the fields whose index is bigger than kEmbedderType
  // (most importantly, BaseObject::kSlot).
  // For Node.js this design is enough for all the native binding that are
  // serializable.
  if (index != BaseObject::kEmbedderType) {
    return StartupData{nullptr, 0};
  }

  void* type_ptr = holder->GetAlignedPointerFromInternalField(index);
  if (type_ptr == nullptr) {
    return StartupData{nullptr, 0};
  }

  uint16_t type = *(static_cast<uint16_t*>(type_ptr));
  per_process::Debug(DebugCategory::MKSNAPSHOT, "type = 0x%x\n", type);
  if (type != kNodeEmbedderId) {
    return StartupData{nullptr, 0};
  }

  per_process::Debug(DebugCategory::MKSNAPSHOT,
                     "Serialize internal field, index=%d, holder=%p\n",
                     static_cast<int>(index),
                     *holder);

  void* native_ptr =
      holder->GetAlignedPointerFromInternalField(BaseObject::kSlot);
  per_process::Debug(DebugCategory::MKSNAPSHOT, "native = %p\n", native_ptr);
  DCHECK(static_cast<BaseObject*>(native_ptr)->is_snapshotable());
  SnapshotableObject* obj = static_cast<SnapshotableObject*>(native_ptr);

  per_process::Debug(DebugCategory::MKSNAPSHOT,
                     "Object %p is %s, ",
                     *holder,
                     obj->GetTypeNameChars());
  InternalFieldInfoBase* info = obj->Serialize(index);

  per_process::Debug(DebugCategory::MKSNAPSHOT,
                     "payload size=%d\n",
                     static_cast<int>(info->length));
  return StartupData{reinterpret_cast<const char*>(info),
                     static_cast<int>(info->length)};
}

void SerializeSnapshotableObjects(Realm* realm,
                                  SnapshotCreator* creator,
                                  RealmSerializeInfo* info) {
  HandleScope scope(realm->isolate());
  Local<Context> context = realm->context();
  uint32_t i = 0;
  realm->ForEachBaseObject([&](BaseObject* obj) {
    // If there are any BaseObjects that are not snapshotable left
    // during context serialization, V8 would crash due to unregistered
    // global handles and print detailed information about them.
    if (!obj->is_snapshotable()) {
      return;
    }
    SnapshotableObject* ptr = static_cast<SnapshotableObject*>(obj);

    const char* type_name = ptr->GetTypeNameChars();
    per_process::Debug(DebugCategory::MKSNAPSHOT,
                       "Serialize snapshotable object %i (%p), "
                       "object=%p, type=%s\n",
                       static_cast<int>(i),
                       ptr,
                       *(ptr->object()),
                       type_name);

    if (ptr->PrepareForSerialization(context, creator)) {
      SnapshotIndex index = creator->AddData(context, obj->object());
      per_process::Debug(DebugCategory::MKSNAPSHOT,
                         "Serialized with index=%d\n",
                         static_cast<int>(index));
      info->native_objects.push_back({type_name, i, index});
    }
    i++;
  });
}

namespace mksnapshot {

void CompileSerializeMain(const FunctionCallbackInfo<Value>& args) {
  CHECK(args[0]->IsString());
  Local<String> filename = args[0].As<String>();
  Local<String> source = args[1].As<String>();
  Isolate* isolate = args.GetIsolate();
  Local<Context> context = isolate->GetCurrentContext();
  ScriptOrigin origin(isolate, filename, 0, 0, true);
  // TODO(joyeecheung): do we need all of these? Maybe we would want a less
  // internal version of them.
  std::vector<Local<String>> parameters = {
      FIXED_ONE_BYTE_STRING(isolate, "require"),
      FIXED_ONE_BYTE_STRING(isolate, "__filename"),
      FIXED_ONE_BYTE_STRING(isolate, "__dirname"),
  };
  ScriptCompiler::Source script_source(source, origin);
  Local<Function> fn;
  if (ScriptCompiler::CompileFunction(context,
                                      &script_source,
                                      parameters.size(),
                                      parameters.data(),
                                      0,
                                      nullptr,
                                      ScriptCompiler::kEagerCompile)
          .ToLocal(&fn)) {
    args.GetReturnValue().Set(fn);
  }
}

void SetSerializeCallback(const FunctionCallbackInfo<Value>& args) {
  Environment* env = Environment::GetCurrent(args);
  CHECK(env->snapshot_serialize_callback().IsEmpty());
  CHECK(args[0]->IsFunction());
  env->set_snapshot_serialize_callback(args[0].As<Function>());
}

void SetDeserializeCallback(const FunctionCallbackInfo<Value>& args) {
  Environment* env = Environment::GetCurrent(args);
  CHECK(env->snapshot_deserialize_callback().IsEmpty());
  CHECK(args[0]->IsFunction());
  env->set_snapshot_deserialize_callback(args[0].As<Function>());
}

void SetDeserializeMainFunction(const FunctionCallbackInfo<Value>& args) {
  Environment* env = Environment::GetCurrent(args);
  CHECK(env->snapshot_deserialize_main().IsEmpty());
  CHECK(args[0]->IsFunction());
  env->set_snapshot_deserialize_main(args[0].As<Function>());
}

void Initialize(Local<Object> target,
                Local<Value> unused,
                Local<Context> context,
                void* priv) {
  SetMethod(context, target, "compileSerializeMain", CompileSerializeMain);
  SetMethod(context, target, "setSerializeCallback", SetSerializeCallback);
  SetMethod(context, target, "setDeserializeCallback", SetDeserializeCallback);
  SetMethod(context,
            target,
            "setDeserializeMainFunction",
            SetDeserializeMainFunction);
}

void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
  registry->Register(CompileSerializeMain);
  registry->Register(SetSerializeCallback);
  registry->Register(SetDeserializeCallback);
  registry->Register(SetDeserializeMainFunction);
}
}  // namespace mksnapshot
}  // namespace node

NODE_MODULE_CONTEXT_AWARE_INTERNAL(mksnapshot, node::mksnapshot::Initialize)
NODE_MODULE_EXTERNAL_REFERENCE(mksnapshot,
                               node::mksnapshot::RegisterExternalReferences)
