2018-06-09 18:32:04 -04:00
|
|
|
// Copyright 2018 Ryan Dahl <ry@tinyclouds.org>
|
|
|
|
// All rights reserved. MIT License.
|
2018-06-12 00:36:01 -04:00
|
|
|
// Hint: --trace_serializer is a useful debugging flag.
|
2018-06-09 18:32:04 -04:00
|
|
|
#include <assert.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <fstream>
|
|
|
|
#include <iterator>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include "v8/include/v8.h"
|
|
|
|
|
2018-06-10 07:17:04 -04:00
|
|
|
#include "./deno_internal.h"
|
2018-06-10 08:18:15 -04:00
|
|
|
#include "include/deno.h"
|
2018-06-09 18:32:04 -04:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
2018-06-10 08:34:59 -04:00
|
|
|
// printf("Wrote %s %d %s \n", name_, sd_.raw_size, filename_);
|
2018-06-09 18:32:04 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
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];
|
|
|
|
|
2018-06-12 00:36:01 -04:00
|
|
|
v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
|
|
|
|
|
2018-06-09 18:32:04 -04:00
|
|
|
auto js_data = ReadFile(js_fn);
|
2018-06-12 16:05:49 -04:00
|
|
|
// Ensure js_source is null-terminated.
|
|
|
|
std::string js_source(js_data.data, js_data.raw_size);
|
2018-06-09 18:32:04 -04:00
|
|
|
auto natives_blob = ReadFile(natives_in_bin);
|
|
|
|
auto snapshot_in_blob = ReadFile(snapshot_in_bin);
|
|
|
|
|
2018-06-10 08:18:15 -04:00
|
|
|
deno_init();
|
|
|
|
auto snapshot_blob =
|
2018-06-12 16:05:49 -04:00
|
|
|
deno::MakeSnapshot(&natives_blob, &snapshot_in_blob, js_fn, js_source.c_str());
|
2018-06-09 18:32:04 -04:00
|
|
|
|
|
|
|
StartupDataCppWriter nativesWriter("natives", natives_out_cc, natives_blob);
|
|
|
|
nativesWriter.Write();
|
|
|
|
|
|
|
|
StartupDataCppWriter snapshotWriter("snapshot", snapshot_out_cc,
|
|
|
|
snapshot_blob);
|
|
|
|
snapshotWriter.Write();
|
|
|
|
}
|