summaryrefslogtreecommitdiff
path: root/deno2/snapshot_creator.cc
diff options
context:
space:
mode:
authorRyan Dahl <ry@tinyclouds.org>2018-06-10 00:32:04 +0200
committerRyan Dahl <ry@tinyclouds.org>2018-06-10 01:02:08 +0200
commit110ddab670cbf477488cceeea2842c980942d7b8 (patch)
tree6bc1e6dd42f01b98f302e97b4dd4dbb3a7be700d /deno2/snapshot_creator.cc
parentfe9ea6dcf8f57cff5c3856a5d54e8f9c8236a924 (diff)
Add deno2 prototype from external repo.
Diffstat (limited to 'deno2/snapshot_creator.cc')
-rw-r--r--deno2/snapshot_creator.cc145
1 files changed, 145 insertions, 0 deletions
diff --git a/deno2/snapshot_creator.cc b/deno2/snapshot_creator.cc
new file mode 100644
index 000000000..4001abe6e
--- /dev/null
+++ b/deno2/snapshot_creator.cc
@@ -0,0 +1,145 @@
+// Copyright 2018 Ryan Dahl <ry@tinyclouds.org>
+// All rights reserved. MIT License.
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <fstream>
+#include <iterator>
+#include <vector>
+
+#include "v8/include/v8.h"
+
+#include "./deno.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<unsigned char>(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<char>((std::istreambuf_iterator<char>(input)),
+ (std::istreambuf_iterator<char>()));
+ v8::StartupData sd;
+ sd.data = buffer->data();
+ sd.raw_size = static_cast<int>(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);
+ }
+}
+
+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];
+
+ v8_init();
+
+ auto js_data = ReadFile(js_fn);
+ auto natives_blob = ReadFile(natives_in_bin);
+ auto snapshot_in_blob = ReadFile(snapshot_in_bin);
+
+ v8::V8::SetNativesDataBlob(&natives_blob);
+ v8::V8::SetSnapshotDataBlob(&snapshot_in_blob);
+
+ auto snapshot_blob = deno_make_snapshot(js_fn, js_data.data);
+
+ StartupDataCppWriter nativesWriter("natives", natives_out_cc, natives_blob);
+ nativesWriter.Write();
+
+ StartupDataCppWriter snapshotWriter("snapshot", snapshot_out_cc,
+ snapshot_blob);
+ snapshotWriter.Write();
+}