diff --git a/deno2/BUILD.gn b/deno2/BUILD.gn index d90cd9de13..37b9f85c69 100644 --- a/deno2/BUILD.gn +++ b/deno2/BUILD.gn @@ -44,6 +44,8 @@ source_set("deno_nosnapshot") { sources = [ "deno.cc", "deno_internal.h", + "file_util.cc", + "file_util.h", "include/deno.h", ] include_dirs = [ "include/" ] diff --git a/deno2/file_util.cc b/deno2/file_util.cc new file mode 100644 index 0000000000..e2c1b30496 --- /dev/null +++ b/deno2/file_util.cc @@ -0,0 +1,98 @@ +// Copyright 2018 Ryan Dahl +// All rights reserved. MIT License. +#include +#include +#include +#include + +#include "file_util.h" + +namespace deno { + +bool ReadFileToString(const char* fn, std::string* contents) { + std::ifstream file(fn, std::ios::binary); + contents->assign(std::istreambuf_iterator{file}, {}); + return !file.bad(); +} + +class StartupDataCppWriter { + public: + StartupDataCppWriter(const char* name, const char* filename, + const std::string& data) + : name_(name), + filename_(filename), + data_(data), + file_(filename_, std::ios::binary) {} + + bool Write() { + if (file_.bad()) { + return false; + } + WritePrefix(); + WriteData(); + WriteSuffix(); + + file_.close(); + // printf("Wrote %s %d %s \n", name_, data_.size(), filename_); + return !file_.bad(); + } + + private: + void WritePrefix() { + file_ << "// Autogenerated snapshot file. Do not edit.\n\n"; + file_ << "#include \"v8/include/v8.h\"\n\n"; + } + + void WriteSuffix() { + char buffer[500]; + snprintf(buffer, sizeof(buffer), + "const v8::StartupData* StartupBlob_%s() {\n", name_); + file_ << buffer; + snprintf(buffer, sizeof(buffer), " return &%s_blob;\n", name_); + file_ << buffer; + file_ << "}\n\n"; + } + + void WriteBinaryContentsAsCArray() { + char buffer[5]; + for (size_t i = 0; i < data_.size(); i++) { + if ((i & 0x1F) == 0x1F) file_ << "\n"; + if (i > 0) file_ << ","; + snprintf(buffer, sizeof(buffer), "%u", + static_cast(data_.at(i))); + file_ << buffer; + } + file_ << "\n"; + } + + void WriteData() { + char buffer[500]; + snprintf(buffer, sizeof(buffer), "static const char %s_blob_data[] = {\n", + name_); + file_ << buffer; + WriteBinaryContentsAsCArray(); + file_ << "};\n"; + snprintf(buffer, sizeof(buffer), "static const int %s_blob_size = %ld;\n", + name_, data_.size()); + file_ << buffer; + snprintf(buffer, sizeof(buffer), "static const v8::StartupData %s_blob =\n", + name_); + file_ << buffer; + snprintf(buffer, sizeof(buffer), + "{ (const char*) %s_blob_data, %s_blob_size };\n", name_, name_); + file_ << buffer; + } + + const char* name_; + const char* filename_; + std::string data_; + std::ofstream file_; +}; + +bool WriteDataAsCpp(const char* name, const char* filename, + const std::string& data) { + StartupDataCppWriter writer(name, filename, data); + return writer.Write(); +} + +} // namespace deno diff --git a/deno2/file_util.h b/deno2/file_util.h new file mode 100644 index 0000000000..87e39299d5 --- /dev/null +++ b/deno2/file_util.h @@ -0,0 +1,14 @@ +// Copyright 2018 Ryan Dahl +// All rights reserved. MIT License. +#ifndef FILE_UTIL_H_ +#define FILE_UTIL_H_ + +#include + +namespace deno { +bool WriteDataAsCpp(const char* name, const char* filename, + const std::string& data); +bool ReadFileToString(const char* fn, std::string* contents); +} // namespace deno + +#endif // FILE_UTIL_H_ diff --git a/deno2/snapshot_creator.cc b/deno2/snapshot_creator.cc index 10ddc15002..481c657cc6 100644 --- a/deno2/snapshot_creator.cc +++ b/deno2/snapshot_creator.cc @@ -1,148 +1,47 @@ // Copyright 2018 Ryan Dahl // All rights reserved. MIT License. // Hint: --trace_serializer is a useful debugging flag. -#include -#include -#include -#include -#include -#include - -#include "v8/include/v8.h" - -#include "./deno_internal.h" +#include "deno_internal.h" +#include "file_util.h" #include "include/deno.h" +#include "v8/include/v8.h" +#include "v8/src/base/logging.h" -class StartupDataCppWriter { - public: - StartupDataCppWriter(const char* name, const char* filename, - v8::StartupData sd) - : name_(name), - filename_(filename), - sd_(sd), - file_(filename_, std::ios::binary) {} - - void Write() { - WritePrefix(); - WriteData(); - WriteSuffix(); - - file_.close(); - if (file_.bad()) { - printf("Unable to open file \"%s\" for writing.\n", filename_); - exit(1); - } - // printf("Wrote %s %d %s \n", name_, sd_.raw_size, filename_); - } - - private: - void WritePrefix() { - file_ << "// Autogenerated snapshot file. Do not edit.\n\n"; - file_ << "#include \"v8/include/v8.h\"\n\n"; - } - - void WriteSuffix() { - char buffer[500]; - snprintf(buffer, sizeof(buffer), - "const v8::StartupData* StartupBlob_%s() {\n", name_); - file_ << buffer; - snprintf(buffer, sizeof(buffer), " return &%s_blob;\n", name_); - file_ << buffer; - file_ << "}\n\n"; - } - - void WriteBinaryContentsAsCArray() { - char buffer[5]; - for (int i = 0; i < sd_.raw_size; i++) { - if ((i & 0x1F) == 0x1F) file_ << "\n"; - if (i > 0) file_ << ","; - snprintf(buffer, sizeof(buffer), "%u", - static_cast(sd_.data[i])); - file_ << buffer; - } - file_ << "\n"; - } - - void WriteData() { - char buffer[500]; - snprintf(buffer, sizeof(buffer), "static const char %s_blob_data[] = {\n", - name_); - file_ << buffer; - WriteBinaryContentsAsCArray(); - file_ << "};\n"; - snprintf(buffer, sizeof(buffer), "static const int %s_blob_size = %d;\n", - name_, sd_.raw_size); - file_ << buffer; - snprintf(buffer, sizeof(buffer), "static const v8::StartupData %s_blob =\n", - name_); - file_ << buffer; - snprintf(buffer, sizeof(buffer), - "{ (const char*) %s_blob_data, %s_blob_size };\n", name_, name_); - file_ << buffer; - } - - const char* name_; - const char* filename_; - v8::StartupData sd_; - std::ofstream file_; -}; - -// Caller must free returned value. -static v8::StartupData ReadFile(const char* fn) { - std::ifstream input(fn, std::ios::binary); - if (input.bad()) { - printf("Error reading %s\n", fn); - exit(1); - } - // Note the allocated buffer is intentionally not freed in this program. - // It may show up as a memory leak some day, but other than that it's - // harmless. - auto* buffer = new std::vector((std::istreambuf_iterator(input)), - (std::istreambuf_iterator())); - v8::StartupData sd; - sd.data = buffer->data(); - sd.raw_size = static_cast(buffer->size()); - if (input.bad()) { - printf("Error reading %s\n", fn); - exit(1); - } - return sd; -} - -void WriteFile(const char* fn, v8::StartupData startup_data) { - std::ofstream output(fn, std::ios::binary); - output.write(startup_data.data, startup_data.raw_size); - output.close(); - if (output.bad()) { - printf("Error writing %s\n", fn); - exit(1); - } +v8::StartupData StringToStartupData(const std::string& s) { + return v8::StartupData{s.c_str(), s.size()}; } int main(int argc, char** argv) { - // The only documentation for this programs arguments is right here. const char* js_fn = argv[1]; const char* natives_in_bin = argv[2]; const char* snapshot_in_bin = argv[3]; const char* natives_out_cc = argv[4]; const char* snapshot_out_cc = argv[5]; + CHECK_NE(js_fn, nullptr); + CHECK_NE(natives_in_bin, nullptr); + CHECK_NE(snapshot_in_bin, nullptr); + CHECK_NE(natives_out_cc, nullptr); + CHECK_NE(snapshot_out_cc, nullptr); + v8::V8::SetFlagsFromCommandLine(&argc, argv, true); - auto js_data = ReadFile(js_fn); - // Ensure js_source is null-terminated. - std::string js_source(js_data.data, js_data.raw_size); - auto natives_blob = ReadFile(natives_in_bin); - auto snapshot_in_blob = ReadFile(snapshot_in_bin); + std::string js_source; + CHECK(deno::ReadFileToString(js_fn, &js_source)); + + std::string natives_str; + CHECK(deno::ReadFileToString(natives_in_bin, &natives_str)); + auto natives_blob = StringToStartupData(natives_str); + + std::string snapshot_in_str; + CHECK(deno::ReadFileToString(snapshot_in_bin, &snapshot_in_str)); + auto snapshot_in_blob = StringToStartupData(snapshot_in_str); deno_init(); auto snapshot_blob = deno::MakeSnapshot(&natives_blob, &snapshot_in_blob, js_fn, js_source.c_str()); + std::string snapshot_str(snapshot_blob.data, snapshot_blob.raw_size); - StartupDataCppWriter nativesWriter("natives", natives_out_cc, natives_blob); - nativesWriter.Write(); - - StartupDataCppWriter snapshotWriter("snapshot", snapshot_out_cc, - snapshot_blob); - snapshotWriter.Write(); + CHECK(deno::WriteDataAsCpp("natives", natives_out_cc, natives_str)); + CHECK(deno::WriteDataAsCpp("snapshot", snapshot_out_cc, snapshot_str)); }