0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-10-31 09:14:20 -04:00
denoland-deno/deno2/snapshot_creator.cc
2018-06-10 14:18:15 +02:00

143 lines
4 KiB
C++

// 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_internal.h"
#include "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];
auto js_data = ReadFile(js_fn);
auto natives_blob = ReadFile(natives_in_bin);
auto snapshot_in_blob = ReadFile(snapshot_in_bin);
deno_init();
auto snapshot_blob =
deno::MakeSnapshot(&natives_blob, &snapshot_in_blob, 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();
}